DarkflameServer/dGame/dComponents/RenderComponent.cpp
David Markowitz 7671cc6865
CDClient cleanup and optimization (#1023)
* CDClient cleanup and optimization

- Use static function to get table name
- Remove unused GetName function
- Replace above function with a static GetTableName function
- Remove verbose comments
- Remove verbose initializers
- Remove need to specify table name when getting a table by name
- Remove unused typedef for mac and linux

* Re-add unused table

Convert tables to singletons

- Convert all CDClient tables to singletons
- Move Singleton.h to dCommon
- Reduce header clutter in CDClientManager
2023-03-17 07:36:21 -07:00

227 lines
4.9 KiB
C++

#include "RenderComponent.h"
#include <sstream>
#include <string>
#include <iomanip>
#include "Entity.h"
#include "PacketUtils.h"
#include "CDClientManager.h"
#include "GameMessages.h"
#include "Game.h"
#include "dLogger.h"
std::unordered_map<int32_t, float> RenderComponent::m_DurationCache{};
RenderComponent::RenderComponent(Entity* parent) : Component(parent) {
m_Effects = std::vector<Effect*>();
return;
/*
auto* table = CDClientManager::Instance().GetTable<CDComponentsRegistryTable>();
const auto entry = table->GetByIDAndType(parent->GetLOT(), eReplicaComponentType::RENDER);
std::stringstream query;
query << "SELECT effect1, effect2, effect3, effect4, effect5, effect6 FROM RenderComponent WHERE id = " << std::to_string(entry) << ";";
auto result = CDClientDatabase::ExecuteQuery(query.str());
if (result.eof())
{
return;
}
for (auto i = 0; i < 6; ++i)
{
if (result.fieldIsNull(i))
{
continue;
}
const auto id = result.getIntField(i);
if (id <= 0)
{
continue;
}
query.clear();
query << "SELECT effectType, effectName FROM BehaviorEffect WHERE effectID = " << std::to_string(id) << ";";
auto effectResult = CDClientDatabase::ExecuteQuery(query.str());
while (!effectResult.eof())
{
const auto type = effectResult.fieldIsNull(0) ? "" : std::string(effectResult.getStringField(0));
const auto name = effectResult.fieldIsNull(1) ? "" : std::string(effectResult.getStringField(1));
auto* effect = new Effect();
effect->name = name;
effect->type = GeneralUtils::ASCIIToUTF16(type);
effect->scale = 1;
effect->effectID = id;
effect->secondary = LWOOBJID_EMPTY;
m_Effects.push_back(effect);
effectResult.nextRow();
}
}
result.finalize();
*/
}
RenderComponent::~RenderComponent() {
for (Effect* eff : m_Effects) {
if (eff) {
delete eff;
eff = nullptr;
}
}
m_Effects.clear();
}
void RenderComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) {
if (!bIsInitialUpdate) return;
outBitStream->Write<uint32_t>(m_Effects.size());
for (Effect* eff : m_Effects) {
// Check that the effect is non-null
assert(eff);
outBitStream->Write<uint8_t>(eff->name.size());
for (const auto& value : eff->name)
outBitStream->Write<uint8_t>(value);
outBitStream->Write(eff->effectID);
outBitStream->Write<uint8_t>(eff->type.size());
for (const auto& value : eff->type)
outBitStream->Write<uint16_t>(value);
outBitStream->Write<float_t>(eff->scale);
outBitStream->Write<int64_t>(eff->secondary);
}
}
Effect* RenderComponent::AddEffect(const int32_t effectId, const std::string& name, const std::u16string& type) {
auto* eff = new Effect();
eff->effectID = effectId;
eff->name = name;
eff->type = type;
m_Effects.push_back(eff);
return eff;
}
void RenderComponent::RemoveEffect(const std::string& name) {
uint32_t index = -1;
for (auto i = 0u; i < m_Effects.size(); ++i) {
auto* eff = m_Effects[i];
if (eff->name == name) {
index = i;
delete eff;
break;
}
}
if (index == -1) {
return;
}
m_Effects.erase(m_Effects.begin() + index);
}
void RenderComponent::Update(const float deltaTime) {
std::vector<Effect*> dead;
for (auto* effect : m_Effects) {
if (effect->time == 0) {
continue; // Skip persistent effects
}
const auto result = effect->time - deltaTime;
if (result <= 0) {
dead.push_back(effect);
continue;
}
effect->time = result;
}
for (auto* effect : dead) {
// StopEffect(effect->name);
}
}
void RenderComponent::PlayEffect(const int32_t effectId, const std::u16string& effectType, const std::string& name, const LWOOBJID secondary, const float priority, const float scale, const bool serialize) {
RemoveEffect(name);
GameMessages::SendPlayFXEffect(m_Parent, effectId, effectType, name, secondary, priority, scale, serialize);
auto* effect = AddEffect(effectId, name, effectType);
const auto& pair = m_DurationCache.find(effectId);
if (pair != m_DurationCache.end()) {
effect->time = pair->second;
return;
}
const std::string effectType_str = GeneralUtils::UTF16ToWTF8(effectType);
auto query = CDClientDatabase::CreatePreppedStmt(
"SELECT animation_length FROM Animations WHERE animation_type IN (SELECT animationName FROM BehaviorEffect WHERE effectID = ? AND effectType = ?);");
query.bind(1, effectId);
query.bind(2, effectType_str.c_str());
auto result = query.execQuery();
if (result.eof() || result.fieldIsNull(0)) {
result.finalize();
m_DurationCache[effectId] = 0;
effect->time = 0; // Persistent effect
return;
}
effect->time = static_cast<float>(result.getFloatField(0));
result.finalize();
m_DurationCache[effectId] = effect->time;
}
void RenderComponent::StopEffect(const std::string& name, const bool killImmediate) {
GameMessages::SendStopFXEffect(m_Parent, killImmediate, name);
RemoveEffect(name);
}
std::vector<Effect*>& RenderComponent::GetEffects() {
return m_Effects;
}