Changeset 272 for trunk/src/game/Unit.cpp
- Timestamp:
- 11/22/08 00:35:41 (17 years ago)
- Files:
-
- 1 modified
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/game/Unit.cpp
r267 r272 1149 1149 if ( GetSpellSchoolMask(spellInfo) & SPELL_SCHOOL_MASK_NORMAL ) 1150 1150 { 1151 uint32 modDamage=*damage; 1152 1151 1153 // apply spellmod to Done damage 1152 1154 if(Player* modOwner = GetSpellModOwner()) … … 1433 1435 if(!this || !pVictim) 1434 1436 return 0; 1435 if(! isAlive() || !pVictim->isAlive())1437 if(!this->isAlive() || !pVictim->isAlive()) 1436 1438 return 0; 1437 1439 … … 3781 3783 { 3782 3784 m_ccAuras.push_back(Aur); 3785 RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_CC); 3783 3786 } 3784 3787 } … … 3896 3899 if(!is_triggered_by_spell) 3897 3900 { 3898 bool sameCaster = Aur->GetCasterGUID() == (*i).second->GetCasterGUID(); 3899 if( spellmgr.IsNoStackSpellDueToSpell(spellId, i_spellId, sameCaster) ) 3900 { 3901 //some spells should be not removed by lower rank of them 3902 // what is this spell? 3903 if (!sameCaster 3904 &&(spellProto->Effect[effIndex]==SPELL_EFFECT_APPLY_AREA_AURA_PARTY) 3905 &&(spellProto->DurationIndex==21) 3906 &&(spellmgr.IsRankSpellDueToSpell(spellProto, i_spellId)) 3907 &&(CompareAuraRanks(spellId, effIndex, i_spellId, i_effIndex) < 0)) 3908 return false; 3901 SpellSpecific i_spellId_spec = GetSpellSpecific(i_spellId); 3902 3903 bool is_sspc = IsSingleFromSpellSpecificPerCaster(spellId_spec,i_spellId_spec); 3904 3905 if( is_sspc && Aur->GetCasterGUID() == (*i).second->GetCasterGUID() ) 3906 { 3907 // cannot remove higher rank 3908 if (spellmgr.IsRankSpellDueToSpell(spellProto, i_spellId)) 3909 if(CompareAuraRanks(spellId, effIndex, i_spellId, i_effIndex) < 0) 3910 return false; 3909 3911 3910 3912 // Its a parent aura (create this aura in ApplyModifier) … … 3920 3922 else 3921 3923 next = m_Auras.begin(); 3924 } 3925 else if( !is_sspc && spellmgr.IsNoStackSpellDueToSpell(spellId, i_spellId) ) 3926 { 3927 // Its a parent aura (create this aura in ApplyModifier) 3928 if ((*i).second->IsInUse()) 3929 { 3930 sLog.outError("Aura (Spell %u Effect %u) is in process but attempt removed at aura (Spell %u Effect %u) adding, need add stack rule for Unit::RemoveNoStackAurasDueToAura", i->second->GetId(), i->second->GetEffIndex(),Aur->GetId(), Aur->GetEffIndex()); 3931 continue; 3932 } 3933 RemoveAurasDueToSpell(i_spellId); 3934 3935 if( m_Auras.empty() ) 3936 break; 3937 else 3938 next = m_Auras.begin(); 3939 } 3940 // Potions stack aura by aura (elixirs/flask already checked) 3941 else if( spellProto->SpellFamilyName == SPELLFAMILY_POTION && i_spellProto->SpellFamilyName == SPELLFAMILY_POTION ) 3942 { 3943 if (IsNoStackAuraDueToAura(spellId, effIndex, i_spellId, i_effIndex)) 3944 { 3945 if(CompareAuraRanks(spellId, effIndex, i_spellId, i_effIndex) < 0) 3946 return false; // cannot remove higher rank 3947 3948 // Its a parent aura (create this aura in ApplyModifier) 3949 if ((*i).second->IsInUse()) 3950 { 3951 sLog.outError("Aura (Spell %u Effect %u) is in process but attempt removed at aura (Spell %u Effect %u) adding, need add stack rule for Unit::RemoveNoStackAurasDueToAura", i->second->GetId(), i->second->GetEffIndex(),Aur->GetId(), Aur->GetEffIndex()); 3952 continue; 3953 } 3954 RemoveAura(i); 3955 next = i; 3956 } 3922 3957 } 3923 3958 } … … 4094 4129 void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode) 4095 4130 { 4096 Aura* Aur = i->second; 4097 SpellEntry const* AurSpellInfo = Aur->GetSpellProto(); 4098 4099 Unit* caster = NULL; 4100 if (IsSingleTargetSpell(AurSpellInfo)) 4101 { 4102 caster = Aur->GetCaster(); 4103 if(caster) 4131 if (IsSingleTargetSpell((*i).second->GetSpellProto())) 4132 { 4133 if(Unit* caster = (*i).second->GetCaster()) 4104 4134 { 4105 4135 AuraList& scAuras = caster->GetSingleCastAuras(); 4106 scAuras.remove( Aur);4136 scAuras.remove((*i).second); 4107 4137 } 4108 4138 else … … 4113 4143 } 4114 4144 4115 // remove from list before mods removing (prevent cyclic calls, mods added before including to aura list - use reverse order) 4116 if (Aur->GetModifier()->m_auraname < TOTAL_AURAS) 4145 if ((*i).second->GetModifier()->m_auraname < TOTAL_AURAS) 4117 4146 { 4118 4147 m_modAuras[(*i).second->GetModifier()->m_auraname].remove((*i).second); … … 4126 4155 } 4127 4156 4157 // remove from list before mods removing (prevent cyclic calls, mods added before including to aura list - use reverse order) 4158 Aura* Aur = i->second; 4128 4159 // Set remove mode 4129 4160 Aur->SetRemoveMode(mode); … … 4133 4164 ++m_removedAuras; // internal count used by unit update 4134 4165 4135 // Statu eunsummoned at aura remove4166 // Status unsummoned at aura remove 4136 4167 Totem* statue = NULL; 4137 bool caster_channeled = false; 4138 if(IsChanneledSpell(AurSpellInfo)) 4139 { 4140 if(!caster) // can be already located for IsSingleTargetSpell case 4141 caster = Aur->GetCaster(); 4142 4143 if(caster) 4144 { 4168 if(IsChanneledSpell(Aur->GetSpellProto())) 4169 if(Unit* caster = Aur->GetCaster()) 4145 4170 if(caster->GetTypeId()==TYPEID_UNIT && ((Creature*)caster)->isTotem() && ((Totem*)caster)->GetTotemType()==TOTEM_STATUE) 4146 4171 statue = ((Totem*)caster); 4147 else 4148 caster_channeled = caster==this; 4149 } 4150 } 4172 4151 4173 4152 4174 if(const std::vector<int32> *spell_triggered = spellmgr.GetSpellLinked(-(int32)Aur->GetSpellProto()->Id)) … … 4165 4187 Aur->_RemoveAura(); 4166 4188 delete Aur; 4167 4168 if(caster_channeled)4169 RemoveAurasAtChanneledTarget (AurSpellInfo);4170 4189 4171 4190 if(statue) … … 4594 4613 } 4595 4614 4596 bool Unit::HandleHasteAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const * /*procSpell*/, uint32 /*procFlag*/, uint32 cooldown) 4597 { 4598 SpellEntry const *hasteSpell = triggeredByAura->GetSpellProto(); 4599 4615 bool Unit::HandleHasteAuraProc(Unit *pVictim, SpellEntry const *hasteSpell, uint32 /*effIndex*/, uint32 damage, Aura* triggeredByAura, SpellEntry const * procSpell, uint32 /*procFlag*/, uint32 cooldown) 4616 { 4600 4617 Item* castItem = triggeredByAura->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER 4601 4618 ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL; … … 4657 4674 } 4658 4675 4659 bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const * procSpell, uint32 procFlag, uint32 cooldown) 4660 { 4661 SpellEntry const *dummySpell = triggeredByAura->GetSpellProto (); 4662 uint32 effIndex = triggeredByAura->GetEffIndex (); 4663 4676 bool Unit::HandleDummyAuraProc(Unit *pVictim, SpellEntry const *dummySpell, uint32 effIndex, uint32 damage, Aura* triggeredByAura, SpellEntry const * procSpell, uint32 procFlag, uint32 cooldown) 4677 { 4664 4678 Item* castItem = triggeredByAura->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER 4665 4679 ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL; … … 6249 6263 return false; 6250 6264 6265 uint32 spell = 0; 6251 6266 switch(triggeredByAura->GetSpellProto()->Id) 6252 6267 { … … 6278 6293 6279 6294 // overwrite non existing triggered spell call in spell.dbc 6295 uint32 spell = 0; 6280 6296 switch(triggeredByAura->GetSpellProto()->Id) 6281 6297 { … … 6477 6493 } 6478 6494 6479 bool Unit::HandleOverrideClassScriptAuraProc(Unit *pVictim, Aura *triggeredByAura, SpellEntry const *procSpell, uint32 cooldown) 6480 { 6481 int32 scriptId = triggeredByAura->GetModifier()->m_miscvalue; 6482 6495 bool Unit::HandleOverrideClassScriptAuraProc(Unit *pVictim, int32 scriptId, uint32 damage, Aura *triggeredByAura, SpellEntry const *procSpell, uint32 cooldown) 6496 { 6483 6497 if(!pVictim || !pVictim->isAlive()) 6484 6498 return false; … … 7246 7260 } 7247 7261 7248 void Unit::SendEnergizeSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage, Powers powertype )7262 void Unit::SendEnergizeSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage, Powers powertype, bool critical) 7249 7263 { 7250 7264 WorldPacket data(SMSG_SPELLENERGIZELOG, (8+8+4+4+4+1)); … … 7346 7360 AuraList const& mModDamagePercentTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN); 7347 7361 for(AuraList::const_iterator i = mModDamagePercentTaken.begin(); i != mModDamagePercentTaken.end(); ++i) 7348 if( (*i)->GetModifier()->m_miscvalue & GetSpellSchoolMask(spellProto))7362 if((*i)->GetModifier()->m_miscvalue & GetSpellSchoolMask(spellProto)) 7349 7363 TakenTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f; 7350 7364 … … 8194 8208 8195 8209 // ..done (for creature type by mask) in taken 8196 AuraList const& mDamageDoneCreature = GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE_CREATURE);8210 AuraList const& mDamageDoneCreature = this->GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE_CREATURE); 8197 8211 for(AuraList::const_iterator i = mDamageDoneCreature.begin();i != mDamageDoneCreature.end(); ++i) 8198 8212 if(creatureTypeMask & uint32((*i)->GetModifier()->m_miscvalue)) … … 8262 8276 // SPELL_AURA_MOD_OFFHAND_DAMAGE_PCT included in weapon damage 8263 8277 8264 AuraList const& mDamageDoneVersus = GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE_VERSUS);8278 AuraList const& mDamageDoneVersus = this->GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE_VERSUS); 8265 8279 for(AuraList::const_iterator i = mDamageDoneVersus.begin();i != mDamageDoneVersus.end(); ++i) 8266 8280 if(creatureTypeMask & uint32((*i)->GetModifier()->m_miscvalue)) … … 8492 8506 target->SetStandState(PLAYER_STATE_NONE); 8493 8507 8494 if(!target->isInCombat() && target->GetTypeId() != TYPEID_PLAYER 8495 && ((Creature*)target)->isAggressive() && ((Creature*)target)->AI()) 8508 if(!target->isInCombat() && target->GetTypeId() != TYPEID_PLAYER && ((Creature*)target)->AI()) 8496 8509 ((Creature*)target)->AI()->AttackStart(this); 8497 8510 … … 8542 8555 { 8543 8556 assert(target); 8544 8545 if(!IsHostileTo(target))8546 return false;8547 8557 8548 8558 if(!target->isAttackableByAOE() || target->hasUnitState(UNIT_STAT_DIED)) … … 8721 8731 if(IsInWorld()) 8722 8732 { 8723 Map *m = GetMap();8733 Map *m = MapManager::Instance().GetMap(GetMapId(), this); 8724 8734 8725 8735 if(GetTypeId()==TYPEID_PLAYER) … … 9130 9140 } 9131 9141 9132 // search nearby enemy before enter evade mode9133 if(Unit *target = ((Creature*)this)->SelectNearestTarget())9134 {9135 ((Creature*)this)->AI()->AttackStart(target);9136 return true;9137 }9138 9139 9142 // enter in evade mode in other case 9140 9143 ((Creature*)this)->AI()->EnterEvadeMode(); … … 9790 9793 } 9791 9794 9795 9796 9792 9797 CharmInfo* Unit::InitCharmInfo(Unit *charm) 9793 9798 { … … 9953 9958 struct ProcTriggeredData 9954 9959 { 9955 ProcTriggeredData( Aura* _triggeredByAura, uint32 _cooldown)9956 : triggeredByAura(_triggeredByAura),9960 ProcTriggeredData(SpellEntry const * _spellInfo, uint32 _spellParam, Aura* _triggeredByAura, uint32 _cooldown) 9961 : spellInfo(_spellInfo), spellParam(_spellParam), triggeredByAura(_triggeredByAura), 9957 9962 triggeredByAura_SpellPair(Unit::spellEffectPair(triggeredByAura->GetId(),triggeredByAura->GetEffIndex())), 9958 9963 cooldown(_cooldown) 9959 {} 9960 9961 Aura* triggeredByAura; // triggred aura, can be invalidate at triggered aura proccessing 9962 Unit::spellEffectPair triggeredByAura_SpellPair; // spell pair, used for re-find aura (by pointer comparison in range) 9963 uint32 cooldown; // possible hidden cooldown 9964 {} 9965 9966 SpellEntry const * spellInfo; 9967 uint32 spellParam; 9968 Aura* triggeredByAura; 9969 Unit::spellEffectPair triggeredByAura_SpellPair; 9970 uint32 cooldown; 9964 9971 }; 9965 9972 … … 9978 9985 next = i; ++next; 9979 9986 9980 Aura* i_aura = *i; 9981 9982 uint32 cooldown; // returned at next line 9983 if(!IsTriggeredAtSpellProcEvent(i_aura->GetSpellProto(), procSpell, procFlag,attType,isVictim,cooldown)) 9987 SpellEntry const *spellProto = (*i)->GetSpellProto(); 9988 if(!spellProto) 9984 9989 continue; 9985 9990 9986 procTriggered.push_back( ProcTriggeredData(i_aura, cooldown) ); 9991 SpellProcEventEntry const *spellProcEvent = spellmgr.GetSpellProcEvent(spellProto->Id); 9992 if(!spellProcEvent) 9993 { 9994 // used to prevent spam in log about same non-handled spells 9995 static std::set<uint32> nonHandledSpellProcSet; 9996 9997 if(spellProto->procFlags != 0 && nonHandledSpellProcSet.find(spellProto->Id)==nonHandledSpellProcSet.end()) 9998 { 9999 sLog.outError("ProcDamageAndSpell: spell %u (%s aura source) not have record in `spell_proc_event`)",spellProto->Id,(isVictim?"a victim's":"an attacker's")); 10000 nonHandledSpellProcSet.insert(spellProto->Id); 10001 } 10002 10003 // spell.dbc use totally different flags, that only can create problems if used. 10004 continue; 10005 } 10006 10007 // Check spellProcEvent data requirements 10008 if(!SpellMgr::IsSpellProcEventCanTriggeredBy(spellProcEvent, procSpell,procFlag)) 10009 continue; 10010 10011 // Check if current equipment allows aura to proc 10012 if(!isVictim && GetTypeId() == TYPEID_PLAYER ) 10013 { 10014 if(spellProto->EquippedItemClass == ITEM_CLASS_WEAPON) 10015 { 10016 Item *item = ((Player*)this)->GetWeaponForAttack(attType,true); 10017 10018 if(!item || !((1<<item->GetProto()->SubClass) & spellProto->EquippedItemSubClassMask)) 10019 continue; 10020 } 10021 else if(spellProto->EquippedItemClass == ITEM_CLASS_ARMOR) 10022 { 10023 // Check if player is wearing shield 10024 Item *item = ((Player*)this)->GetShield(true); 10025 if(!item || !((1<<item->GetProto()->SubClass) & spellProto->EquippedItemSubClassMask)) 10026 continue; 10027 } 10028 } 10029 10030 float chance = (float)spellProto->procChance; 10031 10032 if(Player* modOwner = GetSpellModOwner()) 10033 modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_CHANCE_OF_SUCCESS,chance); 10034 10035 if(!isVictim && spellProcEvent->ppmRate != 0) 10036 { 10037 uint32 WeaponSpeed = GetAttackTime(attType); 10038 chance = GetPPMProcChance(WeaponSpeed, spellProcEvent->ppmRate); 10039 } 10040 10041 if(roll_chance_f(chance)) 10042 { 10043 uint32 cooldown = spellProcEvent->cooldown; 10044 10045 uint32 i_spell_eff = (*i)->GetEffIndex(); 10046 10047 int32 i_spell_param; 10048 switch(*aur) 10049 { 10050 case SPELL_AURA_PROC_TRIGGER_SPELL: 10051 i_spell_param = procFlag; 10052 break; 10053 case SPELL_AURA_DUMMY: 10054 case SPELL_AURA_PRAYER_OF_MENDING: 10055 case SPELL_AURA_MOD_HASTE: 10056 i_spell_param = i_spell_eff; 10057 break; 10058 case SPELL_AURA_OVERRIDE_CLASS_SCRIPTS: 10059 i_spell_param = (*i)->GetModifier()->m_miscvalue; 10060 break; 10061 default: 10062 i_spell_param = (*i)->GetModifier()->m_amount; 10063 break; 10064 } 10065 10066 procTriggered.push_back( ProcTriggeredData(spellProto,i_spell_param,*i, cooldown) ); 10067 } 9987 10068 } 9988 10069 … … 10017 10098 } 10018 10099 10019 /// this is aura triggering code call 10020 Aura* triggeredByAura = i->triggeredByAura; 10021 10022 /// save charges existence before processing to prevent crash at access to deleted triggered aura after 10023 /// used in speedup code check before check aura existance. 10024 bool triggeredByAuraWithCharges = triggeredByAura->m_procCharges > 0; 10025 10026 /// success in event proccesing 10027 /// used in speedup code check before check aura existance. 10100 // save charges existence before processing to prevent crash at access to deleted triggered aura after 10101 bool triggeredByAuraWithCharges = i->triggeredByAura->m_procCharges > 0; 10102 10028 10103 bool casted = false; 10029 10030 /// process triggered code10031 10104 switch(*aur) 10032 10105 { 10033 10106 case SPELL_AURA_PROC_TRIGGER_SPELL: 10034 10107 { 10035 sLog.outDebug("ProcDamageAndSpell: casting spell (triggered by %s proc aura of spell %u)", 10036 (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId()); 10037 casted = HandleProcTriggerSpell(pTarget, damage, triggeredByAura, procSpell, procFlag, attType, i->cooldown); 10108 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()); 10109 casted = HandleProcTriggerSpell(pTarget, damage, i->triggeredByAura, procSpell,i->spellParam,attType,i->cooldown); 10038 10110 break; 10039 10111 } 10040 10112 case SPELL_AURA_PROC_TRIGGER_DAMAGE: 10041 10113 { 10042 uint32 triggered_damage = triggeredByAura->GetModifier()->m_amount; 10043 sLog.outDebug("ProcDamageAndSpell: doing %u damage (triggered by %s aura of spell %u)", 10044 triggered_damage, (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId()); 10045 SpellNonMeleeDamageLog(pTarget, triggeredByAura->GetId(), triggered_damage, true, true); 10114 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()); 10115 uint32 damage = i->spellParam; 10116 SpellNonMeleeDamageLog(pTarget, i->spellInfo->Id, damage, true, true); 10046 10117 casted = true; 10047 10118 break; … … 10049 10120 case SPELL_AURA_DUMMY: 10050 10121 { 10051 uint32 effect = triggeredByAura->GetEffIndex(); 10052 sLog.outDebug("ProcDamageAndSpell: casting spell (triggered by %s dummy aura of spell %u)", 10053 (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId()); 10054 casted = HandleDummyAuraProc(pTarget, damage, triggeredByAura, procSpell, procFlag,i->cooldown); 10122 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()); 10123 casted = HandleDummyAuraProc(pTarget, i->spellInfo, i->spellParam, damage, i->triggeredByAura, procSpell, procFlag,i->cooldown); 10055 10124 break; 10056 10125 } 10057 10126 case SPELL_AURA_PRAYER_OF_MENDING: 10058 10127 { 10059 sLog.outDebug("ProcDamageAndSpell: casting mending (triggered by %s dummy aura of spell %u)", 10060 (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId()); 10061 10062 casted = HandleMeandingAuraProc(triggeredByAura); 10128 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()); 10129 10130 // aura can be deleted at casts 10131 int32 heal = i->triggeredByAura->GetModifier()->m_amount; 10132 uint64 caster_guid = i->triggeredByAura->GetCasterGUID(); 10133 10134 // jumps 10135 int32 jumps = i->triggeredByAura->m_procCharges-1; 10136 10137 // current aura expire 10138 i->triggeredByAura->m_procCharges = 1; // will removed at next charges decrease 10139 10140 // next target selection 10141 if(jumps > 0 && GetTypeId()==TYPEID_PLAYER && IS_PLAYER_GUID(caster_guid)) 10142 { 10143 Aura* aura = i->triggeredByAura; 10144 10145 SpellEntry const* spellProto = aura->GetSpellProto(); 10146 uint32 effIdx = aura->GetEffIndex(); 10147 10148 float radius; 10149 if (spellProto->EffectRadiusIndex[effIdx]) 10150 radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(spellProto->EffectRadiusIndex[effIdx])); 10151 else 10152 radius = GetSpellMaxRange(sSpellRangeStore.LookupEntry(spellProto->rangeIndex)); 10153 10154 if(Player* caster = ((Player*)aura->GetCaster())) 10155 { 10156 caster->ApplySpellMod(spellProto->Id, SPELLMOD_RADIUS, radius,NULL); 10157 10158 if(Player* target = ((Player*)this)->GetNextRandomRaidMember(radius)) 10159 { 10160 // aura will applied from caster, but spell casted from current aura holder 10161 SpellModifier *mod = new SpellModifier; 10162 mod->op = SPELLMOD_CHARGES; 10163 mod->value = jumps-5; // negative 10164 mod->type = SPELLMOD_FLAT; 10165 mod->spellId = spellProto->Id; 10166 mod->effectId = effIdx; 10167 mod->lastAffected = NULL; 10168 mod->mask = spellProto->SpellFamilyFlags; 10169 mod->charges = 0; 10170 10171 caster->AddSpellMod(mod, true); 10172 CastCustomSpell(target,spellProto->Id,&heal,NULL,NULL,true,NULL,aura,caster->GetGUID()); 10173 caster->AddSpellMod(mod, false); 10174 } 10175 } 10176 } 10177 10178 // heal 10179 CastCustomSpell(this,33110,&heal,NULL,NULL,true,NULL,NULL,caster_guid); 10180 casted = true; 10063 10181 break; 10064 10182 } 10065 10183 case SPELL_AURA_MOD_HASTE: 10066 10184 { 10067 sLog.outDebug("ProcDamageAndSpell: casting spell (triggered by %s haste aura of spell %u)", 10068 (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId()); 10069 casted = HandleHasteAuraProc(pTarget, damage, triggeredByAura, procSpell, procFlag,i->cooldown); 10185 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()); 10186 casted = HandleHasteAuraProc(pTarget, i->spellInfo, i->spellParam, damage, i->triggeredByAura, procSpell, procFlag,i->cooldown); 10070 10187 break; 10071 10188 } … … 10074 10191 // nothing do, just charges counter 10075 10192 // but count only in case appropriate school damage 10076 casted = triggeredByAura->GetModifier()->m_miscvalue & damageSchoolMask;10193 casted = i->triggeredByAura->GetModifier()->m_miscvalue & damageSchoolMask; 10077 10194 break; 10078 10195 } 10079 10196 case SPELL_AURA_OVERRIDE_CLASS_SCRIPTS: 10080 10197 { 10081 sLog.outDebug("ProcDamageAndSpell: casting spell (triggered by %s class script aura of spell %u)", 10082 (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId()); 10083 casted = HandleOverrideClassScriptAuraProc(pTarget, triggeredByAura, procSpell,i->cooldown); 10198 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()); 10199 casted = HandleOverrideClassScriptAuraProc(pTarget, i->spellParam, damage, i->triggeredByAura, procSpell,i->cooldown); 10084 10200 break; 10085 10201 } … … 10092 10208 } 10093 10209 10094 // /Update charge (aura can be removed by triggers)10210 // Update charge (aura can be removed by triggers) 10095 10211 if(casted && triggeredByAuraWithCharges) 10096 10212 { 10097 // / need re-found aura (can be dropped by triggers)10213 // need found aura (can be dropped by triggers) 10098 10214 AuraMap::const_iterator lower = GetAuras().lower_bound(i->triggeredByAura_SpellPair); 10099 10215 AuraMap::const_iterator upper = GetAuras().upper_bound(i->triggeredByAura_SpellPair); 10100 10216 for(AuraMap::const_iterator itr = lower; itr!= upper; ++itr) 10101 10217 { 10102 if(itr->second == triggeredByAura) // pointer still valid10218 if(itr->second == i->triggeredByAura) 10103 10219 { 10104 if( triggeredByAura->m_procCharges > 0)10105 triggeredByAura->m_procCharges -= 1;10106 10107 triggeredByAura->UpdateAuraCharges();10220 if(i->triggeredByAura->m_procCharges > 0) 10221 i->triggeredByAura->m_procCharges -= 1; 10222 10223 i->triggeredByAura->UpdateAuraCharges(); 10108 10224 break; 10109 10225 } … … 10112 10228 } 10113 10229 10114 // /Safely remove auras with zero charges10230 // Safely remove auras with zero charges 10115 10231 for(AuraList::const_iterator i = auras.begin(), next; i != auras.end(); i = next) 10116 10232 { … … 10225 10341 // send explicit stop packet 10226 10342 // rely on vmaps here because for example stormwind is in air 10227 //float z = MapManager::Instance().GetBaseMap(GetMapId())->GetHeight(GetPositionX(), GetPositionY(), GetPositionZ(), true);10343 float z = MapManager::Instance().GetBaseMap(GetMapId())->GetHeight(GetPositionX(), GetPositionY(), GetPositionZ(), true); 10228 10344 //if (fabs(GetPositionZ() - z) < 2.0f) 10229 10345 // Relocate(GetPositionX(), GetPositionY(), z); … … 10435 10551 } 10436 10552 10437 Unit* Unit::SelectNearbyTarget( float dist) const10553 Unit* Unit::SelectNearbyTarget() const 10438 10554 { 10439 10555 CellPair p(Trinity::ComputeCellPair(GetPositionX(), GetPositionY())); … … 10445 10561 10446 10562 { 10447 Trinity::AnyUnfriendlyUnitInObjectRangeCheck u_check(this, this, dist);10563 Trinity::AnyUnfriendlyUnitInObjectRangeCheck u_check(this, this, ATTACK_DISTANCE); 10448 10564 Trinity::UnitListSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck> searcher(targets, u_check); 10449 10565 … … 10709 10825 } 10710 10826 10711 pet->SetUInt64Value(UNIT_FIELD_SUMMONEDBY, GetGUID());10712 pet->SetUInt64Value(UNIT_FIELD_CREATEDBY, GetGUID());10713 pet->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, getFaction());10827 pet->SetUInt64Value(UNIT_FIELD_SUMMONEDBY, this->GetGUID()); 10828 pet->SetUInt64Value(UNIT_FIELD_CREATEDBY, this->GetGUID()); 10829 pet->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,this->getFaction()); 10714 10830 pet->SetUInt32Value(UNIT_CREATED_BY_SPELL, spell_id); 10715 10831 … … 10729 10845 return pet; 10730 10846 } 10731 10732 bool Unit::IsTriggeredAtSpellProcEvent(SpellEntry const* spellProto, SpellEntry const* procSpell, uint32 procFlag, WeaponAttackType attType, bool isVictim, uint32& cooldown )10733 {10734 SpellProcEventEntry const * spellProcEvent = spellmgr.GetSpellProcEvent(spellProto->Id);10735 10736 if(!spellProcEvent)10737 {10738 // used to prevent spam in log about same non-handled spells10739 static std::set<uint32> nonHandledSpellProcSet;10740 10741 if(spellProto->procFlags != 0 && nonHandledSpellProcSet.find(spellProto->Id)==nonHandledSpellProcSet.end())10742 {10743 sLog.outError("ProcDamageAndSpell: spell %u (%s aura source) not have record in `spell_proc_event`)",spellProto->Id,(isVictim?"a victim's":"an attacker's"));10744 nonHandledSpellProcSet.insert(spellProto->Id);10745 }10746 10747 // spell.dbc use totally different flags, that only can create problems if used.10748 return false;10749 }10750 10751 // Check spellProcEvent data requirements10752 if(!SpellMgr::IsSpellProcEventCanTriggeredBy(spellProcEvent, procSpell,procFlag))10753 return false;10754 10755 // Check if current equipment allows aura to proc10756 if(!isVictim && GetTypeId() == TYPEID_PLAYER )10757 {10758 if(spellProto->EquippedItemClass == ITEM_CLASS_WEAPON)10759 {10760 Item *item = ((Player*)this)->GetWeaponForAttack(attType,true);10761 10762 if(!item || !((1<<item->GetProto()->SubClass) & spellProto->EquippedItemSubClassMask))10763 return false;10764 }10765 else if(spellProto->EquippedItemClass == ITEM_CLASS_ARMOR)10766 {10767 // Check if player is wearing shield10768 Item *item = ((Player*)this)->GetShield(true);10769 if(!item || !((1<<item->GetProto()->SubClass) & spellProto->EquippedItemSubClassMask))10770 return false;10771 }10772 }10773 10774 float chance = (float)spellProto->procChance;10775 10776 if(Player* modOwner = GetSpellModOwner())10777 modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_CHANCE_OF_SUCCESS,chance);10778 10779 if(!isVictim && spellProcEvent && spellProcEvent->ppmRate != 0)10780 {10781 uint32 WeaponSpeed = GetAttackTime(attType);10782 chance = GetPPMProcChance(WeaponSpeed, spellProcEvent->ppmRate);10783 }10784 10785 cooldown = spellProcEvent ? spellProcEvent->cooldown : 0;10786 return roll_chance_f(chance);10787 }10788 10789 bool Unit::HandleMeandingAuraProc( Aura* triggeredByAura )10790 {10791 // aura can be deleted at casts10792 SpellEntry const* spellProto = triggeredByAura->GetSpellProto();10793 uint32 effIdx = triggeredByAura->GetEffIndex();10794 int32 heal = triggeredByAura->GetModifier()->m_amount;10795 uint64 caster_guid = triggeredByAura->GetCasterGUID();10796 10797 // jumps10798 int32 jumps = triggeredByAura->m_procCharges-1;10799 10800 // current aura expire10801 triggeredByAura->m_procCharges = 1; // will removed at next charges decrease10802 10803 // next target selection10804 if(jumps > 0 && GetTypeId()==TYPEID_PLAYER && IS_PLAYER_GUID(caster_guid))10805 {10806 float radius;10807 if (spellProto->EffectRadiusIndex[effIdx])10808 radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(spellProto->EffectRadiusIndex[effIdx]));10809 else10810 radius = GetSpellMaxRange(sSpellRangeStore.LookupEntry(spellProto->rangeIndex));10811 10812 if(Player* caster = ((Player*)triggeredByAura->GetCaster()))10813 {10814 caster->ApplySpellMod(spellProto->Id, SPELLMOD_RADIUS, radius,NULL);10815 10816 if(Player* target = ((Player*)this)->GetNextRandomRaidMember(radius))10817 {10818 // aura will applied from caster, but spell casted from current aura holder10819 SpellModifier *mod = new SpellModifier;10820 mod->op = SPELLMOD_CHARGES;10821 mod->value = jumps-5; // negative10822 mod->type = SPELLMOD_FLAT;10823 mod->spellId = spellProto->Id;10824 mod->effectId = effIdx;10825 mod->lastAffected = NULL;10826 mod->mask = spellProto->SpellFamilyFlags;10827 mod->charges = 0;10828 10829 caster->AddSpellMod(mod, true);10830 CastCustomSpell(target,spellProto->Id,&heal,NULL,NULL,true,NULL,triggeredByAura,caster->GetGUID());10831 caster->AddSpellMod(mod, false);10832 }10833 }10834 }10835 10836 // heal10837 CastCustomSpell(this,33110,&heal,NULL,NULL,true,NULL,NULL,caster_guid);10838 return true;10839 }10840 10841 void Unit::RemoveAurasAtChanneledTarget(SpellEntry const* spellInfo)10842 {10843 uint64 target_guid = GetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT);10844 10845 if(!IS_UNIT_GUID(target_guid))10846 return;10847 10848 Unit* target = ObjectAccessor::GetUnit(*this, target_guid);10849 if(!target)10850 return;10851 10852 for (AuraMap::iterator iter = target->GetAuras().begin(); iter != target->GetAuras().end(); )10853 {10854 if (iter->second->GetId() == spellInfo->Id && iter->second->GetCasterGUID()==GetGUID())10855 target->RemoveAura(iter);10856 else10857 ++iter;10858 }10859 }