diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/game/ArenaTeamHandler.cpp | 2 | ||||
-rw-r--r-- | src/game/Spell.cpp | 13 | ||||
-rw-r--r-- | src/game/SpellAuras.cpp | 30 | ||||
-rw-r--r-- | src/game/SpellEffects.cpp | 24 | ||||
-rw-r--r-- | src/game/Unit.cpp | 296 | ||||
-rw-r--r-- | src/game/Unit.h | 2 | ||||
-rw-r--r-- | src/shared/revision_nr.h | 2 |
7 files changed, 299 insertions, 70 deletions
diff --git a/src/game/ArenaTeamHandler.cpp b/src/game/ArenaTeamHandler.cpp index f48529a3f77..69f8de2f797 100644 --- a/src/game/ArenaTeamHandler.cpp +++ b/src/game/ArenaTeamHandler.cpp @@ -173,7 +173,7 @@ void WorldSession::HandleArenaTeamInviteAcceptOpcode(WorldPacket & /*recv_data*/ if(!at) return; - if(_player->GetArenaTeamId(at->GetType())) + if(_player->GetArenaTeamId(at->GetSlot())) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S,"","",ERR_ALREADY_IN_ARENA_TEAM); // already in arena team that size return; diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 0007ba874e8..b234ed34829 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -641,6 +641,9 @@ void Spell::prepareDataForTriggerSystem() case SPELLFAMILY_WARLOCK: // For Hellfire Effect / Rain of Fire / Seed of Corruption triggers need do it if (m_spellInfo->SpellFamilyFlags & 0x0000800000000060LL) m_canTrigger = true; break; + case SPELLFAMILY_PRIEST: // For Penance heal/damage triggers need do it + if (m_spellInfo->SpellFamilyFlags & 0x0001800000000000LL) m_canTrigger = true; + break; case SPELLFAMILY_HUNTER: // Hunter Explosive Trap Effect/Immolation Trap Effect/Frost Trap Aura/Snake Trap Effect if (m_spellInfo->SpellFamilyFlags & 0x0000200000000014LL) m_canTrigger = true; break; @@ -2234,9 +2237,13 @@ void Spell::handle_immediate() // start channeling if applicable if(IsChanneledSpell(m_spellInfo)) { - m_spellState = SPELL_STATE_CASTING; - m_caster->AddInterruptMask(m_spellInfo->ChannelInterruptFlags); - SendChannelStart(GetSpellDuration(m_spellInfo)); + int32 duration = GetSpellDuration(m_spellInfo); + if (duration) + { + m_spellState = SPELL_STATE_CASTING; + m_caster->AddInterruptMask(m_spellInfo->ChannelInterruptFlags); + SendChannelStart(duration); + } } // process immediate effects (items, ground, etc.) also initialize some variables diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 0f8ff486880..ddf67982a2f 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -2051,6 +2051,25 @@ void Aura::HandleAuraDummy(bool apply, bool Real) m_target->SetReducedThreatPercent(0, 0); return; } + + if (caster && m_removeMode == AURA_REMOVE_BY_DEATH) + { + // Stop caster Arcane Missle chanelling on death + if (m_spellProto->SpellFamilyName == SPELLFAMILY_MAGE && + m_spellProto->SpellFamilyFlags&0x0000000000000800LL) + { + caster->InterruptSpell(CURRENT_CHANNELED_SPELL); + return; + } + // Stop caster Penance chanelling on death + if (m_spellProto->SpellFamilyName == SPELLFAMILY_PRIEST && + m_spellProto->SpellFamilyFlags2 & 0x00000080) + { + caster->InterruptSpell(CURRENT_CHANNELED_SPELL); + return; + } + + } } // AT APPLY & REMOVE @@ -6461,8 +6480,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: @@ -6471,7 +6495,7 @@ void Aura::PeriodicDummyTick() if (spell->SpellFamilyFlags & 0x0000000000000020LL) { if (caster) - caster->CastCustomSpell(m_target, 52212, &m_modifier.m_amount, NULL, NULL, true); + caster->CastCustomSpell(m_target, 52212, &m_modifier.m_amount, NULL, NULL, true, 0, this); return; } // Raise Dead diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 17514f9d386..605bf3b73d0 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -1442,6 +1442,30 @@ void Spell::EffectDummy(uint32 i) } break; case SPELLFAMILY_PRIEST: + // Penance + if (m_spellInfo->SpellFamilyFlags & 0x0080000000000000LL) + { + if (!unitTarget) + return; + + int hurt = 0; + int heal = 0; + switch(m_spellInfo->Id) + { + case 47540: hurt = 47758; heal = 47757; break; + case 53005: hurt = 53001; heal = 52986; break; + case 53006: hurt = 53002; heal = 52987; break; + case 53007: hurt = 53003; heal = 52988; break; + default: + sLog.outError("Spell::EffectDummy: Spell %u Penance need set correct heal/damage spell", m_spellInfo->Id); + return; + } + if (m_caster->IsFriendlyTo(unitTarget)) + m_caster->CastSpell(unitTarget, heal, true, 0); + else + m_caster->CastSpell(unitTarget, hurt, true, 0); + return; + } switch(m_spellInfo->Id ) { case 28598: // Touch of Weakness triggered spell diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 535465d52d2..5a69f29a927 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -1741,87 +1741,235 @@ 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; - // Cheat Death - if((*i)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_ROGUE && (*i)->GetSpellProto()->SpellIconID == 2109) + 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) { - if (((Player*)pVictim)->HasSpellCooldown(31231)) - continue; - if (pVictim->GetHealth() <= RemainingDamage) + existExpired = true; + continue; + } + // Handle custom absorb auras + // TODO: try find better way + switch(spellProto->SpellFamilyName) + { + case SPELLFAMILY_GENERIC: { - int32 chance = (*i)->GetModifier()->m_amount; - if (roll_chance_i(chance)) + // Astral Shift + if (spellProto->SpellIconID == 3066) { - 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; + //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; } - continue; - } - - int32 currentAbsorb; - - // Reflective Shield - if ((pVictim != this) && (*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_PRIEST && (*i)->GetSpellProto()->SpellFamilyFlags == 0x1) - { - if(Unit* caster = (*i)->GetCaster()) + case SPELLFAMILY_DRUID: { - AuraList const& vOverRideCS = caster->GetAurasByType(SPELL_AURA_DUMMY); - for(AuraList::const_iterator k = vOverRideCS.begin(); k != vOverRideCS.end(); ++k) + // Primal Tenacity + if (spellProto->SpellIconID == 2253) { - switch((*k)->GetModifier()->m_miscvalue) + //reduces all damage taken while Stunned + if (unitflag & UNIT_FLAG_STUNNED) + RemainingDamage -= RemainingDamage * currentAbsorb / 100; + continue; + } + break; + } + case SPELLFAMILY_ROGUE: + { + // Cheat Death + if(spellProto->SpellIconID == 2109) + { + 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 { - case 5065: // Rank 1 - case 5064: // Rank 2 - case 5063: // Rank 3 - { - if(RemainingDamage >= (*i)->GetModifier()->m_amount) - reflectDamage = (*i)->GetModifier()->m_amount * (*k)->GetModifier()->m_amount/100; - else - reflectDamage = (*k)->GetModifier()->m_amount * RemainingDamage/100; - reflectAura = *i; - - } break; - default: break; + 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; } - - if(reflectDamage) + continue; + } + break; + } + case SPELLFAMILY_PRIEST: + { + // Reflective Shield + 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) + { + switch((*k)->GetModifier()->m_miscvalue) + { + case 5065: // Rank 1 + case 5064: // Rank 2 + case 5063: // Rank 3 + { + if(RemainingDamage >= currentAbsorb) + reflectDamage = (*k)->GetModifier()->m_amount * currentAbsorb/100; + else + reflectDamage = (*k)->GetModifier()->m_amount * RemainingDamage/100; + } 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, ®en, 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); @@ -5001,6 +5149,13 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu pVictim->CastCustomSpell(pVictim,34919,&basepoints0,NULL,NULL,true,castItem,triggeredByAura); return true; // no hidden cooldown } + // Divine Aegis + if (dummySpell->SpellIconID == 2820) + { + basepoints0 = damage * triggeredByAura->GetModifier()->m_amount/100; + triggered_spell_id = 47753; + break; + } switch(dummySpell->Id) { // Vampiric Embrace @@ -6305,6 +6460,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: { @@ -6341,7 +6506,7 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB return true; } -bool Unit::HandleOverrideClassScriptAuraProc(Unit *pVictim, Aura *triggeredByAura, SpellEntry const *procSpell, uint32 cooldown) +bool Unit::HandleOverrideClassScriptAuraProc(Unit *pVictim, uint32 damage, Aura *triggeredByAura, SpellEntry const *procSpell, uint32 cooldown) { int32 scriptId = triggeredByAura->GetModifier()->m_miscvalue; @@ -6408,6 +6573,16 @@ bool Unit::HandleOverrideClassScriptAuraProc(Unit *pVictim, Aura *triggeredByAur case 5497: // Improved Mana Gems (Serpent-Coil Braid) triggered_spell_id = 37445; // Mana Surge break; + case 8152: // Serendipity + { + // if heal your target over maximum health + if (pVictim->GetHealth() + damage < pVictim->GetMaxHealth()) + return false; + int32 cost = procSpell->manaCost + procSpell->ManaCostPercentage * GetCreateMana() / 100; + int32 basepoints0 = cost * triggeredByAura->GetModifier()->m_amount/100; + CastCustomSpell(this, 47762, &basepoints0, 0, 0, true, 0, triggeredByAura); + return true; + } } // not processed @@ -9973,7 +10148,6 @@ bool InitTriggerAuraData() isTriggerAura[i]=false; isNonTriggerAura[i] = false; } - isTriggerAura[SPELL_AURA_PERIODIC_DAMAGE] = true; isTriggerAura[SPELL_AURA_DUMMY] = true; isTriggerAura[SPELL_AURA_MOD_CONFUSE] = true; isTriggerAura[SPELL_AURA_MOD_THREAT] = true; @@ -10209,7 +10383,7 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag case SPELL_AURA_OVERRIDE_CLASS_SCRIPTS: { sLog.outDebug("ProcDamageAndSpell: casting spell id %u (triggered by %s aura of spell %u)", spellInfo->Id,(isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId()); - if (!HandleOverrideClassScriptAuraProc(pTarget, triggeredByAura, procSpell, cooldown)) + if (!HandleOverrideClassScriptAuraProc(pTarget, damage, triggeredByAura, procSpell, cooldown)) continue; break; } diff --git a/src/game/Unit.h b/src/game/Unit.h index ced25f4667c..9ec54740e6c 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -1518,7 +1518,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject bool HandleDummyAuraProc( Unit *pVictim, uint32 damage, Aura* triggredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); bool HandleHasteAuraProc( Unit *pVictim, uint32 damage, Aura* triggredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); bool HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); - bool HandleOverrideClassScriptAuraProc(Unit *pVictim, Aura* triggredByAura, SpellEntry const *procSpell, uint32 cooldown); + bool HandleOverrideClassScriptAuraProc(Unit *pVictim, uint32 damage, Aura* triggredByAura, SpellEntry const *procSpell, uint32 cooldown); bool HandleMeandingAuraProc(Aura* triggeredByAura); uint32 m_state; // Even derived shouldn't modify diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 038ed3ff5c9..3b84da0a421 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7059" + #define REVISION_NR "7063" #endif // __REVISION_NR_H__ |