diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/game/SpellAuras.cpp | 144 | ||||
| -rw-r--r-- | src/game/Unit.cpp | 47 | ||||
| -rw-r--r-- | src/game/Unit.h | 4 | 
3 files changed, 96 insertions, 99 deletions
diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index c016d9ca98b..ad00013bbb7 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -797,7 +797,7 @@ void Aura::_AddAura()      // passive auras (except totem auras) do not get placed in the slots      // area auras with SPELL_AURA_NONE are not shown on target      // all further code applies only to active spells -    if(!((m_spellProto->Attributes & 0x80 || !m_isPassive || (caster && caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->isTotem())) && +    if(!(((m_spellProto->Attributes & 0x80 && GetTalentSpellPos(GetId())) || !m_isPassive || (caster && caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->isTotem())) &&          (m_spellProto->Effect[GetEffIndex()] != SPELL_EFFECT_APPLY_AREA_AURA_ENEMY || m_target != caster)))          return; @@ -815,8 +815,6 @@ void Aura::_AddAura()              if(itr->second->GetCasterGUID()==GetCasterGUID())              {                  slot = itr->second->GetAuraSlot(); -                if(slot >= MAX_AURAS) -                    return;                  secondaura = true;                  break;              } @@ -825,46 +823,48 @@ void Aura::_AddAura()              break;      } -    // Lookup free slot -    if (!secondaura) +    Unit::VisibleAuraMap const *visibleAuras = m_target->GetVisibleAuras(); +    if(visibleAuras->size() < MAX_AURAS || slot < MAX_AURAS)       // got free slot      { -        Unit::VisibleAuraMap const *visibleAuras = m_target->GetVisibleAuras(); -        if(visibleAuras->size() >= MAX_AURAS)       // no free slot -            return; - -        Unit::VisibleAuraMap::const_iterator itr = visibleAuras->begin(); -        for(int freeSlot = 0; freeSlot < MAX_AURAS; ++itr, ++freeSlot) +        // Lookup free slot +        if (!secondaura)          { -            if(itr == visibleAuras->end() || itr->first != freeSlot) +            Unit::VisibleAuraMap::const_iterator itr = visibleAuras->begin(); +            for(int freeSlot = 0; freeSlot < MAX_AURAS; ++itr, ++freeSlot)              { -                slot = freeSlot; -                break; +                if(itr == visibleAuras->end() || itr->first != freeSlot) +                { +                    slot = freeSlot; +                    break; +                }              } -        } -        assert(slot < MAX_AURAS);      // assert that we find a slot and it is valid - -        AuraSlotEntry t_entry; -        t_entry.m_Flags=(IsPositive() ? AFLAG_POSITIVE : AFLAG_NEGATIVE) | AFLAG_NOT_CASTER | ((GetAuraMaxDuration() > 0) ? AFLAG_DURATION : AFLAG_NONE); -        t_entry.m_Level=(caster ? caster->getLevel() : sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)); +            assert(slot < MAX_AURAS);      // assert that we find a slot and it is valid -        //init pointers-prevent unexpected behaviour -        for(uint8 i = 0; i < 3; i++) -            t_entry.m_slotAuras[i]=NULL; +            AuraSlotEntry t_entry; +            t_entry.m_Flags=(IsPositive() ? AFLAG_POSITIVE : AFLAG_NEGATIVE) | AFLAG_NOT_CASTER | ((GetAuraMaxDuration() > 0) ? AFLAG_DURATION : AFLAG_NONE); +            t_entry.m_Level=(caster ? caster->getLevel() : sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)); +            t_entry.m_spellId = GetId(); +            //init pointers-prevent unexpected behaviour +            for(uint8 i = 0; i < 3; i++) +                t_entry.m_slotAuras[i]=NULL; -        m_target->SetVisibleAura(slot, t_entry); -    } - -    AuraSlotEntry *entry = m_target->GetVisibleAura(slot); -    if(!entry) -        return; +            m_target->SetVisibleAura(slot, t_entry); +        } -    entry->m_Flags |= (1 << GetEffIndex()); -    entry->m_slotAuras[GetEffIndex()]=this; +        if(AuraSlotEntry *entry = m_target->GetVisibleAura(slot)) +        { +            entry->m_Flags |= (1 << GetEffIndex()); +            entry->m_slotAuras[GetEffIndex()]=this; -    SetAuraSlot( slot ); +            SetAuraSlot( slot ); -    // update for out of range group members (on 1 slot use) -    m_target->UpdateAuraForGroup(slot); +            // update for out of range group members (on 1 slot use) +            m_target->UpdateAuraForGroup(slot); +            sLog.outDebug("Aura: %u Effect: %d put to unit visible auras slot: %u",GetId(), GetEffIndex(), slot); +        } +    } +    else +       sLog.outDebug("Aura: %u Effect: %d could not find empty unit visible slot",GetId(), GetEffIndex());      //*****************************************************      // Update target aura state flag @@ -880,6 +880,18 @@ void Aura::_AddAura()          // register aura diminishing on apply          if (getDiminishGroup() != DIMINISHING_NONE )              m_target->ApplyDiminishingAura(getDiminishGroup(),true); + +        // Apply linked auras (On first aura apply) +        uint32 id = GetId(); +        if(spellmgr.GetSpellCustomAttr(id) & SPELL_ATTR_CU_LINK_AURA) +        { +            if(const std::vector<int32> *spell_triggered = spellmgr.GetSpellLinked(id + SPELL_LINK_AURA)) +                for(std::vector<int32>::const_iterator itr = spell_triggered->begin(); itr != spell_triggered->end(); ++itr) +                    if(*itr < 0) +                        m_target->ApplySpellImmune(id, IMMUNITY_ID, *itr, m_target); +                    else if(Unit* caster = GetCaster()) +                        m_target->AddAura(*itr, m_target); +        }      }      // Update Seals information @@ -930,39 +942,44 @@ void Aura::_RemoveAura()      //    return;      uint8 slot = GetAuraSlot(); -    if(slot >= MAX_AURAS)                                   // slot not set -        return; +    if(slot < MAX_AURAS)                                   // slot not set +    { +        if (AuraSlotEntry *entry = m_target->GetVisibleAura(slot)) +        { +            // we have more auras, do not clear slot +            if (entry->m_slotAuras[GetEffIndex()]==this) +            { +                entry->m_slotAuras[GetEffIndex()]=NULL;                 //unregister aura +            } +        } +    }      bool lastaura=true; - -    AuraSlotEntry *entry = m_target->GetVisibleAura(slot); -    if (entry) +    for(uint8 i = 0; i < 3; i++)      { -        // we have more auras, do not clear slot -        if (entry->m_slotAuras[GetEffIndex()]==this) +        Unit::spellEffectPair spair = Unit::spellEffectPair(GetId(), i); +        for(Unit::AuraMap::const_iterator itr = m_target->GetAuras().lower_bound(spair); itr != m_target->GetAuras().upper_bound(spair); ++itr)          { -            entry->m_slotAuras[GetEffIndex()]=NULL;                 //unregister aura -            for(uint8 i = 0; i < 3; ++i)                              //check slot for more auras of the spell +            if(itr->second->GetCasterGUID()==GetCasterGUID())              { -                if(entry->m_slotAuras[i]) -                { -                    lastaura = false; -                    break; -                } +                lastaura = false; +                break;              }          } +        if(!lastaura) +            break;      } -    // only remove icon when the last aura of the spell is removed (current aura already removed from list) -    if(lastaura) +    if (lastaura)      { +        // update for out of range group members +        if (slot < MAX_AURAS) +            m_target->UpdateAuraForGroup(slot); +          // unregister aura diminishing (and store last time)          if (getDiminishGroup() != DIMINISHING_NONE )              m_target->ApplyDiminishingAura(getDiminishGroup(),false); -        // update for out of range group members -        m_target->UpdateAuraForGroup(slot); -          // Check needed only if aura applies aurastate          if(GetAuraStateMask())          { @@ -986,6 +1003,27 @@ void Aura::_RemoveAura()                  // note: item based cooldowns and cooldown spell mods with charges ignored (unknown existed cases)                  ((Player*)caster)->SendCooldownEvent(GetSpellProto());          } + +        // Remove Linked Auras (on last aura remove) +        uint32 id = GetId(); +        if(spellmgr.GetSpellCustomAttr(id) & SPELL_ATTR_CU_LINK_REMOVE) +        { +            if(const std::vector<int32> *spell_triggered = spellmgr.GetSpellLinked(-(int32)id)) +                for(std::vector<int32>::const_iterator itr = spell_triggered->begin(); itr != spell_triggered->end(); ++itr) +                    if(*itr < 0) +                        m_target->RemoveAurasDueToSpell(-(*itr)); +                    else if(Unit* caster = GetCaster()) +                        m_target->CastSpell(m_target, *itr, true, 0, 0, caster->GetGUID()); +        } +        if(spellmgr.GetSpellCustomAttr(id) & SPELL_ATTR_CU_LINK_AURA) +        { +            if(const std::vector<int32> *spell_triggered = spellmgr.GetSpellLinked(id + SPELL_LINK_AURA)) +                for(std::vector<int32>::const_iterator itr = spell_triggered->begin(); itr != spell_triggered->end(); ++itr) +                    if(*itr < 0) +                        m_target->ApplySpellImmune(id, IMMUNITY_ID, *itr, false); +                    else +                        m_target->RemoveAurasDueToSpell(*itr); +        }      }  } diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 52b7b4f5114..26b3d7ce7a3 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -2013,10 +2013,9 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe                          healAmount = pVictim->GetMaxHealth()/2;                          healCaster = pVictim;                          healSpell = 48153; -                        currentAbsorb = mod->m_amount; +                        mod->m_amount=0;                          RemainingDamage=0;                      } -                    else                          continue;                  } @@ -3895,17 +3894,6 @@ bool Unit::AddAura(Aura *Aur)      Aur->ApplyModifier(true,true); -    uint32 id = Aur->GetId(); -    if(spellmgr.GetSpellCustomAttr(id) & SPELL_ATTR_CU_LINK_AURA) -    { -        if(const std::vector<int32> *spell_triggered = spellmgr.GetSpellLinked(id + SPELL_LINK_AURA)) -            for(std::vector<int32>::const_iterator itr = spell_triggered->begin(); itr != spell_triggered->end(); ++itr) -                if(*itr < 0) -                    ApplySpellImmune(id, IMMUNITY_ID, *itr, true); -                else if(Unit* caster = Aur->GetCaster()) -                    caster->AddAura(*itr, this); -    } -      sLog.outDebug("Aura %u now is in use", Aur->GetModifier()->m_auraname);      return true;  } @@ -4360,40 +4348,10 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode)      Aur->ApplyModifier(false,true);      Aur->_RemoveAura(); -    bool stack = false; -    spellEffectPair spair = spellEffectPair(Aur->GetId(), Aur->GetEffIndex()); -    for(AuraMap::const_iterator itr = GetAuras().lower_bound(spair); itr != GetAuras().upper_bound(spair); ++itr) -    { -        if (itr->second->GetCasterGUID()==GetGUID()) -        { -            stack = true; -        } -    } -    if (!stack) +    //if (mode!=AURA_REMOVE_BY_REPLACE)      {          // Remove all triggered by aura spells vs unlimited duration          Aur->CleanupTriggeredSpells(); - -        // Remove Linked Auras -        uint32 id = Aur->GetId(); -        if(spellmgr.GetSpellCustomAttr(id) & SPELL_ATTR_CU_LINK_REMOVE) -        { -            if(const std::vector<int32> *spell_triggered = spellmgr.GetSpellLinked(-(int32)id)) -                for(std::vector<int32>::const_iterator itr = spell_triggered->begin(); itr != spell_triggered->end(); ++itr) -                    if(*itr < 0) -                        RemoveAurasDueToSpell(-(*itr)); -                    else if(Unit* caster = Aur->GetCaster()) -                        CastSpell(this, *itr, true, 0, 0, caster->GetGUID()); -        } -        if(spellmgr.GetSpellCustomAttr(id) & SPELL_ATTR_CU_LINK_AURA) -        { -            if(const std::vector<int32> *spell_triggered = spellmgr.GetSpellLinked(id + SPELL_LINK_AURA)) -                for(std::vector<int32>::const_iterator itr = spell_triggered->begin(); itr != spell_triggered->end(); ++itr) -                    if(*itr < 0) -                        ApplySpellImmune(id, IMMUNITY_ID, *itr, false); -                    else -                        RemoveAurasDueToSpell(*itr); -        }      }      delete Aur; @@ -13379,6 +13337,7 @@ void Unit::SendAuraUpdate(uint8 slot)      if(!ptr)      { +        sLog.outDebug("Aura %u removed slot %u",entry->m_spellId, slot);          RemoveVisibleAura(slot);          SendMessageToSet(&data, true);          return; diff --git a/src/game/Unit.h b/src/game/Unit.h index 19e188922e6..1f199445f12 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -325,8 +325,8 @@ enum DamageTypeToSchool  enum AuraRemoveMode  {      AURA_REMOVE_BY_DEFAULT, -    AURA_REMOVE_BY_STACK,                                   // at replace by semillar aura -    AURA_REMOVE_BY_CANCEL, +    AURA_REMOVE_BY_STACK,               // at replace by semillar aura +    AURA_REMOVE_BY_CANCEL,              // single target aura remove is considered as cancel      AURA_REMOVE_BY_DISPEL,      AURA_REMOVE_BY_DEATH  };  | 
