mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-02 19:03:43 +00:00
Issue 547. The minigame put the player a guessed distance from wherever the pet had wandered to, in the direction of the player, which often left bricks off screen or the whole minigame over a drop. In the 2014 live captures the positions are the same for every try at the same pet: the pet's destination is where it spawned, and the player is teleported exactly 12 units along the direction the pet spawned facing, turned to face the pet. This matches the spawner in the level file for the Pet Ranch cat (spawned facing -43.4 degrees, player placed at spawn + (-8.24, 8.73) facing 136.6 degrees) and holds for the doberman, buffalo, triceratops, rabbit and the script spawned panda. The pet is now put back on that spot and the player placed that way; the heights come from the navmesh when there is one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
418 lines
12 KiB
C++
418 lines
12 KiB
C++
#ifndef PETCOMPONENT_H
|
|
#define PETCOMPONENT_H
|
|
|
|
#include "Entity.h"
|
|
#include "MovementAIComponent.h"
|
|
#include "Component.h"
|
|
#include "Preconditions.h"
|
|
#include "ePetAbilityType.h"
|
|
#include "eReplicaComponentType.h"
|
|
#include "CDPetComponentTable.h"
|
|
#include "eHelpType.h"
|
|
|
|
/**
|
|
* 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
|
|
{
|
|
public:
|
|
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::PET;
|
|
|
|
// Bits of the serialized pet status. State number N is bit 1 << (N - 1) (the client's StateNumToIndex,
|
|
// 0x00bd19b0); the meanings are what the live server sent (2014 packet captures) and what the client does with them.
|
|
|
|
// State 8: a pet constructed with it plays its spawnAnim (LWOPetComponent::Deserialize, 0x00cd1270). Live
|
|
// constructed summoned pets with 0x84 and cleared this bit once the spawn animation was over.
|
|
static constexpr uint32_t PET_STATE_SPAWNING = 1 << 7;
|
|
|
|
// State 6: the pet is at the object of its ability (a pet switch or a dig) and waits for its owner to use it.
|
|
static constexpr uint32_t PET_STATE_AT_ABILITY_OBJECT = 1 << 5;
|
|
|
|
// State 9: the pet is on its way to, or waiting at, the object of its ability (the client's IsPetUsingAbility
|
|
// checks it).
|
|
static constexpr uint32_t PET_STATE_USING_ABILITY = 1 << 8;
|
|
|
|
// State 11: the pet is on its way to the object of its ability.
|
|
static constexpr uint32_t PET_STATE_GOING_TO_ABILITY_OBJECT = 1 << 10;
|
|
|
|
explicit PetComponent(Entity* parentEntity, const int32_t componentID);
|
|
~PetComponent() override;
|
|
|
|
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
|
void Update(float deltaTime) override;
|
|
|
|
/**
|
|
* 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
|
|
*/
|
|
void OnUse(Entity* originator) override;
|
|
|
|
/**
|
|
* Attempts to complete the pet minigame by passing a list of bricks to build the minigame model.
|
|
* @param bricks the bricks to try to complete the minigame with
|
|
* @param clientFailed unused
|
|
*/
|
|
void TryBuild(uint32_t numBricks, bool clientFailed);
|
|
|
|
/**
|
|
* Handles a notification from the client regarding the completion of the pet minigame, adding the pet to their
|
|
* inventory.
|
|
* @param position the position to spawn the completed model at
|
|
*/
|
|
void NotifyTamingBuildSuccess(NiPoint3 position);
|
|
|
|
/**
|
|
* Handles the notification of the client to set the name of the pet (indicating that minigame was completed
|
|
* successfully).
|
|
* @param name the name of the pet to set
|
|
*/
|
|
void RequestSetPetName(std::u16string name);
|
|
|
|
/**
|
|
* Handles a notification of the client that the taming entity is leaving the minigame, either voluntary or because
|
|
* time ran out.
|
|
* @param voluntaryExit whether the client voluntarily exited the minigame
|
|
*/
|
|
void ClientExitTamingMinigame(bool voluntaryExit);
|
|
|
|
/**
|
|
* Starts the internal timer for the build limit for building the minigame model
|
|
*/
|
|
void StartTimer();
|
|
|
|
/**
|
|
* Notifies the client that they failed the minigame because time ran out
|
|
*/
|
|
void ClientFailTamingMinigame();
|
|
|
|
/**
|
|
* Makes the pet wander around
|
|
*/
|
|
void Wander();
|
|
|
|
/**
|
|
* Spawns a pet from an item in the inventory of an owner
|
|
* @param item the item to create the pet from
|
|
* @param registerPet notifies the client that the pet was spawned, not necessary if this pet is being tamed
|
|
*/
|
|
void Activate(Item* item, bool registerPet = true, bool fromTaming = false);
|
|
|
|
/**
|
|
* Despawns the pet
|
|
*/
|
|
void Deactivate();
|
|
|
|
/**
|
|
* Removes the pet from the inventory
|
|
*/
|
|
void Release();
|
|
|
|
/**
|
|
* Commands the pet to do an action, actions are still a relative mystery, next to playing emotes
|
|
* @param position a position to execute the command at, currently unused
|
|
* @param source the source object that triggered the command
|
|
* @param commandType the type of the command (see function body for types)
|
|
* @param typeId extra information about the command, e.g. the emote to play
|
|
* @param overrideObey unused
|
|
*/
|
|
void Command(const NiPoint3& position, const LWOOBJID source, const int32_t commandType, const int32_t typeId, const bool overrideObey);
|
|
|
|
/**
|
|
* Returns the ID of the owner of this pet (if any)
|
|
* @return the ID of the owner of this pet
|
|
*/
|
|
LWOOBJID GetOwnerId() const;
|
|
|
|
/**
|
|
* Returns the entity that owns this pet (if any)
|
|
* @return the entity that owns this pet
|
|
*/
|
|
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;
|
|
|
|
// A moderator approved or rejected this pet's name (from the dashboard); updates it live for everyone
|
|
void ApplyNameModeration(bool approved);
|
|
|
|
/**
|
|
* 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);
|
|
|
|
/**
|
|
* 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);
|
|
|
|
/**
|
|
* Sets preconditions for the pet that need to be met before it can be tamed
|
|
* @param conditions the preconditions to set
|
|
*/
|
|
void SetPreconditions(const std::string& conditions);
|
|
|
|
/**
|
|
* Returns the entity that this component belongs to
|
|
* @return the entity that this component belongs to
|
|
*/
|
|
Entity* GetParentEntity() const;
|
|
|
|
/**
|
|
* Sets the name of the pet to be moderated
|
|
* @param petName the name of the pet to set
|
|
* @param owner the character that owns the pet, saved with the name
|
|
*/
|
|
void SetPetNameForModeration(const std::string& petName, const LWOOBJID owner);
|
|
|
|
/**
|
|
* Loads the pet name up for moderation along with the moderation status from the database and sets them for this
|
|
* pet.
|
|
*/
|
|
void LoadPetNameFromModeration();
|
|
|
|
/**
|
|
* Returns the component of the pet some entity is currently taming (if any)
|
|
* @param tamer the entity that's currently taming
|
|
* @return the pet component of the entity that's being tamed
|
|
*/
|
|
static PetComponent* GetTamingPet(LWOOBJID tamer);
|
|
|
|
/**
|
|
* Returns the pet that's currently spawned for some entity (if any)
|
|
* @param owner the owner of the pet that's spawned
|
|
* @return the pet component of the entity that was spawned by the owner
|
|
*/
|
|
static PetComponent* GetActivePet(LWOOBJID owner);
|
|
|
|
/**
|
|
* Adds the timer to the owner of this pet to drain imagination at the rate
|
|
* specified by the parameter imaginationDrainRate
|
|
*
|
|
* @param item The item that represents this pet in the inventory.
|
|
*/
|
|
void AddDrainImaginationTimer(bool fromTaming = false);
|
|
|
|
private:
|
|
|
|
/**
|
|
* Sets the object the pet goes to use its ability on (a pet switch or a dig), or none. The pet first goes to it; once it is there
|
|
* its owner gets the pet's action button, which uses the ability.
|
|
* @param object the object, nullptr for none
|
|
* @param ability the ability the object is for
|
|
* @param atObject whether the pet has reached the object
|
|
*/
|
|
void SetAbilityObject(Entity* object, ePetAbilityType ability, bool atObject);
|
|
|
|
/**
|
|
* Uses the ability the owner's action button shows (the owner used the pet: SHIFT or the pet menu)
|
|
*/
|
|
void UseAbility();
|
|
|
|
/**
|
|
* Takes the action button away from the owner, if they have it
|
|
*/
|
|
void HideAbilityButton();
|
|
|
|
/**
|
|
* Shows the owner a one-time tutorial tooltip
|
|
* @param helpId the tooltip
|
|
*/
|
|
void SendHelp(eHelpType helpId) const;
|
|
|
|
/**
|
|
* Returns the imagination using an ability costs (PetAbilities.ImaginationCost)
|
|
*/
|
|
static int32_t GetAbilityImaginationCost(ePetAbilityType ability);
|
|
|
|
/**
|
|
* Information for the minigame to be completed
|
|
*/
|
|
struct PetPuzzleData
|
|
{
|
|
/**
|
|
* The LOT of the object that is to be created
|
|
*/
|
|
LOT puzzleModelLot;
|
|
|
|
/**
|
|
* That file that contains the bricks required to build the model
|
|
*/
|
|
std::string buildFile;
|
|
|
|
/**
|
|
* The time limit to complete the build
|
|
*/
|
|
int32_t timeLimit;
|
|
|
|
/**
|
|
* The imagination cost for the tamer to start the minigame
|
|
*/
|
|
int32_t imaginationCost;
|
|
|
|
/**
|
|
* The number of pieces required to complete the minigame
|
|
*/
|
|
int32_t numValidPieces;
|
|
};
|
|
|
|
/**
|
|
* Cache of all the pets that are currently spawned, indexed by tamer
|
|
*/
|
|
static std::unordered_map<LWOOBJID, LWOOBJID> activePets;
|
|
|
|
/**
|
|
* Cache of all the pets that are currently being tamed, indexed by tamer
|
|
*/
|
|
static std::unordered_map<LWOOBJID, LWOOBJID> currentActivities;
|
|
|
|
/**
|
|
* 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 ID of the entity that owns this pet
|
|
*/
|
|
LWOOBJID m_Owner;
|
|
|
|
/**
|
|
* The ID of the entity that is currently taming this pet
|
|
*/
|
|
LWOOBJID m_Tamer;
|
|
|
|
/**
|
|
* The ID under which this pet is stored in the database (if it's tamed)
|
|
*/
|
|
LWOOBJID m_DatabaseId;
|
|
|
|
/**
|
|
* The ID of the item from which this pet was created
|
|
*/
|
|
LWOOBJID m_ItemId;
|
|
|
|
/**
|
|
* The moderation status for the name of this pet
|
|
*/
|
|
uint32_t m_ModerationStatus;
|
|
|
|
/**
|
|
* The name of this pet
|
|
*/
|
|
std::string m_Name;
|
|
|
|
/**
|
|
* The name of the owner of this pet
|
|
*/
|
|
std::string m_OwnerName;
|
|
|
|
/**
|
|
* The current state of the pet (e.g. tamable, tamed, etc).
|
|
*/
|
|
uint32_t m_Status;
|
|
|
|
/**
|
|
* A currently active ability, mostly unused
|
|
*/
|
|
ePetAbilityType m_Ability;
|
|
|
|
/**
|
|
* The time an entity has left to complete the minigame
|
|
*/
|
|
float m_Timer;
|
|
|
|
/**
|
|
* 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;
|
|
|
|
/**
|
|
* Timer that tracks how long a pet has been digging up some treasure, required to spawn the treasure contents
|
|
* on time
|
|
*/
|
|
float m_TreasureTime;
|
|
|
|
/**
|
|
* The position that this pet was spawned at
|
|
*/
|
|
NiPoint3 m_StartPosition;
|
|
|
|
/**
|
|
* The rotation that this pet was spawned with
|
|
*/
|
|
NiQuaternion m_StartRotation{ QuatUtils::IDENTITY };
|
|
|
|
/**
|
|
* The movement AI component that is related to this pet, required to move it around
|
|
*/
|
|
MovementAIComponent* m_MovementAI;
|
|
|
|
/**
|
|
* Preconditions that need to be met before an entity can tame this pet
|
|
*/
|
|
std::optional<PreconditionExpression> m_Preconditions{};
|
|
|
|
/**
|
|
* Pet information loaded from the CDClientDatabase
|
|
*/
|
|
CDPetComponent m_PetInfo;
|
|
|
|
/**
|
|
* Set once the pet has been sent back to the backpack; it is removed after its despawn effect has played
|
|
*/
|
|
bool m_Despawning{ false };
|
|
|
|
/**
|
|
* The object the pet goes to use its ability on (a pet switch or a dig), if any. Live did not serialize it as the interaction.
|
|
*/
|
|
LWOOBJID m_AbilityObject{ LWOOBJID_EMPTY };
|
|
|
|
/**
|
|
* Whether the owner has the pet's action button
|
|
*/
|
|
bool m_AbilityButtonShown{ false };
|
|
};
|
|
|
|
#endif // !PETCOMPONENT_H
|