mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-11-14 07:47:13 +00:00
LWOCollectibleComponent::Deserialize (0x00c45ec0) reads the 16-bit id on construction and nothing on an update. DLU wrote the id on every serialization, so the client read 16 stray bits as the flag bits of the components after it. The replica decoder follows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
81 lines
3.2 KiB
C++
81 lines
3.2 KiB
C++
#include "CollectibleComponent.h"
|
|
|
|
#include "MissionComponent.h"
|
|
#include "dServer.h"
|
|
#include "Amf3.h"
|
|
#include "CDClientManager.h"
|
|
#include "CDCollectibleComponentTable.h"
|
|
#include "CDMissionsTable.h"
|
|
#include "eMissionState.h"
|
|
#include "Entity.h"
|
|
#include "ObjectLoadState.h"
|
|
#include "DestroyableComponent.h"
|
|
|
|
CollectibleComponent::CollectibleComponent(Entity* parentEntity, const int32_t componentID, const int32_t collectibleId) :
|
|
Component(parentEntity, componentID), m_CollectibleId(collectibleId) {
|
|
RegisterMsg(&CollectibleComponent::MsgGetObjectReportInfo);
|
|
}
|
|
|
|
// The CollectibleComponent row
|
|
void CollectibleComponent::LoadDataFromTemplate() {
|
|
const auto* const row = CDClientManager::GetTable<CDCollectibleComponentTable>()->GetByID(m_ComponentID);
|
|
if (row) m_RequirementMission = row->requirementMission;
|
|
}
|
|
|
|
bool CollectibleComponent::CountsFor(const Entity& player) const {
|
|
if (m_RequirementMission <= 0) return true;
|
|
bool found = false;
|
|
const auto& mission = CDClientManager::GetTable<CDMissionsTable>()->GetByMissionID(m_RequirementMission, found);
|
|
// Not a mission (rows with 66666666), or an achievement: nothing to accept first
|
|
if (!found || !mission.isMission) return true;
|
|
|
|
const auto* const missionComponent = player.GetComponent<MissionComponent>();
|
|
if (!missionComponent) return false;
|
|
switch (missionComponent->GetMissionState(m_RequirementMission)) {
|
|
case eMissionState::ACTIVE:
|
|
case eMissionState::READY_TO_COMPLETE:
|
|
case eMissionState::COMPLETE_ACTIVE:
|
|
case eMissionState::COMPLETE_READY_TO_COMPLETE:
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// LWOCollectibleComponent::Deserialize (0x00c45ec0) reads the id on construction only
|
|
void CollectibleComponent::Serialize(RakNet::BitStream& outBitStream, bool isConstruction) {
|
|
if (isConstruction) outBitStream.Write(GetCollectibleId());
|
|
}
|
|
|
|
bool CollectibleComponent::MsgGetObjectReportInfo(GameMessages::GetObjectReportInfo& reportMsg) {
|
|
auto& cmptType = reportMsg.info->PushDebug("Collectible");
|
|
auto collectibleID = static_cast<uint32_t>(m_CollectibleId) + static_cast<uint32_t>(Game::server->GetZoneID() << 8);
|
|
|
|
cmptType.PushDebug<AMFIntValue>("Component ID") = GetComponentID();
|
|
|
|
cmptType.PushDebug<AMFIntValue>("Collectible ID") = GetCollectibleId();
|
|
cmptType.PushDebug<AMFIntValue>("Requirement mission") = m_RequirementMission;
|
|
cmptType.PushDebug<AMFIntValue>("Mission Tracking ID (for save data)") = collectibleID;
|
|
|
|
auto* localCharEntity = Game::entityManager->GetEntity(reportMsg.clientID);
|
|
bool collected = false;
|
|
if (localCharEntity) {
|
|
auto* missionComponent = localCharEntity->GetComponent<MissionComponent>();
|
|
|
|
if (m_CollectibleId != 0) {
|
|
collected = missionComponent->HasCollectible(collectibleID);
|
|
}
|
|
}
|
|
|
|
cmptType.PushDebug<AMFBoolValue>("Has been collected") = collected;
|
|
return true;
|
|
}
|
|
|
|
void CollectibleComponent::Allocator(Entity& entity, ObjectLoadState& state) {
|
|
if (state.GetComponentID(eReplicaComponentType::COLLECTIBLE) > 0) {
|
|
entity.AddComponent<CollectibleComponent>(state.GetComponentID(eReplicaComponentType::COLLECTIBLE), entity.GetVarAs<int32_t>(u"collectible_id"));
|
|
// The client makes a collectible's destroyable right after it when there is none
|
|
if (!entity.HasComponent(eReplicaComponentType::DESTROYABLE)) entity.AddComponent<DestroyableComponent>(-1);
|
|
}
|
|
}
|