CanCastResult BossSpellWorker::_BSWSpellSelector(uint8 m_uiSpellIdx, Unit* pTarget)
{
    if (_bossSpellCount == 0) return CAST_FAIL_OTHER;
    SpellEntry const *spell;
    SpellTable* pSpell = &m_BossSpell[m_uiSpellIdx];
    Unit* pSummon = NULL;

    debug_log("BSW: Casting spell number %u type %u",pSpell->m_uiSpellEntry[currentDifficulty], pSpell->m_CastTarget);

    switch (pSpell->m_CastTarget) {

    case DO_NOTHING:
        return CAST_OK;

    case CAST_ON_SELF:
        if (!pSpell->m_IsBugged) return _DoCastSpellIfCan(boss, pSpell->m_uiSpellEntry[currentDifficulty]);
        else return _BSWDoCast(m_uiSpellIdx, boss);
        break;

    case CAST_ON_SUMMONS:
        if (!pTarget) return CAST_FAIL_OTHER;
        else return _DoCastSpellIfCan(pTarget, pSpell->m_uiSpellEntry[currentDifficulty]);
        break;

    case CAST_ON_VICTIM:
        pTarget = boss->getVictim();
        return _BSWCastOnTarget(pTarget, m_uiSpellIdx);
        break;

    case CAST_ON_RANDOM:
        pTarget = SelectUnit(SELECT_TARGET_RANDOM);
        return _BSWCastOnTarget(pTarget, m_uiSpellIdx);
        break;

    case CAST_ON_BOTTOMAGGRO:
        pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0);
        return _BSWCastOnTarget(pTarget, m_uiSpellIdx);
        break;

    case CAST_ON_TARGET:
        return _BSWCastOnTarget(pTarget, m_uiSpellIdx);
        break;

    case APPLY_AURA_SELF:
        if (spell = (SpellEntry *)GetSpellStore()->LookupEntry(pSpell->m_uiSpellEntry[currentDifficulty]))
            if(boss->AddAura(pSpell->m_uiSpellEntry[currentDifficulty], boss))
                return CAST_OK;
            else return CAST_FAIL_OTHER;
        break;

    case APPLY_AURA_TARGET:
        if (!pTarget) return CAST_FAIL_OTHER;
        if (spell = (SpellEntry *)GetSpellStore()->LookupEntry(pSpell->m_uiSpellEntry[currentDifficulty]))
            if (pTarget->AddAura(pSpell->m_uiSpellEntry[currentDifficulty], pTarget))
                return CAST_OK;
            else return CAST_FAIL_OTHER;
        break;

    case SUMMON_NORMAL:
        pSummon = _doSummon(m_uiSpellIdx, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000);
        if(pSummon) return CAST_OK;
        else return CAST_FAIL_OTHER;
        break;

    case SUMMON_TEMP:
        pSummon = _doSummon(m_uiSpellIdx, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,
                            urand(pSpell->m_uiSpellTimerMin[currentDifficulty],pSpell->m_uiSpellTimerMax[currentDifficulty]));
        if(pSummon) return CAST_OK;
        else return CAST_FAIL_OTHER;
        break;

    case SUMMON_INSTANT:
        pSummon = _doSummon(m_uiSpellIdx, TEMPSUMMON_MANUAL_DESPAWN,0);
        if(pSummon) return CAST_OK;
        else return CAST_FAIL_OTHER;
        break;

    case CAST_ON_ALLPLAYERS:
    {
        CanCastResult res1 = CAST_FAIL_OTHER;
        Map::PlayerList const& pPlayers = pMap->GetPlayers();
        for (Map::PlayerList::const_iterator itr = pPlayers.begin(); itr != pPlayers.end(); ++itr)
        {
            pTarget = itr->getSource();
            if (pTarget && pTarget->isAlive() && pTarget->IsWithinDistInMap(boss, pSpell->LocData.x))
                if (!pSpell->m_IsBugged) {
                    res1 = _DoCastSpellIfCan(pTarget, pSpell->m_uiSpellEntry[currentDifficulty]);
                }
                else {
                    _BSWDoCast(m_uiSpellIdx, pTarget);
                    res1 = CAST_OK;
                };
            return res1;
        }
        break;
    }

    case CAST_ON_FRENDLY:
        pTarget = SelectLowHPFriendly();
        return _BSWCastOnTarget(pTarget, m_uiSpellIdx);
        break;

    case CAST_ON_FRENDLY_LOWHP:
        pTarget = SelectLowHPFriendly();
        return _BSWCastOnTarget(pTarget, m_uiSpellIdx);
        break;

    default:
        return CAST_FAIL_OTHER;
        break;
    };
    return CAST_FAIL_OTHER;
};
Esempio n. 2
0
CanCastResult BSWScriptedAI::_BSWSpellSelector(uint8 m_uiSpellIdx, Unit* pTarget)
{

    BSWRecord* pSpell = &m_BSWRecords[m_uiSpellIdx];

    Unit* pSummon = NULL;

    CanCastResult result = CAST_FAIL_OTHER;

    debug_log("BSW: Casting spell number %u type %u",pSpell->m_uiSpellEntry[currentDifficulty], pSpell->m_CastTarget);

        if (pSpell->m_uiSpellTimerMax[currentDifficulty] >= HOUR*IN_MILLISECONDS)
            m_creature->InterruptNonMeleeSpells(true);

        switch (pSpell->m_CastTarget) {

            case DO_NOTHING:
                   result = CAST_OK;
                   break;

            case CAST_ON_SELF:
                   result = _BSWCastOnTarget(m_creature, m_uiSpellIdx);
                   break;

            case CAST_ON_SUMMONS:
                   result = _BSWCastOnTarget(pTarget, m_uiSpellIdx);
                   break;

            case CAST_ON_VICTIM:
                   pTarget = m_creature->getVictim();
                   result = _BSWCastOnTarget(pTarget, m_uiSpellIdx);
                   break;

            case CAST_ON_RANDOM:
                   pTarget = _doSelect(0, false, 60.0f);
                   result = _BSWCastOnTarget(pTarget, m_uiSpellIdx);
                   break;

            case CAST_ON_BOTTOMAGGRO:
                   pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_BOTTOMAGGRO,0);
                   result = _BSWCastOnTarget(pTarget, m_uiSpellIdx);
                   break;

            case CAST_ON_TARGET:
                   result = _BSWCastOnTarget(pTarget, m_uiSpellIdx);
                   break;

            case APPLY_AURA_SELF:
                       if (_doAura(m_uiSpellIdx, m_creature, EFFECT_INDEX_0))
                           result = CAST_OK;
                       else result = CAST_FAIL_OTHER;
                   break;

            case APPLY_AURA_TARGET:
                   if (!pTarget || !pTarget->IsInMap(m_creature))
                   {
                       result = CAST_FAIL_OTHER;
                       break;
                   }
                   if (_doAura(m_uiSpellIdx, pTarget, EFFECT_INDEX_0))
                       result = CAST_OK;
                   else result = CAST_FAIL_OTHER;
                   break;

            case SUMMON_NORMAL:
                   pSummon = _doSummon(m_uiSpellIdx, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000);
                   if(pSummon) result = CAST_OK;
                       else result = CAST_FAIL_OTHER;
                   break;

            case SUMMON_TEMP:
                   pSummon = _doSummon(m_uiSpellIdx, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,
                                        urand(pSpell->m_uiSpellTimerMin[currentDifficulty],pSpell->m_uiSpellTimerMax[currentDifficulty]));
                   if(pSummon) result = CAST_OK;
                       else result = CAST_FAIL_OTHER;
                   break;

            case SUMMON_INSTANT:
                   pSummon = _doSummon(m_uiSpellIdx, TEMPSUMMON_MANUAL_DESPAWN,0);
                   if(pSummon) result = CAST_OK;
                       else result = CAST_FAIL_OTHER;
                   break;

            case CAST_ON_ALLPLAYERS:
                   {
                       Map* pMap = m_creature->GetMap();
                       Map::PlayerList const& pPlayers = pMap->GetPlayers();
                       if (!pPlayers.isEmpty())
                       {
                           for (Map::PlayerList::const_iterator itr = pPlayers.begin(); itr != pPlayers.end(); ++itr)
                           {
                               pTarget = itr->getSource();
                               if (pTarget && pTarget->isAlive() && pTarget->IsWithinDistInMap(m_creature, pSpell->LocData.x))
                               {
                                   if (!pSpell->m_IsBugged)
                                   {
                                       m_creature->CastSpell(pTarget, pSpell->m_uiSpellEntry[currentDifficulty], false);
                                   }
                                   else
                                   {
                                       _BSWDoCast(m_uiSpellIdx, pTarget);
                                   };
                               result = CAST_OK;
                               };
                           }
                       } else result = CAST_FAIL_OTHER;
                   }
                   break;

            case CAST_ON_FRENDLY:
                   pTarget = DoSelectLowestHpFriendly(pSpell->LocData.x,0);
                   result = _BSWCastOnTarget(pTarget, m_uiSpellIdx);
                   break;

            case CAST_ON_FRENDLY_LOWHP:
                   pTarget = DoSelectLowestHpFriendly(pSpell->LocData.x,1);
                   result = _BSWCastOnTarget(pTarget, m_uiSpellIdx);
                   break;

            case CAST_ON_RANDOM_POINT:
                   if (!pTarget) pTarget = m_creature;
                   if (pSpell->LocData.z <= 1.0f)
                   {
                         float fPosX, fPosY, fPosZ;
                         if (!pTarget->IsPositionValid() || !pTarget->IsInMap(m_creature))
                         {
                             if (pTarget->GetTypeId() == TYPEID_PLAYER)
                                 error_log("BSW: CAST_ON_RANDOM_POINT FAILED: player has invalid position. SpellID is %u",pSpell->m_uiSpellEntry[currentDifficulty]);
                             else error_log("BSW: CAST_ON_RANDOM_POINT FAILED: creature has invalid position. SpellID is %u",pSpell->m_uiSpellEntry[currentDifficulty]);
                             result = CAST_FAIL_OTHER;
                             break;
                         }

                         pTarget->GetPosition(fPosX, fPosY, fPosZ);
                         pTarget->GetRandomPoint(fPosX, fPosY, fPosZ, urand((uint32)pSpell->LocData.x, (uint32)pSpell->LocData.y), fPosX, fPosY, fPosZ);
                         if ((int)fPosZ == 0)
                         {
                             error_log("BSW: CAST_ON_RANDOM_POINT FAILED: Positon Z is NULL. Strange bug");
                             result = CAST_FAIL_OTHER;
                             break;
                         }

                         if (SpellEntry const *spell = (SpellEntry *)GetSpellStore()->LookupEntry(pSpell->m_uiSpellEntry[currentDifficulty]))
                           if (SpellRangeEntry const *pSpellRange = GetSpellRangeStore()->LookupEntry(spell->rangeIndex))
                              if (m_creature->GetDistance(fPosX, fPosY, fPosZ) <= pSpellRange->maxRange)
                              {
                                   m_creature->CastSpell(fPosX, fPosY, fPosZ, pSpell->m_uiSpellEntry[currentDifficulty], false);
                                   result = CAST_OK;
                                   break;
                               };
                         result = CAST_FAIL_TOO_FAR;
                   } else  result = CAST_FAIL_OTHER;
                   break;

            case CAST_ON_RANDOM_PLAYER:
                   if ( pSpell->LocData.x < 1 ) pTarget = _doSelect(0, false, 60.0f);
                       else pTarget = _doSelect(0, false, (float)pSpell->LocData.x);
                   result = _BSWCastOnTarget(pTarget, m_uiSpellIdx);
                   break;

            case APPLY_AURA_ALLPLAYERS:
                   {
                       Map* pMap = m_creature->GetMap();
                       Map::PlayerList const& pPlayers = pMap->GetPlayers();
                       for (Map::PlayerList::const_iterator itr = pPlayers.begin(); itr != pPlayers.end(); ++itr)
                       {
                           pTarget = itr->getSource();
                           if (pTarget && pTarget->isAlive() && pTarget->IsWithinDistInMap(m_creature, pSpell->LocData.x))
                           {
                               _doAura(m_uiSpellIdx, pTarget, EFFECT_INDEX_0);
                               result = CAST_OK;
                           }
                       }
                   }
                   break;

            case FORCE_CAST:
                   result = _BSWDoForceCast(m_uiSpellIdx, pTarget);
                   break;

            case SPELLTABLEPARM_NUMBER:
            default:
                   error_log("BSW: FAILED casting spell number %u type %u - type not exists",pSpell->m_uiSpellEntry[currentDifficulty], pSpell->m_CastTarget);
                   result = CAST_FAIL_OTHER;
                   break;
            };

        if (pSpell->textEntry && result == CAST_OK)
        {
            if (pTarget)
                DoScriptText(pSpell->textEntry,m_creature,pTarget);
            else
                DoScriptText(pSpell->textEntry,m_creature);
        };

    debug_log("BSW: Casted spell number %u, result = %u",pSpell->m_uiSpellEntry[currentDifficulty], result);

    return result;
};
CanCastResult BossSpellWorker::_BSWSpellSelector(uint8 m_uiSpellIdx, Unit* pTarget)
{
    SpellEntry const *spell;

    SpellTable* pSpell = &m_BossSpell[m_uiSpellIdx];

    Unit* pSummon = NULL;

        debug_log("BSW: Casting spell number %u type %u",pSpell->m_uiSpellEntry[currentDifficulty], pSpell->m_CastTarget);

        switch (pSpell->m_CastTarget) {

            case DO_NOTHING: 
                   return CAST_OK;

            case CAST_ON_SELF:
                   if (!pSpell->m_IsBugged) return _DoCastSpellIfCan(boss, pSpell->m_uiSpellEntry[currentDifficulty]);
                   else return _BSWDoCast(m_uiSpellIdx, boss);
                   break;

            case CAST_ON_SUMMONS:
                   if (!pTarget) return CAST_FAIL_OTHER;
                   else return _DoCastSpellIfCan(pTarget, pSpell->m_uiSpellEntry[currentDifficulty]);
                   break;

            case CAST_ON_VICTIM:
                   pTarget = boss->getVictim();
                   return _BSWCastOnTarget(pTarget, m_uiSpellIdx);
                   break;

            case CAST_ON_RANDOM:
                   pTarget = boss->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0);
                   return _BSWCastOnTarget(pTarget, m_uiSpellIdx);
                   break;

            case CAST_ON_BOTTOMAGGRO:
                   pTarget = boss->SelectAttackingTarget(ATTACKING_TARGET_BOTTOMAGGRO,0);
                   return _BSWCastOnTarget(pTarget, m_uiSpellIdx);
                   break;

            case CAST_ON_TARGET:
                   return _BSWCastOnTarget(pTarget, m_uiSpellIdx);
                   break;

            case APPLY_AURA_SELF:
                   spell = (SpellEntry *)GetSpellStore()->LookupEntry(pSpell->m_uiSpellEntry[currentDifficulty]);
                   if (spell)
                       if (boss->AddAura(new BossAura(spell, EFFECT_INDEX_0, &pSpell->varData, boss, boss)))
                              return CAST_OK;
                   return CAST_FAIL_OTHER;
                   break;

            case APPLY_AURA_TARGET:
                   if (!pTarget || !pTarget->IsInMap(boss)) return CAST_FAIL_OTHER;
                       _doAura(m_uiSpellIdx, pTarget, EFFECT_INDEX_0);
                       return CAST_OK;
                   break;

            case SUMMON_NORMAL:
                   pSummon = _doSummon(m_uiSpellIdx, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000);
                   if(pSummon) return CAST_OK;
                          else return CAST_FAIL_OTHER;
                   break;

            case SUMMON_TEMP:
                   pSummon = _doSummon(m_uiSpellIdx, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,
                                        urand(pSpell->m_uiSpellTimerMin[currentDifficulty],pSpell->m_uiSpellTimerMax[currentDifficulty]));
                   if(pSummon) return CAST_OK;
                          else return CAST_FAIL_OTHER;
                   break;

            case SUMMON_INSTANT:
                   pSummon = _doSummon(m_uiSpellIdx, TEMPSUMMON_MANUAL_DESPAWN,0);
                   if(pSummon) return CAST_OK;
                          else return CAST_FAIL_OTHER;
                   break;

            case CAST_ON_ALLPLAYERS:
            {
                    CanCastResult res1 = CAST_FAIL_OTHER;
                    Map::PlayerList const& pPlayers = pMap->GetPlayers();
                    for (Map::PlayerList::const_iterator itr = pPlayers.begin(); itr != pPlayers.end(); ++itr)
                    {
                        pTarget = itr->getSource();
                        if (pTarget && pTarget->isAlive() && pTarget->IsWithinDistInMap(boss, pSpell->LocData.x))
                           {
                               if (!pSpell->m_IsBugged) 
                                   {
                                       res1 = _DoCastSpellIfCan(pTarget, pSpell->m_uiSpellEntry[currentDifficulty]);
                                   }
                                   else 
                                   {
                                       _BSWDoCast(m_uiSpellIdx, pTarget);
                                       res1 = CAST_OK;
                                   };
                           };
                           return res1;
                     }
                   break;
            }

            case CAST_ON_FRENDLY:
                   pTarget = SelectLowHPFriendly(pSpell->LocData.x);
                   return _BSWCastOnTarget(pTarget, m_uiSpellIdx);
                   break;

            case CAST_ON_FRENDLY_LOWHP:
                   pTarget = SelectLowHPFriendly(pSpell->LocData.x);
                   return _BSWCastOnTarget(pTarget, m_uiSpellIdx);
                   break;

            case CAST_ON_RANDOM_POINT:
                   if (!pTarget) pTarget = boss;
                   if (pSpell->LocData.z <= 1.0f) {
                         float fPosX, fPosY, fPosZ;
                         if (!pTarget->IsPositionValid() || !pTarget->IsInMap(boss))
                            {
                                if (pTarget->GetTypeId() == TYPEID_PLAYER)
                                     error_log("BSW: CAST_ON_RANDOM_POINT FAILED: player has invalid position. SpellID is %u",pSpell->m_uiSpellEntry[currentDifficulty]);
                                else error_log("BSW: CAST_ON_RANDOM_POINT FAILED: creature has invalid position. SpellID is %u",pSpell->m_uiSpellEntry[currentDifficulty]);
                                return CAST_FAIL_OTHER;
                            }
                         pTarget->GetPosition(fPosX, fPosY, fPosZ);
                         pTarget->GetRandomPoint(fPosX, fPosY, fPosZ, urand((uint32)pSpell->LocData.x, (uint32)pSpell->LocData.y), fPosX, fPosY, fPosZ);
                                if ((int)fPosZ == 0)
                                {
                                    error_log("BSW: CAST_ON_RANDOM_POINT FAILED: Positon Z is NULL. Strange bug");
                                    return CAST_FAIL_OTHER;
                                 }
                         if (SpellEntry const *spell = (SpellEntry *)GetSpellStore()->LookupEntry(pSpell->m_uiSpellEntry[currentDifficulty]))
                           if (SpellRangeEntry const *pSpellRange = GetSpellRangeStore()->LookupEntry(spell->rangeIndex))
                              if (boss->GetDistance(fPosX, fPosY, fPosZ) <= pSpellRange->maxRange)
                                 {
                                     boss->CastSpell(fPosX, fPosY, fPosZ, pSpell->m_uiSpellEntry[currentDifficulty], false);
                                     return CAST_OK;
                                 };
                                 return CAST_FAIL_TOO_FAR;
                         } else  return CAST_FAIL_OTHER;
                   break;

            case CAST_ON_RANDOM_PLAYER:
                   if ( pSpell->LocData.x < 1 ) pTarget = SelectRandomPlayer();
                       else pTarget = SelectRandomPlayerAtRange((float)pSpell->LocData.x);
                   if (pTarget && pTarget->IsInMap(boss)) return _BSWCastOnTarget(pTarget, m_uiSpellIdx);
                       else return CAST_FAIL_OTHER;
                   break;

            case APPLY_AURA_ALLPLAYERS:
                   {
                       Map::PlayerList const& pPlayers = pMap->GetPlayers();
                       for (Map::PlayerList::const_iterator itr = pPlayers.begin(); itr != pPlayers.end(); ++itr)
                       {
                           pTarget = itr->getSource();
                           if (pTarget && pTarget->isAlive() && pTarget->IsWithinDistInMap(boss, pSpell->LocData.x))
                               _doAura(m_uiSpellIdx, pTarget, EFFECT_INDEX_0);
                       }
                   return CAST_OK;
                   }
                   break;

            case SPELLTABLEPARM_NUMBER:
            default:
                   return CAST_FAIL_OTHER;
                   break;
            };

    error_log("BSW: FAILED casting spell number %u type %u - type not exists",pSpell->m_uiSpellEntry[currentDifficulty], pSpell->m_CastTarget);

    return CAST_FAIL_OTHER;
};