DarkflameServer/dGame/dComponents/RenderComponent.cpp

227 lines
4.9 KiB
C++
Raw Permalink Normal View History

#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"
2022-07-28 13:39:57 +00:00
std::unordered_map<int32_t, float> RenderComponent::m_DurationCache{};
RenderComponent::RenderComponent(Entity* parent) : Component(parent) {
2022-07-28 13:39:57 +00:00
m_Effects = std::vector<Effect*>();
2022-07-28 13:39:57 +00:00
return;
2022-07-28 13:39:57 +00:00
/*
auto* table = CDClientManager::Instance().GetTable<CDComponentsRegistryTable>();
const auto entry = table->GetByIDAndType(parent->GetLOT(), eReplicaComponentType::RENDER);
std::stringstream query;
2022-07-28 13:39:57 +00:00
query << "SELECT effect1, effect2, effect3, effect4, effect5, effect6 FROM RenderComponent WHERE id = " << std::to_string(entry) << ";";
2022-07-28 13:39:57 +00:00
auto result = CDClientDatabase::ExecuteQuery(query.str());
if (result.eof())
{
return;
}
for (auto i = 0; i < 6; ++i)
2022-07-28 13:39:57 +00:00
{
if (result.fieldIsNull(i))
{
continue;
}
2022-07-28 13:39:57 +00:00
const auto id = result.getIntField(i);
if (id <= 0)
{
continue;
}
2022-07-28 13:39:57 +00:00
query.clear();
query << "SELECT effectType, effectName FROM BehaviorEffect WHERE effectID = " << std::to_string(id) << ";";
2022-07-28 13:39:57 +00:00
auto effectResult = CDClientDatabase::ExecuteQuery(query.str());
2022-07-28 13:39:57 +00:00
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));
2022-07-28 13:39:57 +00:00
auto* effect = new Effect();
2022-07-28 13:39:57 +00:00
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();
2022-07-28 13:39:57 +00:00
*/
}
RenderComponent::~RenderComponent() {
2022-07-28 13:39:57 +00:00
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) {
2022-07-28 13:39:57 +00:00
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) {
2022-07-28 13:39:57 +00:00
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) {
2022-07-28 13:39:57 +00:00
uint32_t index = -1;
2022-07-28 13:39:57 +00:00
for (auto i = 0u; i < m_Effects.size(); ++i) {
auto* eff = m_Effects[i];
2022-07-28 13:39:57 +00:00
if (eff->name == name) {
index = i;
2022-07-28 13:39:57 +00:00
delete eff;
2022-07-28 13:39:57 +00:00
break;
}
}
2022-07-28 13:39:57 +00:00
if (index == -1) {
return;
}
2022-07-28 13:39:57 +00:00
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);
}
}
2022-07-28 13:39:57 +00:00
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);
2022-07-28 13:39:57 +00:00
GameMessages::SendPlayFXEffect(m_Parent, effectId, effectType, name, secondary, priority, scale, serialize);
2022-07-28 13:39:57 +00:00
auto* effect = AddEffect(effectId, name, effectType);
2022-07-28 13:39:57 +00:00
const auto& pair = m_DurationCache.find(effectId);
2022-07-28 13:39:57 +00:00
if (pair != m_DurationCache.end()) {
effect->time = pair->second;
2022-07-28 13:39:57 +00:00
return;
}
2022-07-28 13:39:57 +00:00
const std::string effectType_str = GeneralUtils::UTF16ToWTF8(effectType);
2022-07-28 13:39:57 +00:00
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());
2022-07-28 13:39:57 +00:00
auto result = query.execQuery();
2022-07-28 13:39:57 +00:00
if (result.eof() || result.fieldIsNull(0)) {
result.finalize();
2022-07-28 13:39:57 +00:00
m_DurationCache[effectId] = 0;
effect->time = 0; // Persistent effect
return;
}
effect->time = static_cast<float>(result.getFloatField(0));
result.finalize();
2022-07-28 13:39:57 +00:00
m_DurationCache[effectId] = effect->time;
}
2022-07-28 13:39:57 +00:00
void RenderComponent::StopEffect(const std::string& name, const bool killImmediate) {
GameMessages::SendStopFXEffect(m_Parent, killImmediate, name);
2022-07-28 13:39:57 +00:00
RemoveEffect(name);
}
2022-07-28 13:39:57 +00:00
std::vector<Effect*>& RenderComponent::GetEffects() {
return m_Effects;
}