add most pet messages

This commit is contained in:
jadebenn 2024-03-08 18:43:40 -06:00
parent 9a9254b583
commit e832dfbf71
8 changed files with 60 additions and 20 deletions

View File

@ -3,6 +3,8 @@
#include <cstdint> #include <cstdint>
#include "magic_enum.hpp"
enum class eHelpType : int32_t { enum class eHelpType : int32_t {
NONE = 0, NONE = 0,
UNLOCK_MINIMAP = 2, UNLOCK_MINIMAP = 2,
@ -37,4 +39,10 @@ enum class eHelpType : int32_t {
UI_INVENTORY_FULL_CANNOT_PICKUP_ITEM = 86 UI_INVENTORY_FULL_CANNOT_PICKUP_ITEM = 86
}; };
template <>
struct magic_enum::customize::enum_range<eHelpType> {
static constexpr int min = 0;
static constexpr int max = 86;
};
#endif //!__EHELPTYPE__H__ #endif //!__EHELPTYPE__H__

View File

@ -1204,7 +1204,7 @@ void InventoryComponent::SpawnPet(Item* item) {
auto* current = PetComponent::GetActivePet(m_Parent->GetObjectID()); auto* current = PetComponent::GetActivePet(m_Parent->GetObjectID());
if (current != nullptr) { if (current != nullptr) {
current->Deactivate(); current->Deactivate(eHelpType::PET_DESPAWN_BY_OWNER_HIBERNATE);
if (current->GetDatabaseId() == item->GetSubKey()) { if (current->GetDatabaseId() == item->GetSubKey()) {
return; return;

View File

@ -324,7 +324,7 @@ void PetComponent::OnUse(Entity* originator) {
GameMessages::SendNotifyPetTamingPuzzleSelected(originator->GetObjectID(), bricks, originator->GetSystemAddress()); GameMessages::SendNotifyPetTamingPuzzleSelected(originator->GetObjectID(), bricks, originator->GetSystemAddress());
m_Tamer = originator->GetObjectID(); m_Tamer = originator->GetObjectID();
SetFlag(PetFlag::IDLE, PetFlag::UNKNOWN4); //SetStatus(5); SetFlag(PetFlag::IDLE, PetFlag::UNKNOWN4);
currentActivities.insert_or_assign(m_Tamer, m_Parent->GetObjectID()); currentActivities.insert_or_assign(m_Tamer, m_Parent->GetObjectID());
@ -424,7 +424,7 @@ void PetComponent::TryBuild(uint32_t numBricks, bool clientFailed) {
GameMessages::SendPetTamingTryBuildResult(m_Tamer, !clientFailed, numBricks, tamer->GetSystemAddress()); GameMessages::SendPetTamingTryBuildResult(m_Tamer, !clientFailed, numBricks, tamer->GetSystemAddress());
} }
void PetComponent::NotifyTamingBuildSuccess(NiPoint3 position) { void PetComponent::NotifyTamingBuildSuccess(const NiPoint3 position) {
if (m_Tamer == LWOOBJID_EMPTY) return; if (m_Tamer == LWOOBJID_EMPTY) return;
auto* const tamer = Game::entityManager->GetEntity(m_Tamer); auto* const tamer = Game::entityManager->GetEntity(m_Tamer);
@ -527,7 +527,7 @@ void PetComponent::NotifyTamingBuildSuccess(NiPoint3 position) {
} }
} }
void PetComponent::RequestSetPetName(std::u16string name) { void PetComponent::RequestSetPetName(const std::u16string& name) {
if (m_Tamer == LWOOBJID_EMPTY) { if (m_Tamer == LWOOBJID_EMPTY) {
if (m_Owner != LWOOBJID_EMPTY) { if (m_Owner != LWOOBJID_EMPTY) {
auto* owner = GetOwner(); auto* owner = GetOwner();
@ -630,7 +630,7 @@ void PetComponent::ClientExitTamingMinigame(bool voluntaryExit) {
currentActivities.erase(m_Tamer); currentActivities.erase(m_Tamer);
SetOnlyFlag(PetFlag::TAMEABLE); //SetStatus(PetFlag::TAMEABLE); SetOnlyFlag(PetFlag::TAMEABLE);
m_Tamer = LWOOBJID_EMPTY; m_Tamer = LWOOBJID_EMPTY;
m_Timer = 0; m_Timer = 0;
@ -679,7 +679,7 @@ void PetComponent::ClientFailTamingMinigame() {
currentActivities.erase(m_Tamer); currentActivities.erase(m_Tamer);
SetOnlyFlag(PetFlag::TAMEABLE); //SetStatus(PetFlag::TAMEABLE); SetOnlyFlag(PetFlag::TAMEABLE);
m_Tamer = LWOOBJID_EMPTY; m_Tamer = LWOOBJID_EMPTY;
m_Timer = 0; m_Timer = 0;
@ -917,6 +917,7 @@ void PetComponent::StartInteractBouncer() {
//GameMessages::SendHelp(user->GetObjectID(), eHelpType::PR_NEED_IMAGINATION, user->GetSystemAddress()); // Check if right message! //GameMessages::SendHelp(user->GetObjectID(), eHelpType::PR_NEED_IMAGINATION, user->GetSystemAddress()); // Check if right message!
return; return;
} }
GameMessages::SendHelp(user->GetObjectID(), eHelpType::PR_TOOLTIP_1ST_PET_JUMPED_ON_SWITCH, user->GetSystemAddress());
GameMessages::SendShowPetActionButton(m_Owner, ePetAbilityType::Invalid, false, user->GetSystemAddress()); GameMessages::SendShowPetActionButton(m_Owner, ePetAbilityType::Invalid, false, user->GetSystemAddress());
@ -954,7 +955,7 @@ void PetComponent::HandleInteractBouncer() {
RenderComponent::PlayAnimation(petSwitchEntity, u"launch"); //u"engaged"); //TODO: Check if the timing on this is right RenderComponent::PlayAnimation(petSwitchEntity, u"launch"); //u"engaged"); //TODO: Check if the timing on this is right
// TODO: Need to freeze player movement until the bounce begins! // TODO: Need to freeze player movement until the bounce begins!
Command(NiPoint3Constant::ZERO, LWOOBJID_EMPTY, 1, GeneralUtils::CastUnderlyingType(PetEmote::ActivateSwitch), true); // Plays 'jump on switch' animation Command(NiPoint3Constant::ZERO, LWOOBJID_EMPTY, 1, GeneralUtils::ToUnderlying(PetEmote::ActivateSwitch), true); // Plays 'jump on switch' animation
StopInteract(); StopInteract();
} }
m_Timer += 0.5f; m_Timer += 0.5f;
@ -970,7 +971,7 @@ void PetComponent::SetupInteractTreasureDig() {
SetAbility(petAbility); SetAbility(petAbility);
UnsetFlag(PetFlag::IDLE); UnsetFlag(PetFlag::IDLE);
SetFlag(PetFlag::ON_SWITCH, PetFlag::NOT_WAITING); //SetStatus(PetFlag::NOT_WAITING); // TODO: Double-check this is the right flag being set SetFlag(PetFlag::ON_SWITCH, PetFlag::NOT_WAITING); // TODO: Double-check this is the right flag being set
LOG_DEBUG("m_Flags = %d", m_Flags); LOG_DEBUG("m_Flags = %d", m_Flags);
Game::entityManager->SerializeEntity(m_Parent); // TODO: Double-check pet packet captures Game::entityManager->SerializeEntity(m_Parent); // TODO: Double-check pet packet captures
@ -1007,7 +1008,7 @@ void PetComponent::StartInteractTreasureDig() {
LOG_DEBUG("StartInteractTreasureDig() m_Flags = %d", m_Flags); LOG_DEBUG("StartInteractTreasureDig() m_Flags = %d", m_Flags);
Game::entityManager->SerializeEntity(m_Parent); Game::entityManager->SerializeEntity(m_Parent);
Command(NiPoint3Constant::ZERO, LWOOBJID_EMPTY, 1, GeneralUtils::CastUnderlyingType(PetEmote::DigTreasure), true); // Plays 'dig' animation Command(NiPoint3Constant::ZERO, LWOOBJID_EMPTY, 1, GeneralUtils::ToUnderlying(PetEmote::DigTreasure), true); // Plays 'dig' animation
m_Timer = 2.0f; m_Timer = 2.0f;
} }
@ -1028,7 +1029,7 @@ void PetComponent::HandleInteractTreasureDig() {
} }
if (m_TimerBounce <= 0.0f) { if (m_TimerBounce <= 0.0f) {
Command(NiPoint3Constant::ZERO, LWOOBJID_EMPTY, 1, GeneralUtils::CastUnderlyingType(PetEmote::Bounce), true); // Plays 'bounce' animation Command(NiPoint3Constant::ZERO, LWOOBJID_EMPTY, 1, GeneralUtils::ToUnderlying(PetEmote::Bounce), true); // Plays 'bounce' animation
m_TimerBounce = 1.0f; m_TimerBounce = 1.0f;
} }
@ -1124,19 +1125,21 @@ void PetComponent::AddDrainImaginationTimer(Item* item, bool fromTaming) {
} }
// If we are out of imagination despawn the pet. // If we are out of imagination despawn the pet.
if (playerDestroyableComponent->GetImagination() == 0) { if (playerDestroyableComponent->GetImagination() < 1) {
this->Deactivate(); this->Deactivate(eHelpType::PR_NO_IMAGINATION_HIBERNATE);
auto playerEntity = playerDestroyableComponent->GetParent(); auto playerEntity = playerDestroyableComponent->GetParent();
if (!playerEntity) return; if (!playerEntity) return;
GameMessages::SendUseItemRequirementsResponse(playerEntity->GetObjectID(), playerEntity->GetSystemAddress(), eUseItemResponse::NoImaginationForPet);
} }
this->AddDrainImaginationTimer(item); this->AddDrainImaginationTimer(item);
}); });
} }
void PetComponent::Deactivate() { void PetComponent::Deactivate(const eHelpType msg) {
if (msg != eHelpType::NONE) {
GameMessages::SendHelp(m_Parent->GetObjectID(), msg, m_Parent->GetSystemAddress());
}
GameMessages::SendPlayFXEffect(m_Parent->GetObjectID(), -1, u"despawn", "", LWOOBJID_EMPTY, 1, 1, true); GameMessages::SendPlayFXEffect(m_Parent->GetObjectID(), -1, u"despawn", "", LWOOBJID_EMPTY, 1, 1, true);
GameMessages::SendMarkInventoryItemAsActive(m_Owner, false, eUnequippableActiveType::PET, m_ItemId, GetOwner()->GetSystemAddress()); GameMessages::SendMarkInventoryItemAsActive(m_Owner, false, eUnequippableActiveType::PET, m_ItemId, GetOwner()->GetSystemAddress());

View File

@ -196,7 +196,7 @@ public:
* successfully). * successfully).
* @param name the name of the pet to set * @param name the name of the pet to set
*/ */
void RequestSetPetName(std::u16string name); void RequestSetPetName(const std::u16string& name);
/** /**
* Handles a notification of the client that the taming entity is leaving the minigame, either voluntary or because * Handles a notification of the client that the taming entity is leaving the minigame, either voluntary or because
@ -266,7 +266,7 @@ public:
/** /**
* Despawns the pet * Despawns the pet
*/ */
void Deactivate(); void Deactivate(eHelpType msg = eHelpType::NONE);
/** /**
* Removes the pet from the inventory * Removes the pet from the inventory

View File

@ -3823,7 +3823,7 @@ void GameMessages::HandleDespawnPet(RakNet::BitStream& inStream, Entity* entity,
if (bDeletePet) { if (bDeletePet) {
petComponent->Release(); petComponent->Release();
} else { } else {
petComponent->Deactivate(); petComponent->Deactivate(eHelpType::PET_DESPAWN_BY_OWNER_HIBERNATE);
} }
} }

View File

@ -319,7 +319,7 @@ void Item::UseNonEquip(Item* item) {
if (packageComponentId == 0) return; if (packageComponentId == 0) return;
auto* packCompTable = CDClientManager::GetTable<CDPackageComponentTable>(); auto* packCompTable = CDClientManager::GetTable<CDPackageComponentTable>();
auto packages = packCompTable->Query([=](const CDPackageComponent entry) {return entry.id == static_cast<uint32_t>(packageComponentId); }); auto packages = packCompTable->Query([packageComponentId](const CDPackageComponent entry) {return entry.id == static_cast<uint32_t>(packageComponentId); });
auto success = !packages.empty(); auto success = !packages.empty();
if (success) { if (success) {

View File

@ -59,6 +59,7 @@
#include "dpShapeSphere.h" #include "dpShapeSphere.h"
#include "PossessableComponent.h" #include "PossessableComponent.h"
#include "PossessorComponent.h" #include "PossessorComponent.h"
#include "StringifiedEnum.h"
#include "HavokVehiclePhysicsComponent.h" #include "HavokVehiclePhysicsComponent.h"
#include "BuffComponent.h" #include "BuffComponent.h"
#include "SkillComponent.h" #include "SkillComponent.h"
@ -81,6 +82,7 @@
#include "eControlScheme.h" #include "eControlScheme.h"
#include "eConnectionType.h" #include "eConnectionType.h"
#include "eChatInternalMessageType.h" #include "eChatInternalMessageType.h"
#include "eHelpType.h"
#include "eMasterMessageType.h" #include "eMasterMessageType.h"
#include "PlayerManager.h" #include "PlayerManager.h"
@ -674,6 +676,32 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
return; return;
} }
// Send packet to display help message pop-up
if (chatCommand == "helpmsg") {
if (entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() == 1) {
const auto helpIdOpt = GeneralUtils::TryParse<eHelpType>(args[0]);
if (!helpIdOpt) {
ChatPackets::SendSystemMessage(sysAddr, u"Invalid help message id.");
return;
}
const eHelpType helpId = helpIdOpt.value();
GameMessages::SendHelp(entity->GetObjectID(), helpId, sysAddr);
// Convert and print enum string
const std::u16string msg = u"Sent help message '"
+ GeneralUtils::ASCIIToUTF16(StringifiedEnum::ToString(helpId))
+ u"' (id: "
+ GeneralUtils::to_u16string(GeneralUtils::ToUnderlying(helpId))
+ u')';
ChatPackets::SendSystemMessage(sysAddr, msg);
} else {
ChatPackets::SendSystemMessage(sysAddr, u"Invalid command invocation.");
return;
}
}
if (chatCommand == "setflag" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() == 1) { if (chatCommand == "setflag" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() == 1) {
const auto flagId = GeneralUtils::TryParse<int32_t>(args.at(0)); const auto flagId = GeneralUtils::TryParse<int32_t>(args.at(0));
@ -732,7 +760,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
petComponent->SetFlag(petFlag); petComponent->SetFlag(petFlag);
std::u16string msg = u"Set pet flag to " + (GeneralUtils::to_u16string(GeneralUtils::CastUnderlyingType(petFlag))); std::u16string msg = u"Set pet flag to " + (GeneralUtils::to_u16string(GeneralUtils::ToUnderlying(petFlag)));
ChatPackets::SendSystemMessage(sysAddr, msg); ChatPackets::SendSystemMessage(sysAddr, msg);
} }

View File

@ -79,6 +79,7 @@ These commands are primarily for development and testing. The usage of many of t
|getnavmeshheight|`/getnavmeshheight`|Displays the navmesh height at your current position.|8| |getnavmeshheight|`/getnavmeshheight`|Displays the navmesh height at your current position.|8|
|giveuscore|`/giveuscore <uscore>`|Gives uscore.|8| |giveuscore|`/giveuscore <uscore>`|Gives uscore.|8|
|gmadditem|`/gmadditem <id> (count)`|Adds the given item to your inventory by id.|8| |gmadditem|`/gmadditem <id> (count)`|Adds the given item to your inventory by id.|8|
|helpmsg|`/helpmsg <id> (help id)`|Display help message pop-up for a given id.|8|
|inspect|`/inspect <component> (-m <waypoint> \| -a <animation> \| -s \| -p \| -f (faction) \| -t)`|Finds the closest entity with the given component or LDF variable (ignoring players and racing cars), printing its ID, distance from the player, and whether it is sleeping, as well as the the IDs of all components the entity has. See [Detailed `/inspect` Usage](#detailed-inspect-usage) below.|8| |inspect|`/inspect <component> (-m <waypoint> \| -a <animation> \| -s \| -p \| -f (faction) \| -t)`|Finds the closest entity with the given component or LDF variable (ignoring players and racing cars), printing its ID, distance from the player, and whether it is sleeping, as well as the the IDs of all components the entity has. See [Detailed `/inspect` Usage](#detailed-inspect-usage) below.|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| |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|