/// Spell Target Handling for type 31: related to scripted effects void Spell::SpellTargetScriptedEffects(uint32 i, uint32 j) { if( m_spellInfo->NameHash == SPELL_HASH_WILD_GROWTH || m_spellInfo->NameHash == SPELL_HASH_CIRCLE_OF_HEALING ) { if( p_caster == NULL || !p_caster->IsInWorld() ) return; if( p_caster->GetGroup() ) { uint32 TargetCount = 0; p_caster->GetGroup()->Lock(); for(uint32 x = 0; x < p_caster->GetGroup()->GetSubGroupCount(); ++x) { if( TargetCount == 5 ) break; for(GroupMembersSet::iterator itr = p_caster->GetGroup()->GetSubGroup( x )->GetGroupMembersBegin(); itr != p_caster->GetGroup()->GetSubGroup( x )->GetGroupMembersEnd(); itr++) { if((*itr)->m_loggedInPlayer && TargetCount != 5) { Player* p_target = (*itr)->m_loggedInPlayer; if( p_caster->GetDistance2dSq( p_target ) <= 225 ) // both spells have 15yd range, change in future if needed { _AddTargetForced( (*itr)->m_loggedInPlayer->GetGUID(), i ); TargetCount += 1; } } } } p_caster->GetGroup()->Unlock(); } } else FillAllTargetsInArea(i,m_targets.m_destX,m_targets.m_destY,m_targets.m_destZ,GetDBCCastTime(i)); }
/// Spell Target Handling for type 76 All targets in area void Spell::SpellTargetAllTargetsInArea(uint32 i, uint32 j) { if( !m_caster || !m_caster->IsInWorld() ) return; FillAllTargetsInArea(i, m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, GetDBCCastTime(i)); }
/// Spell Target Handling for type 18: Land under caster void Spell::SpellTargetLandUnderCaster(uint32 i, uint32 j) /// I don't think this is the correct name for this one { TargetsList* tmpMap=&m_targetUnits[i]; if(m_spellInfo->Effect[i] != SPELL_EFFECT_SUMMON_DEMON && m_spellInfo->Effect[i] != SPELL_EFFECT_SUMMON_OBJECT_WILD && m_spellInfo->Effect[i] != SPELL_EFFECT_SUMMON_OBJECT) FillAllTargetsInArea(i,m_caster->GetPositionX(),m_caster->GetPositionY(),m_caster->GetPositionZ(),GetRadius(i)); else SafeAddTarget(tmpMap,m_caster->GetGUID()); }
/// Spell Target Handling for type 29: all object around the caster / object (so it seems) void Spell::SpellTargetTypeTAOE(uint32 i, uint32 j) { Unit* Target = m_caster->GetMapMgr()->GetUnit(m_targets.m_unitTarget); if( Target == NULL ) return; // tranquility if( u_caster != NULL && m_spellInfo->NameHash == SPELL_HASH_TRANQUILITY ) m_targetUnits[i].push_back(u_caster->GetGUID()); else FillAllTargetsInArea( (LocationVector&)Target->GetPosition(), i ); }
/// Spell Target Handling for type 18: Land under caster void Spell::SpellTargetLandUnderCaster(uint32 i, uint32 j) /// I don't think this is the correct name for this one { if( m_spellInfo->Effect[i] != SPELL_EFFECT_SUMMON_DEMON && m_spellInfo->Effect[i] != SPELL_EFFECT_SUMMON_OBJECT_WILD && m_spellInfo->Effect[i] != SPELL_EFFECT_SUMMON_OBJECT_SLOT1 && m_spellInfo->Effect[i] != SPELL_EFFECT_SUMMON_OBJECT_SLOT2 && m_spellInfo->Effect[i] != SPELL_EFFECT_SUMMON_OBJECT_SLOT3 && m_spellInfo->Effect[i] != SPELL_EFFECT_SUMMON_OBJECT_SLOT4 ) FillAllTargetsInArea(i, m_caster->GetPositionX(), m_caster->GetPositionY(), m_caster->GetPositionZ(), GetDBCCastTime(i)); else _AddTargetForced(m_caster->GetGUID(), i); }
/// Spell Target Handling for type 38: Dummy Target (Server-side script effect) void Spell::SpellTargetDummyTarget(uint32 i, uint32 j) { TargetsList* tmpMap=&m_targetUnits[i]; switch( m_spellInfo->Id ) { case 12938: { //FIXME: this'll be immortal targets FillAllTargetsInArea(i,m_targets.m_destX,m_targets.m_destY,m_targets.m_destZ,GetRadius(i)); } break; case 30427: { uint32 cloudtype; Creature *creature; if(!p_caster) return; Object::InRangeSet::iterator itr,itr2; p_caster->AquireInrangeLock(); //make sure to release lock before exit function ! for(itr2 = p_caster->GetInRangeSetBegin(); itr2 != p_caster->GetInRangeSetEnd(); ) { itr=itr2; ++itr2; if((*itr)->GetTypeId() == TYPEID_UNIT && p_caster->GetDistance2dSq((*itr)) < 400) { creature=static_cast<Creature *>((*itr)); cloudtype=creature->GetEntry(); if(cloudtype == 24222 || cloudtype == 17408 || cloudtype == 17407 || cloudtype == 17378) { p_caster->SetSelection(creature->GetGUID()); p_caster->ReleaseInrangeLock(); return; } } } p_caster->ReleaseInrangeLock(); } break; case 51729: // Blessing of Zim'Torga case 51265: // Blessing of Zim'Abwa case 52051: // Blessing of Zim'Rhuk SafeAddTarget(tmpMap, m_targets.m_unitTarget); break; default: break; } SafeAddTarget(tmpMap,m_caster->GetGUID()); }
/// Spell Target Handling for type 53: Target Area by Players CurrentSelection() void Spell::SpellTargetTargetAreaSelectedUnit(uint32 i, uint32 j) { Unit* Target = NULL; if(m_caster->IsInWorld()) { if(p_caster) Target = m_caster->GetMapMgr()->GetUnit(p_caster->GetSelection()); else Target = m_caster->GetMapMgr()->GetUnit(m_targets.m_unitTarget); } if(!Target) return; FillAllTargetsInArea((LocationVector&)Target->GetPosition(), i); }
/// Spell Target Handling for type 38: Dummy Target (Server-side script effect) void Spell::SpellTargetDummyTarget(uint32 i, uint32 j) { //TargetsList *tmpMap=&m_targetUnits[i]; if( m_spellInfo->Id == 51699 ) { if( p_caster ) { Aura* aur = p_caster->FindAura( 52916 ); if( aur && aur->GetUnitCaster() ) { _AddTargetForced(aur->GetUnitCaster()->GetGUID(), i); return; } } } else if( m_spellInfo->Id == 12938 ) { //FIXME:this ll be immortal targets FillAllTargetsInArea(i,m_targets.m_destX,m_targets.m_destY,m_targets.m_destZ,GetDBCCastTime(i)); } _AddTargetForced(m_caster->GetGUID(), i); }
/// Spell Target Handling for type 31: related to scripted effects void Spell::SpellTargetScriptedEffects( uint32 i, uint32 j ) { // Circle of healing or Wild Growth // - target top 5 hp deficient raid members around target. if( GetProto()->NameHash == SPELL_HASH_CIRCLE_OF_HEALING || GetProto()->NameHash == SPELL_HASH_WILD_GROWTH ) { if( p_caster == NULL || !p_caster->IsInWorld() ) return; TargetsList* tmpMap = &m_targetUnits[i]; Unit * pTarget = p_caster->GetMapMgr()->GetUnit( m_targets.m_unitTarget ); if( !pTarget ) return; if( p_caster == pTarget || IsInrange( p_caster->GetPositionX(), p_caster->GetPositionY(), p_caster->GetPositionZ(), pTarget, GetMaxRange( dbcSpellRange.LookupEntry( GetProto()->rangeIndex ) ) ) ) SafeAddTarget( tmpMap, pTarget->GetGUID() ); else { cancastresult = SPELL_FAILED_OUT_OF_RANGE; return; // No point targeting others if the target is not in casting range. } Group * group = p_caster->GetGroup(); if( group == NULL ) return; std::vector<Player*> raidList; std::vector<Player*>::iterator itr; uint32 count = group->GetSubGroupCount(); group->Lock(); for( uint32 k = 0; k < count; k++ ) { SubGroup * subgroup = group->GetSubGroup( k ); if( subgroup ) { for( GroupMembersSet::iterator itr = subgroup->GetGroupMembersBegin(); itr != subgroup->GetGroupMembersEnd(); ++itr ) { if( (*itr)->m_loggedInPlayer && m_caster != (*itr)->m_loggedInPlayer && IsInrange( pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), (*itr)->m_loggedInPlayer, GetRadius(i) ) ) raidList.push_back( (*itr)->m_loggedInPlayer ); } } } group->Unlock(); std::sort( raidList.begin(), raidList.end(), hpLessThan ); uint32 maxTargets = 4; if( GetProto()->NameHash == SPELL_HASH_CIRCLE_OF_HEALING && p_caster->HasSpell( 55675 ) ) // Glyph of circle of healing maxTargets++; for( itr = raidList.begin(); itr != raidList.end() && maxTargets > 0; ++itr, maxTargets-- ) { SafeAddTarget( tmpMap, (*itr)->GetGUID() ); } } else FillAllTargetsInArea( i, m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, GetRadius(i) ); }
/// this is handled in DO /// Spell Target Handling for type 28: All Enemies in Area of Effect(Blizzard/Rain of Fire/volley) channeled void Spell::SpellTargetEnemysAreaOfEffect(uint32 i, uint32 j) { FillAllTargetsInArea(i,m_targets.m_destX,m_targets.m_destY,m_targets.m_destZ,GetRadius(i)); }
/// Spell Target Handling for type 22: Enemy Targets around the Caster//changed party members around you /// place around the target / near the target //targeted Area effect void Spell::SpellTargetAoE(uint32 i, uint32 j) // something special // grep: this is *totally* broken. AoE only attacking friendly party members and self // is NOT correct. // not correct at all:P { FillAllTargetsInArea(i,m_caster->GetPositionX(),m_caster->GetPositionY(),m_caster->GetPositionZ(),GetRadius(i)); }
/// Spell Target Handling for type 8: related to Chess Move (DND), Firecrackers, Spotlight, aedm, Spice Mortar /// Seems to be some kind of custom area of effect... Scripted... or something like that void Spell::SpellTargetCustomAreaOfEffect(uint32 i, uint32 j) { // This should be good enough for now FillAllTargetsInArea(i,m_targets.m_destX,m_targets.m_destY,m_targets.m_destZ,GetRadius(i)); }
/// Spell Target Handling for type 15 / 16: All Enemies in Area of Effect (instant) void Spell::SpellTargetAreaOfEffect(uint32 i, uint32 j) { FillAllTargetsInArea(i,m_targets.m_destX,m_targets.m_destY,m_targets.m_destZ,GetDBCCastTime(i)); }