[Crash Fix] Fix Possible Crashes with Raid Methods (#4955)

This commit is contained in:
Alex King 2025-06-26 19:35:20 -04:00 committed by GitHub
parent 76d46ceaf0
commit 13aad6229f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 62 additions and 52 deletions

View File

@ -717,7 +717,7 @@ uint32 Raid::GetTotalRaidDamage(Mob* other)
return total;
}
void Raid::HealGroup(uint32 heal_amt, Mob* caster, uint32 gid, float range)
void Raid::HealGroup(uint32 heal_amount, Mob* caster, uint32 group_id, float range)
{
if (!caster) {
return;
@ -728,26 +728,30 @@ void Raid::HealGroup(uint32 heal_amt, Mob* caster, uint32 gid, float range)
}
float distance;
float range2 = range*range;
float range_squared = range * range;
int member_count = 0;
int numMem = 0;
for (const auto& m : members) {
if (m.member && m.group_number == gid) {
if (m.member && m.group_number == group_id) {
distance = DistanceSquared(caster->GetPosition(), m.member->GetPosition());
if (distance <= range2) {
numMem += 1;
if (distance <= range_squared) {
member_count += 1;
}
}
}
heal_amt /= numMem;
if (member_count > 0) {
heal_amount /= member_count;
}
for (const auto& m : members) {
if (m.member && m.group_number == gid) {
if (m.member && m.group_number == group_id) {
distance = DistanceSquared(caster->GetPosition(), m.member->GetPosition());
if (distance <= range2) {
m.member->SetHP(m.member->GetHP() + heal_amt);
if (distance <= range_squared) {
m.member->SetHP(m.member->GetHP() + heal_amount);
m.member->SendHPUpdate();
}
}
@ -755,7 +759,7 @@ void Raid::HealGroup(uint32 heal_amt, Mob* caster, uint32 gid, float range)
}
void Raid::BalanceHP(int32 penalty, uint32 gid, float range, Mob* caster, int32 limit)
void Raid::BalanceHP(int32 penalty, uint32 group_id, float range, Mob* caster, int32 limit)
{
if (!caster) {
return;
@ -765,44 +769,48 @@ void Raid::BalanceHP(int32 penalty, uint32 gid, float range, Mob* caster, int32
range = 200;
}
int dmgtaken = 0, numMem = 0, dmgtaken_tmp = 0;
int damage_taken = 0;
int damage_taken_temporary = 0;
int member_count = 0;
float distance;
float range2 = range*range;
float range_squared = range * range;
for (const auto& m : members) {
if (m.member && m.group_number == gid) {
if (m.member && m.group_number == group_id) {
distance = DistanceSquared(caster->GetPosition(), m.member->GetPosition());
if (distance <= range2) {
dmgtaken_tmp = m.member->GetMaxHP() - m.member->GetHP();
if (distance <= range_squared) {
damage_taken_temporary = m.member->GetMaxHP() - m.member->GetHP();
if (limit && (dmgtaken_tmp > limit)) {
dmgtaken_tmp = limit;
if (limit && (damage_taken_temporary > limit)) {
damage_taken_temporary = limit;
}
dmgtaken += dmgtaken_tmp;
numMem += 1;
damage_taken += damage_taken_temporary;
member_count += 1;
}
}
}
dmgtaken += dmgtaken * penalty / 100;
dmgtaken /= numMem;
damage_taken += damage_taken * penalty / 100;
if (member_count > 0) {
damage_taken /= member_count;
}
for (const auto& m : members) {
if (m.member && m.group_number == gid) {
if (m.member && m.group_number == group_id) {
distance = DistanceSquared(caster->GetPosition(), m.member->GetPosition());
//this way the ability will never kill someone
//but it will come darn close
if (distance <= range2) {
if ((m.member->GetMaxHP() - dmgtaken) < 1) {
if (distance <= range_squared) {
if ((m.member->GetMaxHP() - damage_taken) < 1) {
m.member->SetHP(1);
m.member->SendHPUpdate();
}
else {
m.member->SetHP(m.member->GetMaxHP() - dmgtaken);
} else {
m.member->SetHP(m.member->GetMaxHP() - damage_taken);
m.member->SendHPUpdate();
}
}
@ -810,7 +818,7 @@ void Raid::BalanceHP(int32 penalty, uint32 gid, float range, Mob* caster, int32
}
}
void Raid::BalanceMana(int32 penalty, uint32 gid, float range, Mob* caster, int32 limit)
void Raid::BalanceMana(int32 penalty, uint32 group_id, float range, Mob* caster, int32 limit)
{
if (!caster) {
return;
@ -821,54 +829,56 @@ void Raid::BalanceMana(int32 penalty, uint32 gid, float range, Mob* caster, int3
}
float distance;
float range2 = range*range;
float range_squared = range * range;
int manataken = 0;
int numMem = 0;
int manataken_tmp = 0;
int mana_taken = 0;
int mana_taken_temporary = 0;
int member_count = 0;
for (const auto& m : members) {
if (m.is_bot) {
continue;
}
if (m.member && m.group_number == gid && m.member->GetMaxMana() > 0) {
if (m.member && m.group_number == group_id && m.member->GetMaxMana() > 0) {
distance = DistanceSquared(caster->GetPosition(), m.member->GetPosition());
if (distance <= range2) {
manataken_tmp = m.member->GetMaxMana() - m.member->GetMana();
if (distance <= range_squared) {
mana_taken_temporary = m.member->GetMaxMana() - m.member->GetMana();
if (limit && (manataken_tmp > limit)) {
manataken_tmp = limit;
if (limit && (mana_taken_temporary > limit)) {
mana_taken_temporary = limit;
}
manataken += manataken_tmp;
numMem += 1;
mana_taken += mana_taken_temporary;
member_count += 1;
}
}
}
manataken += manataken * penalty / 100;
manataken /= numMem;
mana_taken += mana_taken * penalty / 100;
if (member_count > 0) {
mana_taken /= member_count;
}
for (const auto& m : members) {
if (m.is_bot) {
continue;
}
if (m.member && m.group_number == gid) {
if (m.member && m.group_number == group_id) {
distance = DistanceSquared(caster->GetPosition(), m.member->GetPosition());
if (distance <= range2) {
if ((m.member->GetMaxMana() - manataken) < 1) {
if (distance <= range_squared) {
if ((m.member->GetMaxMana() - mana_taken) < 1) {
m.member->SetMana(1);
if (m.member->IsClient()) {
m.member->CastToClient()->SendManaUpdate();
}
}
else {
m.member->SetMana(m.member->GetMaxMana() - manataken);
} else {
m.member->SetMana(m.member->GetMaxMana() - mana_taken);
if (m.member->IsClient()) {
m.member->CastToClient()->SendManaUpdate();

View File

@ -167,9 +167,9 @@ public:
void CastGroupSpell(Mob* caster,uint16 spellid, uint32 gid);
void SplitExp(ExpSource exp_source, const uint64 exp, Mob* other);
uint32 GetTotalRaidDamage(Mob* other);
void BalanceHP(int32 penalty, uint32 gid, float range = 0, Mob* caster = nullptr, int32 limit = 0);
void BalanceMana(int32 penalty, uint32 gid, float range = 0, Mob* caster = nullptr, int32 limit = 0);
void HealGroup(uint32 heal_amt, Mob* caster, uint32 gid, float range = 0);
void BalanceHP(int32 penalty, uint32 group_id, float range = 0, Mob* caster = nullptr, int32 limit = 0);
void BalanceMana(int32 penalty, uint32 group_id, float range = 0, Mob* caster = nullptr, int32 limit = 0);
void HealGroup(uint32 heal_amount, Mob* caster, uint32 group_id, float range = 0);
void SplitMoney(uint32 gid, uint32 copper, uint32 silver, uint32 gold, uint32 platinum, Client *splitter = nullptr);
void TeleportGroup(Mob* sender, uint32 zoneID, uint16 instance_id, float x, float y, float z, float heading, uint32 gid);