Core/PacketIO: Implemented SMSG_SPELL_ABSORB_LOG

This commit is contained in:
Shauren
2021-04-18 00:12:46 +02:00
parent 530631e0a7
commit 854a55daab
4 changed files with 122 additions and 46 deletions

View File

@@ -920,6 +920,20 @@ uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDam
killed = false;
skipSettingDeathState = true;
if (currentAbsorb)
{
WorldPackets::CombatLog::SpellAbsorbLog absorbLog;
absorbLog.Attacker = GetGUID();
absorbLog.Victim = victim->GetGUID();
absorbLog.Caster = base->GetCasterGUID();
absorbLog.AbsorbedSpellID = spellProto ? spellProto->Id : 0;
absorbLog.AbsorbSpellID = base->GetId();
absorbLog.Absorbed = currentAbsorb;
absorbLog.OriginalDamage = damageInfo.GetOriginalDamage();
absorbLog.LogData.Initialize(victim);
SendCombatLogMessage(&absorbLog);
}
}
damage = damageInfo.GetDamage();
@@ -1815,25 +1829,39 @@ void Unit::CalcAbsorbResist(DamageInfo& damageInfo)
absorbAurEff->GetBase()->CallScriptEffectAbsorbHandlers(absorbAurEff, aurApp, damageInfo, tempAbsorb, defaultPrevented);
currentAbsorb = tempAbsorb;
if (defaultPrevented)
continue;
// absorb must be smaller than the damage itself
currentAbsorb = RoundToInterval(currentAbsorb, 0, int32(damageInfo.GetDamage()));
damageInfo.AbsorbDamage(currentAbsorb);
tempAbsorb = currentAbsorb;
absorbAurEff->GetBase()->CallScriptEffectAfterAbsorbHandlers(absorbAurEff, aurApp, damageInfo, tempAbsorb);
// Check if our aura is using amount to count damage
if (absorbAurEff->GetAmount() >= 0)
if (!defaultPrevented)
{
// Reduce shield amount
absorbAurEff->ChangeAmount(absorbAurEff->GetAmount() - currentAbsorb);
// Aura cannot absorb anything more - remove it
if (absorbAurEff->GetAmount() <= 0)
absorbAurEff->GetBase()->Remove(AURA_REMOVE_BY_ENEMY_SPELL);
// absorb must be smaller than the damage itself
currentAbsorb = RoundToInterval(currentAbsorb, 0, int32(damageInfo.GetDamage()));
damageInfo.AbsorbDamage(currentAbsorb);
tempAbsorb = currentAbsorb;
absorbAurEff->GetBase()->CallScriptEffectAfterAbsorbHandlers(absorbAurEff, aurApp, damageInfo, tempAbsorb);
// Check if our aura is using amount to count damage
if (absorbAurEff->GetAmount() >= 0)
{
// Reduce shield amount
absorbAurEff->ChangeAmount(absorbAurEff->GetAmount() - currentAbsorb);
// Aura cannot absorb anything more - remove it
if (absorbAurEff->GetAmount() <= 0)
absorbAurEff->GetBase()->Remove(AURA_REMOVE_BY_ENEMY_SPELL);
}
}
if (currentAbsorb)
{
WorldPackets::CombatLog::SpellAbsorbLog absorbLog;
absorbLog.Attacker = damageInfo.GetAttacker()->GetGUID();
absorbLog.Victim = damageInfo.GetVictim()->GetGUID();
absorbLog.Caster = absorbAurEff->GetBase()->GetCasterGUID();
absorbLog.AbsorbedSpellID = damageInfo.GetSpellInfo() ? damageInfo.GetSpellInfo()->Id : 0;
absorbLog.AbsorbSpellID = absorbAurEff->GetId();
absorbLog.Absorbed = currentAbsorb;
absorbLog.OriginalDamage = damageInfo.GetOriginalDamage();
absorbLog.LogData.Initialize(damageInfo.GetVictim());
SendCombatLogMessage(&absorbLog);
}
}
@@ -1863,34 +1891,48 @@ void Unit::CalcAbsorbResist(DamageInfo& damageInfo)
absorbAurEff->GetBase()->CallScriptEffectManaShieldHandlers(absorbAurEff, aurApp, damageInfo, tempAbsorb, defaultPrevented);
currentAbsorb = tempAbsorb;
if (defaultPrevented)
continue;
// absorb must be smaller than the damage itself
currentAbsorb = RoundToInterval(currentAbsorb, 0, int32(damageInfo.GetDamage()));
int32 manaReduction = currentAbsorb;
// lower absorb amount by talents
if (float manaMultiplier = absorbAurEff->GetSpellEffectInfo()->CalcValueMultiplier(absorbAurEff->GetCaster()))
manaReduction = int32(float(manaReduction) * manaMultiplier);
int32 manaTaken = -damageInfo.GetVictim()->ModifyPower(POWER_MANA, -manaReduction);
// take case when mana has ended up into account
currentAbsorb = currentAbsorb ? int32(float(currentAbsorb) * (float(manaTaken) / float(manaReduction))) : 0;
damageInfo.AbsorbDamage(currentAbsorb);
tempAbsorb = currentAbsorb;
absorbAurEff->GetBase()->CallScriptEffectAfterManaShieldHandlers(absorbAurEff, aurApp, damageInfo, tempAbsorb);
// Check if our aura is using amount to count damage
if (absorbAurEff->GetAmount() >= 0)
if (!defaultPrevented)
{
absorbAurEff->ChangeAmount(absorbAurEff->GetAmount() - currentAbsorb);
if ((absorbAurEff->GetAmount() <= 0))
absorbAurEff->GetBase()->Remove(AURA_REMOVE_BY_ENEMY_SPELL);
// absorb must be smaller than the damage itself
currentAbsorb = RoundToInterval(currentAbsorb, 0, int32(damageInfo.GetDamage()));
int32 manaReduction = currentAbsorb;
// lower absorb amount by talents
if (float manaMultiplier = absorbAurEff->GetSpellEffectInfo()->CalcValueMultiplier(absorbAurEff->GetCaster()))
manaReduction = int32(float(manaReduction) * manaMultiplier);
int32 manaTaken = -damageInfo.GetVictim()->ModifyPower(POWER_MANA, -manaReduction);
// take case when mana has ended up into account
currentAbsorb = currentAbsorb ? int32(float(currentAbsorb) * (float(manaTaken) / float(manaReduction))) : 0;
damageInfo.AbsorbDamage(currentAbsorb);
tempAbsorb = currentAbsorb;
absorbAurEff->GetBase()->CallScriptEffectAfterManaShieldHandlers(absorbAurEff, aurApp, damageInfo, tempAbsorb);
// Check if our aura is using amount to count damage
if (absorbAurEff->GetAmount() >= 0)
{
absorbAurEff->ChangeAmount(absorbAurEff->GetAmount() - currentAbsorb);
if ((absorbAurEff->GetAmount() <= 0))
absorbAurEff->GetBase()->Remove(AURA_REMOVE_BY_ENEMY_SPELL);
}
}
if (currentAbsorb)
{
WorldPackets::CombatLog::SpellAbsorbLog absorbLog;
absorbLog.Attacker = damageInfo.GetAttacker()->GetGUID();
absorbLog.Victim = damageInfo.GetVictim()->GetGUID();
absorbLog.Caster = absorbAurEff->GetBase()->GetCasterGUID();
absorbLog.AbsorbedSpellID = damageInfo.GetSpellInfo() ? damageInfo.GetSpellInfo()->Id : 0;
absorbLog.AbsorbSpellID = absorbAurEff->GetId();
absorbLog.Absorbed = currentAbsorb;
absorbLog.OriginalDamage = damageInfo.GetOriginalDamage();
absorbLog.LogData.Initialize(damageInfo.GetVictim());
SendCombatLogMessage(&absorbLog);
}
}

View File

@@ -395,3 +395,20 @@ WorldPacket const* WorldPackets::CombatLog::SpellDispellLog::Write()
return &_worldPacket;
}
WorldPacket const* WorldPackets::CombatLog::SpellAbsorbLog::Write()
{
*this << Attacker;
*this << Victim;
*this << int32(AbsorbedSpellID);
*this << int32(AbsorbSpellID);
*this << Caster;
*this << int32(Absorbed);
*this << int32(OriginalDamage);
WriteBit(Unk);
WriteLogDataBit();
FlushBits();
WriteLogData();
return &_worldPacket;
}

View File

@@ -324,6 +324,23 @@ namespace WorldPackets
float Unk = 0.0f;
Spells::ContentTuningParams ContentTuning;
};
class SpellAbsorbLog final : public CombatLogServerPacket
{
public:
SpellAbsorbLog() : CombatLogServerPacket(SMSG_SPELL_ABSORB_LOG, 100) { }
WorldPacket const* Write() override;
ObjectGuid Attacker;
ObjectGuid Victim;
ObjectGuid Caster;
int32 AbsorbedSpellID = 0;
int32 AbsorbSpellID = 0;
int32 Absorbed = 0;
int32 OriginalDamage = 0;
bool Unk = false;
};
}
}

View File

@@ -1900,7 +1900,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SOCKET_GEMS_SUCCESS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPECIAL_MOUNT_ANIM, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPEC_INVOLUNTARILY_CHANGED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_ABSORB_LOG, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_ABSORB_LOG, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_CATEGORY_COOLDOWN, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_CHANNEL_START, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_CHANNEL_UPDATE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);