mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-05-23 15:22:28 +00:00
Buff Component fixes
This commit is contained in:
parent
06acd23cb7
commit
d29287f9d9
@ -16,12 +16,10 @@ std::unordered_map<int32_t, std::vector<BuffParameter>> BuffComponent::m_Cache{}
|
|||||||
|
|
||||||
void BuffComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) {
|
void BuffComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) {
|
||||||
if (!bIsInitialUpdate) return;
|
if (!bIsInitialUpdate) return;
|
||||||
if (m_Buffs.empty()) {
|
|
||||||
outBitStream->Write0();
|
|
||||||
} else {
|
|
||||||
outBitStream->Write1();
|
|
||||||
outBitStream->Write<uint32_t>(m_Buffs.size());
|
|
||||||
|
|
||||||
|
outBitStream->Write(!m_Buffs.empty());
|
||||||
|
if (!m_Buffs.empty()) {
|
||||||
|
outBitStream->Write<uint32_t>(m_Buffs.size());
|
||||||
for (const auto& buff : m_Buffs) {
|
for (const auto& buff : m_Buffs) {
|
||||||
outBitStream->Write<uint32_t>(buff.first);
|
outBitStream->Write<uint32_t>(buff.first);
|
||||||
outBitStream->Write0();
|
outBitStream->Write0();
|
||||||
@ -41,7 +39,7 @@ void BuffComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
outBitStream->Write0();
|
outBitStream->Write0(); // immunities
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuffComponent::Update(float deltaTime) {
|
void BuffComponent::Update(float deltaTime) {
|
||||||
@ -49,30 +47,28 @@ void BuffComponent::Update(float deltaTime) {
|
|||||||
* Loop through all buffs and apply deltaTime to ther time.
|
* Loop through all buffs and apply deltaTime to ther time.
|
||||||
* If they have expired, remove the buff and break.
|
* If they have expired, remove the buff and break.
|
||||||
*/
|
*/
|
||||||
for (auto& buff : m_Buffs) {
|
for (auto& [buffId, buffInfo] : m_Buffs) {
|
||||||
// For damage buffs
|
// For damage buffs
|
||||||
if (buff.second.tick != 0.0f && buff.second.stacks > 0) {
|
if (buffInfo.tick != 0.0f && buffInfo.stacks > 0) {
|
||||||
buff.second.tickTime -= deltaTime;
|
buffInfo.tickTime -= deltaTime;
|
||||||
|
|
||||||
if (buff.second.tickTime <= 0.0f) {
|
if (buffInfo.tickTime <= 0.0f) {
|
||||||
buff.second.tickTime = buff.second.tick;
|
buffInfo.tickTime = buffInfo.tick;
|
||||||
buff.second.stacks--;
|
buffInfo.stacks--;
|
||||||
|
|
||||||
SkillComponent::HandleUnmanaged(buff.second.behaviorID, m_ParentEntity->GetObjectID(), buff.second.source);
|
SkillComponent::HandleUnmanaged(buffInfo.behaviorID, m_ParentEntity->GetObjectID(), buffInfo.source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// These are indefinate buffs, don't update them.
|
// These are indefinate buffs, don't update them.
|
||||||
if (buff.second.time == 0.0f) {
|
if (buffInfo.time == 0.0f) continue;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
buff.second.time -= deltaTime;
|
buffInfo.time -= deltaTime;
|
||||||
|
|
||||||
if (buff.second.time <= 0.0f) {
|
if (buffInfo.time <= 0.0f) {
|
||||||
RemoveBuff(buff.first);
|
RemoveBuff(buffId);
|
||||||
|
|
||||||
break;
|
break; // Break because we modified or may modify the map.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -81,9 +77,7 @@ void BuffComponent::ApplyBuff(const int32_t id, const float duration, const LWOO
|
|||||||
bool cancelOnDamaged, bool cancelOnDeath, bool cancelOnLogout, bool cancelOnRemoveBuff,
|
bool cancelOnDamaged, bool cancelOnDeath, bool cancelOnLogout, bool cancelOnRemoveBuff,
|
||||||
bool cancelOnUi, bool cancelOnUnequip, bool cancelOnZone) {
|
bool cancelOnUi, bool cancelOnUnequip, bool cancelOnZone) {
|
||||||
// Prevent buffs from stacking.
|
// Prevent buffs from stacking.
|
||||||
if (HasBuff(id)) {
|
if (HasBuff(id)) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
GameMessages::SendAddBuff(m_ParentEntity->GetObjectID(), source, (uint32_t)id,
|
GameMessages::SendAddBuff(m_ParentEntity->GetObjectID(), source, (uint32_t)id,
|
||||||
(uint32_t)duration * 1000, addImmunity, cancelOnDamaged, cancelOnDeath,
|
(uint32_t)duration * 1000, addImmunity, cancelOnDamaged, cancelOnDeath,
|
||||||
@ -94,14 +88,14 @@ void BuffComponent::ApplyBuff(const int32_t id, const float duration, const LWOO
|
|||||||
int32_t behaviorID = 0;
|
int32_t behaviorID = 0;
|
||||||
|
|
||||||
const auto& parameters = GetBuffParameters(id);
|
const auto& parameters = GetBuffParameters(id);
|
||||||
|
auto* skillBehaviorTable = CDClientManager::Instance().GetTable<CDSkillBehaviorTable>();
|
||||||
for (const auto& parameter : parameters) {
|
for (const auto& parameter : parameters) {
|
||||||
if (parameter.name == "overtime") {
|
if (parameter.name == "overtime") {
|
||||||
auto* behaviorTemplateTable = CDClientManager::Instance().GetTable<CDSkillBehaviorTable>();
|
|
||||||
|
|
||||||
behaviorID = behaviorTemplateTable->GetSkillByID(parameter.values[0]).behaviorID;
|
behaviorID = skillBehaviorTable->GetSkillByID(parameter.values.skillId).behaviorID;
|
||||||
stacks = static_cast<int32_t>(parameter.values[1]);
|
stacks = static_cast<int32_t>(parameter.values.stacks);
|
||||||
tick = parameter.values[2];
|
tick = parameter.values.tick;
|
||||||
const auto unknown2 = parameter.values[3]; // Always 0
|
const auto unknown2 = parameter.values.unknown2; // Always 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,15 +110,13 @@ void BuffComponent::ApplyBuff(const int32_t id, const float duration, const LWOO
|
|||||||
buff.source = source;
|
buff.source = source;
|
||||||
buff.behaviorID = behaviorID;
|
buff.behaviorID = behaviorID;
|
||||||
|
|
||||||
m_Buffs.emplace(id, buff);
|
m_Buffs.insert_or_assign(id, buff);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuffComponent::RemoveBuff(int32_t id, bool fromUnEquip, bool removeImmunity) {
|
void BuffComponent::RemoveBuff(int32_t id, bool fromUnEquip, bool removeImmunity) {
|
||||||
const auto& iter = m_Buffs.find(id);
|
const auto& iter = m_Buffs.find(id);
|
||||||
|
|
||||||
if (iter == m_Buffs.end()) {
|
if (iter == m_Buffs.end()) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
GameMessages::SendRemoveBuff(m_ParentEntity, fromUnEquip, removeImmunity, id);
|
GameMessages::SendRemoveBuff(m_ParentEntity, fromUnEquip, removeImmunity, id);
|
||||||
|
|
||||||
@ -181,7 +173,7 @@ void BuffComponent::RemoveBuffEffect(int32_t id) {
|
|||||||
|
|
||||||
auto* destroyable = this->GetParentEntity()->GetComponent<DestroyableComponent>();
|
auto* destroyable = this->GetParentEntity()->GetComponent<DestroyableComponent>();
|
||||||
|
|
||||||
if (destroyable == nullptr) return;
|
if (!destroyable) return;
|
||||||
|
|
||||||
destroyable->SetMaxHealth(destroyable->GetMaxHealth() - maxHealth);
|
destroyable->SetMaxHealth(destroyable->GetMaxHealth() - maxHealth);
|
||||||
} else if (parameter.name == "max_armor") {
|
} else if (parameter.name == "max_armor") {
|
||||||
@ -189,7 +181,7 @@ void BuffComponent::RemoveBuffEffect(int32_t id) {
|
|||||||
|
|
||||||
auto* destroyable = this->GetParentEntity()->GetComponent<DestroyableComponent>();
|
auto* destroyable = this->GetParentEntity()->GetComponent<DestroyableComponent>();
|
||||||
|
|
||||||
if (destroyable == nullptr) return;
|
if (!destroyable) return;
|
||||||
|
|
||||||
destroyable->SetMaxArmor(destroyable->GetMaxArmor() - maxArmor);
|
destroyable->SetMaxArmor(destroyable->GetMaxArmor() - maxArmor);
|
||||||
} else if (parameter.name == "max_imagination") {
|
} else if (parameter.name == "max_imagination") {
|
||||||
@ -197,7 +189,7 @@ void BuffComponent::RemoveBuffEffect(int32_t id) {
|
|||||||
|
|
||||||
auto* destroyable = this->GetParentEntity()->GetComponent<DestroyableComponent>();
|
auto* destroyable = this->GetParentEntity()->GetComponent<DestroyableComponent>();
|
||||||
|
|
||||||
if (destroyable == nullptr) return;
|
if (!destroyable) return;
|
||||||
|
|
||||||
destroyable->SetMaxImagination(destroyable->GetMaxImagination() - maxImagination);
|
destroyable->SetMaxImagination(destroyable->GetMaxImagination() - maxImagination);
|
||||||
} else if (parameter.name == "speed") {
|
} else if (parameter.name == "speed") {
|
||||||
@ -210,27 +202,19 @@ void BuffComponent::RemoveBuffEffect(int32_t id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BuffComponent::RemoveAllBuffs() {
|
void BuffComponent::RemoveAllBuffs() {
|
||||||
for (const auto& buff : m_Buffs) {
|
for (const auto& [buffId, buffInfo] : m_Buffs) {
|
||||||
RemoveBuffEffect(buff.first);
|
RemoveBuffEffect(buffId);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Buffs.clear();
|
m_Buffs.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuffComponent::Reset() {
|
|
||||||
RemoveAllBuffs();
|
|
||||||
}
|
|
||||||
|
|
||||||
void BuffComponent::ReApplyBuffs() {
|
void BuffComponent::ReApplyBuffs() {
|
||||||
for (const auto& buff : m_Buffs) {
|
for (const auto& [buffId, buffInfo] : m_Buffs) {
|
||||||
ApplyBuffEffect(buff.first);
|
ApplyBuffEffect(buffId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Entity* BuffComponent::GetParentEntity() const {
|
|
||||||
return m_ParentEntity;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BuffComponent::LoadFromXml(tinyxml2::XMLDocument* doc) {
|
void BuffComponent::LoadFromXml(tinyxml2::XMLDocument* doc) {
|
||||||
// Load buffs
|
// Load buffs
|
||||||
auto* dest = doc->FirstChildElement("obj")->FirstChildElement("dest");
|
auto* dest = doc->FirstChildElement("obj")->FirstChildElement("dest");
|
||||||
@ -239,9 +223,7 @@ void BuffComponent::LoadFromXml(tinyxml2::XMLDocument* doc) {
|
|||||||
auto* buffElement = dest->FirstChildElement("buff");
|
auto* buffElement = dest->FirstChildElement("buff");
|
||||||
|
|
||||||
// Old character, no buffs to load
|
// Old character, no buffs to load
|
||||||
if (buffElement == nullptr) {
|
if (buffElement) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto* buffEntry = buffElement->FirstChildElement("b");
|
auto* buffEntry = buffElement->FirstChildElement("b");
|
||||||
|
|
||||||
@ -299,12 +281,9 @@ void BuffComponent::UpdateXml(tinyxml2::XMLDocument* doc) {
|
|||||||
const std::vector<BuffParameter>& BuffComponent::GetBuffParameters(int32_t buffId) {
|
const std::vector<BuffParameter>& BuffComponent::GetBuffParameters(int32_t buffId) {
|
||||||
const auto& pair = m_Cache.find(buffId);
|
const auto& pair = m_Cache.find(buffId);
|
||||||
|
|
||||||
if (pair != m_Cache.end()) {
|
if (pair != m_Cache.end()) return pair->second;
|
||||||
return pair->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto query = CDClientDatabase::CreatePreppedStmt(
|
auto query = CDClientDatabase::CreatePreppedStmt("SELECT * FROM BuffParameters WHERE BuffID = ?;");
|
||||||
"SELECT * FROM BuffParameters WHERE BuffID = ?;");
|
|
||||||
query.bind(1, (int)buffId);
|
query.bind(1, (int)buffId);
|
||||||
|
|
||||||
auto result = query.execQuery();
|
auto result = query.execQuery();
|
||||||
@ -319,17 +298,15 @@ const std::vector<BuffParameter>& BuffComponent::GetBuffParameters(int32_t buffI
|
|||||||
param.value = result.getFloatField(2);
|
param.value = result.getFloatField(2);
|
||||||
|
|
||||||
if (!result.fieldIsNull(3)) {
|
if (!result.fieldIsNull(3)) {
|
||||||
std::istringstream stream(result.getStringField(3));
|
const auto parameterInfo = result.getStringField(3);
|
||||||
std::string token;
|
const auto values = GeneralUtils::SplitString(parameterInfo, ',');
|
||||||
|
if (values.size() >= 4) {
|
||||||
while (std::getline(stream, token, ',')) {
|
GeneralUtils::TryParse(values.at(0), param.values.skillId);
|
||||||
try {
|
GeneralUtils::TryParse(values.at(1), param.values.stacks);
|
||||||
const auto value = std::stof(token);
|
GeneralUtils::TryParse(values.at(2), param.values.tick);
|
||||||
|
GeneralUtils::TryParse(values.at(3), param.values.unknown2);
|
||||||
param.values.push_back(value);
|
} else {
|
||||||
} catch (std::invalid_argument& exception) {
|
Game::logger->Log("BuffComponent", "Failed to parse %s into parameter struct. Too few parameters to split on.", parameterInfo);
|
||||||
Game::logger->Log("BuffComponent", "Failed to parse value (%s): (%s)!", token.c_str(), exception.what());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,10 +15,16 @@ class Entity;
|
|||||||
* Extra information on effects to apply after applying a buff, for example whether to buff armor, imag or health and by how much
|
* Extra information on effects to apply after applying a buff, for example whether to buff armor, imag or health and by how much
|
||||||
*/
|
*/
|
||||||
struct BuffParameter {
|
struct BuffParameter {
|
||||||
|
struct ParameterValues {
|
||||||
|
int32_t skillId = 0;
|
||||||
|
int32_t stacks = 0;
|
||||||
|
float tick = 0.0f;
|
||||||
|
int32_t unknown2 = 0;
|
||||||
|
};
|
||||||
int32_t buffId = 0;
|
int32_t buffId = 0;
|
||||||
std::string name;
|
std::string name;
|
||||||
float value = 0.0f;
|
float value = 0.0f;
|
||||||
std::vector<float> values;
|
ParameterValues values;
|
||||||
int32_t effectId = 0;
|
int32_t effectId = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -44,8 +50,6 @@ public:
|
|||||||
|
|
||||||
explicit BuffComponent(Entity* parent) : Component(parent) {};
|
explicit BuffComponent(Entity* parent) : Component(parent) {};
|
||||||
|
|
||||||
Entity* GetParentEntity() const;
|
|
||||||
|
|
||||||
void LoadFromXml(tinyxml2::XMLDocument* doc) override;
|
void LoadFromXml(tinyxml2::XMLDocument* doc) override;
|
||||||
|
|
||||||
void UpdateXml(tinyxml2::XMLDocument* doc) override;
|
void UpdateXml(tinyxml2::XMLDocument* doc) override;
|
||||||
@ -106,7 +110,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Removes all buffs for the entity and reverses all of their effects
|
* Removes all buffs for the entity and reverses all of their effects
|
||||||
*/
|
*/
|
||||||
void Reset();
|
void Reset() { RemoveAllBuffs(); };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Applies all effects for all buffs, active or not, again
|
* Applies all effects for all buffs, active or not, again
|
||||||
|
Loading…
x
Reference in New Issue
Block a user