Fixed pet emotes not playing

This commit is contained in:
jadebenn 2023-11-19 16:46:27 -06:00
parent 3f1f51f996
commit 1a74ed676b
7 changed files with 130 additions and 82 deletions

View File

@ -1,18 +0,0 @@
#ifndef __EPETSTATUS__H__
#define __EPETSTATUS__H__
#include <cstdint>
enum ePetStatus : uint32_t {
NONE,
UNKNOWN1 = 0x1,
UNKNOWN2 = 0x2,
UNKNOWN3 = 0x4,
UNKNOWN4 = 0x8,
BEING_TAMED = 0x10,
IS_NOT_WAITING = 0x20, // Right name? - used to be decimal 20
PLAY_SPAWN_ANIM = 0x80,
TAMEABLE = 0x4000000
};
#endif //!__EPETSTATUS__H__

View File

@ -19,7 +19,6 @@
#include "ePetTamingNotifyType.h" #include "ePetTamingNotifyType.h"
#include "eUseItemResponse.h" #include "eUseItemResponse.h"
#include "ePlayerFlag.h" #include "ePlayerFlag.h"
#include "ePetStatus.h"
#include "Game.h" #include "Game.h"
#include "dConfig.h" #include "dConfig.h"
@ -81,7 +80,7 @@ PetComponent::PetComponent(Entity* parent, uint32_t componentId): Component(pare
m_Timer = 0; m_Timer = 0;
m_TimerAway = 0; m_TimerAway = 0;
m_DatabaseId = LWOOBJID_EMPTY; m_DatabaseId = LWOOBJID_EMPTY;
m_Status = ePetStatus::TAMEABLE; // Tameable m_Status = PetStatus::TAMEABLE; // Tameable
m_Ability = PetAbilityType::Invalid; m_Ability = PetAbilityType::Invalid;
m_StartPosition = NiPoint3::ZERO; m_StartPosition = NiPoint3::ZERO;
m_MovementAI = nullptr; m_MovementAI = nullptr;
@ -382,7 +381,7 @@ void PetComponent::Update(float deltaTime) {
return; return;
} }
if (m_TresureTime > 0.0f) { if (m_TresureTime > 0.0f) { //TODO: Find better trigger
InteractDig(deltaTime); InteractDig(deltaTime);
return; return;
} }
@ -450,7 +449,7 @@ void PetComponent::Update(float deltaTime) {
if (distance < 5 * 5) { if (distance < 5 * 5) {
m_Interaction = closestTresure->GetObjectID(); m_Interaction = closestTresure->GetObjectID();
Command(NiPoint3::ZERO, LWOOBJID_EMPTY, 1, 202, true); Command(NiPoint3::ZERO, LWOOBJID_EMPTY, 1, PetEmote::Bounce , true); // Plays 'bounce' animation
SetIsReadyToDig(true); SetIsReadyToDig(true);
@ -478,20 +477,20 @@ void PetComponent::SetIsReadyToDig(bool isReady) {
if (isReady) { if (isReady) {
LOG("Dig state reached!"); LOG("Dig state reached!");
//m_Interaction = closestTresure->GetObjectID(); //m_Interaction = closestTresure->GetObjectID();
SetAbility(PetAbilityType::JumpOnObject); //SetAbility(PetAbilityType::JumpOnObject);
SetStatus(ePetStatus::IS_NOT_WAITING); // Treasure dig status SetStatus(PetStatus::IS_NOT_WAITING); // Treasure dig status
m_ReadyToDig = true; m_ReadyToDig = true;
} }
else { else {
LOG("Dig state ended!"); LOG("Dig state ended!");
//m_Interaction = LWOOBJID_EMPTY; //m_Interaction = LWOOBJID_EMPTY;
SetAbility(PetAbilityType::Invalid); //SetAbility(PetAbilityType::Invalid);
SetStatus(0); // TODO: Check status SetStatus(0); // TODO: Check status
m_ReadyToDig = false; m_ReadyToDig = false;
} }
} }
void PetComponent::InteractDig(float deltaTime) { //Should I rename to InteractDig? void PetComponent::InteractDig(float deltaTime) {
LOG("Pet digging!"); LOG("Pet digging!");
auto* tresure = Game::entityManager->GetEntity(m_Interaction); auto* tresure = Game::entityManager->GetEntity(m_Interaction);
@ -773,7 +772,7 @@ void PetComponent::ClientExitTamingMinigame(bool voluntaryExit) {
currentActivities.erase(m_Tamer); currentActivities.erase(m_Tamer);
SetStatus(ePetStatus::TAMEABLE); SetStatus(PetStatus::TAMEABLE);
m_Tamer = LWOOBJID_EMPTY; m_Tamer = LWOOBJID_EMPTY;
m_Timer = 0; m_Timer = 0;
@ -824,7 +823,7 @@ void PetComponent::ClientFailTamingMinigame() {
currentActivities.erase(m_Tamer); currentActivities.erase(m_Tamer);
SetStatus(ePetStatus::TAMEABLE); SetStatus(PetStatus::TAMEABLE);
m_Tamer = LWOOBJID_EMPTY; m_Tamer = LWOOBJID_EMPTY;
m_Timer = 0; m_Timer = 0;
@ -1024,10 +1023,7 @@ void PetComponent::Release() {
void PetComponent::Command(NiPoint3 position, LWOOBJID source, int32_t commandType, int32_t typeId, bool overrideObey) { void PetComponent::Command(NiPoint3 position, LWOOBJID source, int32_t commandType, int32_t typeId, bool overrideObey) {
auto* owner = GetOwner(); auto* owner = GetOwner();
if (!owner) return;
if (owner == nullptr) {
return;
}
if (commandType == 1) { if (commandType == 1) {
// Emotes // Emotes
@ -1151,3 +1147,13 @@ void PetComponent::LoadPetNameFromModeration() {
void PetComponent::SetPreconditions(std::string& preconditions) { void PetComponent::SetPreconditions(std::string& preconditions) {
m_Preconditions = new PreconditionExpression(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;
}

View File

@ -6,6 +6,24 @@
#include "Preconditions.h" #include "Preconditions.h"
#include "eReplicaComponentType.h" #include "eReplicaComponentType.h"
enum PetStatus : uint32_t {
NONE,
UNKNOWN1 = 0x1,
UNKNOWN2 = 0x2,
UNKNOWN3 = 0x4,
UNKNOWN4 = 0x8,
BEING_TAMED = 0x10,
IS_NOT_WAITING = 0x20, // Right name? - used to be decimal 20
PLAY_SPAWN_ANIM = 0x80,
TAMEABLE = 0x4000000
};
enum PetEmote : int32_t {
ActivateSwitch = 201,
DigTreasure,
Bounce
};
enum class PetAbilityType enum class PetAbilityType
{ {
Invalid, Invalid,
@ -29,12 +47,6 @@ public:
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override; void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override;
void Update(float deltaTime) override; void Update(float deltaTime) override;
/**
* Handles the pet dig interaction
* @param deltaTime time elapsed
*/
void InteractDig(float deltaTime);
/** /**
* Handles an OnUse event from another entity, initializing the pet taming minigame if this pet is untamed. * Handles an OnUse event from another entity, initializing the pet taming minigame if this pet is untamed.
* @param originator the entity that triggered the event * @param originator the entity that triggered the event
@ -189,6 +201,22 @@ public:
*/ */
bool GetIsReadyToDig() { return m_ReadyToDig; }; bool GetIsReadyToDig() { return m_ReadyToDig; };
/**
* Start the dig interaction
*/
void StartInteractDig();
/**
* Handles the pet dig interaction
* @param deltaTime time elapsed
*/
void InteractDig(float deltaTime);
/**
* End the dig interaction
*/
void EndInteractDig();
/** /**
* Sets pet's treasure timer * Sets pet's treasure timer
* @param digTime float representing the treasure dig time in seconds * @param digTime float representing the treasure dig time in seconds

View File

@ -5018,8 +5018,7 @@ void GameMessages::HandlePlayEmote(RakNet::BitStream* inStream, Entity* entity)
std::string sAnimationName = "deaded"; //Default name in case we fail to get the emote std::string sAnimationName = "deaded"; //Default name in case we fail to get the emote
MissionComponent* missionComponent = entity->GetComponent<MissionComponent>(); MissionComponent* missionComponent = entity->GetComponent<MissionComponent>();
if (!missionComponent) return; if (missionComponent) {
if (targetID != LWOOBJID_EMPTY) { if (targetID != LWOOBJID_EMPTY) {
auto* targetEntity = Game::entityManager->GetEntity(targetID); auto* targetEntity = Game::entityManager->GetEntity(targetID);
@ -5042,6 +5041,7 @@ void GameMessages::HandlePlayEmote(RakNet::BitStream* inStream, Entity* entity)
missionComponent->Progress(eMissionTaskType::EMOTE, emoteID, scripted->GetObjectID()); missionComponent->Progress(eMissionTaskType::EMOTE, emoteID, scripted->GetObjectID());
} }
} }
}
CDEmoteTableTable* emotes = CDClientManager::Instance().GetTable<CDEmoteTableTable>(); CDEmoteTableTable* emotes = CDClientManager::Instance().GetTable<CDEmoteTableTable>();
if (emotes) { if (emotes) {

View File

@ -697,32 +697,6 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
entity->GetCharacter()->SetPlayerFlag(flagId, false); entity->GetCharacter()->SetPlayerFlag(flagId, false);
} }
if (chatCommand == "setpetstatus" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
if (args.size() == 0) {
ChatPackets::SendSystemMessage(sysAddr, u"Too few arguments!");
return;
}
uint32_t petStatus;
if (!GeneralUtils::TryParse(args[0], petStatus)) {
ChatPackets::SendSystemMessage(sysAddr, u"Invalid pet status!");
return;
}
// Determine if player has a pet summoned
auto* petComponent = PetComponent::GetActivePet(entity->GetObjectID());
if (!petComponent) {
ChatPackets::SendSystemMessage(sysAddr, u"No active pet found!");
return;
}
petComponent->SetStatus(petStatus);
//Game::entityManager->SerializeEntity(petComponent->GetParentEntity());
std::u16string msg = u"Set pet status to " + (GeneralUtils::to_u16string(petStatus));
ChatPackets::SendSystemMessage(sysAddr, msg);
}
if (chatCommand == "resetmission" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { if (chatCommand == "resetmission" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
if (args.size() == 0) return; if (args.size() == 0) return;
@ -750,6 +724,63 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
return; return;
} }
// Pet status utility
if (chatCommand == "setpetstatus" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
if (args.size() == 0) {
ChatPackets::SendSystemMessage(sysAddr, u"Too few arguments!");
return;
}
uint32_t petStatus;
if (!GeneralUtils::TryParse(args[0], petStatus)) {
ChatPackets::SendSystemMessage(sysAddr, u"Invalid pet status!");
return;
}
// Determine if player has a pet summoned
auto* petComponent = PetComponent::GetActivePet(entity->GetObjectID());
if (!petComponent) {
ChatPackets::SendSystemMessage(sysAddr, u"No active pet found!");
return;
}
petComponent->SetStatus(petStatus);
//Game::entityManager->SerializeEntity(petComponent->GetParentEntity());
std::u16string msg = u"Set pet status to " + (GeneralUtils::to_u16string(petStatus));
ChatPackets::SendSystemMessage(sysAddr, msg);
}
//Pet command utility
if (chatCommand == "petcommand" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
if (args.size() < 2) {
ChatPackets::SendSystemMessage(sysAddr, u"Too few arguments!");
return;
}
int32_t commandType;
if (!GeneralUtils::TryParse(args[0], commandType)) {
ChatPackets::SendSystemMessage(sysAddr, u"Invalid command type!");
return;
}
int32_t typeId;
if (!GeneralUtils::TryParse(args[1], typeId)) {
ChatPackets::SendSystemMessage(sysAddr, u"Invalid command type id!");
return;
}
// Determine if player has a pet summoned
auto* petComponent = PetComponent::GetActivePet(entity->GetObjectID());
if (!petComponent) {
ChatPackets::SendSystemMessage(sysAddr, u"No active pet found!");
return;
}
petComponent->Command(NiPoint3::ZERO, LWOOBJID_EMPTY, commandType, typeId, true);
}
if (chatCommand == "playeffect" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 3) { if (chatCommand == "playeffect" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 3) {
int32_t effectID = 0; int32_t effectID = 0;

View File

@ -115,7 +115,7 @@ void PetDigServer::OnUse(Entity* self, Entity* user) {
auto imagination = destroyableComponent->GetImagination(); auto imagination = destroyableComponent->GetImagination();
if (imagination == 0) return; // TODO: Check if there was special behavior for this in the live game (PR_NEED_IMAGINATION) if (imagination == 0) return; // TODO: Check if there was special behavior for this in the live game (PR_NEED_IMAGINATION)
petComponent->SetTreasureTime(2.0f); // TODO: Get rid of this magic number petComponent->StartInteractDig();
imagination -= 1; // TODO: Get rid of this magic number imagination -= 1; // TODO: Get rid of this magic number
destroyableComponent->SetImagination(imagination); destroyableComponent->SetImagination(imagination);

View File

@ -82,6 +82,7 @@ These commands are primarily for development and testing. The usage of many of t
|list-spawns|`/list-spawns`|Lists all the character spawn points in the zone. Additionally, this command will display the current scene that plays when the character lands in the next zone, if there is one.|8| |list-spawns|`/list-spawns`|Lists all the character spawn points in the zone. Additionally, this command will display the current scene that plays when the character lands in the next zone, if there is one.|8|
|locrow|`/locrow`|Prints the your current position and rotation information to the console.|8| |locrow|`/locrow`|Prints the your current position and rotation information to the console.|8|
|lookup|`/lookup <query>`|Searches through the Objects table in the client SQLite database for items whose display name, name, or description contains the query. Query can be multiple words delimited by spaces.|8| |lookup|`/lookup <query>`|Searches through the Objects table in the client SQLite database for items whose display name, name, or description contains the query. Query can be multiple words delimited by spaces.|8|
|petcommand|`/petcommand <commandType> <typeId>`|Sends pet command to pet with given command type and type ID.|8|
|playanimation|`/playanimation <id>`|Plays animation with given ID. Alias: `/playanim`.|8| |playanimation|`/playanimation <id>`|Plays animation with given ID. Alias: `/playanim`.|8|
|playeffect|`/playeffect <effect id> <effect type> <effect name>`|Plays an effect.|8| |playeffect|`/playeffect <effect id> <effect type> <effect name>`|Plays an effect.|8|
|playlvlfx|`/playlvlfx`|Plays the level up animation on your character.|8| |playlvlfx|`/playlvlfx`|Plays the level up animation on your character.|8|