Changeset 279 for trunk/src/game/Unit.cpp
- Timestamp:
- 11/22/08 00:36:22 (17 years ago)
- Files:
-
- 1 modified
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/game/Unit.cpp
r277 r279 1150 1150 if ( GetSpellSchoolMask(spellInfo) & SPELL_SCHOOL_MASK_NORMAL ) 1151 1151 { 1152 uint32 modDamage=*damage;1153 1154 1152 // apply spellmod to Done damage 1155 1153 if(Player* modOwner = GetSpellModOwner()) … … 1436 1434 if(!this || !pVictim) 1437 1435 return 0; 1438 if(! this->isAlive() || !pVictim->isAlive())1436 if(!isAlive() || !pVictim->isAlive()) 1439 1437 return 0; 1440 1438 … … 3799 3797 { 3800 3798 m_ccAuras.push_back(Aur); 3801 RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_CC);3802 3799 } 3803 3800 } … … 3915 3912 if(!is_triggered_by_spell) 3916 3913 { 3917 SpellSpecific i_spellId_spec = GetSpellSpecific(i_spellId); 3918 3919 bool is_sspc = IsSingleFromSpellSpecificPerCaster(spellId_spec,i_spellId_spec); 3920 3921 if( is_sspc && Aur->GetCasterGUID() == (*i).second->GetCasterGUID() ) 3922 { 3923 // cannot remove higher rank 3924 if (spellmgr.IsRankSpellDueToSpell(spellProto, i_spellId)) 3925 if(CompareAuraRanks(spellId, effIndex, i_spellId, i_effIndex) < 0) 3926 return false; 3914 bool sameCaster = Aur->GetCasterGUID() == (*i).second->GetCasterGUID(); 3915 if( spellmgr.IsNoStackSpellDueToSpell(spellId, i_spellId, sameCaster) ) 3916 { 3917 //some spells should be not removed by lower rank of them 3918 // what is this spell? 3919 if (!sameCaster 3920 &&(spellProto->Effect[effIndex]==SPELL_EFFECT_APPLY_AREA_AURA_PARTY) 3921 &&(spellProto->DurationIndex==21) 3922 &&(spellmgr.IsRankSpellDueToSpell(spellProto, i_spellId)) 3923 &&(CompareAuraRanks(spellId, effIndex, i_spellId, i_effIndex) < 0)) 3924 return false; 3927 3925 3928 3926 // Its a parent aura (create this aura in ApplyModifier) … … 3938 3936 else 3939 3937 next = m_Auras.begin(); 3940 }3941 else if( !is_sspc && spellmgr.IsNoStackSpellDueToSpell(spellId, i_spellId) )3942 {3943 // Its a parent aura (create this aura in ApplyModifier)3944 if ((*i).second->IsInUse())3945 {3946 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());3947 continue;3948 }3949 RemoveAurasDueToSpell(i_spellId);3950 3951 if( m_Auras.empty() )3952 break;3953 else3954 next = m_Auras.begin();3955 }3956 // Potions stack aura by aura (elixirs/flask already checked)3957 else if( spellProto->SpellFamilyName == SPELLFAMILY_POTION && i_spellProto->SpellFamilyName == SPELLFAMILY_POTION )3958 {3959 if (IsNoStackAuraDueToAura(spellId, effIndex, i_spellId, i_effIndex))3960 {3961 if(CompareAuraRanks(spellId, effIndex, i_spellId, i_effIndex) < 0)3962 return false; // cannot remove higher rank3963 3964 // Its a parent aura (create this aura in ApplyModifier)3965 if ((*i).second->IsInUse())3966 {3967 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());3968 continue;3969 }3970 RemoveAura(i);3971 next = i;3972 }3973 3938 } 3974 3939 } … … 4145 4110 void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode) 4146 4111 { 4147 if (IsSingleTargetSpell((*i).second->GetSpellProto())) 4148 { 4149 if(Unit* caster = (*i).second->GetCaster()) 4112 Aura* Aur = i->second; 4113 SpellEntry const* AurSpellInfo = Aur->GetSpellProto(); 4114 4115 Unit* caster = NULL; 4116 if (IsSingleTargetSpell(AurSpellInfo)) 4117 { 4118 caster = Aur->GetCaster(); 4119 if(caster) 4150 4120 { 4151 4121 AuraList& scAuras = caster->GetSingleCastAuras(); 4152 scAuras.remove( (*i).second);4122 scAuras.remove(Aur); 4153 4123 } 4154 4124 else … … 4159 4129 } 4160 4130 4161 if ((*i).second->GetModifier()->m_auraname < TOTAL_AURAS) 4131 // remove from list before mods removing (prevent cyclic calls, mods added before including to aura list - use reverse order) 4132 if (Aur->GetModifier()->m_auraname < TOTAL_AURAS) 4162 4133 { 4163 4134 m_modAuras[(*i).second->GetModifier()->m_auraname].remove((*i).second); … … 4171 4142 } 4172 4143 4173 // remove from list before mods removing (prevent cyclic calls, mods added before including to aura list - use reverse order)4174 Aura* Aur = i->second;4175 4144 // Set remove mode 4176 4145 Aur->SetRemoveMode(mode); … … 4180 4149 ++m_removedAuras; // internal count used by unit update 4181 4150 4182 // Statu sunsummoned at aura remove4151 // Statue unsummoned at aura remove 4183 4152 Totem* statue = NULL; 4184 if(IsChanneledSpell(Aur->GetSpellProto())) 4185 if(Unit* caster = Aur->GetCaster()) 4153 bool caster_channeled = false; 4154 if(IsChanneledSpell(AurSpellInfo)) 4155 { 4156 if(!caster) // can be already located for IsSingleTargetSpell case 4157 caster = Aur->GetCaster(); 4158 4159 if(caster) 4160 { 4186 4161 if(caster->GetTypeId()==TYPEID_UNIT && ((Creature*)caster)->isTotem() && ((Totem*)caster)->GetTotemType()==TOTEM_STATUE) 4187 4162 statue = ((Totem*)caster); 4188 4163 else 4164 caster_channeled = caster==this; 4165 } 4166 } 4189 4167 4190 4168 if(const std::vector<int32> *spell_triggered = spellmgr.GetSpellLinked(-(int32)Aur->GetSpellProto()->Id)) … … 4203 4181 Aur->_RemoveAura(); 4204 4182 delete Aur; 4183 4184 if(caster_channeled) 4185 RemoveAurasAtChanneledTarget (AurSpellInfo); 4205 4186 4206 4187 if(statue) … … 4629 4610 } 4630 4611 4631 bool Unit::HandleHasteAuraProc(Unit *pVictim, SpellEntry const *hasteSpell, uint32 /*effIndex*/, uint32 damage, Aura* triggeredByAura, SpellEntry const * procSpell, uint32 /*procFlag*/, uint32 cooldown) 4632 { 4612 bool Unit::HandleHasteAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const * /*procSpell*/, uint32 /*procFlag*/, uint32 cooldown) 4613 { 4614 SpellEntry const *hasteSpell = triggeredByAura->GetSpellProto(); 4615 4633 4616 Item* castItem = triggeredByAura->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER 4634 4617 ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL; … … 4690 4673 } 4691 4674 4692 bool Unit::HandleDummyAuraProc(Unit *pVictim, SpellEntry const *dummySpell, uint32 effIndex, uint32 damage, Aura* triggeredByAura, SpellEntry const * procSpell, uint32 procFlag, uint32 cooldown) 4693 { 4675 bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const * procSpell, uint32 procFlag, uint32 cooldown) 4676 { 4677 SpellEntry const *dummySpell = triggeredByAura->GetSpellProto (); 4678 uint32 effIndex = triggeredByAura->GetEffIndex (); 4679 4694 4680 Item* castItem = triggeredByAura->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER 4695 4681 ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL; … … 6279 6265 return false; 6280 6266 6281 uint32 spell = 0;6282 6267 switch(triggeredByAura->GetSpellProto()->Id) 6283 6268 { … … 6309 6294 6310 6295 // overwrite non existing triggered spell call in spell.dbc 6311 uint32 spell = 0;6312 6296 switch(triggeredByAura->GetSpellProto()->Id) 6313 6297 { … … 6509 6493 } 6510 6494 6511 bool Unit::HandleOverrideClassScriptAuraProc(Unit *pVictim, int32 scriptId, uint32 damage, Aura *triggeredByAura, SpellEntry const *procSpell, uint32 cooldown) 6512 { 6495 bool Unit::HandleOverrideClassScriptAuraProc(Unit *pVictim, Aura *triggeredByAura, SpellEntry const *procSpell, uint32 cooldown) 6496 { 6497 int32 scriptId = triggeredByAura->GetModifier()->m_miscvalue; 6498 6513 6499 if(!pVictim || !pVictim->isAlive()) 6514 6500 return false; … … 7276 7262 } 7277 7263 7278 void Unit::SendEnergizeSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage, Powers powertype , bool critical)7264 void Unit::SendEnergizeSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage, Powers powertype) 7279 7265 { 7280 7266 WorldPacket data(SMSG_SPELLENERGIZELOG, (8+8+4+4+4+1)); … … 7376 7362 AuraList const& mModDamagePercentTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN); 7377 7363 for(AuraList::const_iterator i = mModDamagePercentTaken.begin(); i != mModDamagePercentTaken.end(); ++i) 7378 if( (*i)->GetModifier()->m_miscvalue & GetSpellSchoolMask(spellProto))7364 if( (*i)->GetModifier()->m_miscvalue & GetSpellSchoolMask(spellProto) ) 7379 7365 TakenTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f; 7380 7366 … … 8224 8210 8225 8211 // ..done (for creature type by mask) in taken 8226 AuraList const& mDamageDoneCreature = this->GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE_CREATURE);8212 AuraList const& mDamageDoneCreature = GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE_CREATURE); 8227 8213 for(AuraList::const_iterator i = mDamageDoneCreature.begin();i != mDamageDoneCreature.end(); ++i) 8228 8214 if(creatureTypeMask & uint32((*i)->GetModifier()->m_miscvalue)) … … 8292 8278 // SPELL_AURA_MOD_OFFHAND_DAMAGE_PCT included in weapon damage 8293 8279 8294 AuraList const& mDamageDoneVersus = this->GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE_VERSUS);8280 AuraList const& mDamageDoneVersus = GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE_VERSUS); 8295 8281 for(AuraList::const_iterator i = mDamageDoneVersus.begin();i != mDamageDoneVersus.end(); ++i) 8296 8282 if(creatureTypeMask & uint32((*i)->GetModifier()->m_miscvalue)) … … 8522 8508 target->SetStandState(PLAYER_STATE_NONE); 8523 8509 8524 if(!target->isInCombat() && target->GetTypeId() != TYPEID_PLAYER && ((Creature*)target)->AI()) 8510 if(!target->isInCombat() && target->GetTypeId() != TYPEID_PLAYER 8511 && ((Creature*)target)->isAggressive() && ((Creature*)target)->AI()) 8525 8512 ((Creature*)target)->AI()->AttackStart(this); 8526 8513 … … 8571 8558 { 8572 8559 assert(target); 8560 8561 if(!IsHostileTo(target)) 8562 return false; 8573 8563 8574 8564 if(!target->isAttackableByAOE() || target->hasUnitState(UNIT_STAT_DIED)) … … 8747 8737 if(IsInWorld()) 8748 8738 { 8749 Map *m = MapManager::Instance().GetMap(GetMapId(), this);8739 Map *m = GetMap(); 8750 8740 8751 8741 if(GetTypeId()==TYPEID_PLAYER) … … 9156 9146 } 9157 9147 9148 // search nearby enemy before enter evade mode 9149 if(Unit *target = ((Creature*)this)->SelectNearestTarget()) 9150 { 9151 ((Creature*)this)->AI()->AttackStart(target); 9152 return true; 9153 } 9154 9158 9155 // enter in evade mode in other case 9159 9156 ((Creature*)this)->AI()->EnterEvadeMode(); … … 9809 9806 } 9810 9807 9811 9812 9813 9808 CharmInfo* Unit::InitCharmInfo(Unit *charm) 9814 9809 { … … 9985 9980 struct ProcTriggeredData 9986 9981 { 9987 ProcTriggeredData( SpellEntry const * _spellInfo, uint32 _spellParam,Aura* _triggeredByAura, uint32 _cooldown)9988 : spellInfo(_spellInfo), spellParam(_spellParam),triggeredByAura(_triggeredByAura),9982 ProcTriggeredData(Aura* _triggeredByAura, uint32 _cooldown) 9983 : triggeredByAura(_triggeredByAura), 9989 9984 triggeredByAura_SpellPair(Unit::spellEffectPair(triggeredByAura->GetId(),triggeredByAura->GetEffIndex())), 9990 9985 cooldown(_cooldown) 9991 {} 9992 9993 SpellEntry const * spellInfo; 9994 uint32 spellParam; 9995 Aura* triggeredByAura; 9996 Unit::spellEffectPair triggeredByAura_SpellPair; 9997 uint32 cooldown; 9986 {} 9987 9988 Aura* triggeredByAura; // triggred aura, can be invalidate at triggered aura proccessing 9989 Unit::spellEffectPair triggeredByAura_SpellPair; // spell pair, used for re-find aura (by pointer comparison in range) 9990 uint32 cooldown; // possible hidden cooldown 9998 9991 }; 9999 9992 … … 10012 10005 next = i; ++next; 10013 10006 10014 SpellEntry const *spellProto = (*i)->GetSpellProto(); 10015 if(!spellProto) 10007 Aura* i_aura = *i; 10008 10009 uint32 cooldown; // returned at next line 10010 if(!IsTriggeredAtSpellProcEvent(i_aura->GetSpellProto(), procSpell, procFlag,attType,isVictim,cooldown)) 10016 10011 continue; 10017 10012 10018 SpellProcEventEntry const *spellProcEvent = spellmgr.GetSpellProcEvent(spellProto->Id); 10019 if(!spellProcEvent) 10020 { 10021 // used to prevent spam in log about same non-handled spells 10022 static std::set<uint32> nonHandledSpellProcSet; 10023 10024 if(spellProto->procFlags != 0 && nonHandledSpellProcSet.find(spellProto->Id)==nonHandledSpellProcSet.end()) 10025 { 10026 sLog.outError("ProcDamageAndSpell: spell %u (%s aura source) not have record in `spell_proc_event`)",spellProto->Id,(isVictim?"a victim's":"an attacker's")); 10027 nonHandledSpellProcSet.insert(spellProto->Id); 10028 } 10029 10030 // spell.dbc use totally different flags, that only can create problems if used. 10031 continue; 10032 } 10033 10034 // Check spellProcEvent data requirements 10035 if(!SpellMgr::IsSpellProcEventCanTriggeredBy(spellProcEvent, procSpell,procFlag)) 10036 continue; 10037 10038 // Check if current equipment allows aura to proc 10039 if(!isVictim && GetTypeId() == TYPEID_PLAYER ) 10040 { 10041 if(spellProto->EquippedItemClass == ITEM_CLASS_WEAPON) 10042 { 10043 Item *item = ((Player*)this)->GetWeaponForAttack(attType,true); 10044 10045 if(!item || !((1<<item->GetProto()->SubClass) & spellProto->EquippedItemSubClassMask)) 10046 continue; 10047 } 10048 else if(spellProto->EquippedItemClass == ITEM_CLASS_ARMOR) 10049 { 10050 // Check if player is wearing shield 10051 Item *item = ((Player*)this)->GetShield(true); 10052 if(!item || !((1<<item->GetProto()->SubClass) & spellProto->EquippedItemSubClassMask)) 10053 continue; 10054 } 10055 } 10056 10057 float chance = (float)spellProto->procChance; 10058 10059 if(Player* modOwner = GetSpellModOwner()) 10060 modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_CHANCE_OF_SUCCESS,chance); 10061 10062 if(!isVictim && spellProcEvent->ppmRate != 0) 10063 { 10064 uint32 WeaponSpeed = GetAttackTime(attType); 10065 chance = GetPPMProcChance(WeaponSpeed, spellProcEvent->ppmRate); 10066 } 10067 10068 if(roll_chance_f(chance)) 10069 { 10070 uint32 cooldown = spellProcEvent->cooldown; 10071 10072 uint32 i_spell_eff = (*i)->GetEffIndex(); 10073 10074 int32 i_spell_param; 10075 switch(*aur) 10076 { 10077 case SPELL_AURA_PROC_TRIGGER_SPELL: 10078 i_spell_param = procFlag; 10079 break; 10080 case SPELL_AURA_DUMMY: 10081 case SPELL_AURA_PRAYER_OF_MENDING: 10082 case SPELL_AURA_MOD_HASTE: 10083 i_spell_param = i_spell_eff; 10084 break; 10085 case SPELL_AURA_OVERRIDE_CLASS_SCRIPTS: 10086 i_spell_param = (*i)->GetModifier()->m_miscvalue; 10087 break; 10088 default: 10089 i_spell_param = (*i)->GetModifier()->m_amount; 10090 break; 10091 } 10092 10093 procTriggered.push_back( ProcTriggeredData(spellProto,i_spell_param,*i, cooldown) ); 10094 } 10013 procTriggered.push_back( ProcTriggeredData(i_aura, cooldown) ); 10095 10014 } 10096 10015 … … 10125 10044 } 10126 10045 10127 // save charges existence before processing to prevent crash at access to deleted triggered aura after 10128 bool triggeredByAuraWithCharges = i->triggeredByAura->m_procCharges > 0; 10129 10046 /// this is aura triggering code call 10047 Aura* triggeredByAura = i->triggeredByAura; 10048 10049 /// save charges existence before processing to prevent crash at access to deleted triggered aura after 10050 /// used in speedup code check before check aura existance. 10051 bool triggeredByAuraWithCharges = triggeredByAura->m_procCharges > 0; 10052 10053 /// success in event proccesing 10054 /// used in speedup code check before check aura existance. 10130 10055 bool casted = false; 10056 10057 /// process triggered code 10131 10058 switch(*aur) 10132 10059 { 10133 10060 case SPELL_AURA_PROC_TRIGGER_SPELL: 10134 10061 { 10135 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()); 10136 casted = HandleProcTriggerSpell(pTarget, damage, i->triggeredByAura, procSpell,i->spellParam,attType,i->cooldown); 10062 sLog.outDebug("ProcDamageAndSpell: casting spell (triggered by %s proc aura of spell %u)", 10063 (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId()); 10064 casted = HandleProcTriggerSpell(pTarget, damage, triggeredByAura, procSpell, procFlag, attType, i->cooldown); 10137 10065 break; 10138 10066 } 10139 10067 case SPELL_AURA_PROC_TRIGGER_DAMAGE: 10140 10068 { 10141 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()); 10142 uint32 damage = i->spellParam; 10143 SpellNonMeleeDamageLog(pTarget, i->spellInfo->Id, damage, true, true); 10069 uint32 triggered_damage = triggeredByAura->GetModifier()->m_amount; 10070 sLog.outDebug("ProcDamageAndSpell: doing %u damage (triggered by %s aura of spell %u)", 10071 triggered_damage, (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId()); 10072 SpellNonMeleeDamageLog(pTarget, triggeredByAura->GetId(), triggered_damage, true, true); 10144 10073 casted = true; 10145 10074 break; … … 10147 10076 case SPELL_AURA_DUMMY: 10148 10077 { 10149 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()); 10150 casted = HandleDummyAuraProc(pTarget, i->spellInfo, i->spellParam, damage, i->triggeredByAura, procSpell, procFlag,i->cooldown); 10078 uint32 effect = triggeredByAura->GetEffIndex(); 10079 sLog.outDebug("ProcDamageAndSpell: casting spell (triggered by %s dummy aura of spell %u)", 10080 (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId()); 10081 casted = HandleDummyAuraProc(pTarget, damage, triggeredByAura, procSpell, procFlag,i->cooldown); 10151 10082 break; 10152 10083 } 10153 10084 case SPELL_AURA_PRAYER_OF_MENDING: 10154 10085 { 10155 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()); 10156 10157 // aura can be deleted at casts 10158 int32 heal = i->triggeredByAura->GetModifier()->m_amount; 10159 uint64 caster_guid = i->triggeredByAura->GetCasterGUID(); 10160 10161 // jumps 10162 int32 jumps = i->triggeredByAura->m_procCharges-1; 10163 10164 // current aura expire 10165 i->triggeredByAura->m_procCharges = 1; // will removed at next charges decrease 10166 10167 // next target selection 10168 if(jumps > 0 && GetTypeId()==TYPEID_PLAYER && IS_PLAYER_GUID(caster_guid)) 10169 { 10170 Aura* aura = i->triggeredByAura; 10171 10172 SpellEntry const* spellProto = aura->GetSpellProto(); 10173 uint32 effIdx = aura->GetEffIndex(); 10174 10175 float radius; 10176 if (spellProto->EffectRadiusIndex[effIdx]) 10177 radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(spellProto->EffectRadiusIndex[effIdx])); 10178 else 10179 radius = GetSpellMaxRange(sSpellRangeStore.LookupEntry(spellProto->rangeIndex)); 10180 10181 if(Player* caster = ((Player*)aura->GetCaster())) 10182 { 10183 caster->ApplySpellMod(spellProto->Id, SPELLMOD_RADIUS, radius,NULL); 10184 10185 if(Player* target = ((Player*)this)->GetNextRandomRaidMember(radius)) 10186 { 10187 // aura will applied from caster, but spell casted from current aura holder 10188 SpellModifier *mod = new SpellModifier; 10189 mod->op = SPELLMOD_CHARGES; 10190 mod->value = jumps-5; // negative 10191 mod->type = SPELLMOD_FLAT; 10192 mod->spellId = spellProto->Id; 10193 mod->effectId = effIdx; 10194 mod->lastAffected = NULL; 10195 mod->mask = spellProto->SpellFamilyFlags; 10196 mod->charges = 0; 10197 10198 caster->AddSpellMod(mod, true); 10199 CastCustomSpell(target,spellProto->Id,&heal,NULL,NULL,true,NULL,aura,caster->GetGUID()); 10200 caster->AddSpellMod(mod, false); 10201 } 10202 } 10203 } 10204 10205 // heal 10206 CastCustomSpell(this,33110,&heal,NULL,NULL,true,NULL,NULL,caster_guid); 10207 casted = true; 10086 sLog.outDebug("ProcDamageAndSpell: casting mending (triggered by %s dummy aura of spell %u)", 10087 (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId()); 10088 10089 casted = HandleMeandingAuraProc(triggeredByAura); 10208 10090 break; 10209 10091 } 10210 10092 case SPELL_AURA_MOD_HASTE: 10211 10093 { 10212 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()); 10213 casted = HandleHasteAuraProc(pTarget, i->spellInfo, i->spellParam, damage, i->triggeredByAura, procSpell, procFlag,i->cooldown); 10094 sLog.outDebug("ProcDamageAndSpell: casting spell (triggered by %s haste aura of spell %u)", 10095 (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId()); 10096 casted = HandleHasteAuraProc(pTarget, damage, triggeredByAura, procSpell, procFlag,i->cooldown); 10214 10097 break; 10215 10098 } … … 10218 10101 // nothing do, just charges counter 10219 10102 // but count only in case appropriate school damage 10220 casted = i->triggeredByAura->GetModifier()->m_miscvalue & damageSchoolMask;10103 casted = triggeredByAura->GetModifier()->m_miscvalue & damageSchoolMask; 10221 10104 break; 10222 10105 } 10223 10106 case SPELL_AURA_OVERRIDE_CLASS_SCRIPTS: 10224 10107 { 10225 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()); 10226 casted = HandleOverrideClassScriptAuraProc(pTarget, i->spellParam, damage, i->triggeredByAura, procSpell,i->cooldown); 10108 sLog.outDebug("ProcDamageAndSpell: casting spell (triggered by %s class script aura of spell %u)", 10109 (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId()); 10110 casted = HandleOverrideClassScriptAuraProc(pTarget, triggeredByAura, procSpell,i->cooldown); 10227 10111 break; 10228 10112 } … … 10235 10119 } 10236 10120 10237 // Update charge (aura can be removed by triggers)10121 /// Update charge (aura can be removed by triggers) 10238 10122 if(casted && triggeredByAuraWithCharges) 10239 10123 { 10240 // needfound aura (can be dropped by triggers)10124 /// need re-found aura (can be dropped by triggers) 10241 10125 AuraMap::const_iterator lower = GetAuras().lower_bound(i->triggeredByAura_SpellPair); 10242 10126 AuraMap::const_iterator upper = GetAuras().upper_bound(i->triggeredByAura_SpellPair); 10243 10127 for(AuraMap::const_iterator itr = lower; itr!= upper; ++itr) 10244 10128 { 10245 if(itr->second == i->triggeredByAura)10129 if(itr->second == triggeredByAura) // pointer still valid 10246 10130 { 10247 if( i->triggeredByAura->m_procCharges > 0)10248 i->triggeredByAura->m_procCharges -= 1;10249 10250 i->triggeredByAura->UpdateAuraCharges();10131 if(triggeredByAura->m_procCharges > 0) 10132 triggeredByAura->m_procCharges -= 1; 10133 10134 triggeredByAura->UpdateAuraCharges(); 10251 10135 break; 10252 10136 } … … 10255 10139 } 10256 10140 10257 // Safely remove auras with zero charges10141 /// Safely remove auras with zero charges 10258 10142 for(AuraList::const_iterator i = auras.begin(), next; i != auras.end(); i = next) 10259 10143 { … … 10368 10252 // send explicit stop packet 10369 10253 // rely on vmaps here because for example stormwind is in air 10370 float z = MapManager::Instance().GetBaseMap(GetMapId())->GetHeight(GetPositionX(), GetPositionY(), GetPositionZ(), true);10254 //float z = MapManager::Instance().GetBaseMap(GetMapId())->GetHeight(GetPositionX(), GetPositionY(), GetPositionZ(), true); 10371 10255 //if (fabs(GetPositionZ() - z) < 2.0f) 10372 10256 // Relocate(GetPositionX(), GetPositionY(), z); … … 10578 10462 } 10579 10463 10580 Unit* Unit::SelectNearbyTarget( ) const10464 Unit* Unit::SelectNearbyTarget(float dist) const 10581 10465 { 10582 10466 CellPair p(Trinity::ComputeCellPair(GetPositionX(), GetPositionY())); … … 10588 10472 10589 10473 { 10590 Trinity::AnyUnfriendlyUnitInObjectRangeCheck u_check(this, this, ATTACK_DISTANCE);10474 Trinity::AnyUnfriendlyUnitInObjectRangeCheck u_check(this, this, dist); 10591 10475 Trinity::UnitListSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck> searcher(targets, u_check); 10592 10476 … … 10852 10736 } 10853 10737 10854 pet->SetUInt64Value(UNIT_FIELD_SUMMONEDBY, this->GetGUID());10855 pet->SetUInt64Value(UNIT_FIELD_CREATEDBY, this->GetGUID());10856 pet->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, this->getFaction());10738 pet->SetUInt64Value(UNIT_FIELD_SUMMONEDBY, GetGUID()); 10739 pet->SetUInt64Value(UNIT_FIELD_CREATEDBY, GetGUID()); 10740 pet->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,getFaction()); 10857 10741 pet->SetUInt32Value(UNIT_CREATED_BY_SPELL, spell_id); 10858 10742 … … 10872 10756 return pet; 10873 10757 } 10758 10759 bool Unit::IsTriggeredAtSpellProcEvent(SpellEntry const* spellProto, SpellEntry const* procSpell, uint32 procFlag, WeaponAttackType attType, bool isVictim, uint32& cooldown ) 10760 { 10761 SpellProcEventEntry const * spellProcEvent = spellmgr.GetSpellProcEvent(spellProto->Id); 10762 10763 if(!spellProcEvent) 10764 { 10765 // used to prevent spam in log about same non-handled spells 10766 static std::set<uint32> nonHandledSpellProcSet; 10767 10768 if(spellProto->procFlags != 0 && nonHandledSpellProcSet.find(spellProto->Id)==nonHandledSpellProcSet.end()) 10769 { 10770 sLog.outError("ProcDamageAndSpell: spell %u (%s aura source) not have record in `spell_proc_event`)",spellProto->Id,(isVictim?"a victim's":"an attacker's")); 10771 nonHandledSpellProcSet.insert(spellProto->Id); 10772 } 10773 10774 // spell.dbc use totally different flags, that only can create problems if used. 10775 return false; 10776 } 10777 10778 // Check spellProcEvent data requirements 10779 if(!SpellMgr::IsSpellProcEventCanTriggeredBy(spellProcEvent, procSpell,procFlag)) 10780 return false; 10781 10782 // Check if current equipment allows aura to proc 10783 if(!isVictim && GetTypeId() == TYPEID_PLAYER ) 10784 { 10785 if(spellProto->EquippedItemClass == ITEM_CLASS_WEAPON) 10786 { 10787 Item *item = ((Player*)this)->GetWeaponForAttack(attType,true); 10788 10789 if(!item || !((1<<item->GetProto()->SubClass) & spellProto->EquippedItemSubClassMask)) 10790 return false; 10791 } 10792 else if(spellProto->EquippedItemClass == ITEM_CLASS_ARMOR) 10793 { 10794 // Check if player is wearing shield 10795 Item *item = ((Player*)this)->GetShield(true); 10796 if(!item || !((1<<item->GetProto()->SubClass) & spellProto->EquippedItemSubClassMask)) 10797 return false; 10798 } 10799 } 10800 10801 float chance = (float)spellProto->procChance; 10802 10803 if(Player* modOwner = GetSpellModOwner()) 10804 modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_CHANCE_OF_SUCCESS,chance); 10805 10806 if(!isVictim && spellProcEvent && spellProcEvent->ppmRate != 0) 10807 { 10808 uint32 WeaponSpeed = GetAttackTime(attType); 10809 chance = GetPPMProcChance(WeaponSpeed, spellProcEvent->ppmRate); 10810 } 10811 10812 cooldown = spellProcEvent ? spellProcEvent->cooldown : 0; 10813 return roll_chance_f(chance); 10814 } 10815 10816 bool Unit::HandleMeandingAuraProc( Aura* triggeredByAura ) 10817 { 10818 // aura can be deleted at casts 10819 SpellEntry const* spellProto = triggeredByAura->GetSpellProto(); 10820 uint32 effIdx = triggeredByAura->GetEffIndex(); 10821 int32 heal = triggeredByAura->GetModifier()->m_amount; 10822 uint64 caster_guid = triggeredByAura->GetCasterGUID(); 10823 10824 // jumps 10825 int32 jumps = triggeredByAura->m_procCharges-1; 10826 10827 // current aura expire 10828 triggeredByAura->m_procCharges = 1; // will removed at next charges decrease 10829 10830 // next target selection 10831 if(jumps > 0 && GetTypeId()==TYPEID_PLAYER && IS_PLAYER_GUID(caster_guid)) 10832 { 10833 float radius; 10834 if (spellProto->EffectRadiusIndex[effIdx]) 10835 radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(spellProto->EffectRadiusIndex[effIdx])); 10836 else 10837 radius = GetSpellMaxRange(sSpellRangeStore.LookupEntry(spellProto->rangeIndex)); 10838 10839 if(Player* caster = ((Player*)triggeredByAura->GetCaster())) 10840 { 10841 caster->ApplySpellMod(spellProto->Id, SPELLMOD_RADIUS, radius,NULL); 10842 10843 if(Player* target = ((Player*)this)->GetNextRandomRaidMember(radius)) 10844 { 10845 // aura will applied from caster, but spell casted from current aura holder 10846 SpellModifier *mod = new SpellModifier; 10847 mod->op = SPELLMOD_CHARGES; 10848 mod->value = jumps-5; // negative 10849 mod->type = SPELLMOD_FLAT; 10850 mod->spellId = spellProto->Id; 10851 mod->effectId = effIdx; 10852 mod->lastAffected = NULL; 10853 mod->mask = spellProto->SpellFamilyFlags; 10854 mod->charges = 0; 10855 10856 caster->AddSpellMod(mod, true); 10857 CastCustomSpell(target,spellProto->Id,&heal,NULL,NULL,true,NULL,triggeredByAura,caster->GetGUID()); 10858 caster->AddSpellMod(mod, false); 10859 } 10860 } 10861 } 10862 10863 // heal 10864 CastCustomSpell(this,33110,&heal,NULL,NULL,true,NULL,NULL,caster_guid); 10865 return true; 10866 } 10867 10868 void Unit::RemoveAurasAtChanneledTarget(SpellEntry const* spellInfo) 10869 { 10870 uint64 target_guid = GetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT); 10871 10872 if(!IS_UNIT_GUID(target_guid)) 10873 return; 10874 10875 Unit* target = ObjectAccessor::GetUnit(*this, target_guid); 10876 if(!target) 10877 return; 10878 10879 for (AuraMap::iterator iter = target->GetAuras().begin(); iter != target->GetAuras().end(); ) 10880 { 10881 if (iter->second->GetId() == spellInfo->Id && iter->second->GetCasterGUID()==GetGUID()) 10882 target->RemoveAura(iter); 10883 else 10884 ++iter; 10885 } 10886 }