#include "LevelProgressionComponent.h" #include "ControllablePhysicsComponent.h" #include "InventoryComponent.h" #include "CharacterComponent.h" #include "tinyxml2.h" #include "CDRewardsTable.h" LevelProgressionComponent::LevelProgressionComponent(Entity* parent) : Component(parent) { m_ParentEntity = parent; m_Level = 1; m_SpeedBase = 500.0f; m_CharacterVersion = eCharacterVersion::LIVE; } void LevelProgressionComponent::UpdateXml(tinyxml2::XMLDocument* doc) { tinyxml2::XMLElement* level = doc->FirstChildElement("obj")->FirstChildElement("lvl"); if (!level) { Game::logger->Log("LevelProgressionComponent", "Failed to find lvl tag while updating XML!"); return; } level->SetAttribute("l", m_Level); level->SetAttribute("sb", m_SpeedBase); level->SetAttribute("cv", static_cast(m_CharacterVersion)); } void LevelProgressionComponent::LoadFromXml(tinyxml2::XMLDocument* doc) { tinyxml2::XMLElement* level = doc->FirstChildElement("obj")->FirstChildElement("lvl"); if (!level) { Game::logger->Log("LevelProgressionComponent", "Failed to find lvl tag while loading XML!"); return; } level->QueryAttribute("l", &m_Level); level->QueryAttribute("sb", &m_SpeedBase); uint32_t characterVersion; level->QueryAttribute("cv", &characterVersion); m_CharacterVersion = static_cast(characterVersion); auto* controllablePhysicsComponent = m_ParentEntity->GetComponent(); if (!controllablePhysicsComponent) return; controllablePhysicsComponent->SetSpeedMultiplier(GetSpeedBase() / 500.0f); } void LevelProgressionComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) { outBitStream->Write(bIsInitialUpdate || m_DirtyLevelInfo); if (bIsInitialUpdate || m_DirtyLevelInfo) { outBitStream->Write(m_Level); if (!bIsInitialUpdate) m_DirtyLevelInfo = false; } } void LevelProgressionComponent::HandleLevelUp() { auto* rewardsTable = CDClientManager::Instance().GetTable(); const auto& rewards = rewardsTable->GetByLevelID(m_Level); if (rewards.empty()) return; auto* inventoryComponent = m_ParentEntity->GetComponent(); auto* controllablePhysicsComponent = m_ParentEntity->GetComponent(); if (!inventoryComponent || !controllablePhysicsComponent) return; // Tell the client we beginning to send level rewards. GameMessages::NotifyLevelRewards(m_ParentEntity->GetObjectID(), m_ParentEntity->GetSystemAddress(), m_Level, true); for (auto* reward : rewards) { switch (reward->rewardType) { case 0: inventoryComponent->AddItem(reward->value, reward->count, eLootSourceType::LEVEL_REWARD); break; case 4: { auto* items = inventoryComponent->GetInventory(eInventoryType::ITEMS); if (!items) continue; items->SetSize(items->GetSize() + reward->value); break; } case 9: SetSpeedBase(static_cast(reward->value)); controllablePhysicsComponent->SetSpeedMultiplier(GetSpeedBase() / 500.0f); break; case 11: case 12: default: break; } } // Tell the client we have finished sending level rewards. GameMessages::NotifyLevelRewards(m_ParentEntity->GetObjectID(), m_ParentEntity->GetSystemAddress(), m_Level, false); } void LevelProgressionComponent::SetRetroactiveBaseSpeed() { if (m_Level >= 20) m_SpeedBase = 525.0f; auto* controllablePhysicsComponent = m_ParentEntity->GetComponent(); if (controllablePhysicsComponent) controllablePhysicsComponent->SetSpeedMultiplier(m_SpeedBase / 500.0f); }