mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-11-14 15:57:13 +00:00
The level, forced movement, possessable, possessor and combat AI parts are each read behind a flag bit (LWOLevelProgressionComponent:: Deserialize 0x00c63bd0 and the others). DLU cleared their dirty flags when it wrote a construction, which goes only to the client the object came into range of, so a change waiting for the next update never reached the clients already watching: a level up, a mount or dismount, a rail ride. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
66 lines
2.4 KiB
C++
66 lines
2.4 KiB
C++
#include "PossessableComponent.h"
|
|
#include "ObjectMessages.h"
|
|
#include "PossessorComponent.h"
|
|
#include "EntityManager.h"
|
|
#include "Inventory.h"
|
|
#include "Item.h"
|
|
|
|
PossessableComponent::PossessableComponent(Entity* parent, const int32_t componentID) : Component(parent, componentID) {
|
|
RegisterMsg(&PossessableComponent::OnRequestUse);
|
|
m_Possessor = LWOOBJID_EMPTY;
|
|
}
|
|
|
|
// The item's animation flag and the PossessableComponent row
|
|
void PossessableComponent::LoadDataFromTemplate() {
|
|
CDItemComponent item = Inventory::FindItemComponent(m_Parent->GetLOT());
|
|
m_AnimationFlag = static_cast<eAnimationFlags>(item.animationFlag);
|
|
|
|
// Get the possession Type from the CDClient
|
|
auto query = CDClientDatabase::CreatePreppedStmt("SELECT possessionType, depossessOnHit, skillSet FROM PossessableComponent WHERE id = ?;");
|
|
|
|
query.bind(1, static_cast<int>(m_ComponentID));
|
|
|
|
auto result = query.execQuery();
|
|
|
|
// Should a result not exist for this default to attached visible
|
|
if (!result.eof()) {
|
|
m_PossessionType = static_cast<ePossessionType>(result.getIntField("possessionType", 1)); // Default to Attached Visible
|
|
m_DepossessOnHit = static_cast<bool>(result.getIntField("depossessOnHit", 0));
|
|
m_SkillSet = result.getIntField("skillSet", 0);
|
|
} else {
|
|
m_PossessionType = ePossessionType::ATTACHED_VISIBLE;
|
|
m_DepossessOnHit = false;
|
|
}
|
|
result.finalize();
|
|
}
|
|
|
|
void PossessableComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
|
outBitStream.Write(m_DirtyPossessable || bIsInitialUpdate);
|
|
if (m_DirtyPossessable || bIsInitialUpdate) {
|
|
if (!bIsInitialUpdate) m_DirtyPossessable = false; // reset flag
|
|
outBitStream.Write(m_Possessor != LWOOBJID_EMPTY);
|
|
if (m_Possessor != LWOOBJID_EMPTY) outBitStream.Write(m_Possessor);
|
|
|
|
outBitStream.Write(m_AnimationFlag != eAnimationFlags::IDLE_NONE);
|
|
if (m_AnimationFlag != eAnimationFlags::IDLE_NONE) outBitStream.Write(m_AnimationFlag);
|
|
|
|
outBitStream.Write(m_ImmediatelyDepossess);
|
|
if (!bIsInitialUpdate) m_ImmediatelyDepossess = false; // reset flag
|
|
}
|
|
}
|
|
|
|
void PossessableComponent::Dismount() {
|
|
SetPossessor(LWOOBJID_EMPTY);
|
|
if (m_ItemSpawned) m_Parent->ScheduleKillAfterUpdate();
|
|
}
|
|
|
|
bool PossessableComponent::OnRequestUse(GameMessages::RequestUseEvent& event) {
|
|
if (event.msg.IsMissionChoice()) return false;
|
|
auto* const originator = event.user;
|
|
auto* possessor = originator->GetComponent<PossessorComponent>();
|
|
if (possessor) {
|
|
possessor->Mount(m_Parent);
|
|
}
|
|
return true;
|
|
}
|