[7063] Absorb auras fixes (add custom handle for some auras)

Fix Shaman 51474 and ranks
Fix Rogue 31130 and ranks
Fix Druid 33851 and ranks
Fix DK 49145 and ranks, 49157 (TODO: need use only on transform), 50462, 53766, 51052,
Fix 41475 - boss cast
Fix 39228, 60218 (item 27770/37220 spells)
Hidden cooldown for 53601.

Signed-off-by: DiSlord <dislord@nomail.com>
This commit is contained in:
DiSlord 2009-01-10 19:07:24 +03:00
parent 4051db9767
commit 48bebc4056
6 changed files with 245 additions and 64 deletions

View file

@ -22,7 +22,7 @@
DROP TABLE IF EXISTS `db_version`;
CREATE TABLE `db_version` (
`version` varchar(120) default NULL,
`required_7061_01_mangos_spell_proc_event` bit(1) default NULL
`required_7063_01_mangos_spell_proc_event` bit(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
--
@ -16730,6 +16730,8 @@ INSERT INTO `spell_proc_event` VALUES
(51359, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 10),
(51466, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
(51470, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
(51474, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0),
(51478, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0),
(51556, 0x00000000, 11, 0x000000C0, 0x00000000, 0x00000010, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
(51557, 0x00000000, 11, 0x000000C0, 0x00000000, 0x00000010, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
(51558, 0x00000000, 11, 0x000000C0, 0x00000000, 0x00000010, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
@ -16804,6 +16806,7 @@ INSERT INTO `spell_proc_event` VALUES
(53553, 0x00000000, 10, 0x00001000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(53569, 0x00000000, 10, 0x00200000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
(53576, 0x00000000, 10, 0x00200000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
(53601, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 6),
(53671, 0x00000000, 10, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(53673, 0x00000000, 10, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(54149, 0x00000000, 10, 0x00200000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),

View file

@ -0,0 +1,13 @@
ALTER TABLE db_version CHANGE COLUMN required_7061_01_mangos_spell_proc_event required_7063_01_mangos_spell_proc_event bit;
-- (51474) Astral Shift (Rank 1)
DELETE FROM `spell_proc_event` WHERE `entry` IN (51474);
INSERT INTO `spell_proc_event` VALUES (51474, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0);
-- (51478) Astral Shift (Rank 2)
DELETE FROM `spell_proc_event` WHERE `entry` IN (51478);
INSERT INTO `spell_proc_event` VALUES (51478, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0);
-- (53601) Sacred Shield (Rank 1)
DELETE FROM `spell_proc_event` WHERE `entry` IN (53601);
INSERT INTO `spell_proc_event` VALUES (53601, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 6);

View file

@ -128,6 +128,7 @@ pkgdata_DATA = \
7059_02_characters_pet_spell.sql \
7060_01_mangos_spell_proc_event.sql \
7061_01_mangos_spell_proc_event.sql \
7063_01_mangos_spell_proc_event.sql \
README
## Additional files to include when running 'make dist'
@ -236,4 +237,5 @@ EXTRA_DIST = \
7059_02_characters_pet_spell.sql \
7060_01_mangos_spell_proc_event.sql \
7061_01_mangos_spell_proc_event.sql \
7063_01_mangos_spell_proc_event.sql \
README

View file

@ -6582,8 +6582,13 @@ void Aura::PeriodicDummyTick()
case SPELLFAMILY_SHAMAN:
{
// Astral Shift
// if (spell->Id == 52179)
// return;
if (spell->Id == 52179)
{
// Periodic need for remove visual on stun/fear/silence lost
if (!(m_target->GetUInt32Value(UNIT_FIELD_FLAGS)&(UNIT_FLAG_STUNNED|UNIT_FLAG_FLEEING|UNIT_FLAG_SILENCED)))
m_target->RemoveAurasDueToSpell(52179);
return;
}
break;
}
case SPELLFAMILY_DEATHKNIGHT:

View file

@ -1621,45 +1621,124 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe
int32 RemainingDamage = damage - *resist;
// Get unit state (need for some absorb check)
uint32 unitflag = pVictim->GetUInt32Value(UNIT_FIELD_FLAGS);
// Need remove expired auras after
bool existExpired = false;
// absorb without mana cost
int32 reflectDamage = 0;
Aura* reflectAura = NULL;
AuraList const& vSchoolAbsorb = pVictim->GetAurasByType(SPELL_AURA_SCHOOL_ABSORB);
for(AuraList::const_iterator i = vSchoolAbsorb.begin(), next; i != vSchoolAbsorb.end() && RemainingDamage > 0; i = next)
for(AuraList::const_iterator i = vSchoolAbsorb.begin(); i != vSchoolAbsorb.end() && RemainingDamage > 0; ++i)
{
next = i; ++next;
if (((*i)->GetModifier()->m_miscvalue & schoolMask)==0)
Modifier* mod = (*i)->GetModifier();
if (!(mod->m_miscvalue & schoolMask))
continue;
SpellEntry const* spellProto = (*i)->GetSpellProto();
// Max Amount can be absorbed by this aura
int32 currentAbsorb = mod->m_amount;
// Found empty aura (umpossible but..)
if (currentAbsorb <=0)
{
existExpired = true;
continue;
}
// Handle custom absorb auras
// TODO: try find better way
switch(spellProto->SpellFamilyName)
{
case SPELLFAMILY_GENERIC:
{
// Astral Shift
if (spellProto->SpellIconID == 3066)
{
//reduces all damage taken while stun, fear or silence
if (unitflag & (UNIT_FLAG_STUNNED|UNIT_FLAG_FLEEING|UNIT_FLAG_SILENCED))
RemainingDamage -= RemainingDamage * currentAbsorb / 100;
continue;
}
// Nerves of Steel
if (spellProto->SpellIconID == 2115)
{
// while affected by Stun and Fear
if (unitflag&(UNIT_FLAG_STUNNED|UNIT_FLAG_FLEEING))
RemainingDamage -= RemainingDamage * currentAbsorb / 100;
continue;
}
// Spell Deflection
if (spellProto->SpellIconID == 3006)
{
// You have a chance equal to your Parry chance
if (damagetype == DIRECT_DAMAGE && // Only for direct damage
roll_chance_f(pVictim->GetUnitParryChance())) // Roll chance
RemainingDamage -= RemainingDamage * currentAbsorb / 100;
continue;
}
// Reflective Shield (Lady Malande boss)
if (spellProto->Id == 41475)
{
int32 reflectDamage = 0;
if(RemainingDamage < currentAbsorb)
reflectDamage = RemainingDamage / 2;
else
reflectDamage = currentAbsorb / 2;
pVictim->CastCustomSpell(this, 33619, &reflectDamage, NULL, NULL, true, NULL, *i);
break;
}
if (spellProto->Id == 39228 || // Argussian Compass
spellProto->Id == 60218) // Essence of Gossamer
{
// Max absorb stored in 1 dummy effect
if (spellProto->EffectBasePoints[1] < currentAbsorb)
currentAbsorb = spellProto->EffectBasePoints[1];
break;
}
break;
}
case SPELLFAMILY_DRUID:
{
// Primal Tenacity
if (spellProto->SpellIconID == 2253)
{
//reduces all damage taken while Stunned
if (unitflag & UNIT_FLAG_STUNNED)
RemainingDamage -= RemainingDamage * currentAbsorb / 100;
continue;
}
break;
}
case SPELLFAMILY_ROGUE:
{
// Cheat Death
if((*i)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_ROGUE && (*i)->GetSpellProto()->SpellIconID == 2109)
if(spellProto->SpellIconID == 2109)
{
if (((Player*)pVictim)->HasSpellCooldown(31231))
continue;
if (pVictim->GetHealth() <= RemainingDamage)
{
int32 chance = (*i)->GetModifier()->m_amount;
if (roll_chance_i(chance))
if (pVictim->GetTypeId()==TYPEID_PLAYER && // Only players
pVictim->GetHealth() <= RemainingDamage && // Only if damage kill
!((Player*)pVictim)->HasSpellCooldown(31231) && // Only if no cooldown
roll_chance_i(currentAbsorb)) // Only if roll
{
pVictim->CastSpell(pVictim,31231,true);
((Player*)pVictim)->AddSpellCooldown(31231,0,time(NULL)+60);
// with health > 10% lost health until health==10%, in other case no losses
uint32 health10 = pVictim->GetMaxHealth()/10;
RemainingDamage = pVictim->GetHealth() > health10 ? pVictim->GetHealth() - health10 : 0;
}
}
continue;
}
int32 currentAbsorb;
break;
}
case SPELLFAMILY_PRIEST:
{
// Reflective Shield
if ((pVictim != this) && (*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_PRIEST && (*i)->GetSpellProto()->SpellFamilyFlags == 0x1)
{
if(Unit* caster = (*i)->GetCaster())
if (spellProto->SpellFamilyFlags == 0x1)
{
if (pVictim == this)
break;
Unit* caster = (*i)->GetCaster();
if (!caster)
break;
int32 reflectDamage = 0;
AuraList const& vOverRideCS = caster->GetAurasByType(SPELL_AURA_DUMMY);
for(AuraList::const_iterator k = vOverRideCS.begin(); k != vOverRideCS.end(); ++k)
{
@ -1669,39 +1748,108 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe
case 5064: // Rank 2
case 5063: // Rank 3
{
if(RemainingDamage >= (*i)->GetModifier()->m_amount)
reflectDamage = (*i)->GetModifier()->m_amount * (*k)->GetModifier()->m_amount/100;
if(RemainingDamage >= currentAbsorb)
reflectDamage = (*k)->GetModifier()->m_amount * currentAbsorb/100;
else
reflectDamage = (*k)->GetModifier()->m_amount * RemainingDamage/100;
reflectAura = *i;
} break;
default: break;
}
if (reflectDamage)
{
pVictim->CastCustomSpell(this, 33619, &reflectDamage, NULL, NULL, true, NULL, *i);
break;
}
}
break;
}
break;
}
case SPELLFAMILY_SHAMAN:
{
// Astral Shift
if (spellProto->SpellIconID == 3066)
{
//reduces all damage taken while stun, fear or silence
if (unitflag & (UNIT_FLAG_STUNNED|UNIT_FLAG_FLEEING|UNIT_FLAG_SILENCED))
RemainingDamage -= RemainingDamage * currentAbsorb / 100;
continue;
}
break;
}
case SPELLFAMILY_DEATHKNIGHT:
{
// Shadow of Death
if (spellProto->SpellIconID == 1958)
{
// TODO: absorb only while transform
continue;
}
// Anti-Magic Shell (on self)
if (spellProto->Id == 48707)
{
// damage absorbed by Anti-Magic Shell energizes the DK with additional runic power.
// This, if I'm not mistaken, shows that we get back ~2% of the absorbed damage as runic power.
int32 absorbed = RemainingDamage * currentAbsorb / 100;
int32 regen = absorbed * 2 / 10;
pVictim->CastCustomSpell(pVictim, 49088, &regen, 0, 0, true, 0, *i);
RemainingDamage -= absorbed;
continue;
}
// Anti-Magic Shell (on single party/raid member)
if (spellProto->Id == 50462)
{
RemainingDamage -= RemainingDamage * currentAbsorb / 100;
continue;
}
// Anti-Magic Zone
if (spellProto->Id == 50461)
{
Unit* caster = (*i)->GetCaster();
if (!caster)
continue;
int32 absorbed = RemainingDamage * currentAbsorb / 100;
int32 canabsorb = caster->GetHealth();
if (canabsorb < absorbed)
absorbed = canabsorb;
DealDamage(caster, absorbed, NULL, damagetype, schoolMask, 0, false);
RemainingDamage -= absorbed;
continue;
}
break;
}
default:
break;
}
if (RemainingDamage >= (*i)->GetModifier()->m_amount)
{
currentAbsorb = (*i)->GetModifier()->m_amount;
pVictim->RemoveAurasDueToSpell((*i)->GetId());
next = vSchoolAbsorb.begin();
}
else
{
// currentAbsorb - damage can be absorbed by shield
// If need absorb less damage
if (RemainingDamage < currentAbsorb)
currentAbsorb = RemainingDamage;
(*i)->GetModifier()->m_amount -= RemainingDamage;
}
RemainingDamage -= currentAbsorb;
// Reduce shield amount
mod->m_amount-=currentAbsorb;
// Need remove it later
if (mod->m_amount<=0)
existExpired = true;
}
// Remove all expired absorb auras
if (existExpired)
{
for(AuraList::const_iterator i = vSchoolAbsorb.begin(), next; i != vSchoolAbsorb.end();)
{
if ((*i)->GetModifier()->m_amount<=0)
{
pVictim->RemoveAurasDueToSpell((*i)->GetId());
i = vSchoolAbsorb.begin();
}
else
++i;
}
}
// do not cast spells while looping auras; auras can get invalid otherwise
if (reflectDamage)
pVictim->CastCustomSpell(this, 33619, &reflectDamage, NULL, NULL, true, NULL, reflectAura);
// absorb by mana cost
AuraList const& vManaShield = pVictim->GetAurasByType(SPELL_AURA_MANA_SHIELD);
@ -6147,6 +6295,16 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
}
break;
}
// Astral Shift
case 52179:
{
if(!procSpell)
return false;
// Need stun, fear or silence mechanic
if (!(GetAllSpellMechanicMask(procSpell) & ((1<<MECHANIC_SILENCE)|(1<<MECHANIC_STUN)|(1<<MECHANIC_FEAR))))
return false;
break;
}
// Burning Determination
case 54748:
{

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "7062"
#define REVISION_NR "7063"
#endif // __REVISION_NR_H__