Changeset 251 for trunk

Show
Ignore:
Timestamp:
11/19/08 13:50:51 (17 years ago)
Author:
yumileroy
Message:

*Merge from Mangos
*[6833] More correct aura cancel for channeled spells. By VladimirMangos?.
*[6820] Cleanup spell proc event code. Avoid send same information by 2 ways to function. By VladimirMangos?.

Original author: megamage
Date: 2008-11-17 19:39:24-06:00

Location:
trunk/src/game
Files:
4 modified

Legend:

Unmodified
Added
Removed
  • trunk/src/game/SpellAuras.cpp

    r236 r251  
    20002000        } 
    20012001 
     2002        // Waiting to Resurrect 
     2003        if(GetId()==2584) 
     2004        { 
     2005            // Waiting to resurrect spell cancel, we must remove player from resurrect queue 
     2006            if(m_target->GetTypeId() == TYPEID_PLAYER) 
     2007                if(BattleGround *bg = ((Player*)m_target)->GetBattleGround()) 
     2008                    bg->RemovePlayerFromResurrectQueue(m_target->GetGUID()); 
     2009            return; 
     2010        } 
     2011 
    20022012        // Dark Fiend 
    2003         if(GetId()==45934) 
     2013        /*if(GetId()==45934) 
    20042014        { 
    20052015            // Kill target if dispelled 
     
    20072017                m_target->DealDamage(m_target, m_target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); 
    20082018            return; 
    2009         } 
     2019        }*/ 
    20102020 
    20112021        // Burning Winds 
  • trunk/src/game/SpellHandler.cpp

    r233 r251  
    378378        return; 
    379379 
     380    // channeled spell case (it currently casted then) 
     381    if(IsChanneledSpell(spellInfo)) 
     382    { 
     383        if(Spell* spell = _player->m_currentSpells[CURRENT_CHANNELED_SPELL]) 
     384        { 
     385            if(spell->m_spellInfo->Id==spellId) 
     386            { 
     387                spell->cancel(); 
     388                spell->SetReferencedFromCurrent(false); 
     389                _player->m_currentSpells[CURRENT_CHANNELED_SPELL] = NULL; 
     390            } 
     391        } 
     392        return; 
     393    } 
     394 
     395    // non channeled case 
    380396    _player->RemoveAurasDueToSpellByCancel(spellId); 
    381  
    382     if (spellId == 2584)                                    // Waiting to resurrect spell cancel, we must remove player from resurrect queue 
    383     { 
    384         BattleGround *bg = _player->GetBattleGround(); 
    385         if(!bg) 
    386             return; 
    387         bg->RemovePlayerFromResurrectQueue(_player->GetGUID()); 
    388     } 
    389397} 
    390398 
  • trunk/src/game/Unit.cpp

    r250 r251  
    40954095void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode) 
    40964096{ 
    4097     if (IsSingleTargetSpell((*i).second->GetSpellProto())) 
    4098     { 
    4099         if(Unit* caster = (*i).second->GetCaster()) 
     4097    Aura* Aur = i->second; 
     4098    SpellEntry const* AurSpellInfo = Aur->GetSpellProto(); 
     4099 
     4100    Unit* caster = NULL; 
     4101    if (IsSingleTargetSpell(AurSpellInfo)) 
     4102    { 
     4103        caster = Aur->GetCaster(); 
     4104        if(caster) 
    41004105        { 
    41014106            AuraList& scAuras = caster->GetSingleCastAuras(); 
    4102             scAuras.remove((*i).second); 
     4107            scAuras.remove(Aur); 
    41034108        } 
    41044109        else 
     
    41094114    } 
    41104115 
    4111     if ((*i).second->GetModifier()->m_auraname < TOTAL_AURAS) 
    4112     { 
    4113         m_modAuras[(*i).second->GetModifier()->m_auraname].remove((*i).second); 
    4114         if((*i).second->GetSpellProto()->AuraInterruptFlags) 
    4115         { 
    4116             m_interruptableAuras.remove((*i).second); 
     4116    // remove from list before mods removing (prevent cyclic calls, mods added before including to aura list - use reverse order) 
     4117    if (Aur->GetModifier()->m_auraname < TOTAL_AURAS) 
     4118    { 
     4119        m_modAuras[Aur->GetModifier()->m_auraname].remove(Aur); 
     4120        if(Aur->GetSpellProto()->AuraInterruptFlags) 
     4121        { 
     4122            m_interruptableAuras.remove(Aur); 
    41174123            UpdateInterruptMask(); 
    41184124        } 
    4119         if((*i).second->GetSpellProto()->Attributes & SPELL_ATTR_BREAKABLE_BY_DAMAGE) 
    4120             m_ccAuras.remove((*i).second); 
    4121     } 
    4122  
    4123     // remove from list before mods removing (prevent cyclic calls, mods added before including to aura list - use reverse order) 
    4124     Aura* Aur = i->second; 
     4125        if(Aur->GetSpellProto()->Attributes & SPELL_ATTR_BREAKABLE_BY_DAMAGE) 
     4126            m_ccAuras.remove(Aur); 
     4127    } 
     4128 
    41254129    // Set remove mode 
    41264130    Aur->SetRemoveMode(mode); 
     
    41304134    ++m_removedAuras;                                       // internal count used by unit update 
    41314135 
    4132     // Status unsummoned at aura remove 
     4136    // Statue unsummoned at aura remove 
    41334137    Totem* statue = NULL; 
    4134     if(IsChanneledSpell(Aur->GetSpellProto())) 
    4135         if(Unit* caster = Aur->GetCaster()) 
     4138    bool caster_channeled = false; 
     4139    if(IsChanneledSpell(AurSpellInfo)) 
     4140    { 
     4141        if(!caster)                                         // can be already located for IsSingleTargetSpell case 
     4142            caster = Aur->GetCaster(); 
     4143 
     4144        if(caster) 
     4145        { 
    41364146            if(caster->GetTypeId()==TYPEID_UNIT && ((Creature*)caster)->isTotem() && ((Totem*)caster)->GetTotemType()==TOTEM_STATUE) 
    41374147                statue = ((Totem*)caster); 
     4148            else 
     4149                caster_channeled = caster==this; 
     4150        } 
     4151    } 
    41384152 
    41394153 
     
    41534167    Aur->_RemoveAura(); 
    41544168    delete Aur; 
     4169 
     4170    if(caster_channeled) 
     4171        RemoveAurasAtChanneledTarget (AurSpellInfo); 
    41554172 
    41564173    if(statue) 
     
    45794596} 
    45804597 
    4581 bool Unit::HandleHasteAuraProc(Unit *pVictim, SpellEntry const *hasteSpell, uint32 /*effIndex*/, uint32 damage, Aura* triggeredByAura, SpellEntry const * procSpell, uint32 /*procFlag*/, uint32 cooldown) 
    4582 { 
     4598bool Unit::HandleHasteAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const * /*procSpell*/, uint32 /*procFlag*/, uint32 cooldown) 
     4599{ 
     4600    SpellEntry const *hasteSpell = triggeredByAura->GetSpellProto(); 
     4601 
    45834602    Item* castItem = triggeredByAura->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER 
    45844603        ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL; 
     
    46404659} 
    46414660 
    4642 bool Unit::HandleDummyAuraProc(Unit *pVictim, SpellEntry const *dummySpell, uint32 effIndex, uint32 damage, Aura* triggeredByAura, SpellEntry const * procSpell, uint32 procFlag, uint32 cooldown) 
    4643 { 
     4661bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const * procSpell, uint32 procFlag, uint32 cooldown) 
     4662{ 
     4663    SpellEntry const *dummySpell = triggeredByAura->GetSpellProto (); 
     4664    uint32 effIndex = triggeredByAura->GetEffIndex (); 
     4665 
    46444666    Item* castItem = triggeredByAura->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER 
    46454667        ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL; 
     
    64596481} 
    64606482 
    6461 bool Unit::HandleOverrideClassScriptAuraProc(Unit *pVictim, int32 scriptId, uint32 damage, Aura *triggeredByAura, SpellEntry const *procSpell, uint32 cooldown) 
    6462 { 
     6483bool Unit::HandleOverrideClassScriptAuraProc(Unit *pVictim, Aura *triggeredByAura, SpellEntry const *procSpell, uint32 cooldown) 
     6484{ 
     6485    int32 scriptId = triggeredByAura->GetModifier()->m_miscvalue; 
     6486 
    64636487    if(!pVictim || !pVictim->isAlive()) 
    64646488        return false; 
     
    99249948struct ProcTriggeredData 
    99259949{ 
    9926     ProcTriggeredData(SpellEntry const * _spellInfo, uint32 _spellParam, Aura* _triggeredByAura, uint32 _cooldown) 
    9927         : spellInfo(_spellInfo), spellParam(_spellParam), triggeredByAura(_triggeredByAura), 
     9950    ProcTriggeredData(Aura* _triggeredByAura, uint32 _cooldown) 
     9951        : triggeredByAura(_triggeredByAura), 
    99289952        triggeredByAura_SpellPair(Unit::spellEffectPair(triggeredByAura->GetId(),triggeredByAura->GetEffIndex())), 
    99299953        cooldown(_cooldown) 
    9930         {} 
    9931  
    9932     SpellEntry const * spellInfo; 
    9933     uint32 spellParam; 
    9934     Aura* triggeredByAura; 
    9935     Unit::spellEffectPair triggeredByAura_SpellPair; 
    9936     uint32 cooldown; 
     9954    {} 
     9955 
     9956    Aura* triggeredByAura;                                  // triggred aura, can be invalidate at triggered aura proccessing 
     9957    Unit::spellEffectPair triggeredByAura_SpellPair;        // spell pair, used for re-find aura (by pointer comparison in range) 
     9958    uint32 cooldown;                                        // possible hidden cooldown 
    99379959}; 
    99389960 
     
    99519973            next = i; ++next; 
    99529974 
    9953             SpellEntry const *spellProto = (*i)->GetSpellProto(); 
    9954             if(!spellProto) 
     9975            Aura* i_aura = *i; 
     9976 
     9977            uint32 cooldown;                                // returned at next line 
     9978            if(!IsTriggeredAtSpellProcEvent(i_aura->GetSpellProto(), procSpell, procFlag,attType,isVictim,cooldown)) 
    99559979                continue; 
    99569980 
    9957             SpellProcEventEntry const *spellProcEvent = spellmgr.GetSpellProcEvent(spellProto->Id); 
    9958             if(!spellProcEvent) 
    9959             { 
    9960                 // used to prevent spam in log about same non-handled spells 
    9961                 static std::set<uint32> nonHandledSpellProcSet; 
    9962  
    9963                 if(spellProto->procFlags != 0 && nonHandledSpellProcSet.find(spellProto->Id)==nonHandledSpellProcSet.end()) 
    9964                 { 
    9965                     sLog.outError("ProcDamageAndSpell: spell %u (%s aura source) not have record in `spell_proc_event`)",spellProto->Id,(isVictim?"a victim's":"an attacker's")); 
    9966                     nonHandledSpellProcSet.insert(spellProto->Id); 
    9967                 } 
    9968  
    9969                 // spell.dbc use totally different flags, that only can create problems if used. 
    9970                 continue; 
    9971             } 
    9972  
    9973             // Check spellProcEvent data requirements 
    9974             if(!SpellMgr::IsSpellProcEventCanTriggeredBy(spellProcEvent, procSpell,procFlag)) 
    9975                 continue; 
    9976  
    9977             // Check if current equipment allows aura to proc 
    9978             if(!isVictim && GetTypeId() == TYPEID_PLAYER ) 
    9979             { 
    9980                 if(spellProto->EquippedItemClass == ITEM_CLASS_WEAPON) 
    9981                 { 
    9982                     Item *item = ((Player*)this)->GetWeaponForAttack(attType,true); 
    9983  
    9984                     if(!item || !((1<<item->GetProto()->SubClass) & spellProto->EquippedItemSubClassMask)) 
    9985                         continue; 
    9986                 } 
    9987                 else if(spellProto->EquippedItemClass == ITEM_CLASS_ARMOR) 
    9988                 { 
    9989                     // Check if player is wearing shield 
    9990                     Item *item = ((Player*)this)->GetShield(true); 
    9991                     if(!item || !((1<<item->GetProto()->SubClass) & spellProto->EquippedItemSubClassMask)) 
    9992                         continue; 
    9993                 } 
    9994             } 
    9995  
    9996             float chance = (float)spellProto->procChance; 
    9997  
    9998             if(Player* modOwner = GetSpellModOwner()) 
    9999                 modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_CHANCE_OF_SUCCESS,chance); 
    10000  
    10001             if(!isVictim && spellProcEvent->ppmRate != 0) 
    10002             { 
    10003                 uint32 WeaponSpeed = GetAttackTime(attType); 
    10004                 chance = GetPPMProcChance(WeaponSpeed, spellProcEvent->ppmRate); 
    10005             } 
    10006  
    10007             if(roll_chance_f(chance)) 
    10008             { 
    10009                 uint32 cooldown = spellProcEvent->cooldown; 
    10010  
    10011                 uint32 i_spell_eff = (*i)->GetEffIndex(); 
    10012  
    10013                 int32 i_spell_param; 
    10014                 switch(*aur) 
    10015                 { 
    10016                     case SPELL_AURA_PROC_TRIGGER_SPELL: 
    10017                         i_spell_param = procFlag; 
    10018                         break; 
    10019                     case SPELL_AURA_DUMMY: 
    10020                     case SPELL_AURA_PRAYER_OF_MENDING: 
    10021                     case SPELL_AURA_MOD_HASTE: 
    10022                         i_spell_param = i_spell_eff; 
    10023                         break; 
    10024                     case SPELL_AURA_OVERRIDE_CLASS_SCRIPTS: 
    10025                         i_spell_param = (*i)->GetModifier()->m_miscvalue; 
    10026                         break; 
    10027                     default: 
    10028                         i_spell_param = (*i)->GetModifier()->m_amount; 
    10029                         break; 
    10030                 } 
    10031  
    10032                 procTriggered.push_back( ProcTriggeredData(spellProto,i_spell_param,*i, cooldown) ); 
    10033             } 
     9981            procTriggered.push_back( ProcTriggeredData(i_aura, cooldown) ); 
    100349982        } 
    100359983 
     
    1006410012            } 
    1006510013 
     10014            // this is aura triggering code call 
     10015            Aura* triggeredByAura = i->triggeredByAura; 
     10016 
    1006610017            // save charges existence before processing to prevent crash at access to deleted triggered aura after 
    10067             bool triggeredByAuraWithCharges =  i->triggeredByAura->m_procCharges > 0; 
     10018            bool triggeredByAuraWithCharges =  triggeredByAura->m_procCharges > 0; 
    1006810019 
    1006910020            bool casted = false; 
     
    1007210023                case SPELL_AURA_PROC_TRIGGER_SPELL: 
    1007310024                { 
    10074                     sLog.outDebug("ProcDamageAndSpell: casting spell %u (triggered by %s aura of spell %u)", i->spellInfo->Id,(isVictim?"a victim's":"an attacker's"),i->triggeredByAura->GetId()); 
    10075                     casted = HandleProcTriggerSpell(pTarget, damage, i->triggeredByAura, procSpell,i->spellParam,attType,i->cooldown); 
     10025                    sLog.outDebug("ProcDamageAndSpell: casting spell (triggered by %s proc aura of spell %u)", 
     10026                        (isVictim?"a victim's":"an attacker's"),i->triggeredByAura->GetId()); 
     10027                    casted = HandleProcTriggerSpell(pTarget, damage, triggeredByAura, procSpell, procFlag, attType, i->cooldown); 
    1007610028                    break; 
    1007710029                } 
    1007810030                case SPELL_AURA_PROC_TRIGGER_DAMAGE: 
    1007910031                { 
    10080                     sLog.outDebug("ProcDamageAndSpell: doing %u damage from spell id %u (triggered by %s aura of spell %u)", i->spellParam, i->spellInfo->Id,(isVictim?"a victim's":"an attacker's"),i->triggeredByAura->GetId()); 
    10081                     uint32 damage = i->spellParam; 
    10082                     SpellNonMeleeDamageLog(pTarget, i->spellInfo->Id, damage, true, true); 
     10032                    uint32 triggered_damage = triggeredByAura->GetModifier()->m_amount; 
     10033                    sLog.outDebug("ProcDamageAndSpell: doing %u damage (triggered by %s aura of spell %u)", 
     10034                        triggered_damage, (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId()); 
     10035                    SpellNonMeleeDamageLog(pTarget, triggeredByAura->GetId(), triggered_damage, true, true); 
    1008310036                    casted = true; 
    1008410037                    break; 
     
    1008610039                case SPELL_AURA_DUMMY: 
    1008710040                { 
    10088                     sLog.outDebug("ProcDamageAndSpell: casting spell id %u (triggered by %s dummy aura of spell %u)", i->spellInfo->Id,(isVictim?"a victim's":"an attacker's"),i->triggeredByAura->GetId()); 
    10089                     casted = HandleDummyAuraProc(pTarget, i->spellInfo, i->spellParam, damage, i->triggeredByAura, procSpell, procFlag,i->cooldown); 
     10041                    uint32 effect = triggeredByAura->GetEffIndex(); 
     10042                    sLog.outDebug("ProcDamageAndSpell: casting spell (triggered by %s dummy aura of spell %u)", 
     10043                        (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId()); 
     10044                    casted = HandleDummyAuraProc(pTarget, damage, triggeredByAura, procSpell, procFlag,i->cooldown); 
    1009010045                    break; 
    1009110046                } 
    1009210047                case SPELL_AURA_PRAYER_OF_MENDING: 
    1009310048                { 
    10094                     sLog.outDebug("ProcDamageAndSpell(mending): casting spell id %u (triggered by %s dummy aura of spell %u)", i->spellInfo->Id,(isVictim?"a victim's":"an attacker's"),i->triggeredByAura->GetId()); 
    10095  
    10096                     // aura can be deleted at casts 
    10097                     int32 heal = i->triggeredByAura->GetModifier()->m_amount; 
    10098                     uint64 caster_guid = i->triggeredByAura->GetCasterGUID(); 
    10099  
    10100                     // jumps 
    10101                     int32 jumps = i->triggeredByAura->m_procCharges-1; 
    10102  
    10103                     // current aura expire 
    10104                     i->triggeredByAura->m_procCharges = 1;  // will removed at next charges decrease 
    10105  
    10106                     // next target selection 
    10107                     if(jumps > 0 && GetTypeId()==TYPEID_PLAYER && IS_PLAYER_GUID(caster_guid)) 
    10108                     { 
    10109                         Aura* aura = i->triggeredByAura; 
    10110  
    10111                         SpellEntry const* spellProto = aura->GetSpellProto(); 
    10112                         uint32 effIdx = aura->GetEffIndex(); 
    10113  
    10114                         float radius; 
    10115                         if (spellProto->EffectRadiusIndex[effIdx]) 
    10116                             radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(spellProto->EffectRadiusIndex[effIdx])); 
    10117                         else 
    10118                             radius = GetSpellMaxRange(sSpellRangeStore.LookupEntry(spellProto->rangeIndex)); 
    10119  
    10120                         if(Player* caster = ((Player*)aura->GetCaster())) 
    10121                         { 
    10122                             caster->ApplySpellMod(spellProto->Id, SPELLMOD_RADIUS, radius,NULL); 
    10123  
    10124                             if(Player* target = ((Player*)this)->GetNextRandomRaidMember(radius)) 
    10125                             { 
    10126                                 // aura will applied from caster, but spell casted from current aura holder 
    10127                                 SpellModifier *mod = new SpellModifier; 
    10128                                 mod->op = SPELLMOD_CHARGES; 
    10129                                 mod->value = jumps-5;               // negative 
    10130                                 mod->type = SPELLMOD_FLAT; 
    10131                                 mod->spellId = spellProto->Id; 
    10132                                 mod->effectId = effIdx; 
    10133                                 mod->lastAffected = NULL; 
    10134                                 mod->mask = spellProto->SpellFamilyFlags; 
    10135                                 mod->charges = 0; 
    10136  
    10137                                 caster->AddSpellMod(mod, true); 
    10138                                 CastCustomSpell(target,spellProto->Id,&heal,NULL,NULL,true,NULL,aura,caster->GetGUID()); 
    10139                                 caster->AddSpellMod(mod, false); 
    10140                             } 
    10141                         } 
    10142                     } 
    10143  
    10144                     // heal 
    10145                     CastCustomSpell(this,33110,&heal,NULL,NULL,true,NULL,NULL,caster_guid); 
    10146                     casted = true; 
     10049                    sLog.outDebug("ProcDamageAndSpell: casting mending (triggered by %s dummy aura of spell %u)", 
     10050                        (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId()); 
     10051 
     10052                    casted = HandleMeandingAuraProc(triggeredByAura); 
    1014710053                    break; 
    1014810054                } 
    1014910055                case SPELL_AURA_MOD_HASTE: 
    1015010056                { 
    10151                     sLog.outDebug("ProcDamageAndSpell: casting spell id %u (triggered by %s haste aura of spell %u)", i->spellInfo->Id,(isVictim?"a victim's":"an attacker's"),i->triggeredByAura->GetId()); 
    10152                     casted = HandleHasteAuraProc(pTarget, i->spellInfo, i->spellParam, damage, i->triggeredByAura, procSpell, procFlag,i->cooldown); 
     10057                    sLog.outDebug("ProcDamageAndSpell: casting spell (triggered by %s haste aura of spell %u)", 
     10058                        (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId()); 
     10059                    casted = HandleHasteAuraProc(pTarget, damage, i->triggeredByAura, procSpell, procFlag,i->cooldown); 
    1015310060                    break; 
    1015410061                } 
     
    1015710064                    // nothing do, just charges counter 
    1015810065                    // but count only in case appropriate school damage 
    10159                     casted = i->triggeredByAura->GetModifier()->m_miscvalue & damageSchoolMask; 
     10066                    casted = triggeredByAura->GetModifier()->m_miscvalue & damageSchoolMask; 
    1016010067                    break; 
    1016110068                } 
    1016210069                case SPELL_AURA_OVERRIDE_CLASS_SCRIPTS: 
    1016310070                { 
    10164                     sLog.outDebug("ProcDamageAndSpell: casting spell id %u (triggered by %s aura of spell %u)", i->spellInfo->Id,(isVictim?"a victim's":"an attacker's"),i->triggeredByAura->GetId()); 
    10165                     casted = HandleOverrideClassScriptAuraProc(pTarget, i->spellParam, damage, i->triggeredByAura, procSpell,i->cooldown); 
     10071                    sLog.outDebug("ProcDamageAndSpell: casting spell id %u (triggered by %s class script aura of spell %u)", 
     10072                        (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId()); 
     10073                    casted = HandleOverrideClassScriptAuraProc(pTarget, i->triggeredByAura, procSpell,i->cooldown); 
    1016610074                    break; 
    1016710075                } 
     
    1081110719    return pet; 
    1081210720} 
     10721 
     10722bool Unit::IsTriggeredAtSpellProcEvent(SpellEntry const* spellProto, SpellEntry const* procSpell, uint32 procFlag, WeaponAttackType attType, bool isVictim, uint32& cooldown ) 
     10723{ 
     10724    SpellProcEventEntry const * spellProcEvent = spellmgr.GetSpellProcEvent(spellProto->Id); 
     10725 
     10726    if(!spellProcEvent) 
     10727    { 
     10728        // used to prevent spam in log about same non-handled spells 
     10729        static std::set<uint32> nonHandledSpellProcSet; 
     10730 
     10731        if(spellProto->procFlags != 0 && nonHandledSpellProcSet.find(spellProto->Id)==nonHandledSpellProcSet.end()) 
     10732        { 
     10733            sLog.outError("ProcDamageAndSpell: spell %u (%s aura source) not have record in `spell_proc_event`)",spellProto->Id,(isVictim?"a victim's":"an attacker's")); 
     10734            nonHandledSpellProcSet.insert(spellProto->Id); 
     10735        } 
     10736 
     10737        // spell.dbc use totally different flags, that only can create problems if used. 
     10738        return false; 
     10739    } 
     10740 
     10741    // Check spellProcEvent data requirements 
     10742    if(!SpellMgr::IsSpellProcEventCanTriggeredBy(spellProcEvent, procSpell,procFlag)) 
     10743        return false; 
     10744 
     10745    // Check if current equipment allows aura to proc 
     10746    if(!isVictim && GetTypeId() == TYPEID_PLAYER ) 
     10747    { 
     10748        if(spellProto->EquippedItemClass == ITEM_CLASS_WEAPON) 
     10749        { 
     10750            Item *item = ((Player*)this)->GetWeaponForAttack(attType,true); 
     10751 
     10752            if(!item || !((1<<item->GetProto()->SubClass) & spellProto->EquippedItemSubClassMask)) 
     10753                return false; 
     10754        } 
     10755        else if(spellProto->EquippedItemClass == ITEM_CLASS_ARMOR) 
     10756        { 
     10757            // Check if player is wearing shield 
     10758            Item *item = ((Player*)this)->GetShield(true); 
     10759            if(!item || !((1<<item->GetProto()->SubClass) & spellProto->EquippedItemSubClassMask)) 
     10760                return false; 
     10761        } 
     10762    } 
     10763 
     10764    float chance = (float)spellProto->procChance; 
     10765 
     10766    if(Player* modOwner = GetSpellModOwner()) 
     10767        modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_CHANCE_OF_SUCCESS,chance); 
     10768 
     10769    if(!isVictim && spellProcEvent && spellProcEvent->ppmRate != 0) 
     10770    { 
     10771        uint32 WeaponSpeed = GetAttackTime(attType); 
     10772        chance = GetPPMProcChance(WeaponSpeed, spellProcEvent->ppmRate); 
     10773    } 
     10774 
     10775    cooldown = spellProcEvent ? spellProcEvent->cooldown : 0; 
     10776    return roll_chance_f(chance); 
     10777} 
     10778 
     10779bool Unit::HandleMeandingAuraProc( Aura* triggeredByAura ) 
     10780{ 
     10781    // aura can be deleted at casts 
     10782    SpellEntry const* spellProto = triggeredByAura->GetSpellProto(); 
     10783    uint32 effIdx = triggeredByAura->GetEffIndex(); 
     10784    int32 heal = triggeredByAura->GetModifier()->m_amount; 
     10785    uint64 caster_guid = triggeredByAura->GetCasterGUID(); 
     10786 
     10787    // jumps 
     10788    int32 jumps = triggeredByAura->m_procCharges-1; 
     10789 
     10790    // current aura expire 
     10791    triggeredByAura->m_procCharges = 1;             // will removed at next charges decrease 
     10792 
     10793    // next target selection 
     10794    if(jumps > 0 && GetTypeId()==TYPEID_PLAYER && IS_PLAYER_GUID(caster_guid)) 
     10795    { 
     10796        float radius; 
     10797        if (spellProto->EffectRadiusIndex[effIdx]) 
     10798            radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(spellProto->EffectRadiusIndex[effIdx])); 
     10799        else 
     10800            radius = GetSpellMaxRange(sSpellRangeStore.LookupEntry(spellProto->rangeIndex)); 
     10801 
     10802        if(Player* caster = ((Player*)triggeredByAura->GetCaster())) 
     10803        { 
     10804            caster->ApplySpellMod(spellProto->Id, SPELLMOD_RADIUS, radius,NULL); 
     10805 
     10806            if(Player* target = ((Player*)this)->GetNextRandomRaidMember(radius)) 
     10807            { 
     10808                // aura will applied from caster, but spell casted from current aura holder 
     10809                SpellModifier *mod = new SpellModifier; 
     10810                mod->op = SPELLMOD_CHARGES; 
     10811                mod->value = jumps-5;               // negative 
     10812                mod->type = SPELLMOD_FLAT; 
     10813                mod->spellId = spellProto->Id; 
     10814                mod->effectId = effIdx; 
     10815                mod->lastAffected = NULL; 
     10816                mod->mask = spellProto->SpellFamilyFlags; 
     10817                mod->charges = 0; 
     10818 
     10819                caster->AddSpellMod(mod, true); 
     10820                CastCustomSpell(target,spellProto->Id,&heal,NULL,NULL,true,NULL,triggeredByAura,caster->GetGUID()); 
     10821                caster->AddSpellMod(mod, false); 
     10822            } 
     10823        } 
     10824    } 
     10825 
     10826    // heal 
     10827    CastCustomSpell(this,33110,&heal,NULL,NULL,true,NULL,NULL,caster_guid); 
     10828    return true; 
     10829} 
     10830 
     10831void Unit::RemoveAurasAtChanneledTarget(SpellEntry const* spellInfo) 
     10832{ 
     10833    uint64 target_guid = GetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT); 
     10834 
     10835    if(!IS_UNIT_GUID(target_guid)) 
     10836        return; 
     10837 
     10838    Unit* target = ObjectAccessor::GetUnit(*this, target_guid); 
     10839    if(!target) 
     10840        return; 
     10841 
     10842    for (AuraMap::iterator iter = target->GetAuras().begin(); iter != target->GetAuras().end(); ) 
     10843    { 
     10844        if (iter->second->GetId() == spellInfo->Id && iter->second->GetCasterGUID()==GetGUID()) 
     10845            target->RemoveAura(iter); 
     10846        else 
     10847            ++iter; 
     10848    } 
     10849} 
  • trunk/src/game/Unit.h

    r233 r251  
    10401040        void RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit *stealer); 
    10411041        void RemoveAurasDueToSpellByCancel(uint32 spellId); 
     1042        void RemoveAurasAtChanneledTarget(SpellEntry const* spellInfo); 
    10421043        void RemoveNotOwnSingleTargetAuras(); 
    10431044 
     
    13711372 
    13721373        void ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag, AuraTypeSet const& procAuraTypes, WeaponAttackType attType, SpellEntry const * procSpell, uint32 damage, SpellSchoolMask damageSchoolMask ); 
    1373         bool HandleDummyAuraProc(Unit *pVictim, SpellEntry const *spellProto, uint32 effIndex, uint32 damage, Aura* triggeredByAura, SpellEntry const * procSpell, uint32 procFlag,uint32 cooldown); 
    1374         bool HandleProcTriggerSpell(Unit *pVictim,uint32 damage, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 procFlags,WeaponAttackType attType,uint32 cooldown); 
    1375         bool HandleHasteAuraProc(Unit *pVictim, SpellEntry const *spellProto, uint32 effIndex, uint32 damage, Aura* triggeredByAura, SpellEntry const * procSpell, uint32 procFlag,uint32 cooldown); 
    1376         bool HandleOverrideClassScriptAuraProc(Unit *pVictim, int32 scriptId, uint32 damage, Aura* triggeredByAura, SpellEntry const *procSpell,uint32 cooldown); 
     1374        bool IsTriggeredAtSpellProcEvent( SpellEntry const* spellProto, SpellEntry const* procSpell, uint32 procFlag, WeaponAttackType attType, bool isVictim, uint32& cooldown ); 
     1375        bool HandleDummyAuraProc(   Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const* procSpell, uint32 procFlag, uint32 cooldown); 
     1376        bool HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const* procSpell, uint32 procFlag, WeaponAttackType attType, uint32 cooldown); 
     1377        bool HandleHasteAuraProc(   Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const* procSpell, uint32 procFlag, uint32 cooldown); 
     1378        bool HandleOverrideClassScriptAuraProc(Unit *pVictim, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 cooldown); 
     1379        bool HandleMeandingAuraProc(Aura* triggeredByAura); 
    13771380 
    13781381        uint32 m_state;                                     // Even derived shouldn't modify