Changeset 108

Show
Ignore:
Timestamp:
11/19/08 13:36:37 (17 years ago)
Author:
yumileroy
Message:

[svn] Continue the work of rewriting spell target selection functions (warning: this may cause some spells broken).
Add some spell_script_target.
Delete some workaround in scripts (since core provides spell support now).

Original author: megamage
Date: 2008-10-25 10:37:28-05:00

Location:
trunk
Files:
1 added
6 modified

Legend:

Unmodified
Added
Removed
  • trunk/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp

    r106 r108  
    9797//Phase Normal spells 
    9898#define SPELL_FLAME_CRASH_EFFECT        40836 // Firey blue ring of circle that the other flame crash summons 
     99#define SPELL_SUMMON_SHADOWDEMON        41117 // Summon four shadowfiends 
    99100#define SPELL_SHADOWFIEND_PASSIVE       41913 // Passive aura for shadowfiends 
    100101#define SPELL_SHADOW_DEMON_PASSIVE      41079 // Adds the "shadowform" aura to Shadow Demons. 
     
    386387    void Reset(); 
    387388 
    388     void JustSummoned(Creature* summon)//, TempSummonType type) 
    389     { 
    390         if(summon->GetCreatureInfo()->Entry == FLAME_CRASH) 
    391         { 
    392         //    type = TEMPSUMMON_TIMED_DESPAWN; 
    393         } 
    394         //error_log("justsummoned %d %d", summon->GetCreatureInfo()->Entry, summon->GetGUID()); 
     389    void JustSummoned(Creature* summon) 
     390    { 
     391        if(summon->GetCreatureInfo()->Entry == SHADOW_DEMON) 
     392        { 
     393            Unit *target = SelectUnit(SELECT_TARGET_RANDOM, 0); 
     394            if(target && target->GetTypeId() == TYPEID_PLAYER) // only on players. 
     395            { 
     396                summon->AddThreat(target, 5000000.0f); 
     397                summon->AI()->AttackStart(target); 
     398            } 
     399            DoZoneInCombat(summon); 
     400        } 
    395401    } 
    396402 
     
    559565    void SummonFlamesOfAzzinoth(); 
    560566    void SummonMaiev(); 
    561     void SummonShadowDemon() 
    562     { 
    563         Creature* ShadowDemon = NULL; 
    564         Unit* target = NULL; 
    565         for(uint8 i = 0; i < 4; i++) 
    566         { 
    567             ShadowDemon = DoSpawnCreature(SHADOW_DEMON, 0,0,0,0,TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN,25000); 
    568             if(ShadowDemon) 
    569             { 
    570                 target = SelectUnit(SELECT_TARGET_RANDOM, 0); 
    571                 if(target && target->GetTypeId() == TYPEID_PLAYER) // only on players. 
    572                 { 
    573                     ShadowDemon->AddThreat(target, 5000000.0f); 
    574                     ShadowDemon->AI()->AttackStart(target); 
    575                 } 
    576                 DoZoneInCombat(ShadowDemon); 
    577             } 
    578         } 
    579     } 
    580567    void HandleTalkSequence(); 
    581568    void HandleFlightSequence() 
     
    944931                        break; 
    945932                    case EVENT_SHADOWDEMON: 
    946                         SummonShadowDemon(); 
     933                        DoCast(m_creature, SPELL_SUMMON_SHADOWDEMON); 
    947934                        Timer[EVENT_SHADOWDEMON] = 0; 
    948935                        Timer[EVENT_FLAME_BURST] += 10000; 
  • trunk/src/bindings/scripts/scripts/zone/black_temple/illidari_council.cpp

    r90 r108  
    696696        if(CircleOfHealingTimer < diff) 
    697697        { 
    698             //Currently bugged and puts Malande on the threatlist of the other council members. It also heals players. 
    699             //DoCast(m_creature, SPELL_CIRCLE_OF_HEALING); 
     698            DoCast(m_creature, SPELL_CIRCLE_OF_HEALING); 
    700699            CircleOfHealingTimer = 60000; 
    701700        }else CircleOfHealingTimer -= diff; 
  • trunk/src/game/SharedDefines.h

    r102 r108  
    808808    //TARGET_UNIT_CONE_ENEMY 
    809809    TARGET_DUELVSPLAYER                = 25, 
    810     //TARGET_UNIT_SINGLE 
     810    //TARGET_UNIT_TARGET 
    811811    TARGET_GAMEOBJECT_ITEM             = 26, 
    812812    //TARGET_OBJECT_ITEM_PICKLOCK 
     
    843843    //TARGET_UNIT_CHAINHEAL 
    844844    TARGET_SCRIPT_COORDINATES          = 46, 
    845     //TARGET_DEST_TABLE_UNKNOWN 
     845    //TARGET_DEST_NEARBY_ENTRY 
    846846    TARGET_DEST_CASTER_FRONT           = 47, 
    847847    TARGET_DEST_CASTER_BACK            = 48, 
  • trunk/src/game/Spell.cpp

    r102 r108  
    393393            continue; 
    394394 
    395         // targets for TARGET_SCRIPT_COORDINATES (A) and TARGET_SCRIPT  filled in Spell::canCast call 
    396         if( m_spellInfo->EffectImplicitTargetA[i] == TARGET_SCRIPT_COORDINATES || 
    397             m_spellInfo->EffectImplicitTargetA[i] == TARGET_SCRIPT || 
    398             m_spellInfo->EffectImplicitTargetB[i] == TARGET_SCRIPT && m_spellInfo->EffectImplicitTargetA[i] != TARGET_SELF ) 
    399             continue; 
    400  
    401395        // TODO: find a way so this is not needed? 
    402396        // for area auras always add caster as target (needed for totems for example) 
     
    406400        std::list<Unit*> tmpUnitMap; 
    407401 
    408         // TargetA/TargetB dependent from each other, we not switch to full support this dependences 
    409         // but need it support in some know cases 
    410         switch(m_spellInfo->EffectImplicitTargetA[i]) 
    411         { 
    412             case TARGET_ALL_AROUND_CASTER: 
    413                 if( m_spellInfo->EffectImplicitTargetB[i]==TARGET_ALL_PARTY || 
    414                     m_spellInfo->EffectImplicitTargetB[i]==TARGET_ALL_FRIENDLY_UNITS_AROUND_CASTER || 
    415                     m_spellInfo->EffectImplicitTargetB[i]==TARGET_RANDOM_RAID_MEMBER ) 
    416                 { 
    417                     SetTargetMap(i,m_spellInfo->EffectImplicitTargetB[i],tmpUnitMap); 
    418                 } 
    419                 // Note: this hack with search required until GO casting not implemented 
    420                 // environment damage spells already have around enemies targeting but this not help in case not existed GO casting support 
    421                 // currently each enemy selected explicitly and self cast damage 
    422                 else if(m_spellInfo->EffectImplicitTargetB[i]==TARGET_ALL_ENEMY_IN_AREA && m_spellInfo->Effect[i]==SPELL_EFFECT_ENVIRONMENTAL_DAMAGE) 
    423                 { 
    424                     if(m_targets.getUnitTarget()) 
    425                         tmpUnitMap.push_back(m_targets.getUnitTarget()); 
    426                 } 
    427                 else 
    428                 { 
    429                     SetTargetMap(i,m_spellInfo->EffectImplicitTargetA[i],tmpUnitMap); 
    430                     SetTargetMap(i,m_spellInfo->EffectImplicitTargetB[i],tmpUnitMap); 
    431                 } 
    432                 break; 
    433             case TARGET_TABLE_X_Y_Z_COORDINATES: 
    434                 // Only if target A, for target B (used in teleports) dest select in effect 
    435                 SetTargetMap(i,m_spellInfo->EffectImplicitTargetA[i],tmpUnitMap); 
    436                 break; 
    437             default: 
    438                 switch(m_spellInfo->EffectImplicitTargetB[i]) 
    439                 { 
    440                     case TARGET_SCRIPT_COORDINATES:         // B case filled in canCast but we need fill unit list base at A case 
    441                         SetTargetMap(i,m_spellInfo->EffectImplicitTargetA[i],tmpUnitMap); 
    442                         break; 
    443                     default: 
    444                         SetTargetMap(i,m_spellInfo->EffectImplicitTargetA[i],tmpUnitMap); 
    445                         SetTargetMap(i,m_spellInfo->EffectImplicitTargetB[i],tmpUnitMap); 
    446                         break; 
    447                 } 
    448                 break; 
    449         } 
    450  
    451         if( (m_spellInfo->EffectImplicitTargetA[i]==0 || m_spellInfo->EffectImplicitTargetA[i]==TARGET_EFFECT_SELECT) && 
    452             (m_spellInfo->EffectImplicitTargetB[i]==0 || m_spellInfo->EffectImplicitTargetB[i]==TARGET_EFFECT_SELECT) ) 
    453         { 
     402        // Note: this hack with search required until GO casting not implemented 
     403        // environment damage spells already have around enemies targeting but this not help in case not existed GO casting support 
     404        // currently each enemy selected explicitly and self cast damage 
     405        if(m_spellInfo->EffectImplicitTargetA[i] == TARGET_ALL_AROUND_CASTER 
     406            && m_spellInfo->EffectImplicitTargetB[i]==TARGET_ALL_ENEMY_IN_AREA  
     407            && m_spellInfo->Effect[i]==SPELL_EFFECT_ENVIRONMENTAL_DAMAGE) 
     408        { 
     409            tmpUnitMap.push_back(m_targets.getUnitTarget()); 
     410        } 
     411        else 
     412        { 
     413            SetTargetMap(i,m_spellInfo->EffectImplicitTargetA[i],tmpUnitMap); 
     414            SetTargetMap(i,m_spellInfo->EffectImplicitTargetB[i],tmpUnitMap); 
     415        } 
     416 
     417        if(tmpUnitMap.empty()) 
     418        { 
     419            if( m_spellInfo->EffectImplicitTargetA[i]==TARGET_SCRIPT || 
     420                m_spellInfo->EffectImplicitTargetB[i]==TARGET_SCRIPT || 
     421                m_spellInfo->EffectImplicitTargetA[i]==TARGET_SCRIPT_COORDINATES || 
     422                m_spellInfo->EffectImplicitTargetB[i]==TARGET_SCRIPT_COORDINATES ) 
     423            { 
     424                if(!(m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION)) 
     425                    continue; 
     426            } 
    454427            // add here custom effects that need default target. 
    455428            // FOR EVERY TARGET TYPE THERE IS A DIFFERENT FILL!! 
     
    11671140}; 
    11681141 
     1142void Spell::SearchChainTarget(std::list<Unit*> &TagUnitMap, Unit* pUnitTarget, float max_range, uint32 unMaxTargets) 
     1143{ 
     1144    if(!pUnitTarget) 
     1145        return; 
     1146 
     1147    //FIXME: This very like horrible hack and wrong for most spells 
     1148    if(m_spellInfo->DmgClass != SPELL_DAMAGE_CLASS_MELEE) 
     1149        max_range += unMaxTargets * CHAIN_SPELL_JUMP_RADIUS; 
     1150 
     1151    CellPair p(Trinity::ComputeCellPair(m_caster->GetPositionX(), m_caster->GetPositionY())); 
     1152    Cell cell(p); 
     1153    cell.data.Part.reserved = ALL_DISTRICT; 
     1154    cell.SetNoCreate(); 
     1155 
     1156    std::list<Unit *> tempUnitMap; 
     1157 
     1158    { 
     1159        Trinity::AnyAoETargetUnitInObjectRangeCheck u_check(pUnitTarget, m_caster, max_range); 
     1160        Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck> searcher(tempUnitMap, u_check); 
     1161 
     1162        TypeContainerVisitor<Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck>, WorldTypeMapContainer > world_unit_searcher(searcher); 
     1163        TypeContainerVisitor<Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck>, GridTypeMapContainer >  grid_unit_searcher(searcher); 
     1164 
     1165        CellLock<GridReadGuard> cell_lock(cell, p); 
     1166        cell_lock->Visit(cell_lock, world_unit_searcher, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); 
     1167        cell_lock->Visit(cell_lock, grid_unit_searcher, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); 
     1168    } 
     1169 
     1170    tempUnitMap.sort(TargetDistanceOrder(pUnitTarget)); 
     1171 
     1172    if(tempUnitMap.empty()) 
     1173        return; 
     1174 
     1175    uint32 t = unMaxTargets; 
     1176    if(pUnitTarget != m_caster) 
     1177    { 
     1178        if(*tempUnitMap.begin() == pUnitTarget) 
     1179            tempUnitMap.erase(tempUnitMap.begin()); 
     1180        TagUnitMap.push_back(pUnitTarget); 
     1181        --t; 
     1182    } 
     1183    Unit *prev = pUnitTarget; 
     1184 
     1185    std::list<Unit*>::iterator next = tempUnitMap.begin(); 
     1186 
     1187    while(t && next != tempUnitMap.end()) 
     1188    { 
     1189        if(prev->GetDistance(*next) > CHAIN_SPELL_JUMP_RADIUS) 
     1190            break; 
     1191 
     1192        if(!prev->IsWithinLOSInMap(*next) 
     1193            || m_spellInfo->DmgClass==SPELL_DAMAGE_CLASS_MELEE && !m_caster->isInFront(*next, max_range)) 
     1194        { 
     1195            ++next; 
     1196            continue; 
     1197        } 
     1198 
     1199        prev = *next; 
     1200        TagUnitMap.push_back(prev); 
     1201        tempUnitMap.erase(next); 
     1202        tempUnitMap.sort(TargetDistanceOrder(prev)); 
     1203        next = tempUnitMap.begin(); 
     1204        --t; 
     1205    } 
     1206} 
     1207 
     1208void Spell::SearchAreaTarget(std::list<Unit*> &TagUnitMap, float radius, const uint32 &type, SpellTargets TargetType, uint32 entry) 
     1209{ 
     1210    if(type == PUSH_DEST_CENTER && !m_targets.m_destX && !m_targets.m_destY && !m_targets.m_destZ) 
     1211    { 
     1212        sLog.outError( "SPELL: cannot find destination for spell ID %u\n", m_spellInfo->Id ); 
     1213        return; 
     1214    } 
     1215 
     1216    CellPair p(Trinity::ComputeCellPair(m_targets.m_destX, m_targets.m_destY)); 
     1217    Cell cell(p); 
     1218    cell.data.Part.reserved = ALL_DISTRICT; 
     1219    cell.SetNoCreate(); 
     1220    CellLock<GridReadGuard> cell_lock(cell, p); 
     1221 
     1222    Trinity::SpellNotifierCreatureAndPlayer notifier(*this, TagUnitMap, radius, type, TargetType, entry); 
     1223     
     1224    if(TargetType != SPELL_TARGETS_ENTRY) 
     1225    { 
     1226        TypeContainerVisitor<Trinity::SpellNotifierCreatureAndPlayer, WorldTypeMapContainer > world_object_notifier(notifier); 
     1227        cell_lock->Visit(cell_lock, world_object_notifier, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); 
     1228    } 
     1229    TypeContainerVisitor<Trinity::SpellNotifierCreatureAndPlayer, GridTypeMapContainer >  grid_object_notifier(notifier); 
     1230    cell_lock->Visit(cell_lock, grid_object_notifier, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); 
     1231} 
     1232 
     1233Unit* Spell::SearchNearbyTarget(float radius, SpellTargets TargetType, uint32 entry) 
     1234{ 
     1235    CellPair p(Trinity::ComputeCellPair(m_caster->GetPositionX(), m_caster->GetPositionY())); 
     1236    Cell cell(p); 
     1237    cell.data.Part.reserved = ALL_DISTRICT; 
     1238    cell.SetNoCreate(); 
     1239    CellLock<GridReadGuard> cell_lock(cell, p); 
     1240 
     1241    Unit* target = NULL; 
     1242    switch(TargetType) 
     1243    { 
     1244        case SPELL_TARGETS_ENTRY: 
     1245        { 
     1246            Creature* target = NULL; 
     1247            Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck u_check(*m_caster, entry, true, radius); 
     1248            Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(target, u_check); 
     1249            TypeContainerVisitor<Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck>, GridTypeMapContainer >  grid_unit_searcher(searcher); 
     1250            cell_lock->Visit(cell_lock, grid_unit_searcher, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); 
     1251            return target; 
     1252        }break; 
     1253        default: 
     1254        case SPELL_TARGETS_AOE_DAMAGE: 
     1255        { 
     1256            Trinity::AnyUnfriendlyUnitInObjectRangeCheck u_check(m_caster, m_caster, radius); 
     1257            Trinity::UnitLastSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck> searcher(target, u_check); 
     1258            TypeContainerVisitor<Trinity::UnitLastSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck>, WorldTypeMapContainer > world_unit_searcher(searcher); 
     1259            TypeContainerVisitor<Trinity::UnitLastSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck>, GridTypeMapContainer >  grid_unit_searcher(searcher); 
     1260            cell_lock->Visit(cell_lock, world_unit_searcher, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); 
     1261            cell_lock->Visit(cell_lock, grid_unit_searcher, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); 
     1262        }break; 
     1263        case SPELL_TARGETS_FRIENDLY: 
     1264        { 
     1265            Trinity::AnyFriendlyUnitInObjectRangeCheck u_check(m_caster, m_caster, radius); 
     1266            Trinity::UnitLastSearcher<Trinity::AnyFriendlyUnitInObjectRangeCheck> searcher(target, u_check); 
     1267            TypeContainerVisitor<Trinity::UnitLastSearcher<Trinity::AnyFriendlyUnitInObjectRangeCheck>, WorldTypeMapContainer > world_unit_searcher(searcher); 
     1268            TypeContainerVisitor<Trinity::UnitLastSearcher<Trinity::AnyFriendlyUnitInObjectRangeCheck>, GridTypeMapContainer >  grid_unit_searcher(searcher); 
     1269            cell_lock->Visit(cell_lock, world_unit_searcher, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); 
     1270            cell_lock->Visit(cell_lock, grid_unit_searcher, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); 
     1271        }break; 
     1272    } 
     1273    return target; 
     1274} 
     1275 
    11691276void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap) 
    11701277{ 
     
    11871294    switch(cur) 
    11881295    { 
    1189         // destination around caster 
    1190         case TARGET_DEST_CASTER_FRONT_LEFT: 
    1191         case TARGET_DEST_CASTER_BACK_LEFT: 
    1192         case TARGET_DEST_CASTER_BACK_RIGHT: 
    1193         case TARGET_DEST_CASTER_FRONT_RIGHT: 
    1194         case TARGET_DEST_CASTER_FRONT: 
    1195         case TARGET_DEST_CASTER_BACK: 
    1196         case TARGET_DEST_CASTER_RIGHT: 
    1197         case TARGET_DEST_CASTER_LEFT: 
    1198         case TARGET_DEST_CASTER_RANDOM: 
    1199         case TARGET_DEST_CASTER_RADIUS: 
    1200         { 
    1201             float x, y, z, angle, dist; 
    1202  
    1203             if (m_spellInfo->EffectRadiusIndex[i]) 
    1204                 dist = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); 
    1205             else 
    1206                 dist = 3.0f;//do we need this? 
    1207             if (cur == TARGET_DEST_CASTER_RANDOM) 
    1208                 dist *= rand_norm(); // This case we need to consider caster size 
    1209             else 
    1210                 dist -= m_caster->GetObjectSize(); // Size is calculated in GetNearPoint(), but we do not need it  
    1211             //need a new function to remove this repeated work 
    1212  
    1213             switch(cur) 
    1214             { 
    1215                 case TARGET_DEST_CASTER_FRONT_LEFT: angle = -M_PI/4;    break; 
    1216                 case TARGET_DEST_CASTER_BACK_LEFT:  angle = -3*M_PI/4;  break; 
    1217                 case TARGET_DEST_CASTER_BACK_RIGHT: angle = 3*M_PI/4;   break; 
    1218                 case TARGET_DEST_CASTER_FRONT_RIGHT:angle = M_PI/4;     break; 
    1219                 case TARGET_DEST_CASTER_FRONT:      angle = 0.0f;       break; 
    1220                 case TARGET_DEST_CASTER_BACK:       angle = M_PI;       break; 
    1221                 case TARGET_DEST_CASTER_RIGHT:      angle = M_PI/2;     break; 
    1222                 case TARGET_DEST_CASTER_LEFT:       angle = -M_PI/2;    break; 
    1223                 default:                            angle = rand_norm()*2*M_PI; break; 
    1224             } 
    1225  
    1226             m_caster->GetClosePoint(x, y, z, 0, dist, angle); 
    1227             m_targets.setDestination(x, y, z); // do not know if has ground visual 
    1228             TagUnitMap.push_back(m_caster); // may remove this in the future, if unitmap is empty, push m_caster 
    1229         }break; 
    1230  
    1231         // destination around target 
    1232         case TARGET_DEST_TARGET_FRONT: 
    1233         case TARGET_DEST_TARGET_BACK: 
    1234         case TARGET_DEST_TARGET_RIGHT: 
    1235         case TARGET_DEST_TARGET_LEFT: 
    1236         case TARGET_DEST_TARGET_RANDOM: 
    1237         case TARGET_DEST_TARGET_RADIUS: 
    1238         { 
    1239             Unit *target = m_targets.getUnitTarget(); 
    1240             if(!target) 
    1241             { 
    1242                 sLog.outError("SPELL: no unit target for spell ID %u\n", m_spellInfo->Id); 
    1243                 break; 
    1244             } 
    1245  
    1246             float x, y, z, angle, dist; 
    1247  
    1248             if (m_spellInfo->EffectRadiusIndex[i]) 
    1249                 dist = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); 
    1250             else 
    1251                 dist = 3.0f;//do we need this? 
    1252             if (cur == TARGET_DEST_TARGET_RANDOM) 
    1253                 dist *= rand_norm(); // This case we need to consider caster size 
    1254             else 
    1255                 dist -= target->GetObjectSize(); // Size is calculated in GetNearPoint(), but we do not need it  
    1256             //need a new function to remove this repeated work 
    1257  
    1258             switch(cur) 
    1259             { 
    1260                 case TARGET_DEST_TARGET_FRONT:      angle = 0.0f;       break; 
    1261                 case TARGET_DEST_TARGET_BACK:       angle = M_PI;       break; 
    1262                 case TARGET_DEST_TARGET_RIGHT:      angle = M_PI/2;     break; 
    1263                 case TARGET_DEST_TARGET_LEFT:       angle = -M_PI/2;    break; 
    1264                 default:                            angle = rand_norm()*2*M_PI; break; 
    1265             } 
    1266  
    1267             target->GetClosePoint(x, y, z, 0, dist, angle); 
    1268             m_targets.setDestination(x, y, z); // do not know if has ground visual 
    1269             TagUnitMap.push_back(m_caster); // may remove this in the future, if unitmap is empty, push m_caster 
    1270         }break; 
    1271  
    1272         // destination around destination 
    1273         case TARGET_DEST_DEST_RANDOM: 
    1274         { 
    1275             if(!(m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION)) 
    1276             { 
    1277                 sLog.outError("SPELL: no destination for spell ID %u\n", m_spellInfo->Id); 
    1278                 break; 
    1279             } 
    1280             float x, y, z, dist, px, py, pz; 
    1281             dist = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); 
    1282             x = m_targets.m_destX; 
    1283             y = m_targets.m_destY; 
    1284             z = m_targets.m_destZ; 
    1285             m_caster->GetRandomPoint(x, y, z, dist, px, py, pz); 
    1286             m_targets.setDestination(px, py, pz); 
     1296        // specific unit 
     1297        case TARGET_SELF: 
     1298        case TARGET_SELF_FISHING: 
     1299        { 
    12871300            TagUnitMap.push_back(m_caster); 
    12881301        }break; 
    1289         case TARGET_SELF2: 
    1290         { 
    1291             TagUnitMap.push_back(m_caster); 
     1302        case TARGET_MASTER: 
     1303        { 
     1304            if(Unit* owner = m_caster->GetCharmerOrOwner()) 
     1305                TagUnitMap.push_back(owner); 
    12921306        }break; 
    1293  
    1294         case TARGET_SELF: 
     1307        case TARGET_PET: 
     1308        { 
     1309            if(Pet* tmpUnit = m_caster->GetPet()) 
     1310                TagUnitMap.push_back(tmpUnit); 
     1311        }break; 
     1312        case TARGET_NONCOMBAT_PET: 
     1313        { 
     1314            if(Unit* target = m_targets.getUnitTarget()) 
     1315                if( target->GetTypeId() == TYPEID_UNIT && ((Creature*)target)->isPet() && ((Pet*)target)->getPetType() == MINI_PET) 
     1316                    TagUnitMap.push_back(target); 
     1317        }break; 
     1318        case TARGET_SINGLE_FRIEND: // ally 
     1319        case TARGET_SINGLE_FRIEND_2: // raid member 
     1320        case TARGET_DUELVSPLAYER: // all (SelectMagnetTarget()?) 
     1321        case TARGET_UNIT_SINGLE_UNKNOWN: 
     1322        { 
     1323            if(m_targets.getUnitTarget()) 
     1324                TagUnitMap.push_back(m_targets.getUnitTarget()); 
     1325        }break; 
     1326        case TARGET_CHAIN_DAMAGE: 
     1327        { 
     1328            if(Unit* pUnitTarget = SelectMagnetTarget()) 
     1329            { 
     1330                if(EffectChainTarget <= 1) 
     1331                    TagUnitMap.push_back(pUnitTarget); 
     1332                else //TODO: chain target should also use magnet target 
     1333                    SearchChainTarget(TagUnitMap, pUnitTarget, radius, EffectChainTarget); 
     1334            } 
     1335        }break; 
     1336        case TARGET_GAMEOBJECT: 
     1337        { 
     1338            if(m_targets.getGOTarget()) 
     1339                AddGOTarget(m_targets.getGOTarget(), i); 
     1340        }break; 
     1341        case TARGET_GAMEOBJECT_ITEM: 
     1342        { 
     1343            if(m_targets.getGOTargetGUID()) 
     1344                AddGOTarget(m_targets.getGOTarget(), i); 
     1345            else if(m_targets.getItemTarget()) 
     1346                AddItemTarget(m_targets.getItemTarget(), i); 
     1347        }break; 
     1348 
     1349        // reference dest 
     1350        case TARGET_EFFECT_SELECT: 
     1351            m_targets.m_targetMask |= TARGET_FLAG_DEST_LOCATION; 
     1352        case TARGET_ALL_AROUND_CASTER: 
     1353        { 
     1354            m_caster->GetPosition(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ); 
     1355        }break; 
     1356        case TARGET_CURRENT_ENEMY_COORDINATES: 
     1357            m_targets.m_targetMask |= TARGET_FLAG_DEST_LOCATION; 
     1358        case TARGET_DUELVSPLAYER_COORDINATES: // no ground? 
     1359        { 
     1360            if(Unit* currentTarget = m_targets.getUnitTarget()) 
     1361                currentTarget->GetPosition(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ); 
     1362        }break; 
     1363        case TARGET_DEST_TABLE_UNKNOWN2: 
     1364        case TARGET_TABLE_X_Y_Z_COORDINATES: 
     1365        { 
     1366            SpellTargetPosition const* st = spellmgr.GetSpellTargetPosition(m_spellInfo->Id); 
     1367            if(st) 
     1368            { 
     1369                if (st->target_mapId == m_caster->GetMapId()) 
     1370                    m_targets.setDestination(st->target_X, st->target_Y, st->target_Z); 
     1371            } 
     1372            else 
     1373                sLog.outError( "SPELL: unknown target coordinates for spell ID %u\n", m_spellInfo->Id ); 
     1374        }break; 
     1375 
     1376        // area targets 
     1377        case TARGET_ALL_ENEMY_IN_AREA_INSTANT: 
     1378        { 
     1379            if(m_spellInfo->Effect[i] == SPELL_EFFECT_PERSISTENT_AREA_AURA) 
     1380                break; 
     1381            m_targets.m_targetMask |= TARGET_FLAG_DEST_LOCATION; 
     1382        } 
     1383        case TARGET_ALL_ENEMY_IN_AREA: 
     1384        { 
     1385            SearchAreaTarget(TagUnitMap, radius, PUSH_DEST_CENTER, SPELL_TARGETS_AOE_DAMAGE); 
     1386        }break; 
     1387        case TARGET_ALL_FRIENDLY_UNITS_IN_AREA: 
     1388            m_targets.m_targetMask |= TARGET_FLAG_DEST_LOCATION; 
     1389        case TARGET_ALL_FRIENDLY_UNITS_AROUND_CASTER: 
     1390        { 
     1391            SearchAreaTarget(TagUnitMap, radius, PUSH_DEST_CENTER, SPELL_TARGETS_FRIENDLY); 
     1392        }break; 
    12951393        case TARGET_AREAEFFECT_CUSTOM: 
     1394            m_targets.m_targetMask |= TARGET_FLAG_DEST_LOCATION; 
     1395        case TARGET_UNIT_AREA_ENTRY: 
     1396        { 
     1397            SpellScriptTarget::const_iterator lower = spellmgr.GetBeginSpellScriptTarget(m_spellInfo->Id); 
     1398            SpellScriptTarget::const_iterator upper = spellmgr.GetEndSpellScriptTarget(m_spellInfo->Id); 
     1399            if(lower==upper) 
     1400            { 
     1401                sLog.outErrorDb("Spell (ID: %u) has effect EffectImplicitTargetA/EffectImplicitTargetB = TARGET_SCRIPT, but does not have record in `spell_script_target`",m_spellInfo->Id); 
     1402                break; 
     1403            } 
     1404            // let it be done in one check? 
     1405            for(SpellScriptTarget::const_iterator i_spellST = lower; i_spellST != upper; ++i_spellST) 
     1406            { 
     1407                if(i_spellST->second.type != SPELL_TARGET_TYPE_CREATURE) 
     1408                { 
     1409                    sLog.outError( "SPELL: spell ID %u requires non-creature target\n", m_spellInfo->Id ); 
     1410                    continue; 
     1411                } 
     1412                SearchAreaTarget(TagUnitMap, radius, PUSH_DEST_CENTER, SPELL_TARGETS_ENTRY, i_spellST->second.targetEntry); 
     1413            } 
     1414        }break; 
     1415        case TARGET_IN_FRONT_OF_CASTER: 
     1416        { 
     1417            bool inFront = m_spellInfo->SpellVisual != 3879; 
     1418            SearchAreaTarget(TagUnitMap, radius, inFront ? PUSH_IN_FRONT : PUSH_IN_BACK,SPELL_TARGETS_AOE_DAMAGE); 
     1419        }break; 
     1420 
     1421        // nearby target 
     1422        case TARGET_UNIT_NEARBY_ALLY: 
     1423        { 
     1424            if(Unit* pUnitTarget = SearchNearbyTarget(radius, SPELL_TARGETS_FRIENDLY)) 
     1425                TagUnitMap.push_back(pUnitTarget); 
     1426        }break; 
     1427        case TARGET_RANDOM_ENEMY_CHAIN_IN_AREA: 
     1428        { 
     1429            if(EffectChainTarget <= 1) 
     1430            { 
     1431                if(Unit* pUnitTarget = SearchNearbyTarget(radius, SPELL_TARGETS_AOE_DAMAGE)) 
     1432                    TagUnitMap.push_back(pUnitTarget); 
     1433            } 
     1434            else 
     1435                SearchChainTarget(TagUnitMap, m_caster, radius, EffectChainTarget); 
     1436        }break; 
     1437        case TARGET_SCRIPT: 
     1438        case TARGET_SCRIPT_COORDINATES: 
     1439        { 
     1440            SpellScriptTarget::const_iterator lower = spellmgr.GetBeginSpellScriptTarget(m_spellInfo->Id); 
     1441            SpellScriptTarget::const_iterator upper = spellmgr.GetEndSpellScriptTarget(m_spellInfo->Id); 
     1442            if(lower==upper) 
     1443                sLog.outErrorDb("Spell (ID: %u) has effect EffectImplicitTargetA/EffectImplicitTargetB = TARGET_SCRIPT or TARGET_SCRIPT_COORDINATES, but does not have record in `spell_script_target`",m_spellInfo->Id); 
     1444 
     1445            SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex); 
     1446            float range = GetSpellMaxRange(srange); 
     1447 
     1448            Creature* creatureScriptTarget = NULL; 
     1449            GameObject* goScriptTarget = NULL; 
     1450 
     1451            for(SpellScriptTarget::const_iterator i_spellST = lower; i_spellST != upper; ++i_spellST) 
     1452            { 
     1453                switch(i_spellST->second.type) 
     1454                { 
     1455                case SPELL_TARGET_TYPE_GAMEOBJECT: 
     1456                    { 
     1457                        GameObject* p_GameObject = NULL; 
     1458 
     1459                        if(i_spellST->second.targetEntry) 
     1460                        { 
     1461                            CellPair p(Trinity::ComputeCellPair(m_caster->GetPositionX(), m_caster->GetPositionY())); 
     1462                            Cell cell(p); 
     1463                            cell.data.Part.reserved = ALL_DISTRICT; 
     1464 
     1465                            Trinity::NearestGameObjectEntryInObjectRangeCheck go_check(*m_caster,i_spellST->second.targetEntry,range); 
     1466                            Trinity::GameObjectLastSearcher<Trinity::NearestGameObjectEntryInObjectRangeCheck> checker(p_GameObject,go_check); 
     1467 
     1468                            TypeContainerVisitor<Trinity::GameObjectLastSearcher<Trinity::NearestGameObjectEntryInObjectRangeCheck>, GridTypeMapContainer > object_checker(checker); 
     1469                            CellLock<GridReadGuard> cell_lock(cell, p); 
     1470                            cell_lock->Visit(cell_lock, object_checker, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); 
     1471 
     1472                            if(p_GameObject) 
     1473                            { 
     1474                                // remember found target and range, next attempt will find more near target with another entry 
     1475                                creatureScriptTarget = NULL; 
     1476                                goScriptTarget = p_GameObject; 
     1477                                range = go_check.GetLastRange(); 
     1478                            } 
     1479                        } 
     1480                        else if( focusObject )          //Focus Object 
     1481                        { 
     1482                            float frange = m_caster->GetDistance(focusObject); 
     1483                            if(range >= frange) 
     1484                            { 
     1485                                creatureScriptTarget = NULL; 
     1486                                goScriptTarget = focusObject; 
     1487                                range = frange; 
     1488                            } 
     1489                        } 
     1490                        break; 
     1491                    } 
     1492                case SPELL_TARGET_TYPE_CREATURE: 
     1493                case SPELL_TARGET_TYPE_DEAD: 
     1494                default: 
     1495                    { 
     1496                        Creature *p_Creature = NULL; 
     1497 
     1498                        CellPair p(Trinity::ComputeCellPair(m_caster->GetPositionX(), m_caster->GetPositionY())); 
     1499                        Cell cell(p); 
     1500                        cell.data.Part.reserved = ALL_DISTRICT; 
     1501                        cell.SetNoCreate();             // Really don't know what is that??? 
     1502 
     1503                        Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck u_check(*m_caster,i_spellST->second.targetEntry,i_spellST->second.type!=SPELL_TARGET_TYPE_DEAD,range); 
     1504                        Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(p_Creature, u_check); 
     1505 
     1506                        TypeContainerVisitor<Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck>, GridTypeMapContainer >  grid_creature_searcher(searcher); 
     1507 
     1508                        CellLock<GridReadGuard> cell_lock(cell, p); 
     1509                        cell_lock->Visit(cell_lock, grid_creature_searcher, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); 
     1510 
     1511                        if(p_Creature ) 
     1512                        { 
     1513                            creatureScriptTarget = p_Creature; 
     1514                            goScriptTarget = NULL; 
     1515                            range = u_check.GetLastRange(); 
     1516                        } 
     1517                        break; 
     1518                    } 
     1519                } 
     1520            } 
     1521 
     1522            if(cur == TARGET_SCRIPT_COORDINATES) 
     1523            { 
     1524                if(creatureScriptTarget) 
     1525                    m_targets.setDestination(creatureScriptTarget->GetPositionX(),creatureScriptTarget->GetPositionY(),creatureScriptTarget->GetPositionZ()); 
     1526                else if(goScriptTarget) 
     1527                    m_targets.setDestination(goScriptTarget->GetPositionX(),goScriptTarget->GetPositionY(),goScriptTarget->GetPositionZ()); 
     1528            } 
     1529        }break; 
     1530 
     1531 
     1532        // dummy 
    12961533        case TARGET_AREAEFFECT_CUSTOM_2: 
    12971534        { 
     
    12991536            break; 
    13001537        } 
    1301         case TARGET_RANDOM_ENEMY_CHAIN_IN_AREA: 
    1302         { 
    1303             m_targets.m_targetMask = 0; 
    1304             unMaxTargets = EffectChainTarget; 
    1305             float max_range = radius + unMaxTargets * CHAIN_SPELL_JUMP_RADIUS; 
    1306  
    1307             CellPair p(Trinity::ComputeCellPair(m_caster->GetPositionX(), m_caster->GetPositionY())); 
    1308             Cell cell(p); 
    1309             cell.data.Part.reserved = ALL_DISTRICT; 
    1310             cell.SetNoCreate(); 
    1311  
    1312             std::list<Unit *> tempUnitMap; 
    1313  
    1314             { 
    1315                 Trinity::AnyAoETargetUnitInObjectRangeCheck u_check(m_caster, m_caster, max_range); 
    1316                 Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck> searcher(tempUnitMap, u_check); 
    1317  
    1318                 TypeContainerVisitor<Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck>, WorldTypeMapContainer > world_unit_searcher(searcher); 
    1319                 TypeContainerVisitor<Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck>, GridTypeMapContainer >  grid_unit_searcher(searcher); 
    1320  
    1321                 CellLock<GridReadGuard> cell_lock(cell, p); 
    1322                 cell_lock->Visit(cell_lock, world_unit_searcher, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); 
    1323                 cell_lock->Visit(cell_lock, grid_unit_searcher, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); 
    1324             } 
    1325  
    1326             if(tempUnitMap.empty()) 
    1327                 break; 
    1328  
    1329             tempUnitMap.sort(TargetDistanceOrder(m_caster)); 
    1330  
    1331             //Now to get us a random target that's in the initial range of the spell 
    1332             uint32 t = 0; 
    1333             std::list<Unit *>::iterator itr = tempUnitMap.begin(); 
    1334             while(itr!= tempUnitMap.end() && (*itr)->GetDistance(m_caster) < radius) 
    1335                 ++t, ++itr; 
    1336  
    1337             if(!t) 
    1338                 break; 
    1339  
    1340             itr = tempUnitMap.begin(); 
    1341             std::advance(itr, rand()%t); 
    1342             Unit *pUnitTarget = *itr; 
    1343             TagUnitMap.push_back(pUnitTarget); 
    1344  
    1345             tempUnitMap.erase(itr); 
    1346  
    1347             tempUnitMap.sort(TargetDistanceOrder(pUnitTarget)); 
    1348  
    1349             t = unMaxTargets - 1; 
    1350             Unit *prev = pUnitTarget; 
    1351             std::list<Unit*>::iterator next = tempUnitMap.begin(); 
    1352  
    1353             while(t && next != tempUnitMap.end() ) 
    1354             { 
    1355                 if(prev->GetDistance(*next) > CHAIN_SPELL_JUMP_RADIUS) 
    1356                     break; 
    1357  
    1358                 if(!prev->IsWithinLOSInMap(*next)) 
    1359                 { 
    1360                     ++next; 
    1361                     continue; 
    1362                 } 
    1363  
    1364                 prev = *next; 
    1365                 TagUnitMap.push_back(prev); 
    1366                 tempUnitMap.erase(next); 
    1367                 tempUnitMap.sort(TargetDistanceOrder(prev)); 
    1368                 next = tempUnitMap.begin(); 
    1369  
    1370                 --t; 
    1371             } 
    1372         }break; 
    1373         case TARGET_PET: 
    1374         { 
    1375             Pet* tmpUnit = m_caster->GetPet(); 
    1376             if (!tmpUnit) break; 
    1377             TagUnitMap.push_back(tmpUnit); 
    1378             break; 
    1379         } 
    1380         case TARGET_CHAIN_DAMAGE: 
    1381         { 
    1382             if (EffectChainTarget <= 1) 
    1383             { 
    1384                 Unit* pUnitTarget = SelectMagnetTarget(); 
    1385                 if(pUnitTarget) 
    1386                     TagUnitMap.push_back(pUnitTarget); 
    1387             } 
    1388             else 
    1389             { 
    1390                 Unit* pUnitTarget = m_targets.getUnitTarget(); 
    1391                 if(!pUnitTarget) 
    1392                     break; 
    1393  
    1394                 unMaxTargets = EffectChainTarget; 
    1395  
    1396                 float max_range; 
    1397                 if(m_spellInfo->DmgClass==SPELL_DAMAGE_CLASS_MELEE) 
    1398                     max_range = radius;                     // 
    1399                 else 
    1400                     //FIXME: This very like horrible hack and wrong for most spells 
    1401                     max_range = radius + unMaxTargets * CHAIN_SPELL_JUMP_RADIUS; 
    1402  
    1403                 CellPair p(Trinity::ComputeCellPair(m_caster->GetPositionX(), m_caster->GetPositionY())); 
    1404                 Cell cell(p); 
    1405                 cell.data.Part.reserved = ALL_DISTRICT; 
    1406                 cell.SetNoCreate(); 
    1407  
    1408                 Unit* originalCaster = GetOriginalCaster(); 
    1409                 if(originalCaster) 
    1410                 { 
    1411                     std::list<Unit *> tempUnitMap; 
    1412  
    1413                     { 
    1414                         Trinity::AnyAoETargetUnitInObjectRangeCheck u_check(pUnitTarget, originalCaster, max_range); 
    1415                         Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck> searcher(tempUnitMap, u_check); 
    1416  
    1417                         TypeContainerVisitor<Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck>, WorldTypeMapContainer > world_unit_searcher(searcher); 
    1418                         TypeContainerVisitor<Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck>, GridTypeMapContainer >  grid_unit_searcher(searcher); 
    1419  
    1420                         CellLock<GridReadGuard> cell_lock(cell, p); 
    1421                         cell_lock->Visit(cell_lock, world_unit_searcher, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); 
    1422                         cell_lock->Visit(cell_lock, grid_unit_searcher, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); 
    1423                     } 
    1424  
    1425                     tempUnitMap.sort(TargetDistanceOrder(pUnitTarget)); 
    1426  
    1427                     if(tempUnitMap.empty()) 
    1428                         break; 
    1429  
    1430                     if(*tempUnitMap.begin() == pUnitTarget) 
    1431                         tempUnitMap.erase(tempUnitMap.begin()); 
    1432  
    1433                     TagUnitMap.push_back(pUnitTarget); 
    1434                     uint32 t = unMaxTargets - 1; 
    1435                     Unit *prev = pUnitTarget; 
    1436                     std::list<Unit*>::iterator next = tempUnitMap.begin(); 
    1437  
    1438                     while(t && next != tempUnitMap.end() ) 
    1439                     { 
    1440                         if(prev->GetDistance(*next) > CHAIN_SPELL_JUMP_RADIUS) 
    1441                             break; 
    1442  
    1443                         if(!prev->IsWithinLOSInMap(*next)) 
    1444                         { 
    1445                             ++next; 
    1446                             continue; 
    1447                         } 
    1448  
    1449                         prev = *next; 
    1450                         TagUnitMap.push_back(prev); 
    1451                         tempUnitMap.erase(next); 
    1452                         tempUnitMap.sort(TargetDistanceOrder(prev)); 
    1453                         next = tempUnitMap.begin(); 
    1454  
    1455                         --t; 
    1456                     } 
    1457                 } 
    1458             } 
    1459         }break; 
    1460         case TARGET_ALL_ENEMY_IN_AREA: 
    1461         { 
    1462         }break; 
    1463         case TARGET_ALL_ENEMY_IN_AREA_INSTANT: 
    1464         { 
    1465             // targets the ground, not the units in the area 
    1466             if (m_spellInfo->Effect[i]!=SPELL_EFFECT_PERSISTENT_AREA_AURA) 
    1467             { 
    1468                 CellPair p(Trinity::ComputeCellPair(m_targets.m_destX, m_targets.m_destY)); 
    1469                 Cell cell(p); 
    1470                 cell.data.Part.reserved = ALL_DISTRICT; 
    1471                 cell.SetNoCreate(); 
    1472  
    1473                 Trinity::SpellNotifierCreatureAndPlayer notifier(*this, TagUnitMap, radius, PUSH_DEST_CENTER,SPELL_TARGETS_AOE_DAMAGE); 
    1474  
    1475                 TypeContainerVisitor<Trinity::SpellNotifierCreatureAndPlayer, WorldTypeMapContainer > world_object_notifier(notifier); 
    1476                 TypeContainerVisitor<Trinity::SpellNotifierCreatureAndPlayer, GridTypeMapContainer >  grid_object_notifier(notifier); 
    1477  
    1478                 CellLock<GridReadGuard> cell_lock(cell, p); 
    1479                 cell_lock->Visit(cell_lock, world_object_notifier, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); 
    1480                 cell_lock->Visit(cell_lock, grid_object_notifier, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); 
    1481  
    1482                 // exclude caster (this can be important if this not original caster) 
    1483                 TagUnitMap.remove(m_caster); 
    1484             } 
    1485         }break; 
    1486         case TARGET_DUELVSPLAYER_COORDINATES: 
    1487         { 
    1488             if(Unit* currentTarget = m_targets.getUnitTarget()) 
    1489             { 
    1490                 m_targets.setDestination(currentTarget->GetPositionX(), currentTarget->GetPositionY(), currentTarget->GetPositionZ()); 
    1491                 TagUnitMap.push_back(currentTarget); 
    1492             } 
    1493         }break; 
     1538 
    14941539        case TARGET_ALL_PARTY_AROUND_CASTER: 
    14951540        case TARGET_ALL_PARTY_AROUND_CASTER_2: 
     
    15341579                if(Player* target = ((Player*)m_caster)->GetNextRandomRaidMember(radius)) 
    15351580                    TagUnitMap.push_back(target); 
    1536         }break; 
    1537         case TARGET_SINGLE_FRIEND: 
    1538         case TARGET_SINGLE_FRIEND_2: 
    1539         { 
    1540             if(m_targets.getUnitTarget()) 
    1541                 TagUnitMap.push_back(m_targets.getUnitTarget()); 
    1542         }break; 
    1543         case TARGET_NONCOMBAT_PET: 
    1544         { 
    1545             if(Unit* target = m_targets.getUnitTarget()) 
    1546                 if( target->GetTypeId() == TYPEID_UNIT && ((Creature*)target)->isPet() && ((Pet*)target)->getPetType() == MINI_PET) 
    1547                     TagUnitMap.push_back(target); 
    1548         }break; 
    1549         case TARGET_ALL_AROUND_CASTER: 
    1550         { 
    1551             CellPair p(Trinity::ComputeCellPair(m_caster->GetPositionX(), m_caster->GetPositionY())); 
    1552             Cell cell(p); 
    1553             cell.data.Part.reserved = ALL_DISTRICT; 
    1554             cell.SetNoCreate(); 
    1555  
    1556             Trinity::SpellNotifierCreatureAndPlayer notifier(*this, TagUnitMap, radius, PUSH_SELF_CENTER,SPELL_TARGETS_AOE_DAMAGE); 
    1557  
    1558             TypeContainerVisitor<Trinity::SpellNotifierCreatureAndPlayer, WorldTypeMapContainer > world_object_notifier(notifier); 
    1559             TypeContainerVisitor<Trinity::SpellNotifierCreatureAndPlayer, GridTypeMapContainer >  grid_object_notifier(notifier); 
    1560  
    1561             CellLock<GridReadGuard> cell_lock(cell, p); 
    1562             cell_lock->Visit(cell_lock, world_object_notifier, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); 
    1563             cell_lock->Visit(cell_lock, grid_object_notifier, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); 
    1564         }break; 
    1565         case TARGET_ALL_FRIENDLY_UNITS_AROUND_CASTER: 
    1566         { 
    1567             CellPair p(Trinity::ComputeCellPair(m_caster->GetPositionX(), m_caster->GetPositionY())); 
    1568             Cell cell(p); 
    1569             cell.data.Part.reserved = ALL_DISTRICT; 
    1570             cell.SetNoCreate(); 
    1571  
    1572             Trinity::SpellNotifierCreatureAndPlayer notifier(*this, TagUnitMap, radius, PUSH_SELF_CENTER,SPELL_TARGETS_FRIENDLY); 
    1573  
    1574             TypeContainerVisitor<Trinity::SpellNotifierCreatureAndPlayer, WorldTypeMapContainer > world_object_notifier(notifier); 
    1575             TypeContainerVisitor<Trinity::SpellNotifierCreatureAndPlayer, GridTypeMapContainer >  grid_object_notifier(notifier); 
    1576  
    1577             CellLock<GridReadGuard> cell_lock(cell, p); 
    1578             cell_lock->Visit(cell_lock, world_object_notifier, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); 
    1579             cell_lock->Visit(cell_lock, grid_object_notifier, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); 
    1580         }break; 
    1581         case TARGET_ALL_FRIENDLY_UNITS_IN_AREA: 
    1582         { 
    1583             CellPair p(Trinity::ComputeCellPair(m_targets.m_destX, m_targets.m_destY)); 
    1584             Cell cell(p); 
    1585             cell.data.Part.reserved = ALL_DISTRICT; 
    1586             cell.SetNoCreate(); 
    1587  
    1588             Trinity::SpellNotifierCreatureAndPlayer notifier(*this, TagUnitMap, radius, PUSH_DEST_CENTER,SPELL_TARGETS_FRIENDLY); 
    1589  
    1590             TypeContainerVisitor<Trinity::SpellNotifierCreatureAndPlayer, WorldTypeMapContainer > world_object_notifier(notifier); 
    1591             TypeContainerVisitor<Trinity::SpellNotifierCreatureAndPlayer, GridTypeMapContainer >  grid_object_notifier(notifier); 
    1592  
    1593             CellLock<GridReadGuard> cell_lock(cell, p); 
    1594             cell_lock->Visit(cell_lock, world_object_notifier, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); 
    1595             cell_lock->Visit(cell_lock, grid_object_notifier, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); 
    15961581        }break; 
    15971582        // TARGET_SINGLE_PARTY means that the spells can only be casted on a party member and not on the caster (some sceals, fire shield from imp, etc..) 
     
    16501635            } 
    16511636        }break; 
    1652         case TARGET_GAMEOBJECT: 
    1653         { 
    1654             if(m_targets.getGOTarget()) 
    1655                 AddGOTarget(m_targets.getGOTarget(), i); 
    1656         }break; 
    1657         case TARGET_IN_FRONT_OF_CASTER: 
    1658         { 
    1659             CellPair p(Trinity::ComputeCellPair(m_caster->GetPositionX(), m_caster->GetPositionY())); 
    1660             Cell cell(p); 
    1661             cell.data.Part.reserved = ALL_DISTRICT; 
    1662             cell.SetNoCreate(); 
    1663  
    1664             bool inFront = m_spellInfo->SpellVisual != 3879; 
    1665             Trinity::SpellNotifierCreatureAndPlayer notifier(*this, TagUnitMap, radius, inFront ? PUSH_IN_FRONT : PUSH_IN_BACK,SPELL_TARGETS_AOE_DAMAGE); 
    1666  
    1667             TypeContainerVisitor<Trinity::SpellNotifierCreatureAndPlayer, WorldTypeMapContainer > world_object_notifier(notifier); 
    1668             TypeContainerVisitor<Trinity::SpellNotifierCreatureAndPlayer, GridTypeMapContainer >  grid_object_notifier(notifier); 
    1669  
    1670             CellLock<GridReadGuard> cell_lock(cell, p); 
    1671             cell_lock->Visit(cell_lock, world_object_notifier, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); 
    1672             cell_lock->Visit(cell_lock, grid_object_notifier, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); 
    1673         }break; 
    1674         case TARGET_DUELVSPLAYER: 
    1675         { 
    1676             Unit *target = m_targets.getUnitTarget(); 
    1677             if(target) 
    1678             { 
    1679                 if(m_caster->IsFriendlyTo(target)) 
    1680                 { 
    1681                     TagUnitMap.push_back(target); 
    1682                 } 
    1683                 else 
    1684                 { 
    1685                     Unit* pUnitTarget = SelectMagnetTarget(); 
    1686                     if(pUnitTarget) 
    1687                         TagUnitMap.push_back(pUnitTarget); 
    1688                 } 
    1689             } 
    1690         }break; 
    1691         case TARGET_GAMEOBJECT_ITEM: 
    1692         { 
    1693             if(m_targets.getGOTargetGUID()) 
    1694                 AddGOTarget(m_targets.getGOTarget(), i); 
    1695             else if(m_targets.getItemTarget()) 
    1696                 AddItemTarget(m_targets.getItemTarget(), i); 
    1697             break; 
    1698         } 
    1699         case TARGET_MASTER: 
    1700         { 
    1701             if(Unit* owner = m_caster->GetCharmerOrOwner()) 
    1702                 TagUnitMap.push_back(owner); 
    1703             break; 
    1704         } 
    17051637        case TARGET_ALL_ENEMY_IN_AREA_CHANNELED: 
    17061638        { 
     
    18001732 
    18011733        }break; 
    1802         case TARGET_SCRIPT: 
    1803         { 
    1804             if(m_targets.getUnitTarget()) 
    1805                 TagUnitMap.push_back(m_targets.getUnitTarget()); 
    1806             if(m_targets.getItemTarget()) 
    1807                 AddItemTarget(m_targets.getItemTarget(), i); 
    1808         }break; 
    1809         case TARGET_SELF_FISHING: 
    1810         { 
    1811             TagUnitMap.push_back(m_caster); 
    1812         }break; 
    18131734        case TARGET_CHAIN_HEAL: 
    18141735        { 
     
    18831804 
    18841805                    --t; 
    1885                 } 
    1886             } 
    1887         }break; 
    1888         case TARGET_CURRENT_ENEMY_COORDINATES: 
    1889         { 
    1890             Unit* currentTarget = m_targets.getUnitTarget(); 
    1891             if(currentTarget) 
    1892             { 
    1893                 TagUnitMap.push_back(currentTarget); 
    1894                 m_targets.setDestination(currentTarget->GetPositionX(), currentTarget->GetPositionY(), currentTarget->GetPositionZ()); 
    1895                 if(m_spellInfo->EffectImplicitTargetB[i]==TARGET_ALL_ENEMY_IN_AREA_INSTANT) 
    1896                 { 
    1897                     CellPair p(Trinity::ComputeCellPair(currentTarget->GetPositionX(), currentTarget->GetPositionY())); 
    1898                     Cell cell(p); 
    1899                     cell.data.Part.reserved = ALL_DISTRICT; 
    1900                     cell.SetNoCreate(); 
    1901                     Trinity::SpellNotifierCreatureAndPlayer notifier(*this, TagUnitMap, radius,PUSH_TARGET_CENTER, SPELL_TARGETS_AOE_DAMAGE); 
    1902                     TypeContainerVisitor<Trinity::SpellNotifierCreatureAndPlayer, WorldTypeMapContainer > world_notifier(notifier); 
    1903                     TypeContainerVisitor<Trinity::SpellNotifierCreatureAndPlayer, GridTypeMapContainer > grid_notifier(notifier); 
    1904                     CellLock<GridReadGuard> cell_lock(cell, p); 
    1905                     cell_lock->Visit(cell_lock, world_notifier, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); 
    1906                     cell_lock->Visit(cell_lock, grid_notifier, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); 
    19071806                } 
    19081807            } 
     
    19331832            break; 
    19341833        } 
    1935         case TARGET_TABLE_X_Y_Z_COORDINATES: 
    1936         { 
    1937             SpellTargetPosition const* st = spellmgr.GetSpellTargetPosition(m_spellInfo->Id); 
    1938             if(st) 
    1939             { 
    1940                 if (st->target_mapId == m_caster->GetMapId()) 
    1941                     m_targets.setDestination(st->target_X, st->target_Y, st->target_Z); 
    1942  
    1943                 // if B==TARGET_TABLE_X_Y_Z_COORDINATES then A already fill all required targets 
    1944                 if (m_spellInfo->EffectImplicitTargetB[i] && m_spellInfo->EffectImplicitTargetB[i]!=TARGET_TABLE_X_Y_Z_COORDINATES) 
    1945                 { 
    1946                     CellPair p(Trinity::ComputeCellPair(m_caster->GetPositionX(), m_caster->GetPositionY())); 
    1947                     Cell cell(p); 
    1948                     cell.data.Part.reserved = ALL_DISTRICT; 
    1949                     cell.SetNoCreate(); 
    1950  
    1951                     SpellTargets targetB = SPELL_TARGETS_AOE_DAMAGE; 
    1952                     // Select friendly targets for positive effect 
    1953                     if (IsPositiveEffect(m_spellInfo->Id, i)) 
    1954                         targetB = SPELL_TARGETS_FRIENDLY; 
    1955  
    1956                     Trinity::SpellNotifierCreatureAndPlayer notifier(*this, TagUnitMap, radius,PUSH_DEST_CENTER, targetB); 
    1957  
    1958                     TypeContainerVisitor<Trinity::SpellNotifierCreatureAndPlayer, WorldTypeMapContainer > world_notifier(notifier); 
    1959                     TypeContainerVisitor<Trinity::SpellNotifierCreatureAndPlayer, GridTypeMapContainer > grid_notifier(notifier); 
    1960  
    1961                     CellLock<GridReadGuard> cell_lock(cell, p); 
    1962                     cell_lock->Visit(cell_lock, world_notifier, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); 
    1963                     cell_lock->Visit(cell_lock, grid_notifier, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); 
    1964                 } 
    1965             } 
     1834 
     1835        // destination around caster 
     1836        case TARGET_DEST_CASTER_FRONT_LEFT: 
     1837        case TARGET_DEST_CASTER_BACK_LEFT: 
     1838        case TARGET_DEST_CASTER_BACK_RIGHT: 
     1839        case TARGET_DEST_CASTER_FRONT_RIGHT: 
     1840        case TARGET_DEST_CASTER_FRONT: 
     1841        case TARGET_DEST_CASTER_BACK: 
     1842        case TARGET_DEST_CASTER_RIGHT: 
     1843        case TARGET_DEST_CASTER_LEFT: 
     1844        case TARGET_DEST_CASTER_RANDOM: 
     1845        case TARGET_DEST_CASTER_RADIUS: 
     1846        { 
     1847            float x, y, z, angle, dist; 
     1848 
     1849            if (m_spellInfo->EffectRadiusIndex[i]) 
     1850                dist = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); 
    19661851            else 
    1967                 sLog.outError( "SPELL: unknown target coordinates for spell ID %u\n", m_spellInfo->Id ); 
     1852                dist = 3.0f;//do we need this? 
     1853            if (cur == TARGET_DEST_CASTER_RANDOM) 
     1854                dist *= rand_norm(); // This case we need to consider caster size 
     1855            else 
     1856                dist -= m_caster->GetObjectSize(); // Size is calculated in GetNearPoint(), but we do not need it  
     1857            //need a new function to remove this repeated work 
     1858 
     1859            switch(cur) 
     1860            { 
     1861                case TARGET_DEST_CASTER_FRONT_LEFT: angle = -M_PI/4;    break; 
     1862                case TARGET_DEST_CASTER_BACK_LEFT:  angle = -3*M_PI/4;  break; 
     1863                case TARGET_DEST_CASTER_BACK_RIGHT: angle = 3*M_PI/4;   break; 
     1864                case TARGET_DEST_CASTER_FRONT_RIGHT:angle = M_PI/4;     break; 
     1865                case TARGET_DEST_CASTER_FRONT:      angle = 0.0f;       break; 
     1866                case TARGET_DEST_CASTER_BACK:       angle = M_PI;       break; 
     1867                case TARGET_DEST_CASTER_RIGHT:      angle = M_PI/2;     break; 
     1868                case TARGET_DEST_CASTER_LEFT:       angle = -M_PI/2;    break; 
     1869                default:                            angle = rand_norm()*2*M_PI; break; 
     1870            } 
     1871 
     1872            m_caster->GetClosePoint(x, y, z, 0, dist, angle); 
     1873            m_targets.setDestination(x, y, z); // do not know if has ground visual 
    19681874        }break; 
     1875 
     1876        // destination around target 
     1877        case TARGET_DEST_TARGET_FRONT: 
     1878        case TARGET_DEST_TARGET_BACK: 
     1879        case TARGET_DEST_TARGET_RIGHT: 
     1880        case TARGET_DEST_TARGET_LEFT: 
     1881        case TARGET_DEST_TARGET_RANDOM: 
     1882        case TARGET_DEST_TARGET_RADIUS: 
     1883        { 
     1884            Unit *target = m_targets.getUnitTarget(); 
     1885            if(!target) 
     1886            { 
     1887                sLog.outError("SPELL: no unit target for spell ID %u\n", m_spellInfo->Id); 
     1888                break; 
     1889            } 
     1890 
     1891            float x, y, z, angle, dist; 
     1892 
     1893            if (m_spellInfo->EffectRadiusIndex[i]) 
     1894                dist = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); 
     1895            else 
     1896                dist = 3.0f;//do we need this? 
     1897            if (cur == TARGET_DEST_TARGET_RANDOM) 
     1898                dist *= rand_norm(); // This case we need to consider caster size 
     1899            else 
     1900                dist -= target->GetObjectSize(); // Size is calculated in GetNearPoint(), but we do not need it  
     1901            //need a new function to remove this repeated work 
     1902 
     1903            switch(cur) 
     1904            { 
     1905                case TARGET_DEST_TARGET_FRONT:      angle = 0.0f;       break; 
     1906                case TARGET_DEST_TARGET_BACK:       angle = M_PI;       break; 
     1907                case TARGET_DEST_TARGET_RIGHT:      angle = M_PI/2;     break; 
     1908                case TARGET_DEST_TARGET_LEFT:       angle = -M_PI/2;    break; 
     1909                default:                            angle = rand_norm()*2*M_PI; break; 
     1910            } 
     1911 
     1912            target->GetClosePoint(x, y, z, 0, dist, angle); 
     1913            m_targets.setDestination(x, y, z); // do not know if has ground visual 
     1914        }break; 
     1915 
     1916        // destination around destination 
     1917        case TARGET_DEST_DEST_RANDOM: 
     1918        { 
     1919            if(!(m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION)) 
     1920            { 
     1921                sLog.outError("SPELL: no destination for spell ID %u\n", m_spellInfo->Id); 
     1922                break; 
     1923            } 
     1924            float x, y, z, dist, px, py, pz; 
     1925            dist = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); 
     1926            x = m_targets.m_destX; 
     1927            y = m_targets.m_destY; 
     1928            z = m_targets.m_destZ; 
     1929            m_caster->GetRandomPoint(x, y, z, dist, px, py, pz); 
     1930            m_targets.setDestination(px, py, pz); 
     1931        }break; 
     1932        case TARGET_SELF2: 
     1933            break; 
    19691934        default: 
    19701935            break; 
     
    20131978    m_spellState = SPELL_STATE_PREPARING; 
    20141979 
    2015     m_castPositionX = m_caster->GetPositionX(); 
    2016     m_castPositionY = m_caster->GetPositionY(); 
    2017     m_castPositionZ = m_caster->GetPositionZ(); 
     1980    m_caster->GetPosition(m_castPositionX, m_castPositionY, m_castPositionZ); 
    20181981    m_castOrientation = m_caster->GetOrientation(); 
    20191982 
     
    21712134    } 
    21722135 
     2136    FillTargetMap(); 
     2137 
     2138    // who did this hack? 
    21732139    // Conflagrate - consumes immolate 
    21742140    if ((m_spellInfo->TargetAuraState == AURA_STATE_IMMOLATE) && m_targets.getUnitTarget()) 
     
    21962162    TakePower(); 
    21972163    TakeReagents();                                         // we must remove reagents before HandleEffects to allow place crafted item in same slot 
    2198     FillTargetMap(); 
    21992164 
    22002165    if(m_spellState == SPELL_STATE_FINISHED)                // stop cast if spell marked as finish somewhere in Take*/FillTargetMap 
     
    34393404            return castResult; 
    34403405 
    3441     //ImpliciteTargetA-B = 38, If fact there is 0 Spell with  ImpliciteTargetB=38 
    3442     if(m_UniqueTargetInfo.empty())                          // skip second canCast apply (for delayed spells for example) 
    3443     { 
    3444         for(uint8 j = 0; j < 3; j++) 
    3445         { 
    3446             if( m_spellInfo->EffectImplicitTargetA[j] == TARGET_SCRIPT || 
    3447                 m_spellInfo->EffectImplicitTargetB[j] == TARGET_SCRIPT && m_spellInfo->EffectImplicitTargetA[j] != TARGET_SELF || 
    3448                 m_spellInfo->EffectImplicitTargetA[j] == TARGET_SCRIPT_COORDINATES || 
    3449                 m_spellInfo->EffectImplicitTargetB[j] == TARGET_SCRIPT_COORDINATES ) 
    3450             { 
    3451                 bool okDoo = false; 
    3452  
    3453                 SpellScriptTarget::const_iterator lower = spellmgr.GetBeginSpellScriptTarget(m_spellInfo->Id); 
    3454                 SpellScriptTarget::const_iterator upper = spellmgr.GetEndSpellScriptTarget(m_spellInfo->Id); 
    3455                 if(lower==upper) 
    3456                     sLog.outErrorDb("Spell (ID: %u) has effect EffectImplicitTargetA/EffectImplicitTargetB = TARGET_SCRIPT or TARGET_SCRIPT_COORDINATES, but does not have record in `spell_script_target`",m_spellInfo->Id); 
    3457  
    3458                 SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex); 
    3459                 float range = GetSpellMaxRange(srange); 
    3460  
    3461                 Creature* creatureScriptTarget = NULL; 
    3462                 GameObject* goScriptTarget = NULL; 
    3463  
    3464                 for(SpellScriptTarget::const_iterator i_spellST = lower; i_spellST != upper; ++i_spellST) 
    3465                 { 
    3466                     switch(i_spellST->second.type) 
    3467                     { 
    3468                         case SPELL_TARGET_TYPE_GAMEOBJECT: 
    3469                         { 
    3470                             GameObject* p_GameObject = NULL; 
    3471  
    3472                             if(i_spellST->second.targetEntry) 
    3473                             { 
    3474                                 CellPair p(Trinity::ComputeCellPair(m_caster->GetPositionX(), m_caster->GetPositionY())); 
    3475                                 Cell cell(p); 
    3476                                 cell.data.Part.reserved = ALL_DISTRICT; 
    3477  
    3478                                 Trinity::NearestGameObjectEntryInObjectRangeCheck go_check(*m_caster,i_spellST->second.targetEntry,range); 
    3479                                 Trinity::GameObjectLastSearcher<Trinity::NearestGameObjectEntryInObjectRangeCheck> checker(p_GameObject,go_check); 
    3480  
    3481                                 TypeContainerVisitor<Trinity::GameObjectLastSearcher<Trinity::NearestGameObjectEntryInObjectRangeCheck>, GridTypeMapContainer > object_checker(checker); 
    3482                                 CellLock<GridReadGuard> cell_lock(cell, p); 
    3483                                 cell_lock->Visit(cell_lock, object_checker, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); 
    3484  
    3485                                 if(p_GameObject) 
    3486                                 { 
    3487                                     // remember found target and range, next attempt will find more near target with another entry 
    3488                                     creatureScriptTarget = NULL; 
    3489                                     goScriptTarget = p_GameObject; 
    3490                                     range = go_check.GetLastRange(); 
    3491                                 } 
    3492                             } 
    3493                             else if( focusObject )          //Focus Object 
    3494                             { 
    3495                                 float frange = m_caster->GetDistance(focusObject); 
    3496                                 if(range >= frange) 
    3497                                 { 
    3498                                     creatureScriptTarget = NULL; 
    3499                                     goScriptTarget = focusObject; 
    3500                                     range = frange; 
    3501                                 } 
    3502                             } 
    3503                             break; 
    3504                         } 
    3505                         case SPELL_TARGET_TYPE_CREATURE: 
    3506                         case SPELL_TARGET_TYPE_DEAD: 
    3507                         default: 
    3508                         { 
    3509                             Creature *p_Creature = NULL; 
    3510  
    3511                             CellPair p(Trinity::ComputeCellPair(m_caster->GetPositionX(), m_caster->GetPositionY())); 
    3512                             Cell cell(p); 
    3513                             cell.data.Part.reserved = ALL_DISTRICT; 
    3514                             cell.SetNoCreate();             // Really don't know what is that??? 
    3515  
    3516                             Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck u_check(*m_caster,i_spellST->second.targetEntry,i_spellST->second.type!=SPELL_TARGET_TYPE_DEAD,range); 
    3517                             Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(p_Creature, u_check); 
    3518  
    3519                             TypeContainerVisitor<Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck>, GridTypeMapContainer >  grid_creature_searcher(searcher); 
    3520  
    3521                             CellLock<GridReadGuard> cell_lock(cell, p); 
    3522                             cell_lock->Visit(cell_lock, grid_creature_searcher, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); 
    3523  
    3524                             if(p_Creature ) 
    3525                             { 
    3526                                 creatureScriptTarget = p_Creature; 
    3527                                 goScriptTarget = NULL; 
    3528                                 range = u_check.GetLastRange(); 
    3529                             } 
    3530                             break; 
    3531                         } 
    3532                     } 
    3533                 } 
    3534  
    3535                 if(creatureScriptTarget) 
    3536                 { 
    3537                     // store coordinates for TARGET_SCRIPT_COORDINATES 
    3538                     if (m_spellInfo->EffectImplicitTargetA[j] == TARGET_SCRIPT_COORDINATES || 
    3539                         m_spellInfo->EffectImplicitTargetB[j] == TARGET_SCRIPT_COORDINATES ) 
    3540                     { 
    3541                         m_targets.setDestination(creatureScriptTarget->GetPositionX(),creatureScriptTarget->GetPositionY(),creatureScriptTarget->GetPositionZ()); 
    3542  
    3543                         if(m_spellInfo->EffectImplicitTargetA[j] == TARGET_SCRIPT_COORDINATES && m_spellInfo->EffectImplicitTargetB[j] == 0 && m_spellInfo->Effect[j]!=SPELL_EFFECT_PERSISTENT_AREA_AURA) 
    3544                             AddUnitTarget(creatureScriptTarget, j); 
    3545                     } 
    3546                     // store explicit target for TARGET_SCRIPT 
    3547                     else 
    3548                         AddUnitTarget(creatureScriptTarget, j); 
    3549                 } 
    3550                 else if(goScriptTarget) 
    3551                 { 
    3552                     // store coordinates for TARGET_SCRIPT_COORDINATES 
    3553                     if (m_spellInfo->EffectImplicitTargetA[j] == TARGET_SCRIPT_COORDINATES || 
    3554                         m_spellInfo->EffectImplicitTargetB[j] == TARGET_SCRIPT_COORDINATES ) 
    3555                     { 
    3556                         m_targets.setDestination(goScriptTarget->GetPositionX(),goScriptTarget->GetPositionY(),goScriptTarget->GetPositionZ()); 
    3557  
    3558                         if(m_spellInfo->EffectImplicitTargetA[j] == TARGET_SCRIPT_COORDINATES && m_spellInfo->EffectImplicitTargetB[j] == 0 && m_spellInfo->Effect[j]!=SPELL_EFFECT_PERSISTENT_AREA_AURA) 
    3559                             AddGOTarget(goScriptTarget, j); 
    3560                     } 
    3561                     // store explicit target for TARGET_SCRIPT 
    3562                     else 
    3563                         AddGOTarget(goScriptTarget, j); 
    3564                 } 
    3565                 //Missing DB Entry or targets for this spellEffect. 
    3566                 else 
    3567                 { 
    3568                     // not report target not existence for triggered spells 
    3569                     if(m_triggeredByAuraSpell || m_IsTriggeredSpell) 
    3570                         return SPELL_FAILED_DONT_REPORT; 
    3571                     else 
    3572                         return SPELL_FAILED_BAD_TARGETS; 
    3573                 } 
    3574             } 
    3575         } 
    3576     } 
    3577  
    35783406    if(uint8 castResult = CheckRange(strict)) 
    35793407        return castResult; 
  • trunk/src/game/Spell.h

    r102 r108  
    7676    PUSH_SELF_CENTER, 
    7777    PUSH_DEST_CENTER, 
    78     PUSH_TARGET_CENTER 
    7978}; 
    8079 
     
    8382namespace Trinity 
    8483{ 
    85     struct SpellNotifierPlayer; 
    8684    struct SpellNotifierCreatureAndPlayer; 
    8785} 
     
    181179}; 
    182180 
     181enum ReplenishType 
     182{ 
     183    REPLENISH_UNDEFINED = 0, 
     184    REPLENISH_HEALTH    = 20, 
     185    REPLENISH_MANA      = 21, 
     186    REPLENISH_RAGE      = 22 
     187}; 
     188 
     189enum SpellTargets 
     190{ 
     191    SPELL_TARGETS_FRIENDLY, 
     192    SPELL_TARGETS_AOE_DAMAGE, 
     193    SPELL_TARGETS_ENTRY 
     194}; 
     195 
    183196#define SPELL_SPELL_CHANNEL_UPDATE_INTERVAL 1000 
    184197 
     
    187200class Spell 
    188201{ 
    189     friend struct Trinity::SpellNotifierPlayer; 
    190202    friend struct Trinity::SpellNotifierCreatureAndPlayer; 
    191203    public: 
     
    498510        void DoAllEffectOnTarget(ItemTargetInfo *target); 
    499511        bool IsAliveUnitPresentInTargetList(); 
     512        void SearchAreaTarget(std::list<Unit*> &data, float radius, const uint32 &type, 
     513            SpellTargets TargetType, uint32 entry = 0); 
     514        Unit* SearchNearbyTarget(float radius, SpellTargets TargetType, uint32 entry = 0); 
     515        void SearchChainTarget(std::list<Unit*> &data, Unit* pUnitTarget, float max_range, uint32 unMaxTargets); 
    500516        // ------------------------------------------- 
    501517 
     
    519535}; 
    520536 
    521 enum ReplenishType 
    522 { 
    523     REPLENISH_UNDEFINED = 0, 
    524     REPLENISH_HEALTH    = 20, 
    525     REPLENISH_MANA      = 21, 
    526     REPLENISH_RAGE      = 22 
    527 }; 
    528  
    529 enum SpellTargets 
    530 { 
    531     SPELL_TARGETS_HOSTILE, 
    532     SPELL_TARGETS_NOT_FRIENDLY, 
    533     SPELL_TARGETS_NOT_HOSTILE, 
    534     SPELL_TARGETS_FRIENDLY, 
    535     SPELL_TARGETS_AOE_DAMAGE 
    536 }; 
    537  
    538537namespace Trinity 
    539538{ 
    540     struct TRINITY_DLL_DECL SpellNotifierPlayer 
    541     { 
    542         std::list<Unit*> &i_data; 
    543         Spell &i_spell; 
    544         const uint32& i_index; 
    545         float i_radius; 
    546         Unit* i_originalCaster; 
    547  
    548         SpellNotifierPlayer(Spell &spell, std::list<Unit*> &data, const uint32 &i, float radius) 
    549             : i_data(data), i_spell(spell), i_index(i), i_radius(radius) 
    550         { 
    551             i_originalCaster = i_spell.GetOriginalCaster(); 
    552         } 
    553  
    554         void Visit(PlayerMapType &m) 
    555         { 
    556             if(!i_originalCaster) 
    557                 return; 
    558  
    559             for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr) 
    560             { 
    561                 Player * pPlayer = itr->getSource(); 
    562                 if( !pPlayer->isAlive() || pPlayer->isInFlight()) 
    563                     continue; 
    564  
    565                 if( i_originalCaster->IsFriendlyTo(pPlayer) ) 
    566                     continue; 
    567  
    568                 if( pPlayer->GetDistance(i_spell.m_targets.m_destX, i_spell.m_targets.m_destY, i_spell.m_targets.m_destZ) < i_radius ) 
    569                     i_data.push_back(pPlayer); 
    570             } 
    571         } 
    572         template<class SKIP> void Visit(GridRefManager<SKIP> &) {} 
    573     }; 
    574  
    575539    struct TRINITY_DLL_DECL SpellNotifierCreatureAndPlayer 
    576540    { 
     
    581545        SpellTargets i_TargetType; 
    582546        Unit* i_originalCaster; 
     547        uint32 i_entry; 
    583548 
    584549        SpellNotifierCreatureAndPlayer(Spell &spell, std::list<Unit*> &data, float radius, const uint32 &type, 
    585             SpellTargets TargetType = SPELL_TARGETS_NOT_FRIENDLY) 
    586             : i_data(&data), i_spell(spell), i_push_type(type), i_radius(radius), i_TargetType(TargetType) 
     550            SpellTargets TargetType = SPELL_TARGETS_AOE_DAMAGE, uint32 entry = 0) 
     551            : i_data(&data), i_spell(spell), i_push_type(type), i_radius(radius), i_TargetType(TargetType), i_entry(entry) 
    587552        { 
    588553            i_originalCaster = spell.GetOriginalCaster(); 
     
    603568                switch (i_TargetType) 
    604569                { 
    605                     case SPELL_TARGETS_HOSTILE: 
    606                         if (!itr->getSource()->isTargetableForAttack() || !i_originalCaster->IsHostileTo( itr->getSource() )) 
    607                             continue; 
    608                         break; 
    609                     case SPELL_TARGETS_NOT_FRIENDLY: 
    610                         if (!itr->getSource()->isTargetableForAttack() || i_originalCaster->IsFriendlyTo( itr->getSource() )) 
    611                             continue; 
    612                         break; 
    613                     case SPELL_TARGETS_NOT_HOSTILE: 
    614                         if (!itr->getSource()->isTargetableForAttack() || i_originalCaster->IsHostileTo( itr->getSource() )) 
    615                             continue; 
    616                         break; 
    617570                    case SPELL_TARGETS_FRIENDLY: 
    618571                        if (!itr->getSource()->isTargetableForAttack() || !i_originalCaster->IsFriendlyTo( itr->getSource() )) 
     
    638591                                continue; 
    639592                        } 
    640                     } 
    641                     break; 
     593                    }break; 
     594                    case SPELL_TARGETS_ENTRY: 
     595                    { 
     596                        if(itr->getSource()->GetTypeId()!=TYPEID_UNIT || itr->getSource()->GetEntry()!= i_entry) 
     597                            continue; 
     598                    }break; 
    642599                    default: continue; 
    643600                } 
     
    661618                            i_data->push_back(itr->getSource()); 
    662619                        break; 
    663                     case PUSH_TARGET_CENTER: 
    664                         if(i_spell.m_targets.getUnitTarget()->IsWithinDistInMap((Unit*)(itr->getSource()), i_radius)) 
    665                             i_data->push_back(itr->getSource()); 
    666                         break; 
    667620                } 
    668621            } 
  • trunk/src/game/SpellMgr.cpp

    r102 r108  
    17941794        } 
    17951795 
    1796         bool targetfound = false; 
     1796        /*bool targetfound = false; 
    17971797        for(int i = 0; i <3; ++i) 
    17981798        { 
     
    18101810            sLog.outErrorDb("Table `spell_script_target`: spellId %u listed for TargetEntry %u does not have any implicit target TARGET_SCRIPT(38) or TARGET_SCRIPT_COORDINATES (46).",spellId,targetEntry); 
    18111811            continue; 
    1812         } 
     1812        }*/ 
    18131813 
    18141814        if( type >= MAX_SPELL_TARGET_TYPE )