diff --git a/dGame/dComponents/PetComponent.cpp b/dGame/dComponents/PetComponent.cpp index 1d8602f3..ed0f73f8 100644 --- a/dGame/dComponents/PetComponent.cpp +++ b/dGame/dComponents/PetComponent.cpp @@ -886,7 +886,7 @@ void PetComponent::OnInteract() { } } -void PetComponent::StartInteract(const NiPoint3 position, const PetInteractType interactType, const LWOOBJID interactID) { +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(ePetAbilityType::GoToObject); @@ -978,6 +978,7 @@ void PetComponent::HandleInteractBouncer() { if (IsHandlingInteraction()) { auto* const owner = GetOwner(); if (!owner) return; + const auto sysAddr = owner->GetSystemAddress(); auto* const petSwitch = SwitchComponent::GetClosestSwitch(m_MovementAI->GetDestination()); // TODO: Find a better way to do this if (!petSwitch) return; @@ -985,16 +986,25 @@ void PetComponent::HandleInteractBouncer() { auto* const petSwitchEntity = petSwitch->GetParentEntity(); if (!petSwitchEntity) return; - m_Parent->AddCallbackTimer(2.0f, [petSwitch, petSwitchEntity]() { + m_Parent->AddCallbackTimer(1.0f, [this, petSwitch, petSwitchEntity, sysAddr]() { LOG_DEBUG("Callback start!"); - petSwitch->GetPetBouncer()->SetPetBouncerEnabled(false); + const auto bouncerComp = petSwitch->GetPetBouncer(); + const auto bouncerCompPos = bouncerComp->GetParentEntity()->GetPosition(); + const auto bouncerId = bouncerComp->GetParentEntity()->GetObjectID(); + + const auto petId = this->GetParentEntity()->GetObjectID(); + + RenderComponent::PlayAnimation(petSwitchEntity, u"launch"); //u"engaged"); + bouncerComp->SetPetBouncerEnabled(true); + GameMessages::SendRequestClientBounce(bouncerId, this->GetOwnerId(), NiPoint3::ZERO, NiPoint3::ZERO, bouncerId, true, false, UNASSIGNED_SYSTEM_ADDRESS); //TODO: Check packet captures!! + bouncerComp->SetPetBouncerEnabled(false); RenderComponent::PlayAnimation(petSwitchEntity, u"up"); LOG_DEBUG("Callback end!"); - }); + }); - RenderComponent::PlayAnimation(petSwitchEntity, u"launch"); //u"engaged"); + //RenderComponent::PlayAnimation(petSwitchEntity, u"launch"); //u"engaged"); auto* const petBouncer = petSwitch->GetPetBouncer(); petBouncer->SetPetBouncerEnabled(true); @@ -1223,7 +1233,7 @@ void PetComponent::Release() { item->SetCount(0, false, false); } -void PetComponent::Command(NiPoint3 position, LWOOBJID source, int32_t commandType, int32_t typeId, bool overrideObey) { +void PetComponent::Command(const NiPoint3& position, const LWOOBJID& source, int32_t commandType, int32_t typeId, bool overrideObey) { auto* owner = GetOwner(); if (!owner) return; diff --git a/dGame/dComponents/PetComponent.h b/dGame/dComponents/PetComponent.h index 689db919..f8008231 100644 --- a/dGame/dComponents/PetComponent.h +++ b/dGame/dComponents/PetComponent.h @@ -93,35 +93,35 @@ public: * @param flag PetFlag(s) to set */ template - void SetFlag(varArg... flag) { m_Flags |= (static_cast(flag) | ...); }; + inline void SetFlag(varArg... flag) { m_Flags |= (static_cast(flag) | ...); }; /** * Sets the pet to ONLY have the specified flag(s), clearing all others * @param flag PetFlag(s) to set exclusively */ template - void SetOnlyFlag(varArg... flag) { m_Flags = (static_cast(flag) | ...); }; + inline void SetOnlyFlag(varArg... flag) { m_Flags = (static_cast(flag) | ...); }; /** * Unsets one or more pet flags * @param flag PetFlag(s) to unset */ template - void UnsetFlag(varArg... flag) { m_Flags &= ~(static_cast(flag) | ...); }; + inline void UnsetFlag(varArg... flag) { m_Flags &= ~(static_cast(flag) | ...); }; /** * Returns true if the pet has all the specified flag(s) * @param flag PetFlag(s) to check */ template - const bool HasFlag(varArg... flag) { return (m_Flags & (static_cast(flag) | ...)) == (static_cast(flag) | ...); }; + inline constexpr bool HasFlag(varArg... flag) { return (m_Flags & (static_cast(flag) | ...)) == (static_cast(flag) | ...); }; /** * Returns true if the pet has ONLY the specified flag(s) * @param flag PetFlag(s) to check if the pet has exclusively */ template - const bool HasOnlyFlag(varArg... flag) { return m_Flags == (static_cast(flag) | ...); }; + inline constexpr bool HasOnlyFlag(varArg... flag) { return m_Flags == (static_cast(flag) | ...); }; /** * Governs the pet update loop @@ -202,7 +202,7 @@ public: /** * Start a pet interaction with an object at a given position */ - void StartInteract(const NiPoint3 position, const PetInteractType interactType, const LWOOBJID interactID); + void StartInteract(const NiPoint3& position, const PetInteractType interactType, const LWOOBJID& interactID); /** * Stop a pet interaction with an object @@ -245,7 +245,7 @@ public: * @param typeId extra information about the command, e.g. the emote to play * @param overrideObey unused */ - void Command(NiPoint3 position, LWOOBJID source, int32_t commandType, int32_t typeId, bool overrideObey); + void Command(const NiPoint3& position, const LWOOBJID& source, int32_t commandType, int32_t typeId, bool overrideObey); /** * Returns the ID of the owner of this pet (if any) diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 2151005a..fd334097 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -3589,6 +3589,35 @@ void GameMessages::SendBouncerActiveStatus(LWOOBJID objectId, bool bActive, cons SEND_PACKET; } +void GameMessages::SendRequestClientBounce(const LWOOBJID& objectId, const LWOOBJID& bounceTargetId, const NiPoint3& bounceTargetPos, const NiPoint3& bouncedObjLinVel, const LWOOBJID& requestSourceId, const bool bAllBounced, const bool bAllowClientOverload, const SystemAddress& sysAddr) { + LOG_DEBUG("REQUEST CLIENT BOUNCE!"); + + CBITSTREAM; + CMSGHEADER; + + bitStream.Write(objectId); + LOG_DEBUG("Object id: %llu", objectId); + bitStream.Write(eGameMessageType::REQUEST_CLIENT_BOUNCE); + + bitStream.Write(bounceTargetId); + LOG_DEBUG("Bounce target id: %llu", bounceTargetId); + bitStream.Write(bounceTargetPos.x); + bitStream.Write(bounceTargetPos.y); + bitStream.Write(bounceTargetPos.z); + LOG_DEBUG("Bounce target pos on server: %f %f %f", bounceTargetPos.x, bounceTargetPos.y, bounceTargetPos.z); + bitStream.Write(bouncedObjLinVel.x); + bitStream.Write(bouncedObjLinVel.y); + bitStream.Write(bouncedObjLinVel.z); + LOG_DEBUG("Bounced object linear velocity: %f %f %f", bouncedObjLinVel.x, bouncedObjLinVel.y, bouncedObjLinVel.z); + bitStream.Write(requestSourceId); + LOG_DEBUG("Request source id: %llu", requestSourceId); + + bitStream.Write(bAllBounced); + bitStream.Write(bAllowClientOverload); + + if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST; + SEND_PACKET; +} void GameMessages::SendSetPetName(LWOOBJID objectId, std::u16string name, LWOOBJID petDBID, const SystemAddress& sysAddr) { CBITSTREAM; diff --git a/dGame/dGameMessages/GameMessages.h b/dGame/dGameMessages/GameMessages.h index 132a6143..bd898299 100644 --- a/dGame/dGameMessages/GameMessages.h +++ b/dGame/dGameMessages/GameMessages.h @@ -393,8 +393,26 @@ namespace GameMessages { void SendPlayEmote(LWOOBJID objectId, int32_t emoteID, LWOOBJID target, const SystemAddress& sysAddr); + /** + * Sends the bouncer active status + * @param objectId Object ID of the bouncer + * @param bActive Active state of the bouncer + * @param sysAddr System address of the user + */ void SendBouncerActiveStatus(LWOOBJID objectId, bool bActive, const SystemAddress& sysAddr); + /** + * Sends a request to the client to bounce (I think?) + * @param objectId Object ID + * @param bounceTargetId The object ID of the bounce target + * @param bounceTargetPos The position of the bounce target + * @param bouncedObjLinVel TODO: UNUSED + * @param requestSourceId The object Id of the entity requesting the bounce + * @param bAllBounced Whether to bounce all entities standing on the bouncer pad + * @param bAllowClientOverload TODO: UNUSED + */ + void SendRequestClientBounce(const LWOOBJID& objectId, const LWOOBJID& bounceTargetId, const NiPoint3& bounceTargetPos, const NiPoint3& bouncedObjLinVel, const LWOOBJID& requestSourceId, const bool bAllBounced, const bool bAllowClientOverload, const SystemAddress& sysAddr); + void SendSetPetName(LWOOBJID objectId, std::u16string name, LWOOBJID petDBID, const SystemAddress& sysAddr); void SendSetPetNameModerated(LWOOBJID objectId, LWOOBJID petDBID, int32_t nModerationStatus, const SystemAddress& sysAddr);