mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-01-11 15:27:07 +00:00
Re-implemented treasure dig handling
This commit is contained in:
parent
5b738dfc58
commit
a99f7a7fc1
@ -80,17 +80,17 @@ PetComponent::PetComponent(Entity* parent, uint32_t componentId): Component(pare
|
||||
m_ModelId = LWOOBJID_EMPTY;
|
||||
m_Timer = 0;
|
||||
m_TimerAway = 0;
|
||||
m_TimerBounce = 0;
|
||||
m_DatabaseId = LWOOBJID_EMPTY;
|
||||
m_Status = PetStatus::TAMEABLE; // Tameable
|
||||
m_Ability = PetAbilityType::Invalid;
|
||||
m_StartPosition = m_Parent->GetPosition(); //NiPoint3::ZERO;
|
||||
m_MovementAI = nullptr;
|
||||
m_TresureTime = 0;
|
||||
m_Preconditions = nullptr;
|
||||
|
||||
m_ReadyToDig = false;
|
||||
m_ReadyToInteract = false;
|
||||
SetPetAiState(PetAiState::spawn);
|
||||
m_FollowRadius = 5.0f;
|
||||
//m_FollowRadius = 8.0f;
|
||||
|
||||
std::string checkPreconditions = GeneralUtils::UTF16ToWTF8(parent->GetVar<std::u16string>(u"CheckPrecondition"));
|
||||
|
||||
@ -160,7 +160,6 @@ void PetComponent::SetPetAiState(PetAiState newState) {
|
||||
if (newState == GetPetAiState()) return;
|
||||
this->m_State = newState;
|
||||
LOG_DEBUG("Set pet AI state!");
|
||||
//Game::entityManager->SerializeEntity(m_Parent); // Do we need to serialize entity?
|
||||
}
|
||||
|
||||
void PetComponent::OnUse(Entity* originator) {
|
||||
@ -341,16 +340,24 @@ void PetComponent::Update(float deltaTime) {
|
||||
return;
|
||||
}*/
|
||||
|
||||
if (m_StartPosition == NiPoint3::ZERO) {
|
||||
m_StartPosition = m_Parent->GetPosition();
|
||||
}
|
||||
// Update timers
|
||||
m_TimerBounce -= deltaTime;
|
||||
|
||||
// Update timer
|
||||
if (m_Timer > 0) {
|
||||
m_Timer -= deltaTime;
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove "left behind" pets
|
||||
if (m_Owner != LWOOBJID_EMPTY) {
|
||||
Entity* owner = GetOwner();
|
||||
if (!owner) {
|
||||
m_Parent->Kill();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle pet AI states
|
||||
switch (m_State) {
|
||||
case PetAiState::spawn:
|
||||
LOG_DEBUG("Pet spawn beginning!");
|
||||
@ -468,7 +475,7 @@ skipTresure:
|
||||
m_Timer = 1;*/
|
||||
}
|
||||
|
||||
void PetComponent::UpdateUnowned(float deltaTime) { //CURRENTLY UNUSED
|
||||
void PetComponent::UpdateUnowned(float deltaTime) { //TODO: CURRENTLY UNUSED
|
||||
if (m_Tamer != LWOOBJID_EMPTY) {
|
||||
if (m_Timer > 0) {
|
||||
m_Timer -= deltaTime;
|
||||
@ -491,7 +498,7 @@ void PetComponent::UpdateUnowned(float deltaTime) { //CURRENTLY UNUSED
|
||||
}
|
||||
}
|
||||
|
||||
void PetComponent::SetIsReadyToDig(bool isReady) {
|
||||
/*void PetComponent::SetIsReadyToDig(bool isReady) {
|
||||
if (isReady) {
|
||||
LOG("Dig state reached!");
|
||||
//m_Interaction = closestTresure->GetObjectID();
|
||||
@ -508,33 +515,7 @@ void PetComponent::SetIsReadyToDig(bool isReady) {
|
||||
m_ReadyToDig = false;
|
||||
Game::entityManager->SerializeEntity(m_Parent);
|
||||
}
|
||||
}
|
||||
|
||||
void PetComponent::InteractDig(float deltaTime) {
|
||||
LOG("Pet digging!");
|
||||
|
||||
auto* tresure = Game::entityManager->GetEntity(m_Interaction);
|
||||
|
||||
if (tresure == nullptr) {
|
||||
m_TresureTime = 0.0f;
|
||||
return;
|
||||
}
|
||||
|
||||
m_TresureTime -= deltaTime;
|
||||
|
||||
m_MovementAI->Stop();
|
||||
|
||||
if (m_TresureTime <= 0.0f) {
|
||||
m_Parent->SetOwnerOverride(m_Owner);
|
||||
|
||||
tresure->Smash(m_Parent->GetObjectID());
|
||||
|
||||
LOG("Pet dig completed!");
|
||||
m_Interaction = LWOOBJID_EMPTY;
|
||||
m_TresureTime = 0.0f;
|
||||
SetIsReadyToDig(false);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
void PetComponent::TryBuild(uint32_t numBricks, bool clientFailed) {
|
||||
if (m_Tamer == LWOOBJID_EMPTY) return;
|
||||
@ -856,9 +837,9 @@ void PetComponent::ClientFailTamingMinigame() {
|
||||
}
|
||||
|
||||
void PetComponent::Wander() {
|
||||
m_MovementAI = m_Parent->GetComponent<MovementAIComponent>();
|
||||
//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);
|
||||
|
||||
@ -889,48 +870,48 @@ void PetComponent::Wander() {
|
||||
return;
|
||||
}
|
||||
|
||||
m_MovementAI->SetMaxSpeed(info.wanderSpeed);
|
||||
m_MovementAI->SetMaxSpeed(m_SprintSpeed); //info.wanderSpeed);
|
||||
|
||||
m_MovementAI->SetDestination(destination);
|
||||
|
||||
m_Timer += (m_MovementAI->GetParent()->GetPosition().x - destination.x) / info.wanderSpeed;
|
||||
m_Timer += (m_MovementAI->GetParent()->GetPosition().x - destination.x) / m_SprintSpeed; //info.wanderSpeed;
|
||||
}
|
||||
|
||||
void PetComponent::OnSpawn() {
|
||||
m_MovementAI = m_Parent->GetComponent<MovementAIComponent>();
|
||||
if (!m_MovementAI) return;
|
||||
//if (!m_MovementAI) return;
|
||||
|
||||
if (m_StartPosition == NiPoint3::ZERO) {
|
||||
m_StartPosition = m_Parent->GetPosition();
|
||||
}
|
||||
|
||||
LOG_DEBUG("Pet spawn complete, setting AI state.");
|
||||
|
||||
if (m_Owner != LWOOBJID_EMPTY) SetPetAiState(PetAiState::follow);
|
||||
else SetPetAiState(PetAiState::idle);
|
||||
if (m_Owner != LWOOBJID_EMPTY) {
|
||||
m_Parent->SetOwnerOverride(m_Owner);
|
||||
m_MovementAI->SetMaxSpeed(m_SprintSpeed);
|
||||
m_MovementAI->SetHaltDistance(m_FollowRadius);
|
||||
SetStatus(PetStatus::NONE);
|
||||
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 (!owner) return;
|
||||
const NiPoint3 ownerPos = owner->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
|
||||
// Find interactions
|
||||
SwitchComponent* closestSwitch = SwitchComponent::GetClosestSwitch(ownerPos);
|
||||
if (closestSwitch != nullptr && !closestSwitch->GetActive()) {
|
||||
NiPoint3 switchPos = closestSwitch->GetParentEntity()->GetPosition();
|
||||
const NiPoint3 switchPos = closestSwitch->GetParentEntity()->GetPosition();
|
||||
const LWOOBJID switchID = closestSwitch->GetParentEntity()->GetObjectID();
|
||||
const float distance = Vector3::DistanceSquared(ownerPos, switchPos);
|
||||
if (distance < 20 * 20) {
|
||||
StartInteract(switchPos, PetInteractType::bouncer);
|
||||
if (distance < 16 * 16) {
|
||||
StartInteract(switchPos, PetInteractType::bouncer, switchID);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -942,22 +923,36 @@ void PetComponent::OnFollow() {
|
||||
|
||||
Entity* closestTreasure = PetDigServer::GetClosestTresure(ownerPos);
|
||||
if (closestTreasure != nullptr && digUnlocked) {
|
||||
NiPoint3 treasurePos = closestTreasure->GetPosition();
|
||||
const NiPoint3 treasurePos = closestTreasure->GetPosition();
|
||||
const LWOOBJID treasureID = closestTreasure->GetObjectID();
|
||||
const float distance = Vector3::DistanceSquared(ownerPos, treasurePos);
|
||||
if (distance < 10 * 10) {
|
||||
StartInteract(treasurePos, PetInteractType::treasure);
|
||||
if (distance < 16 * 16) {
|
||||
StartInteract(treasurePos, PetInteractType::treasure, treasureID);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle actual following logic
|
||||
const 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->SetDestination(ownerPos);
|
||||
LOG_DEBUG("New pet destination: %f %f %f", ownerPos.x, ownerPos.y, ownerPos.z);
|
||||
}
|
||||
|
||||
m_Timer += 0.5f;
|
||||
}
|
||||
|
||||
void PetComponent::OnInteract() {
|
||||
LOG_DEBUG("Beginning interaction with object!");
|
||||
Entity* owner = GetOwner();
|
||||
if (!owner) return;
|
||||
|
||||
NiPoint3 ownerPos = GetOwner()->GetPosition();
|
||||
NiPoint3 currentPos = m_MovementAI->GetParent()->GetPosition();
|
||||
const NiPoint3 ownerPos = owner->GetPosition();
|
||||
const NiPoint3 currentPos = m_MovementAI->GetParent()->GetPosition();
|
||||
const float distanceFromOwner = Vector3::DistanceSquared(ownerPos, currentPos);
|
||||
|
||||
if (distanceFromOwner > 25 * 25) {
|
||||
@ -968,11 +963,13 @@ void PetComponent::OnInteract() {
|
||||
|
||||
switch (GetInteractType()) {
|
||||
case PetInteractType::bouncer:
|
||||
StartInteractBouncer();
|
||||
if (GetIsReadyToInteract()) LOG_DEBUG("Add the HandleInteractBouncer()!");
|
||||
else SetupInteractBouncer();
|
||||
break;
|
||||
|
||||
case PetInteractType::treasure:
|
||||
StartInteractDig();
|
||||
if (GetIsReadyToInteract()) HandleInteractTreasureDig();
|
||||
else SetupInteractTreasureDig();
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -983,11 +980,8 @@ void PetComponent::OnInteract() {
|
||||
}
|
||||
}
|
||||
|
||||
void PetComponent::OnTether() {
|
||||
m_Timer += 0.5f;
|
||||
}
|
||||
|
||||
void PetComponent::StartInteract(NiPoint3 position, PetInteractType interactType) {
|
||||
void PetComponent::StartInteract(const NiPoint3 position, const PetInteractType interactType, const LWOOBJID interactID) {
|
||||
SetInteraction(interactID); // TODO: Check if this should be serialized for goToObj
|
||||
SetInteractType(interactType);
|
||||
SetAbility(PetAbilityType::GoToObject);
|
||||
SetPetAiState(PetAiState::goToObj);
|
||||
@ -999,30 +993,68 @@ void PetComponent::StartInteract(NiPoint3 position, PetInteractType interactType
|
||||
}
|
||||
|
||||
void PetComponent::StopInteract() {
|
||||
SetInteraction(LWOOBJID_EMPTY);
|
||||
SetInteractType(PetInteractType::none);
|
||||
SetAbility(PetAbilityType::Invalid);
|
||||
SetPetAiState(PetAiState::follow);
|
||||
SetStatus(PetStatus::NONE);
|
||||
SetIsReadyToInteract(false);
|
||||
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);
|
||||
void PetComponent::SetupInteractBouncer() {
|
||||
// THIS IS ALL BAD, BAD, BAD! FIX IT, ME! >:(
|
||||
/*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);
|
||||
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::SetupInteractTreasureDig() {
|
||||
LOG_DEBUG("Setting up dig interaction!");
|
||||
Entity* closestTreasure = Game::entityManager->GetEntity(GetInteraction());
|
||||
if (!closestTreasure) return;
|
||||
|
||||
SetIsReadyToInteract(true);
|
||||
|
||||
SetStatus(PetStatus::IS_NOT_WAITING); // TODO: Double-check this is the right flag being set
|
||||
Game::entityManager->SerializeEntity(m_Parent); // TODO: Double-check pet packet captures
|
||||
m_Timer += 0.5f;
|
||||
}
|
||||
|
||||
void PetComponent::StartInteractTreasureDig() {
|
||||
SetAbility(PetAbilityType::DigAtPosition);
|
||||
Game::entityManager->SerializeEntity(m_Parent);
|
||||
|
||||
Command(NiPoint3::ZERO, LWOOBJID_EMPTY, 1, PetEmote::DigTreasure, true); // Plays 'dig' animation
|
||||
m_Timer = 1.5f;
|
||||
}
|
||||
|
||||
void PetComponent::HandleInteractTreasureDig() {
|
||||
if (GetAbility() == PetAbilityType::DigAtPosition) {
|
||||
auto* owner = GetOwner();
|
||||
|
||||
auto* treasure = Game::entityManager->GetEntity(GetInteraction());
|
||||
if (!treasure) return;
|
||||
treasure->Smash(m_Parent->GetObjectID());
|
||||
|
||||
LOG_DEBUG("Pet dig completed!");
|
||||
StopInteract(); //TODO: This may not be totally consistent with live behavior, where the pet seems to stay near the dig and not immediately follow
|
||||
m_Timer = 1.5f;
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_TimerBounce <= 0.0f) {
|
||||
Command(NiPoint3::ZERO, LWOOBJID_EMPTY, 1, PetEmote::Bounce, true); // Plays 'bounce' animation
|
||||
m_TimerBounce = 1.0f;
|
||||
}
|
||||
|
||||
m_Timer += 0.5f;
|
||||
}
|
||||
|
||||
void PetComponent::Activate(Item* item, bool registerPet, bool fromTaming) {
|
||||
@ -1042,7 +1074,7 @@ void PetComponent::Activate(Item* item, bool registerPet, bool fromTaming) {
|
||||
auto* owner = GetOwner();
|
||||
|
||||
if (owner == nullptr) return;
|
||||
SetStatus(1);
|
||||
SetStatus(PetStatus::PLAY_SPAWN_ANIM);
|
||||
|
||||
auto databaseData = inventoryComponent->GetDatabasePet(m_DatabaseId);
|
||||
|
||||
@ -1075,7 +1107,7 @@ void PetComponent::Activate(Item* item, bool registerPet, bool fromTaming) {
|
||||
|
||||
activePets[m_Owner] = m_Parent->GetObjectID();
|
||||
|
||||
m_Timer = 3;
|
||||
//m_Timer = 3;
|
||||
|
||||
Game::entityManager->SerializeEntity(m_Parent);
|
||||
|
||||
|
@ -32,6 +32,7 @@ enum class PetInteractType : uint8_t {
|
||||
*/
|
||||
enum PetStatus : uint32_t {
|
||||
NONE,
|
||||
//READY_TO_DIG,
|
||||
BEING_TAMED = 0x10,
|
||||
IS_NOT_WAITING = 0x20,
|
||||
PLAY_SPAWN_ANIM = 0x80,
|
||||
@ -148,15 +149,10 @@ public:
|
||||
*/
|
||||
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);
|
||||
void StartInteract(const NiPoint3 position, const PetInteractType interactType, const LWOOBJID interactID);
|
||||
|
||||
/**
|
||||
* Stop a pet interaction with an object
|
||||
@ -268,42 +264,35 @@ public:
|
||||
void SetPreconditions(std::string& conditions);
|
||||
|
||||
/**
|
||||
* Sets if the pet is ready to dig
|
||||
* @param isReady whether the pet is ready to dig (true) or not (false)
|
||||
* 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 SetIsReadyToDig(bool isReady);
|
||||
void SetIsReadyToInteract(bool isReady) { m_ReadyToInteract = isReady; };
|
||||
|
||||
/**
|
||||
* @return is pet ready to dig
|
||||
* @return is pet ready to interact with an object
|
||||
*/
|
||||
bool GetIsReadyToDig() { return m_ReadyToDig; };
|
||||
bool GetIsReadyToInteract() { return m_ReadyToInteract; };
|
||||
|
||||
/**
|
||||
* Start the pet bouncer interaction
|
||||
* Set up the pet bouncer interaction
|
||||
*/
|
||||
void StartInteractBouncer();
|
||||
void SetupInteractBouncer();
|
||||
|
||||
/**
|
||||
* Start the treasure dig interaction
|
||||
* Set up the treasure dig interaction
|
||||
*/
|
||||
void StartInteractDig();
|
||||
void SetupInteractTreasureDig();
|
||||
|
||||
/**
|
||||
* Handles the pet dig interaction
|
||||
* @param deltaTime time elapsed
|
||||
*/
|
||||
void InteractDig(float deltaTime);
|
||||
* Starts the pet treasure dig interaction
|
||||
*/
|
||||
void StartInteractTreasureDig();
|
||||
|
||||
/**
|
||||
* End the dig interaction
|
||||
*/
|
||||
void EndInteractDig();
|
||||
|
||||
/**
|
||||
* Sets pet's treasure timer
|
||||
* @param digTime float representing the treasure dig time in seconds
|
||||
*/
|
||||
void SetTreasureTime(float digTime) { m_TresureTime = digTime; };
|
||||
* Handles the pet treasure dig interaction
|
||||
*/
|
||||
void HandleInteractTreasureDig();
|
||||
|
||||
/**
|
||||
* Returns the entity that this component belongs to
|
||||
@ -479,15 +468,14 @@ private:
|
||||
float m_TimerAway;
|
||||
|
||||
/**
|
||||
* Timer that tracks how long a pet has been digging up some treasure, required to spawn the treasure contents
|
||||
* on time
|
||||
*/
|
||||
float m_TresureTime;
|
||||
* A timer that tracks how long until a tamed pet will bounce again when standing over a treasure dig site
|
||||
*/
|
||||
float m_TimerBounce;
|
||||
|
||||
/**
|
||||
* Boolean that sets if a pet is ready to dig and display the interact prompt
|
||||
* Boolean that sets if a pet is ready to interact with an object
|
||||
*/
|
||||
bool m_ReadyToDig;
|
||||
bool m_ReadyToInteract;
|
||||
|
||||
/**
|
||||
* The position that this pet was spawned at
|
||||
@ -497,7 +485,7 @@ private:
|
||||
/**
|
||||
* The halting radius of the pet while following a player
|
||||
*/
|
||||
float m_FollowRadius;
|
||||
const float m_FollowRadius = 8.0f;
|
||||
|
||||
/**
|
||||
* The movement AI component that is related to this pet, required to move it around
|
||||
|
@ -108,14 +108,14 @@ void PetDigServer::OnUse(Entity* self, Entity* user) {
|
||||
auto* petComponent = PetComponent::GetActivePet(user->GetObjectID());
|
||||
if (!petComponent) return;
|
||||
|
||||
if(petComponent->GetIsReadyToDig()) { // TODO: Add handling of the "first time" dig message
|
||||
if(petComponent->GetIsReadyToInteract()) { // TODO: Add handling of the "first time" dig message
|
||||
auto* destroyableComponent = user->GetComponent<DestroyableComponent>();
|
||||
if (!destroyableComponent) return;
|
||||
|
||||
auto imagination = destroyableComponent->GetImagination();
|
||||
if (imagination == 0) return; // TODO: Check if there was special behavior for this in the live game (PR_NEED_IMAGINATION)
|
||||
|
||||
petComponent->StartInteractDig();
|
||||
petComponent->StartInteractTreasureDig();
|
||||
|
||||
imagination -= 1; // TODO: Get rid of this magic number
|
||||
destroyableComponent->SetImagination(imagination);
|
||||
|
Loading…
Reference in New Issue
Block a user