Changeset 257 for trunk/src/game/Unit.cpp
- Timestamp:
- 11/19/08 13:51:33 (17 years ago)
- Files:
-
- 1 modified
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/game/Unit.cpp
r253 r257 1149 1149 if ( GetSpellSchoolMask(spellInfo) & SPELL_SCHOOL_MASK_NORMAL ) 1150 1150 { 1151 uint32 modDamage=*damage;1152 1153 1151 // apply spellmod to Done damage 1154 1152 if(Player* modOwner = GetSpellModOwner()) … … 1435 1433 if(!this || !pVictim) 1436 1434 return 0; 1437 if(! this->isAlive() || !pVictim->isAlive())1435 if(!isAlive() || !pVictim->isAlive()) 1438 1436 return 0; 1439 1437 … … 4128 4126 void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode) 4129 4127 { 4130 if (IsSingleTargetSpell((*i).second->GetSpellProto())) 4131 { 4132 if(Unit* caster = (*i).second->GetCaster()) 4128 Aura* Aur = i->second; 4129 SpellEntry const* AurSpellInfo = Aur->GetSpellProto(); 4130 4131 Unit* caster = NULL; 4132 if (IsSingleTargetSpell(AurSpellInfo)) 4133 { 4134 caster = Aur->GetCaster(); 4135 if(caster) 4133 4136 { 4134 4137 AuraList& scAuras = caster->GetSingleCastAuras(); 4135 scAuras.remove( (*i).second);4138 scAuras.remove(Aur); 4136 4139 } 4137 4140 else … … 4142 4145 } 4143 4146 4144 if ((*i).second->GetModifier()->m_auraname < TOTAL_AURAS) 4147 // remove from list before mods removing (prevent cyclic calls, mods added before including to aura list - use reverse order) 4148 if (Aur->GetModifier()->m_auraname < TOTAL_AURAS) 4145 4149 { 4146 4150 m_modAuras[(*i).second->GetModifier()->m_auraname].remove((*i).second); … … 4154 4158 } 4155 4159 4156 // remove from list before mods removing (prevent cyclic calls, mods added before including to aura list - use reverse order)4157 Aura* Aur = i->second;4158 4160 // Set remove mode 4159 4161 Aur->SetRemoveMode(mode); … … 4163 4165 ++m_removedAuras; // internal count used by unit update 4164 4166 4165 // Statu sunsummoned at aura remove4167 // Statue unsummoned at aura remove 4166 4168 Totem* statue = NULL; 4167 if(IsChanneledSpell(Aur->GetSpellProto())) 4168 if(Unit* caster = Aur->GetCaster()) 4169 bool caster_channeled = false; 4170 if(IsChanneledSpell(AurSpellInfo)) 4171 { 4172 if(!caster) // can be already located for IsSingleTargetSpell case 4173 caster = Aur->GetCaster(); 4174 4175 if(caster) 4176 { 4169 4177 if(caster->GetTypeId()==TYPEID_UNIT && ((Creature*)caster)->isTotem() && ((Totem*)caster)->GetTotemType()==TOTEM_STATUE) 4170 4178 statue = ((Totem*)caster); 4171 4179 else 4180 caster_channeled = caster==this; 4181 } 4182 } 4172 4183 4173 4184 if(const std::vector<int32> *spell_triggered = spellmgr.GetSpellLinked(-(int32)Aur->GetSpellProto()->Id)) … … 4186 4197 Aur->_RemoveAura(); 4187 4198 delete Aur; 4199 4200 if(caster_channeled) 4201 RemoveAurasAtChanneledTarget (AurSpellInfo); 4188 4202 4189 4203 if(statue) … … 4612 4626 } 4613 4627 4614 bool Unit::HandleHasteAuraProc(Unit *pVictim, SpellEntry const *hasteSpell, uint32 /*effIndex*/, uint32 damage, Aura* triggeredByAura, SpellEntry const * procSpell, uint32 /*procFlag*/, uint32 cooldown) 4615 { 4628 bool Unit::HandleHasteAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const * /*procSpell*/, uint32 /*procFlag*/, uint32 cooldown) 4629 { 4630 SpellEntry const *hasteSpell = triggeredByAura->GetSpellProto(); 4631 4616 4632 Item* castItem = triggeredByAura->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER 4617 4633 ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL; … … 4673 4689 } 4674 4690 4675 bool Unit::HandleDummyAuraProc(Unit *pVictim, SpellEntry const *dummySpell, uint32 effIndex, uint32 damage, Aura* triggeredByAura, SpellEntry const * procSpell, uint32 procFlag, uint32 cooldown) 4676 { 4691 bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const * procSpell, uint32 procFlag, uint32 cooldown) 4692 { 4693 SpellEntry const *dummySpell = triggeredByAura->GetSpellProto (); 4694 uint32 effIndex = triggeredByAura->GetEffIndex (); 4695 4677 4696 Item* castItem = triggeredByAura->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER 4678 4697 ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL; … … 6262 6281 return false; 6263 6282 6264 uint32 spell = 0;6265 6283 switch(triggeredByAura->GetSpellProto()->Id) 6266 6284 { … … 6292 6310 6293 6311 // overwrite non existing triggered spell call in spell.dbc 6294 uint32 spell = 0;6295 6312 switch(triggeredByAura->GetSpellProto()->Id) 6296 6313 { … … 6492 6509 } 6493 6510 6494 bool Unit::HandleOverrideClassScriptAuraProc(Unit *pVictim, int32 scriptId, uint32 damage, Aura *triggeredByAura, SpellEntry const *procSpell, uint32 cooldown) 6495 { 6511 bool Unit::HandleOverrideClassScriptAuraProc(Unit *pVictim, Aura *triggeredByAura, SpellEntry const *procSpell, uint32 cooldown) 6512 { 6513 int32 scriptId = triggeredByAura->GetModifier()->m_miscvalue; 6514 6496 6515 if(!pVictim || !pVictim->isAlive()) 6497 6516 return false; … … 7259 7278 } 7260 7279 7261 void Unit::SendEnergizeSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage, Powers powertype , bool critical)7280 void Unit::SendEnergizeSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage, Powers powertype) 7262 7281 { 7263 7282 WorldPacket data(SMSG_SPELLENERGIZELOG, (8+8+4+4+4+1)); … … 7359 7378 AuraList const& mModDamagePercentTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN); 7360 7379 for(AuraList::const_iterator i = mModDamagePercentTaken.begin(); i != mModDamagePercentTaken.end(); ++i) 7361 if( (*i)->GetModifier()->m_miscvalue & GetSpellSchoolMask(spellProto))7380 if( (*i)->GetModifier()->m_miscvalue & GetSpellSchoolMask(spellProto) ) 7362 7381 TakenTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f; 7363 7382 … … 8207 8226 8208 8227 // ..done (for creature type by mask) in taken 8209 AuraList const& mDamageDoneCreature = this->GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE_CREATURE);8228 AuraList const& mDamageDoneCreature = GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE_CREATURE); 8210 8229 for(AuraList::const_iterator i = mDamageDoneCreature.begin();i != mDamageDoneCreature.end(); ++i) 8211 8230 if(creatureTypeMask & uint32((*i)->GetModifier()->m_miscvalue)) … … 8275 8294 // SPELL_AURA_MOD_OFFHAND_DAMAGE_PCT included in weapon damage 8276 8295 8277 AuraList const& mDamageDoneVersus = this->GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE_VERSUS);8296 AuraList const& mDamageDoneVersus = GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE_VERSUS); 8278 8297 for(AuraList::const_iterator i = mDamageDoneVersus.begin();i != mDamageDoneVersus.end(); ++i) 8279 8298 if(creatureTypeMask & uint32((*i)->GetModifier()->m_miscvalue)) … … 8730 8749 if(IsInWorld()) 8731 8750 { 8732 Map *m = MapManager::Instance().GetMap(GetMapId(), this);8751 Map *m = GetMap(); 8733 8752 8734 8753 if(GetTypeId()==TYPEID_PLAYER) … … 9792 9811 } 9793 9812 9794 9795 9796 9813 CharmInfo* Unit::InitCharmInfo(Unit *charm) 9797 9814 { … … 9957 9974 struct ProcTriggeredData 9958 9975 { 9959 ProcTriggeredData( SpellEntry const * _spellInfo, uint32 _spellParam,Aura* _triggeredByAura, uint32 _cooldown)9960 : spellInfo(_spellInfo), spellParam(_spellParam),triggeredByAura(_triggeredByAura),9976 ProcTriggeredData(Aura* _triggeredByAura, uint32 _cooldown) 9977 : triggeredByAura(_triggeredByAura), 9961 9978 triggeredByAura_SpellPair(Unit::spellEffectPair(triggeredByAura->GetId(),triggeredByAura->GetEffIndex())), 9962 9979 cooldown(_cooldown) 9963 {} 9964 9965 SpellEntry const * spellInfo; 9966 uint32 spellParam; 9967 Aura* triggeredByAura; 9968 Unit::spellEffectPair triggeredByAura_SpellPair; 9969 uint32 cooldown; 9980 {} 9981 9982 Aura* triggeredByAura; // triggred aura, can be invalidate at triggered aura proccessing 9983 Unit::spellEffectPair triggeredByAura_SpellPair; // spell pair, used for re-find aura (by pointer comparison in range) 9984 uint32 cooldown; // possible hidden cooldown 9970 9985 }; 9971 9986 … … 9984 9999 next = i; ++next; 9985 10000 9986 SpellEntry const *spellProto = (*i)->GetSpellProto(); 9987 if(!spellProto) 10001 Aura* i_aura = *i; 10002 10003 uint32 cooldown; // returned at next line 10004 if(!IsTriggeredAtSpellProcEvent(i_aura->GetSpellProto(), procSpell, procFlag,attType,isVictim,cooldown)) 9988 10005 continue; 9989 10006 9990 SpellProcEventEntry const *spellProcEvent = spellmgr.GetSpellProcEvent(spellProto->Id); 9991 if(!spellProcEvent) 9992 { 9993 // used to prevent spam in log about same non-handled spells 9994 static std::set<uint32> nonHandledSpellProcSet; 9995 9996 if(spellProto->procFlags != 0 && nonHandledSpellProcSet.find(spellProto->Id)==nonHandledSpellProcSet.end()) 9997 { 9998 sLog.outError("ProcDamageAndSpell: spell %u (%s aura source) not have record in `spell_proc_event`)",spellProto->Id,(isVictim?"a victim's":"an attacker's")); 9999 nonHandledSpellProcSet.insert(spellProto->Id); 10000 } 10001 10002 // spell.dbc use totally different flags, that only can create problems if used. 10003 continue; 10004 } 10005 10006 // Check spellProcEvent data requirements 10007 if(!SpellMgr::IsSpellProcEventCanTriggeredBy(spellProcEvent, procSpell,procFlag)) 10008 continue; 10009 10010 // Check if current equipment allows aura to proc 10011 if(!isVictim && GetTypeId() == TYPEID_PLAYER ) 10012 { 10013 if(spellProto->EquippedItemClass == ITEM_CLASS_WEAPON) 10014 { 10015 Item *item = ((Player*)this)->GetWeaponForAttack(attType,true); 10016 10017 if(!item || !((1<<item->GetProto()->SubClass) & spellProto->EquippedItemSubClassMask)) 10018 continue; 10019 } 10020 else if(spellProto->EquippedItemClass == ITEM_CLASS_ARMOR) 10021 { 10022 // Check if player is wearing shield 10023 Item *item = ((Player*)this)->GetShield(true); 10024 if(!item || !((1<<item->GetProto()->SubClass) & spellProto->EquippedItemSubClassMask)) 10025 continue; 10026 } 10027 } 10028 10029 float chance = (float)spellProto->procChance; 10030 10031 if(Player* modOwner = GetSpellModOwner()) 10032 modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_CHANCE_OF_SUCCESS,chance); 10033 10034 if(!isVictim && spellProcEvent->ppmRate != 0) 10035 { 10036 uint32 WeaponSpeed = GetAttackTime(attType); 10037 chance = GetPPMProcChance(WeaponSpeed, spellProcEvent->ppmRate); 10038 } 10039 10040 if(roll_chance_f(chance)) 10041 { 10042 uint32 cooldown = spellProcEvent->cooldown; 10043 10044 uint32 i_spell_eff = (*i)->GetEffIndex(); 10045 10046 int32 i_spell_param; 10047 switch(*aur) 10048 { 10049 case SPELL_AURA_PROC_TRIGGER_SPELL: 10050 i_spell_param = procFlag; 10051 break; 10052 case SPELL_AURA_DUMMY: 10053 case SPELL_AURA_PRAYER_OF_MENDING: 10054 case SPELL_AURA_MOD_HASTE: 10055 i_spell_param = i_spell_eff; 10056 break; 10057 case SPELL_AURA_OVERRIDE_CLASS_SCRIPTS: 10058 i_spell_param = (*i)->GetModifier()->m_miscvalue; 10059 break; 10060 default: 10061 i_spell_param = (*i)->GetModifier()->m_amount; 10062 break; 10063 } 10064 10065 procTriggered.push_back( ProcTriggeredData(spellProto,i_spell_param,*i, cooldown) ); 10066 } 10007 procTriggered.push_back( ProcTriggeredData(i_aura, cooldown) ); 10067 10008 } 10068 10009 … … 10097 10038 } 10098 10039 10099 // save charges existence before processing to prevent crash at access to deleted triggered aura after 10100 bool triggeredByAuraWithCharges = i->triggeredByAura->m_procCharges > 0; 10101 10040 /// this is aura triggering code call 10041 Aura* triggeredByAura = i->triggeredByAura; 10042 10043 /// save charges existence before processing to prevent crash at access to deleted triggered aura after 10044 /// used in speedup code check before check aura existance. 10045 bool triggeredByAuraWithCharges = triggeredByAura->m_procCharges > 0; 10046 10047 /// success in event proccesing 10048 /// used in speedup code check before check aura existance. 10102 10049 bool casted = false; 10050 10051 /// process triggered code 10103 10052 switch(*aur) 10104 10053 { 10105 10054 case SPELL_AURA_PROC_TRIGGER_SPELL: 10106 10055 { 10107 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()); 10108 casted = HandleProcTriggerSpell(pTarget, damage, i->triggeredByAura, procSpell,i->spellParam,attType,i->cooldown); 10056 sLog.outDebug("ProcDamageAndSpell: casting spell (triggered by %s proc aura of spell %u)", 10057 (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId()); 10058 casted = HandleProcTriggerSpell(pTarget, damage, triggeredByAura, procSpell, procFlag, attType, i->cooldown); 10109 10059 break; 10110 10060 } 10111 10061 case SPELL_AURA_PROC_TRIGGER_DAMAGE: 10112 10062 { 10113 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()); 10114 uint32 damage = i->spellParam; 10115 SpellNonMeleeDamageLog(pTarget, i->spellInfo->Id, damage, true, true); 10063 uint32 triggered_damage = triggeredByAura->GetModifier()->m_amount; 10064 sLog.outDebug("ProcDamageAndSpell: doing %u damage (triggered by %s aura of spell %u)", 10065 triggered_damage, (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId()); 10066 SpellNonMeleeDamageLog(pTarget, triggeredByAura->GetId(), triggered_damage, true, true); 10116 10067 casted = true; 10117 10068 break; … … 10119 10070 case SPELL_AURA_DUMMY: 10120 10071 { 10121 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()); 10122 casted = HandleDummyAuraProc(pTarget, i->spellInfo, i->spellParam, damage, i->triggeredByAura, procSpell, procFlag,i->cooldown); 10072 uint32 effect = triggeredByAura->GetEffIndex(); 10073 sLog.outDebug("ProcDamageAndSpell: casting spell (triggered by %s dummy aura of spell %u)", 10074 (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId()); 10075 casted = HandleDummyAuraProc(pTarget, damage, triggeredByAura, procSpell, procFlag,i->cooldown); 10123 10076 break; 10124 10077 } 10125 10078 case SPELL_AURA_PRAYER_OF_MENDING: 10126 10079 { 10127 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()); 10128 10129 // aura can be deleted at casts 10130 int32 heal = i->triggeredByAura->GetModifier()->m_amount; 10131 uint64 caster_guid = i->triggeredByAura->GetCasterGUID(); 10132 10133 // jumps 10134 int32 jumps = i->triggeredByAura->m_procCharges-1; 10135 10136 // current aura expire 10137 i->triggeredByAura->m_procCharges = 1; // will removed at next charges decrease 10138 10139 // next target selection 10140 if(jumps > 0 && GetTypeId()==TYPEID_PLAYER && IS_PLAYER_GUID(caster_guid)) 10141 { 10142 Aura* aura = i->triggeredByAura; 10143 10144 SpellEntry const* spellProto = aura->GetSpellProto(); 10145 uint32 effIdx = aura->GetEffIndex(); 10146 10147 float radius; 10148 if (spellProto->EffectRadiusIndex[effIdx]) 10149 radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(spellProto->EffectRadiusIndex[effIdx])); 10150 else 10151 radius = GetSpellMaxRange(sSpellRangeStore.LookupEntry(spellProto->rangeIndex)); 10152 10153 if(Player* caster = ((Player*)aura->GetCaster())) 10154 { 10155 caster->ApplySpellMod(spellProto->Id, SPELLMOD_RADIUS, radius,NULL); 10156 10157 if(Player* target = ((Player*)this)->GetNextRandomRaidMember(radius)) 10158 { 10159 // aura will applied from caster, but spell casted from current aura holder 10160 SpellModifier *mod = new SpellModifier; 10161 mod->op = SPELLMOD_CHARGES; 10162 mod->value = jumps-5; // negative 10163 mod->type = SPELLMOD_FLAT; 10164 mod->spellId = spellProto->Id; 10165 mod->effectId = effIdx; 10166 mod->lastAffected = NULL; 10167 mod->mask = spellProto->SpellFamilyFlags; 10168 mod->charges = 0; 10169 10170 caster->AddSpellMod(mod, true); 10171 CastCustomSpell(target,spellProto->Id,&heal,NULL,NULL,true,NULL,aura,caster->GetGUID()); 10172 caster->AddSpellMod(mod, false); 10173 } 10174 } 10175 } 10176 10177 // heal 10178 CastCustomSpell(this,33110,&heal,NULL,NULL,true,NULL,NULL,caster_guid); 10179 casted = true; 10080 sLog.outDebug("ProcDamageAndSpell: casting mending (triggered by %s dummy aura of spell %u)", 10081 (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId()); 10082 10083 casted = HandleMeandingAuraProc(triggeredByAura); 10180 10084 break; 10181 10085 } 10182 10086 case SPELL_AURA_MOD_HASTE: 10183 10087 { 10184 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()); 10185 casted = HandleHasteAuraProc(pTarget, i->spellInfo, i->spellParam, damage, i->triggeredByAura, procSpell, procFlag,i->cooldown); 10088 sLog.outDebug("ProcDamageAndSpell: casting spell (triggered by %s haste aura of spell %u)", 10089 (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId()); 10090 casted = HandleHasteAuraProc(pTarget, damage, triggeredByAura, procSpell, procFlag,i->cooldown); 10186 10091 break; 10187 10092 } … … 10190 10095 // nothing do, just charges counter 10191 10096 // but count only in case appropriate school damage 10192 casted = i->triggeredByAura->GetModifier()->m_miscvalue & damageSchoolMask;10097 casted = triggeredByAura->GetModifier()->m_miscvalue & damageSchoolMask; 10193 10098 break; 10194 10099 } 10195 10100 case SPELL_AURA_OVERRIDE_CLASS_SCRIPTS: 10196 10101 { 10197 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()); 10198 casted = HandleOverrideClassScriptAuraProc(pTarget, i->spellParam, damage, i->triggeredByAura, procSpell,i->cooldown); 10102 sLog.outDebug("ProcDamageAndSpell: casting spell (triggered by %s class script aura of spell %u)", 10103 (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId()); 10104 casted = HandleOverrideClassScriptAuraProc(pTarget, triggeredByAura, procSpell,i->cooldown); 10199 10105 break; 10200 10106 } … … 10207 10113 } 10208 10114 10209 // Update charge (aura can be removed by triggers)10115 /// Update charge (aura can be removed by triggers) 10210 10116 if(casted && triggeredByAuraWithCharges) 10211 10117 { 10212 // needfound aura (can be dropped by triggers)10118 /// need re-found aura (can be dropped by triggers) 10213 10119 AuraMap::const_iterator lower = GetAuras().lower_bound(i->triggeredByAura_SpellPair); 10214 10120 AuraMap::const_iterator upper = GetAuras().upper_bound(i->triggeredByAura_SpellPair); 10215 10121 for(AuraMap::const_iterator itr = lower; itr!= upper; ++itr) 10216 10122 { 10217 if(itr->second == i->triggeredByAura)10123 if(itr->second == triggeredByAura) // pointer still valid 10218 10124 { 10219 if( i->triggeredByAura->m_procCharges > 0)10220 i->triggeredByAura->m_procCharges -= 1;10221 10222 i->triggeredByAura->UpdateAuraCharges();10125 if(triggeredByAura->m_procCharges > 0) 10126 triggeredByAura->m_procCharges -= 1; 10127 10128 triggeredByAura->UpdateAuraCharges(); 10223 10129 break; 10224 10130 } … … 10227 10133 } 10228 10134 10229 // Safely remove auras with zero charges10135 /// Safely remove auras with zero charges 10230 10136 for(AuraList::const_iterator i = auras.begin(), next; i != auras.end(); i = next) 10231 10137 { … … 10340 10246 // send explicit stop packet 10341 10247 // rely on vmaps here because for example stormwind is in air 10342 float z = MapManager::Instance().GetBaseMap(GetMapId())->GetHeight(GetPositionX(), GetPositionY(), GetPositionZ(), true);10248 //float z = MapManager::Instance().GetBaseMap(GetMapId())->GetHeight(GetPositionX(), GetPositionY(), GetPositionZ(), true); 10343 10249 //if (fabs(GetPositionZ() - z) < 2.0f) 10344 10250 // Relocate(GetPositionX(), GetPositionY(), z); … … 10824 10730 } 10825 10731 10826 pet->SetUInt64Value(UNIT_FIELD_SUMMONEDBY, this->GetGUID());10827 pet->SetUInt64Value(UNIT_FIELD_CREATEDBY, this->GetGUID());10828 pet->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, this->getFaction());10732 pet->SetUInt64Value(UNIT_FIELD_SUMMONEDBY, GetGUID()); 10733 pet->SetUInt64Value(UNIT_FIELD_CREATEDBY, GetGUID()); 10734 pet->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,getFaction()); 10829 10735 pet->SetUInt32Value(UNIT_CREATED_BY_SPELL, spell_id); 10830 10736 … … 10844 10750 return pet; 10845 10751 } 10752 10753 bool Unit::IsTriggeredAtSpellProcEvent(SpellEntry const* spellProto, SpellEntry const* procSpell, uint32 procFlag, WeaponAttackType attType, bool isVictim, uint32& cooldown ) 10754 { 10755 SpellProcEventEntry const * spellProcEvent = spellmgr.GetSpellProcEvent(spellProto->Id); 10756 10757 if(!spellProcEvent) 10758 { 10759 // used to prevent spam in log about same non-handled spells 10760 static std::set<uint32> nonHandledSpellProcSet; 10761 10762 if(spellProto->procFlags != 0 && nonHandledSpellProcSet.find(spellProto->Id)==nonHandledSpellProcSet.end()) 10763 { 10764 sLog.outError("ProcDamageAndSpell: spell %u (%s aura source) not have record in `spell_proc_event`)",spellProto->Id,(isVictim?"a victim's":"an attacker's")); 10765 nonHandledSpellProcSet.insert(spellProto->Id); 10766 } 10767 10768 // spell.dbc use totally different flags, that only can create problems if used. 10769 return false; 10770 } 10771 10772 // Check spellProcEvent data requirements 10773 if(!SpellMgr::IsSpellProcEventCanTriggeredBy(spellProcEvent, procSpell,procFlag)) 10774 return false; 10775 10776 // Check if current equipment allows aura to proc 10777 if(!isVictim && GetTypeId() == TYPEID_PLAYER ) 10778 { 10779 if(spellProto->EquippedItemClass == ITEM_CLASS_WEAPON) 10780 { 10781 Item *item = ((Player*)this)->GetWeaponForAttack(attType,true); 10782 10783 if(!item || !((1<<item->GetProto()->SubClass) & spellProto->EquippedItemSubClassMask)) 10784 return false; 10785 } 10786 else if(spellProto->EquippedItemClass == ITEM_CLASS_ARMOR) 10787 { 10788 // Check if player is wearing shield 10789 Item *item = ((Player*)this)->GetShield(true); 10790 if(!item || !((1<<item->GetProto()->SubClass) & spellProto->EquippedItemSubClassMask)) 10791 return false; 10792 } 10793 } 10794 10795 float chance = (float)spellProto->procChance; 10796 10797 if(Player* modOwner = GetSpellModOwner()) 10798 modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_CHANCE_OF_SUCCESS,chance); 10799 10800 if(!isVictim && spellProcEvent && spellProcEvent->ppmRate != 0) 10801 { 10802 uint32 WeaponSpeed = GetAttackTime(attType); 10803 chance = GetPPMProcChance(WeaponSpeed, spellProcEvent->ppmRate); 10804 } 10805 10806 cooldown = spellProcEvent ? spellProcEvent->cooldown : 0; 10807 return roll_chance_f(chance); 10808 } 10809 10810 bool Unit::HandleMeandingAuraProc( Aura* triggeredByAura ) 10811 { 10812 // aura can be deleted at casts 10813 SpellEntry const* spellProto = triggeredByAura->GetSpellProto(); 10814 uint32 effIdx = triggeredByAura->GetEffIndex(); 10815 int32 heal = triggeredByAura->GetModifier()->m_amount; 10816 uint64 caster_guid = triggeredByAura->GetCasterGUID(); 10817 10818 // jumps 10819 int32 jumps = triggeredByAura->m_procCharges-1; 10820 10821 // current aura expire 10822 triggeredByAura->m_procCharges = 1; // will removed at next charges decrease 10823 10824 // next target selection 10825 if(jumps > 0 && GetTypeId()==TYPEID_PLAYER && IS_PLAYER_GUID(caster_guid)) 10826 { 10827 float radius; 10828 if (spellProto->EffectRadiusIndex[effIdx]) 10829 radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(spellProto->EffectRadiusIndex[effIdx])); 10830 else 10831 radius = GetSpellMaxRange(sSpellRangeStore.LookupEntry(spellProto->rangeIndex)); 10832 10833 if(Player* caster = ((Player*)triggeredByAura->GetCaster())) 10834 { 10835 caster->ApplySpellMod(spellProto->Id, SPELLMOD_RADIUS, radius,NULL); 10836 10837 if(Player* target = ((Player*)this)->GetNextRandomRaidMember(radius)) 10838 { 10839 // aura will applied from caster, but spell casted from current aura holder 10840 SpellModifier *mod = new SpellModifier; 10841 mod->op = SPELLMOD_CHARGES; 10842 mod->value = jumps-5; // negative 10843 mod->type = SPELLMOD_FLAT; 10844 mod->spellId = spellProto->Id; 10845 mod->effectId = effIdx; 10846 mod->lastAffected = NULL; 10847 mod->mask = spellProto->SpellFamilyFlags; 10848 mod->charges = 0; 10849 10850 caster->AddSpellMod(mod, true); 10851 CastCustomSpell(target,spellProto->Id,&heal,NULL,NULL,true,NULL,triggeredByAura,caster->GetGUID()); 10852 caster->AddSpellMod(mod, false); 10853 } 10854 } 10855 } 10856 10857 // heal 10858 CastCustomSpell(this,33110,&heal,NULL,NULL,true,NULL,NULL,caster_guid); 10859 return true; 10860 } 10861 10862 void Unit::RemoveAurasAtChanneledTarget(SpellEntry const* spellInfo) 10863 { 10864 uint64 target_guid = GetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT); 10865 10866 if(!IS_UNIT_GUID(target_guid)) 10867 return; 10868 10869 Unit* target = ObjectAccessor::GetUnit(*this, target_guid); 10870 if(!target) 10871 return; 10872 10873 for (AuraMap::iterator iter = target->GetAuras().begin(); iter != target->GetAuras().end(); ) 10874 { 10875 if (iter->second->GetId() == spellInfo->Id && iter->second->GetCasterGUID()==GetGUID()) 10876 target->RemoveAura(iter); 10877 else 10878 ++iter; 10879 } 10880 }