[10475] Implement SPELL_AURA_HEAL_ABSORB (301)

Used for example in spells 66237 and 70659.

Also rename CalculateAbsorbAndResist -> CalculateDamageAbsorbAndResist
This commit is contained in:
VladimirMangos 2010-09-12 02:38:29 +04:00
parent ae53d49352
commit 84a915e1b1
9 changed files with 112 additions and 28 deletions

View file

@ -1584,7 +1584,7 @@ void Unit::CalculateMeleeDamage(Unit *pVictim, uint32 damage, CalcDamageInfo *da
// Calculate absorb & resists
uint32 absorb_affected_damage = CalcNotIgnoreAbsorbDamage(damageInfo->damage,damageInfo->damageSchoolMask);
damageInfo->target->CalculateAbsorbAndResist(this, damageInfo->damageSchoolMask, DIRECT_DAMAGE, absorb_affected_damage, &damageInfo->absorb, &damageInfo->resist, true);
damageInfo->target->CalculateDamageAbsorbAndResist(this, damageInfo->damageSchoolMask, DIRECT_DAMAGE, absorb_affected_damage, &damageInfo->absorb, &damageInfo->resist, true);
damageInfo->damage-=damageInfo->absorb + damageInfo->resist;
if (damageInfo->absorb)
{
@ -1822,7 +1822,7 @@ uint32 Unit::CalcArmorReducedDamage(Unit* pVictim, const uint32 damage)
return (newdamage > 1) ? newdamage : 1;
}
void Unit::CalculateAbsorbAndResist(Unit *pCaster, SpellSchoolMask schoolMask, DamageEffectType damagetype, const uint32 damage, uint32 *absorb, uint32 *resist, bool canReflect)
void Unit::CalculateDamageAbsorbAndResist(Unit *pCaster, SpellSchoolMask schoolMask, DamageEffectType damagetype, const uint32 damage, uint32 *absorb, uint32 *resist, bool canReflect)
{
if(!pCaster || !isAlive() || !damage)
return;
@ -2354,10 +2354,71 @@ void Unit::CalculateAbsorbResistBlock(Unit *pCaster, SpellNonMeleeDamage *damage
}
uint32 absorb_affected_damage = pCaster->CalcNotIgnoreAbsorbDamage(damageInfo->damage,GetSpellSchoolMask(spellProto),spellProto);
CalculateAbsorbAndResist(pCaster, GetSpellSchoolMask(spellProto), SPELL_DIRECT_DAMAGE, absorb_affected_damage, &damageInfo->absorb, &damageInfo->resist, !(spellProto->AttributesEx2 & SPELL_ATTR_EX2_CANT_REFLECTED));
CalculateDamageAbsorbAndResist(pCaster, GetSpellSchoolMask(spellProto), SPELL_DIRECT_DAMAGE, absorb_affected_damage, &damageInfo->absorb, &damageInfo->resist, !(spellProto->AttributesEx2 & SPELL_ATTR_EX2_CANT_REFLECTED));
damageInfo->damage-= damageInfo->absorb + damageInfo->resist;
}
void Unit::CalculateHealAbsorb(const uint32 heal, uint32 *absorb)
{
if (!isAlive() || !heal)
return;
int32 RemainingHeal = heal;
// Need remove expired auras after
bool existExpired = false;
// absorb
AuraList const& vHealAbsorb = GetAurasByType(SPELL_AURA_HEAL_ABSORB);
for(AuraList::const_iterator i = vHealAbsorb.begin(); i != vHealAbsorb.end() && RemainingHeal > 0; ++i)
{
Modifier* mod = (*i)->GetModifier();
SpellEntry const* spellProto = (*i)->GetSpellProto();
// Max Amount can be absorbed by this aura
int32 currentAbsorb = mod->m_amount;
// Found empty aura (impossible but..)
if (currentAbsorb <=0)
{
existExpired = true;
continue;
}
// currentAbsorb - heal can be absorbed
// If need absorb less heal
if (RemainingHeal < currentAbsorb)
currentAbsorb = RemainingHeal;
RemainingHeal -= currentAbsorb;
// Reduce aura amount
mod->m_amount -= currentAbsorb;
if ((*i)->GetHolder()->DropAuraCharge())
mod->m_amount = 0;
// Need remove it later
if (mod->m_amount<=0)
existExpired = true;
}
// Remove all expired absorb auras
if (existExpired)
{
for(AuraList::const_iterator i = vHealAbsorb.begin(); i != vHealAbsorb.end();)
{
if ((*i)->GetModifier()->m_amount<=0)
{
RemoveAurasDueToSpell((*i)->GetId(), NULL, AURA_REMOVE_BY_SHIELD_BREAK);
i = vHealAbsorb.begin();
}
else
++i;
}
}
*absorb = heal - RemainingHeal;
}
void Unit::AttackerStateUpdate (Unit *pVictim, WeaponAttackType attType, bool extra )
{
if(hasUnitState(UNIT_STAT_CAN_NOT_REACT) || HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED) )
@ -5866,7 +5927,7 @@ void Unit::UnsummonAllTotems()
totem->UnSummon();
}
int32 Unit::DealHeal(Unit *pVictim, uint32 addhealth, SpellEntry const *spellProto, bool critical)
int32 Unit::DealHeal(Unit *pVictim, uint32 addhealth, SpellEntry const *spellProto, bool critical, uint32 absorb)
{
int32 gain = pVictim->ModifyHealth(int32(addhealth));
@ -5878,7 +5939,7 @@ int32 Unit::DealHeal(Unit *pVictim, uint32 addhealth, SpellEntry const *spellPro
if (unit->GetTypeId()==TYPEID_PLAYER)
{
// overheal = addhealth - gain
unit->SendHealSpellLog(pVictim, spellProto->Id, addhealth, addhealth - gain, critical);
unit->SendHealSpellLog(pVictim, spellProto->Id, addhealth, addhealth - gain, critical, absorb);
if (BattleGround *bg = ((Player*)unit)->GetBattleGround())
bg->UpdatePlayerScore((Player*)unit, SCORE_HEALING_DONE, gain);
@ -5927,7 +5988,7 @@ Unit* Unit::SelectMagnetTarget(Unit *victim, SpellEntry const *spellInfo)
return victim;
}
void Unit::SendHealSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage, uint32 OverHeal, bool critical)
void Unit::SendHealSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage, uint32 OverHeal, bool critical, uint32 absorb)
{
// we guess size
WorldPacket data(SMSG_SPELLHEALLOG, (8+8+4+4+1));
@ -5936,7 +5997,7 @@ void Unit::SendHealSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage, uint32
data << uint32(SpellID);
data << uint32(Damage);
data << uint32(OverHeal);
data << uint32(0); // absorb, not implemented, look 301 aura
data << uint32(absorb);
data << uint8(critical ? 1 : 0);
data << uint8(0); // unused in client?
SendMessageToSet(&data, true);