/// Spell Target Handling for type 45: Chain,!!only for healing!! for chain lightning =6 void Spell::SpellTargetChainTargeting(uint32 i, uint32 j) { if( !m_caster->IsInWorld() ) return; TargetsList* tmpMap=&m_targetUnits[i]; //if selected target is party member, then jumps on party Unit* firstTarget; bool PartyOnly = false; float range = GetMaxRange(dbcSpellRange.LookupEntry(m_spellInfo->rangeIndex));//this is probably wrong, //this is cast distance, not searching distance range *= range; firstTarget = m_caster->GetMapMgr()->GetPlayer((uint32)m_targets.m_unitTarget); if( firstTarget && p_caster != NULL ) { if( p_caster->InGroup() ) if( p_caster->GetSubGroup() == static_cast< Player* >( firstTarget )->GetSubGroup() ) PartyOnly=true; } else { firstTarget = m_caster->GetMapMgr()->GetUnit(m_targets.m_unitTarget); if(!firstTarget) return; } uint32 jumps=m_spellInfo->EffectChainTarget[i]; if(m_spellInfo->SpellGroupType && u_caster) { SM_FIValue(u_caster->SM_FAdditionalTargets,(int32*)&jumps,m_spellInfo->SpellGroupType); } SafeAddTarget(tmpMap,firstTarget->GetGUID()); if(!jumps) return; jumps--; if(PartyOnly) { GroupMembersSet::iterator itr; SubGroup * pGroup = p_caster->GetGroup() ? p_caster->GetGroup()->GetSubGroup(p_caster->GetSubGroup()) : 0; if(pGroup) { p_caster->GetGroup()->Lock(); for(itr = pGroup->GetGroupMembersBegin(); itr != pGroup->GetGroupMembersEnd(); ++itr) { if(!(*itr)->m_loggedInPlayer || (*itr)->m_loggedInPlayer==u_caster || !(*itr)->m_loggedInPlayer->isAlive() ) continue; //we target stuff that has no full health. No idea if we must fill target list or not :( if( (*itr)->m_loggedInPlayer->GetUInt32Value( UNIT_FIELD_HEALTH ) == (*itr)->m_loggedInPlayer->GetUInt32Value( UNIT_FIELD_MAXHEALTH ) ) continue; if( sWorld.Collision && u_caster != NULL ) { if (u_caster->GetMapId() == (*itr)->m_loggedInPlayer->GetMapId() && !CollideInterface.CheckLOS(u_caster->GetMapId(),u_caster->GetPositionNC(),(*itr)->m_loggedInPlayer->GetPositionNC())) continue; } if( IsInrange(u_caster,(*itr)->m_loggedInPlayer, range) ) { SafeAddTarget(tmpMap,(*itr)->m_loggedInPlayer->GetGUID()); if(!--jumps) { p_caster->GetGroup()->Unlock(); return; } } } p_caster->GetGroup()->Unlock(); } }//find nearby friendly target else { std::set<Object*>::iterator itr; firstTarget->AquireInrangeLock(); //make sure to release lock before exit function ! for( itr = firstTarget->GetInRangeSetBegin(); itr != firstTarget->GetInRangeSetEnd(); itr++ ) { if( !(*itr)->IsUnit() || !((Unit*)(*itr))->isAlive()) continue; //we target stuff that has no full health. No idea if we must fill target list or not :( if( (*itr)->GetUInt32Value( UNIT_FIELD_HEALTH ) == (*itr)->GetUInt32Value( UNIT_FIELD_MAXHEALTH ) ) continue; if (sWorld.Collision) { if (u_caster->GetMapId() == (*itr)->GetMapId() && !CollideInterface.CheckLOS(u_caster->GetMapId(),u_caster->GetPositionNC(),(*itr)->GetPositionNC())) continue; } if(IsInrange(firstTarget,*itr, range)) { if(!isAttackable(u_caster,(Unit*)(*itr))) { SafeAddTarget(tmpMap,(*itr)->GetGUID()); if(!--jumps) { firstTarget->ReleaseInrangeLock(); return; } } } } firstTarget->ReleaseInrangeLock(); } }
SPELL_EFFECT_OVERRIDE_RETURNS AH_31821( Aura *aur, bool apply, uint8 i ) { if( i == 0 ) { Unit *target = aur->GetTarget(); //this is actually caster Aura *a; if( apply ) { InRangeSetRecProt::iterator itr; target->AquireInrangeLock(); //make sure to release lock before exit function ! InrangeLoopExitAutoCallback AutoLock; for( itr = target->GetInRangeSetBegin( AutoLock ); itr != target->GetInRangeSetEnd(); itr++ ) { if(!((*itr)->IsUnit()) || !SafeUnitCast((*itr))->isAlive()) continue; a = SafeUnitCast((*itr))->HasAuraWithNameHash( SPELL_HASH_CONCENTRATION_AURA, target->GetGUID(), AURA_SEARCH_POSITIVE ); if( a != NULL ) target->CastSpell( SafeUnitCast((*itr)), 64364, true ); //immunity } target->ReleaseInrangeLock(); a = target->HasAuraWithNameHash( SPELL_HASH_CONCENTRATION_AURA, target->GetGUID(), AURA_SEARCH_POSITIVE ); if( a != NULL ) { target->CastSpell( target, 64364, true ); //immunity } else { if( a == NULL ) a = target->HasAuraWithNameHash( SPELL_HASH_DEVOTION_AURA, target->GetGUID(), AURA_SEARCH_POSITIVE ); if( a == NULL ) a = target->HasAuraWithNameHash( SPELL_HASH_RESISTANCE_AURA, target->GetGUID(), AURA_SEARCH_POSITIVE ); if( a == NULL ) a = target->HasAuraWithNameHash( SPELL_HASH_RETRIBUTION_AURA, target->GetGUID(), AURA_SEARCH_POSITIVE ); if( a != NULL ) { SpellEntry *sp = a->GetSpellProto(); a->Remove(); a = NULL; target->CastSpellDelayed( target->GetGUID(), sp->Id, 1, true ); } } } else { target->RemoveAura( 64364 ); //immunity a = target->HasAuraWithNameHash( SPELL_HASH_DEVOTION_AURA, target->GetGUID(), AURA_SEARCH_POSITIVE ); if( a == NULL ) a = target->HasAuraWithNameHash( SPELL_HASH_RESISTANCE_AURA, target->GetGUID(), AURA_SEARCH_POSITIVE ); if( a == NULL ) a = target->HasAuraWithNameHash( SPELL_HASH_RETRIBUTION_AURA, target->GetGUID(), AURA_SEARCH_POSITIVE ); if( a != NULL ) { SpellEntry *sp = a->GetSpellProto(); a->Remove(); a = NULL; target->CastSpellDelayed( target->GetGUID(), sp->Id, 1, true ); } } } return SPELL_EFFECT_OVERRIDE_CONTINUE_EXECUTION; }