Exemplo n.º 1
0
    static bool HandleLearnAllGMCommand(ChatHandler* handler, const char* /*args*/)
    {
        for (uint32 i = 0; i < GetSpellStore()->GetNumRows(); ++i)
        {
            SpellEntry const* spellInfo = sSpellStore.LookupEntry(i);
            if (!spellInfo || !SpellMgr::IsSpellValid(spellInfo, handler->GetSession()->GetPlayer(), false))
                continue;

            if (!sSpellMgr->IsSkillTypeSpell(i, SKILL_INTERNAL))
                continue;

            handler->GetSession()->GetPlayer()->learnSpell(i, false);
        }

        handler->SendSysMessage(LANG_LEARNING_GM_SKILLS);
        return true;
    }
Exemplo n.º 2
0
    boss_netherspiteAI(Creature* c) : ScriptedAI(c)
    {
        pInstance = c->GetInstanceData();

        for (int i=0; i<3; ++i)
        {
            PortalGUID[i] = 0;
            BeamTarget[i] = 0;
            BeamerGUID[i] = 0;
        }
        // need core fix
        for (int i=0; i<3; ++i)
        {
            if (SpellEntry *spell = (SpellEntry*)GetSpellStore()->LookupEntry(PlayerBuff[i]))
                spell->AttributesEx |= SPELL_ATTR_EX_NEGATIVE;
        }
    }
Exemplo n.º 3
0
bool ItemUse_item_petrov_cluster_bombs(Player* pPlayer, Item* pItem, const SpellCastTargets &pTargets)
{
    if (pPlayer->GetZoneId() != ZONE_ID_HOWLING)
        return false;

    if (!pPlayer->GetTransport() || pPlayer->GetAreaId() != AREA_ID_SHATTERED_STRAITS)
    {
        pPlayer->SendEquipError(EQUIP_ERR_NONE, pItem, NULL);

        if (const SpellEntry* pSpellInfo = GetSpellStore()->LookupEntry(SPELL_PETROV_BOMB))
            Spell::SendCastResult(pPlayer, pSpellInfo, 1, SPELL_FAILED_NOT_HERE);

        return true;
    }

    return false;
}
CanCastResult BossSpellWorker::_DoCastSpellIfCan(Unit* pTarget, uint32 uiSpell, uint32 uiCastFlags, uint64 uiOriginalCasterGUID)
{
    Unit* pCaster = boss;
    if (!pTarget) return CAST_FAIL_OTHER;

    if (uiCastFlags & CAST_FORCE_TARGET_SELF)
        pCaster = pTarget;

    // Allowed to cast only if not casting (unless we interrupt ourself) or if spell is triggered
    if (!pCaster->IsNonMeleeSpellCasted(false) || (uiCastFlags & (CAST_TRIGGERED | CAST_INTERRUPT_PREVIOUS)))
    {
        if (const SpellEntry* pSpell = GetSpellStore()->LookupEntry(uiSpell))
        {
            // If cast flag CAST_AURA_NOT_PRESENT is active, check if target already has aura on them
            if (uiCastFlags & CAST_AURA_NOT_PRESENT)
            {
                if (pTarget->HasAura(uiSpell))
                    return CAST_FAIL_TARGET_AURA;
            }

            // Check if cannot cast spell
            if (!(uiCastFlags & (CAST_FORCE_TARGET_SELF | CAST_FORCE_CAST)))
            {
                CanCastResult castResult = _CanCastSpell(pTarget, pSpell, uiCastFlags & CAST_TRIGGERED);

                if (castResult != CAST_OK)
                    return castResult;
            }

            // Interrupt any previous spell
            if (uiCastFlags & CAST_INTERRUPT_PREVIOUS && pCaster->IsNonMeleeSpellCasted(false))
                pCaster->InterruptNonMeleeSpells(false);

            pCaster->CastSpell(pTarget, pSpell, uiCastFlags & CAST_TRIGGERED, NULL, NULL, uiOriginalCasterGUID);
            return CAST_OK;
        }
        else
        {
            error_log("BSW: DoCastSpellIfCan by creature entry %u attempt to cast spell %u but spell does not exist.", boss->GetEntry(), uiSpell);
            return CAST_FAIL_OTHER;
        }
    }
    else
        return CAST_FAIL_IS_CASTING;
}
Exemplo n.º 5
0
    boss_nalorakkAI(Creature *c) : ScriptedAI(c)
    {
        MoveEvent = true;
        MovePhase = 0;
        pInstance = (c->GetInstanceData());

        SpellEntry *TempSpell = (SpellEntry*)GetSpellStore()->LookupEntry(SPELL_MANGLE);
        if(TempSpell)
        {
            TempSpell->EffectImplicitTargetA[1] = TARGET_UNIT_TARGET_ENEMY;
        }
        wLoc.coord_x = NalorakkWay[7][0];
        wLoc.coord_y = NalorakkWay[7][1];
        wLoc.coord_z = NalorakkWay[7][2];
        wLoc.orientation = 0;
        wLoc.mapid = m_creature->GetMapId();
        m_creature->setActive(true);
    }
Exemplo n.º 6
0
bool ItemUse_item_Capteur_Tellurique(Player* pPlayer, Item* pItem, const SpellCastTargets &pTargets)
{
	if(pPlayer->GetAreaId() == 4157)
	{
		if(pPlayer->GetPositionZ()  < 185.0f)
		{ 
			pPlayer->TeleportTo(pPlayer->GetMapId(),3329.524f,2543.395f,197.317f,4.950f);
			pPlayer->KilledMonsterCredit(27853,0);
		}
		else
			pPlayer->TeleportTo(pPlayer->GetMapId(),3414.0f,2363.01f,37.911f,3.102f);
	}
	else
	{
		Spell::SendCastResult(pPlayer, GetSpellStore()->LookupEntry(47097), 1, SPELL_FAILED_INCORRECT_AREA);
		return false;
	}
	return true;
}
    void EnfeebleHealthEffect()
    {
        const SpellEntry *info = GetSpellStore()->LookupEntry(SPELL_ENFEEBLE_EFFECT);
        if (!info)
            return;

        ThreatList const& tList = m_creature->getThreatManager().getThreatList();
        std::vector<Unit *> targets;

        if (tList.empty())
            return;

        //begin + 1 , so we don't target the one with the highest threat
        ThreatList::const_iterator itr = tList.begin();
        std::advance(itr, 1);
        for(; itr!= tList.end(); ++itr)                    //store the threat list in a different container
        {
            Unit *target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid());
                                                            //only on alive players
            if (target && target->isAlive() && target->GetTypeId() == TYPEID_PLAYER)
                targets.push_back(target);
        }

        //cut down to size if we have more than 5 targets
        while(targets.size() > 5)
            targets.erase(targets.begin()+rand()%targets.size());

        int i = 0;
        for(std::vector<Unit *>::iterator iter = targets.begin(); iter!= targets.end(); ++iter, ++i)
        {
            Unit *target = *iter;
            if (target)
            {
                enfeeble_targets[i] = target->GetGUID();
                enfeeble_health[i] = target->GetHealth();

                target->CastSpell(target, SPELL_ENFEEBLE, true, 0, 0, m_creature->GetGUID());
                target->SetHealth(1);
            }
        }

    }
Exemplo n.º 8
0
bool GOGossipSelect_go_ulduar_teleporter(Player *pPlayer, GameObject* pGo, uint32 sender, uint32 action)
{
    int32 damage = 0;
    if(sender != GOSSIP_SENDER_MAIN) return false;

    if(!pPlayer->getAttackers().empty()) return false;

    if(action >= 0 && action <= PORTALS_COUNT)
    pPlayer->TeleportTo(PortalLoc[action].map_num, PortalLoc[action].x, PortalLoc[action].y, PortalLoc[action].z, PortalLoc[action].o);
    if (PortalLoc[action].spellID != 0 )
           if (SpellEntry const* spell = (SpellEntry *)GetSpellStore()->LookupEntry(PortalLoc[action].spellID))
           {
               SpellAuraHolder *holder = CreateSpellAuraHolder(spell, pPlayer, pPlayer);
               Aura *aura = CreateAura(spell, EFFECT_INDEX_2, NULL, holder, pPlayer);
               holder->AddAura(aura, EFFECT_INDEX_2);
           }

    pPlayer->CLOSE_GOSSIP_MENU();
    return true;
}
Exemplo n.º 9
0
bool GOGossipSelect_go_ulduar_teleporter(Player *pPlayer, GameObject* pGo, uint32 sender, uint32 action)
{
    int32 damage = 0;
    if(sender != GOSSIP_SENDER_MAIN) return true;

    if(pPlayer->IsInCombat()) 
        return true;

    if(action >= 0 && action <= PORTALS_COUNT)
    pPlayer->TeleportTo(PortalLoc[action].map_num, PortalLoc[action].x, PortalLoc[action].y, PortalLoc[action].z, PortalLoc[action].o);
    if (PortalLoc[action].spellID != 0 )
        if (SpellEntry const* spell = (SpellEntry *)GetSpellStore()->LookupEntry(PortalLoc[action].spellID))
        {
            SpellAuraHolderPtr holder = CreateSpellAuraHolder(spell, pPlayer, pPlayer);
            Aura* aura = holder->CreateAura(AURA_CLASS_AURA, EFFECT_INDEX_2, NULL, holder, pPlayer, pPlayer, NULL);
            pPlayer->AddSpellAuraHolder(holder);
        }

    pPlayer->CLOSE_GOSSIP_MENU();
    return true;
}
Exemplo n.º 10
0
bool PlayerbotClassAI::castDispel (uint32 dispelSpell, Unit *dTarget, bool checkFirst, bool castExistingAura, bool skipFriendlyCheck, bool skipEquipStanceCheck)
{
    if (dispelSpell == 0 || !dTarget ) return false;
    //if (!canCast(dispelSpell, dTarget, true)) return false; //Needless cpu cycles wasted, usually a playerbot can cast a dispell
    const SpellEntry *dSpell = GetSpellStore()->LookupEntry(dispelSpell);
    if (!dSpell) return false;

    for (uint8 i = 0 ; i < MAX_SPELL_EFFECTS ; ++i)
    {
        if (dSpell->Effect[i] != (uint32)SPELL_EFFECT_DISPEL) continue;
        uint32 dispel_type = dSpell->EffectMiscValue[i];
        uint32 dispelMask  = GetDispellMask(DispelType(dispel_type));
        Unit::AuraMap const& auras = dTarget->GetOwnedAuras();
        for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); itr++)
        {
            Aura * aura = itr->second;
            AuraApplication * aurApp = aura->GetApplicationOfTarget(dTarget->GetGUID());
            if (!aurApp)
                continue;

            if ((1<<aura->GetSpellProto()->Dispel) & dispelMask)
            {
                if(aura->GetSpellProto()->Dispel == DISPEL_MAGIC)
                {
                    bool positive = aurApp->IsPositive() ? (!(aura->GetSpellProto()->AttributesEx & SPELL_ATTR0_UNK7)) : false;

                    // do not remove positive auras if friendly target
                    //               negative auras if non-friendly target
                    if(positive == dTarget->IsFriendlyTo(GetPlayerBot()))
                        continue;
                }
                // If there is a successfull match return, else continue searching.
                if (CastSpell(dSpell, dTarget, checkFirst, castExistingAura, skipFriendlyCheck, skipEquipStanceCheck)) {
                    return true;
                }
            }
        }
    }
    return false;
}
Exemplo n.º 11
0
 void CastDoom()
 {
     SpellEntry *spellInfo = (SpellEntry *)GetSpellStore()->LookupEntry(SPELL_DOOM);
     if (spellInfo)
         //target without tank
         if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,1))
         {
             if (pTarget->GetTypeId() == TYPEID_PLAYER)
             {
                 for(uint8 i=0; i< MAX_EFFECT_INDEX; ++i)
                 {
                     uint8 eff = spellInfo->Effect[SpellEffectIndex(i)];
                     if (eff >= TOTAL_SPELL_EFFECTS)
                         continue;
                     //uint8 i=1;
                     /*pTarget->AddAura(new AzgalorDoom(spellInfo, SpellEffectIndex(i), NULL, pTarget, pTarget));*/
                 }
             }
             else
                 DoomTimer = 1000;
         }
 }
Exemplo n.º 12
0
 void CastMark()
 {
     SpellEntry *spellInfo = (SpellEntry *)GetSpellStore()->LookupEntry(SPELL_MARK);
     if (spellInfo)
     {
         std::list<HostileReference *> t_list = m_creature->getThreatManager().getThreatList();
         for(std::list<HostileReference *>::iterator itr = t_list.begin(); itr!= t_list.end(); ++itr)
         {
             Unit *target = m_creature->GetMap()->GetUnit((*itr)->getUnitGuid());
             if (target && target->GetTypeId() == TYPEID_PLAYER && target->getPowerType() == POWER_MANA)
             {
                 for(uint32 i=0; i < MAX_EFFECT_INDEX; ++i)
                 {
                     uint8 eff = spellInfo->Effect[SpellEffectIndex(i)];
                     if (eff >= TOTAL_SPELL_EFFECTS)
                         continue;
                     /*target->AddAura(new KazrogalMark(spellInfo, SpellEffectIndex(i), NULL, target, target));*/
                 }    
             }
         }
     }
 }
Exemplo n.º 13
0
		void EnfeebleHealthEffect() {
			const SpellEntry *info = GetSpellStore()->LookupEntry(
					SPELL_ENFEEBLE_EFFECT);
			if (!info)
				return;

			std::list<HostileReference *> t_list =
					me->getThreatManager().getThreatList();
			std::vector<Unit *> targets;

			if (!t_list.size())
				return;

			//begin + 1, so we don't target the one with the highest threat
			std::list<HostileReference *>::const_iterator itr = t_list.begin();
			std::advance(itr, 1);
			for (; itr != t_list.end(); ++itr) //store the threat list in a different container
				if (Unit *pTarget = Unit::GetUnit(*me, (*itr)->getUnitGuid()))
					if (pTarget->isAlive()
							&& pTarget->GetTypeId() == TYPEID_PLAYER)
						targets.push_back(pTarget);

			//cut down to size if we have more than 5 targets
			while (targets.size() > 5)
				targets.erase(targets.begin() + rand() % targets.size());

			uint32 i = 0;
			for (std::vector<Unit *>::const_iterator iter = targets.begin();
					iter != targets.end(); ++iter, ++i)
				if (Unit *pTarget = *iter) {
					enfeeble_targets[i] = pTarget->GetGUID();
					enfeeble_health[i] = pTarget->GetHealth();

					pTarget->CastSpell(pTarget, SPELL_ENFEEBLE, true, 0, 0,
							me->GetGUID());
					pTarget->SetHealth(1);
				}
		}
Exemplo n.º 14
0
bool BSWScriptedAI::_doAura(uint8 m_uiSpellIdx, Unit* pTarget, SpellEffectIndex index)
{
    SpellTable* pSpell = &m_BossSpell[m_uiSpellIdx];

    if (!pTarget || !pTarget->IsInMap(m_creature) || !pTarget->isAlive())
        {
           error_log("BSW: FAILED adding aura of spell number %u - no target or target not in map or target is dead",pSpell->m_uiSpellEntry[currentDifficulty]);
           return false;
        }

    if (_hasAura(m_uiSpellIdx,pTarget))
         debug_log("BSW: adding aura stack from spell %u index %u",pSpell->m_uiSpellEntry[currentDifficulty], index);
    else debug_log("BSW: adding new aura from spell %u index %u",pSpell->m_uiSpellEntry[currentDifficulty], index);

    SpellEntry const *spell = (SpellEntry *)GetSpellStore()->LookupEntry(pSpell->m_uiSpellEntry[currentDifficulty]);
    if (spell && spell->Effect[index] < TOTAL_SPELL_EFFECTS)
    {
        if (IsSpellAppliesAura(spell, (1 << EFFECT_INDEX_0) | (1 << EFFECT_INDEX_1) | (1 << EFFECT_INDEX_2)) || IsSpellHaveEffect(spell, SPELL_EFFECT_PERSISTENT_AREA_AURA))
        {
            SpellAuraHolder *holder = CreateSpellAuraHolder(spell, pTarget, pTarget);

            int32 basepoint = pSpell->varData ?  pSpell->varData - 1 : spell->EffectBasePoints[index] + 1;

            if ( IsAreaAuraEffect(spell->Effect[index]) ||
                spell->Effect[index] == SPELL_EFFECT_APPLY_AURA  ||
                spell->Effect[index] == SPELL_EFFECT_PERSISTENT_AREA_AURA )
                {
                    Aura *aura = CreateAura(spell, SpellEffectIndex(index), &basepoint, holder, pTarget);
                    holder->AddAura(aura, SpellEffectIndex(index));
                    return true;
                }
        }
    }

    error_log("BSW: FAILED adding aura from spell %u index %u",pSpell->m_uiSpellEntry[currentDifficulty], index);

    return false;
};
Exemplo n.º 15
0
		// some targeting issues with the spell, so use this workaround as temporary solution
		void DoWorkaroundForQuestCredit() {
			Map* pMap = me->GetMap();

			if (!pMap || pMap->IsHeroic())
				return;

			Map::PlayerList const &lList = pMap->GetPlayers();

			if (lList.isEmpty())
				return;

			SpellEntry const* pSpell = GetSpellStore()->LookupEntry(
					SPELL_ORB_KILL_CREDIT);

			for (Map::PlayerList::const_iterator i = lList.begin();
					i != lList.end(); ++i) {
				if (Player* pPlayer = i->getSource()) {
					if (pSpell && pSpell->EffectMiscValue[0])
						pPlayer->KilledMonsterCredit(pSpell->EffectMiscValue[0],
								0);
				}
			}
		}
Exemplo n.º 16
0
    void UpdateAI(const uint32 diff)
    {
      if(!me->IsNonMeleeSpellCasted(false) && !me->isInCombat())
      {
          if(OOCTimer < diff)
          {
              HandleOffCombatEffects();
              OOCTimer = 10000;
          }
          else
              OOCTimer -= diff;
      }

      if(!UpdateVictim())
          return;

      if(Frostbolt_Timer < diff)
      {
          AddSpellToCast(me->getVictim(), SPELL_FROSTBOLT);
          Frostbolt_Timer = SpellMgr::GetSpellCastTime(GetSpellStore()->LookupEntry(SPELL_FROSTBOLT))-(diff+100);
      }
      else
          Frostbolt_Timer -= diff;

      if(Arcane_Nova_Timer < diff)
      {
          ClearCastQueue();
          AddSpellToCast(SPELL_ARCANE_NOVA, CAST_SELF);
          Arcane_Nova_Timer = urand(16000, 20000);
      }
      else
          Arcane_Nova_Timer -= diff;

      CheckCasterNoMovementInRange(diff, 35.0);
      CastNextSpellIfAnyAndReady();
      DoMeleeAttackIfReady();
    }
Exemplo n.º 17
0
 void UpdateAI(const uint32 diff)
 {
     if (!Vorpil)
     {
         me->DealDamage(me, me->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
         return;
     }
     if (move <= diff)
     {
         if (sacrificed)
         {
             SpellEntry* spell = (SpellEntry*)GetSpellStore()->LookupEntry(HeroicMode ? H_SPELL_EMPOWERING_SHADOWS : SPELL_EMPOWERING_SHADOWS);
             if (spell)
                 Vorpil->AddAura(new EmpoweringShadowsAura(spell, 0, NULL, Vorpil, me));
             Vorpil->SetHealth(Vorpil->GetHealth() + Vorpil->GetMaxHealth() / 25);
             DoCast(me, SPELL_SHADOW_NOVA, true);
             me->DealDamage(me, me->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
             return;
         }
         me->GetMotionMaster()->MoveFollow(Vorpil, 0, 0);
         if (me->GetDistance(Vorpil) < 3)
         {
             DoCast(me, SPELL_SACRIFICE, false);
             sacrificed = true;
             move = 500;
             return;
         }
         if (!Vorpil->IsInCombat() || Vorpil->isDead())
         {
             me->DealDamage(me, me->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
             return;
         }
         move = 1000;
     }
     else move -= diff;
 }
Exemplo n.º 18
0
void FillSpellSummary()
{
    SpellSummary = new TSpellSummary[GetSpellStore()->GetNumRows()];

    SpellEntry const* TempSpell;

    for (int i=0; i < GetSpellStore()->GetNumRows(); i++)
    {
        SpellSummary[i].Effects = 0;
        SpellSummary[i].Targets = 0;

        TempSpell = GetSpellStore()->LookupEntry(i);
        //This spell doesn't exist
        if (!TempSpell)
            continue;

        for (int j=0; j<3; j++)
        {
            //Spell targets self
            if (TempSpell->EffectImplicitTargetA[j] == TARGET_SELF)
                SpellSummary[i].Targets |= 1 << (SELECT_TARGET_SELF-1);

            //Spell targets a single enemy
            if (TempSpell->EffectImplicitTargetA[j] == TARGET_CHAIN_DAMAGE ||
                TempSpell->EffectImplicitTargetA[j] == TARGET_CURRENT_ENEMY_COORDINATES)
                SpellSummary[i].Targets |= 1 << (SELECT_TARGET_SINGLE_ENEMY-1);

            //Spell targets AoE at enemy
            if (TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA ||
                TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA_INSTANT ||
                TempSpell->EffectImplicitTargetA[j] == TARGET_CASTER_COORDINATES ||
                TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA_CHANNELED)
                SpellSummary[i].Targets |= 1 << (SELECT_TARGET_AOE_ENEMY-1);

            //Spell targets an enemy
            if (TempSpell->EffectImplicitTargetA[j] == TARGET_CHAIN_DAMAGE ||
                TempSpell->EffectImplicitTargetA[j] == TARGET_CURRENT_ENEMY_COORDINATES ||
                TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA ||
                TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA_INSTANT ||
                TempSpell->EffectImplicitTargetA[j] == TARGET_CASTER_COORDINATES ||
                TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA_CHANNELED)
                SpellSummary[i].Targets |= 1 << (SELECT_TARGET_ANY_ENEMY-1);

            //Spell targets a single friend(or self)
            if (TempSpell->EffectImplicitTargetA[j] == TARGET_SELF ||
                TempSpell->EffectImplicitTargetA[j] == TARGET_SINGLE_FRIEND ||
                TempSpell->EffectImplicitTargetA[j] == TARGET_SINGLE_PARTY)
                SpellSummary[i].Targets |= 1 << (SELECT_TARGET_SINGLE_FRIEND-1);

            //Spell targets aoe friends
            if (TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_PARTY_AROUND_CASTER ||
                TempSpell->EffectImplicitTargetA[j] == TARGET_AREAEFFECT_PARTY ||
                TempSpell->EffectImplicitTargetA[j] == TARGET_CASTER_COORDINATES)
                SpellSummary[i].Targets |= 1 << (SELECT_TARGET_AOE_FRIEND-1);

            //Spell targets any friend(or self)
            if (TempSpell->EffectImplicitTargetA[j] == TARGET_SELF ||
                TempSpell->EffectImplicitTargetA[j] == TARGET_SINGLE_FRIEND ||
                TempSpell->EffectImplicitTargetA[j] == TARGET_SINGLE_PARTY ||
                TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_PARTY_AROUND_CASTER ||
                TempSpell->EffectImplicitTargetA[j] == TARGET_AREAEFFECT_PARTY ||
                TempSpell->EffectImplicitTargetA[j] == TARGET_CASTER_COORDINATES)
                SpellSummary[i].Targets |= 1 << (SELECT_TARGET_ANY_FRIEND-1);

            //Make sure that this spell includes a damage effect
            if (TempSpell->Effect[j] == SPELL_EFFECT_SCHOOL_DAMAGE ||
                TempSpell->Effect[j] == SPELL_EFFECT_INSTAKILL ||
                TempSpell->Effect[j] == SPELL_EFFECT_ENVIRONMENTAL_DAMAGE ||
                TempSpell->Effect[j] == SPELL_EFFECT_HEALTH_LEECH)
                SpellSummary[i].Effects |= 1 << (SELECT_EFFECT_DAMAGE-1);

            //Make sure that this spell includes a healing effect (or an apply aura with a periodic heal)
            if (TempSpell->Effect[j] == SPELL_EFFECT_HEAL ||
                TempSpell->Effect[j] == SPELL_EFFECT_HEAL_MAX_HEALTH ||
                TempSpell->Effect[j] == SPELL_EFFECT_HEAL_MECHANICAL ||
                (TempSpell->Effect[j] == SPELL_EFFECT_APPLY_AURA  && TempSpell->EffectApplyAuraName[j]== 8))
                SpellSummary[i].Effects |= 1 << (SELECT_EFFECT_HEALING-1);

            //Make sure that this spell applies an aura
            if (TempSpell->Effect[j] == SPELL_EFFECT_APPLY_AURA)
                SpellSummary[i].Effects |= 1 << (SELECT_EFFECT_AURA-1);
        }
    }
}
Exemplo n.º 19
0
SpellEntry const* ScriptedAI::SelectSpell(Unit* Target, int32 School, int32 Mechanic, SelectTarget Targets, uint32 PowerCostMin, uint32 PowerCostMax, float RangeMin, float RangeMax, SelectEffect Effects)
{
    //No target so we can't cast
    if (!Target)
        return false;

    //Silenced so we can't cast
    if (m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED))
        return false;

    //Using the extended script system we first create a list of viable spells
    SpellEntry const* Spell[4];
    Spell[0] = 0;
    Spell[1] = 0;
    Spell[2] = 0;
    Spell[3] = 0;

    uint32 SpellCount = 0;

    SpellEntry const* TempSpell;
    SpellRangeEntry const* TempRange;

    //Check if each spell is viable(set it to null if not)
    for (uint32 i = 0; i < 4; i++)
    {
        TempSpell = GetSpellStore()->LookupEntry(m_creature->m_spells[i]);

        //This spell doesn't exist
        if (!TempSpell)
            continue;

        // Targets and Effects checked first as most used restrictions
        //Check the spell targets if specified
        if (Targets && !(SpellSummary[m_creature->m_spells[i]].Targets & (1 << (Targets-1))))
            continue;

        //Check the type of spell if we are looking for a specific spell type
        if (Effects && !(SpellSummary[m_creature->m_spells[i]].Effects & (1 << (Effects-1))))
            continue;

        //Check for school if specified
        if (School >= 0 && TempSpell->SchoolMask & School)
            continue;

        //Check for spell mechanic if specified
        if (Mechanic >= 0 && TempSpell->Mechanic != Mechanic)
            continue;

        //Make sure that the spell uses the requested amount of power
        if (PowerCostMin &&  TempSpell->manaCost < PowerCostMin)
            continue;

        if (PowerCostMax && TempSpell->manaCost > PowerCostMax)
            continue;

        //Continue if we don't have the mana to actually cast this spell
        if (TempSpell->manaCost > m_creature->GetPower((Powers)TempSpell->powerType))
            continue;

        //Get the Range
        TempRange = GetSpellRangeStore()->LookupEntry(TempSpell->rangeIndex);

        //Spell has invalid range store so we can't use it
        if (!TempRange)
            continue;

        //Check if the spell meets our range requirements
        if (RangeMin && TempRange->maxRange < RangeMin)
            continue;
        if (RangeMax && TempRange->maxRange > RangeMax)
            continue;

        //Check if our target is in range
        if (m_creature->IsWithinDistInMap(Target, TempRange->minRange) || !m_creature->IsWithinDistInMap(Target, TempRange->maxRange))
            continue;

        //All good so lets add it to the spell list
        Spell[SpellCount] = TempSpell;
        SpellCount++;
    }

    //We got our usable spells so now lets randomly pick one
    if (!SpellCount)
        return NULL;

    return Spell[rand()%SpellCount];
}
Exemplo n.º 20
0
bool EffectDummyCreature_spell_dummy_npc(Unit* pCaster, uint32 uiSpellId, SpellEffectIndex uiEffIndex, Creature* pCreatureTarget)
{
    switch (uiSpellId)
    {
        case SPELL_ADMINISTER_ANTIDOTE:
        {
            if (uiEffIndex == EFFECT_INDEX_0)
            {
                if (pCreatureTarget->GetEntry() != NPC_HELBOAR)
                    return true;

                // possible needs check for quest state, to not have any effect when quest really complete

                pCreatureTarget->UpdateEntry(NPC_DREADTUSK);
                return true;
            }
            return true;
        }
        case SPELL_APPLY_SALVE:
        {
            if (uiEffIndex == EFFECT_INDEX_0)
            {
                if (pCaster->GetTypeId() != TYPEID_PLAYER)
                    return true;

                if (pCreatureTarget->GetEntry() != NPC_SICKLY_DEER && pCreatureTarget->GetEntry() != NPC_SICKLY_GAZELLE)
                    return true;

                // Update entry, remove aura, set the kill credit and despawn
                uint32 uiUpdateEntry = pCreatureTarget->GetEntry() == NPC_SICKLY_DEER ? NPC_CURED_DEER : NPC_CURED_GAZELLE;
                pCreatureTarget->RemoveAurasDueToSpell(SPELL_SICKLY_AURA);
                pCreatureTarget->UpdateEntry(uiUpdateEntry);
                ((Player*)pCaster)->KilledMonsterCredit(uiUpdateEntry);
                pCreatureTarget->ForcedDespawn(20000);

                return true;
            }
            return true;
        }
        case SPELL_DARKMENDER_TINCTURE:
        {
            if (uiEffIndex == EFFECT_INDEX_0)
            {
                if (pCaster->GetTypeId() != TYPEID_PLAYER)
                    return true;

                // TODO: find/fix visual for effect, no related spells found doing this

                pCreatureTarget->CastSpell(pCreatureTarget, SPELL_SUMMON_CORRUPTED_SCARLET, true);

                ((Player*)pCaster)->KilledMonsterCredit(NPC_CORPSES_RISE_CREDIT_BUNNY);

                pCreatureTarget->ForcedDespawn();
                return true;
            }
            return true;
        }
        case SPELL_DISCIPLINING_ROD:
        {
            if (uiEffIndex == EFFECT_INDEX_0)
            {
                if (pCreatureTarget->getStandState() == UNIT_STAND_STATE_STAND)
                    return true;

                switch (urand(1, 2))
                {
                    case 1:
                    {
                        switch (urand(1, 3))
                        {
                            case 1: DoScriptText(SAY_RAND_ATTACK1, pCreatureTarget); break;
                            case 2: DoScriptText(SAY_RAND_ATTACK2, pCreatureTarget); break;
                            case 3: DoScriptText(SAY_RAND_ATTACK3, pCreatureTarget); break;
                        }

                        pCreatureTarget->SetStandState(UNIT_STAND_STATE_STAND);
                        pCreatureTarget->AI()->AttackStart(pCaster);
                        break;
                    }
                    case 2:
                    {
                        switch (urand(1, 3))
                        {
                            case 1: DoScriptText(SAY_RAND_WORK1, pCreatureTarget); break;
                            case 2: DoScriptText(SAY_RAND_WORK2, pCreatureTarget); break;
                            case 3: DoScriptText(SAY_RAND_WORK3, pCreatureTarget); break;
                        }

                        pCreatureTarget->SetStandState(UNIT_STAND_STATE_STAND);
                        pCreatureTarget->HandleEmote(EMOTE_STATE_WORK);
                        break;
                    }
                }

                return true;
            }
            return true;
        }
        case SPELL_INOCULATE_OWLKIN:
        {
            if (uiEffIndex == EFFECT_INDEX_0)
            {
                if (pCreatureTarget->GetEntry() != NPC_OWLKIN)
                    return true;

                pCreatureTarget->UpdateEntry(NPC_OWLKIN_INOC);
                ((Player*)pCaster)->KilledMonsterCredit(NPC_OWLKIN_INOC);

                // set despawn timer, since we want to remove creature after a short time
                pCreatureTarget->ForcedDespawn(15000);

                return true;
            }
            return true;
        }
        case SPELL_LIQUID_FIRE:
        {
            if (uiEffIndex == EFFECT_INDEX_0)
            {
                if (pCaster->GetTypeId() == TYPEID_PLAYER)
                {
                    if (pCreatureTarget->HasAura(SPELL_LIQUID_FIRE_AURA))
                        return true;

                    if (pCreatureTarget->GetEntry() == NPC_ELK)
                    {
                        pCreatureTarget->CastSpell(pCreatureTarget, SPELL_LIQUID_FIRE_AURA, true);
                        ((Player*)pCaster)->KilledMonsterCredit(NPC_ELK_BUNNY);
                    }
                    else if (pCreatureTarget->GetEntry() == NPC_GRIZZLY)
                    {
                        pCreatureTarget->CastSpell(pCreatureTarget, SPELL_LIQUID_FIRE_AURA, true);
                        ((Player*)pCaster)->KilledMonsterCredit(NPC_GRIZZLY_BUNNY);
                    }
                }
                return true;
            }
            return true;
        }
        case SPELL_MODIFIED_MOJO:
        {
            if (uiEffIndex == EFFECT_INDEX_0)
            {
                if (pCreatureTarget->GetEntry() != NPC_PROPHET_OF_SSERATUS)
                    return true;

                // Apparently done before updateEntry, so need to make a way to handle that
                // "Mmm, more mojo"
                // "%s drinks the Mojo"
                // "NOOOOOOOOOOOOooooooo...............!"

                pCreatureTarget->UpdateEntry(NPC_WEAK_PROPHET_OF_SSERATUS);
                return true;
            }
            return true;
        }
        case SPELL_FEL_SIPHON_DUMMY:
        {
            if (uiEffIndex == EFFECT_INDEX_0)
            {
                if (pCreatureTarget->GetEntry() != NPC_FELBLOOD_INITIATE)
                    return true;

                pCreatureTarget->UpdateEntry(NPC_EMACIATED_FELBLOOD);
                return true;
            }
            return true;
        }
        case SPELL_SACRED_CLEANSING:
        {
            if (uiEffIndex == EFFECT_INDEX_1)
            {
                if (pCreatureTarget->GetEntry() != NPC_MORBENT)
                    return true;

                pCreatureTarget->UpdateEntry(NPC_WEAKENED_MORBENT);
                return true;
            }
            return true;
        }
        case SPELL_SEEDS_OF_NATURES_WRATH:
        {
            if (uiEffIndex == EFFECT_INDEX_0)
            {
                uint32 uiNewEntry = 0;

                switch (pCreatureTarget->GetEntry())
                {
                    case NPC_REANIMATED_FROSTWYRM:  uiNewEntry = NPC_WEAK_REANIMATED_FROSTWYRM; break;
                    case NPC_TURGID:                uiNewEntry = NPC_WEAK_TURGID; break;
                    case NPC_DEATHGAZE:             uiNewEntry = NPC_WEAK_DEATHGAZE; break;
                }

                if (uiNewEntry)
                    pCreatureTarget->UpdateEntry(uiNewEntry);

                return true;
            }
            return true;
        }
        case SPELL_STRENGTH_ANCIENTS:
        {
            if (uiEffIndex == EFFECT_INDEX_0)
            {
                if (pCaster->GetTypeId() == TYPEID_PLAYER)
                {
                    if (urand(0, 1))
                    {
                        DoScriptText(EMOTE_AGGRO, pCreatureTarget);
                        pCreatureTarget->setFaction(FACTION_HOSTILE);
                        pCreatureTarget->AI()->AttackStart(pCaster);
                    }
                    else
                    {
                        DoScriptText(EMOTE_CREATE, pCreatureTarget);
                        pCaster->CastSpell(pCaster, SPELL_CREATE_BARK_WALKERS, true);
                        pCreatureTarget->ForcedDespawn(5000);
                    }
                }
                return true;
            }
            return true;
        }
        case SPELL_TAG_MURLOC_PROC:
        {
            if (uiEffIndex == EFFECT_INDEX_0)
            {
                if (pCreatureTarget->GetEntry() == NPC_BLACKSILT_MURLOC)
                    pCreatureTarget->UpdateEntry(NPC_TAGGED_MURLOC);
            }
            return true;
        }
        case SPELL_THROW_BOULDER:
        {
            if (uiEffIndex == EFFECT_INDEX_0)
            {
                if (pCaster->GetTypeId() != TYPEID_PLAYER)
                    return true;

                if (pCreatureTarget->GetEntry() != NPC_IRON_RUNESHAPER && pCreatureTarget->GetEntry() != NPC_RUNE_REAVER)
                    return true;

                pCreatureTarget->CastSpell(pCreatureTarget, SPELL_BOULBER_IMPACT, true);
                pCaster->CastSpell(pCaster, SPELL_BOULDER_TOSS_CREDIT, true);

                return true;
            }
            return true;
        }
        case SPELL_ULTRASONIC_SCREWDRIVER:
        {
            if (uiEffIndex == EFFECT_INDEX_0)
            {
                if (pCreatureTarget->IsCorpse())
                {
                    uint32 newSpellId = 0;

                    switch (pCreatureTarget->GetEntry())
                    {
                        case NPC_COLLECT_A_TRON:    newSpellId = SPELL_SUMMON_COLLECT_A_TRON; break;
                        case NPC_DEFENDO_TANK:      newSpellId = SPELL_SUMMON_DEFENDO_TANK; break;
                        case NPC_SCAVENGE_A8:       newSpellId = SPELL_SUMMON_SCAVENGE_A8; break;
                        case NPC_SCAVENGE_B6:       newSpellId = SPELL_SUMMON_SCAVENGE_B6; break;
                        case NPC_SENTRY_BOT:        newSpellId = SPELL_SUMMON_SENTRY_BOT; break;
                    }

                    if (const SpellEntry* pSpell = GetSpellStore()->LookupEntry(newSpellId))
                    {
                        pCaster->CastSpell(pCreatureTarget, pSpell->Id, true);

                        if (Pet* pPet = pCaster->FindGuardianWithEntry(pSpell->GetEffectMiscValue(SpellEffectIndex(uiEffIndex))))
                            pPet->CastSpell(pCaster, SPELL_REPROGRAM_KILL_CREDIT, true);

                        pCreatureTarget->ForcedDespawn();
                    }
                }
                return true;
            }
            return true;
        }
        case SPELL_ORB_OF_MURLOC_CONTROL:
        {
            pCreatureTarget->CastSpell(pCaster, SPELL_GREENGILL_SLAVE_FREED, true);

            // Freed Greengill Slave
            pCreatureTarget->UpdateEntry(NPC_FREED_GREENGILL_SLAVE);

            pCreatureTarget->CastSpell(pCreatureTarget, SPELL_ENRAGE, true);

            return true;
        }
        case SPELL_FUMPING:
        {
            if (uiEffIndex == EFFECT_INDEX_2)
            {
                switch (urand(0, 2))
                {
                    case 0:
                    {
                        pCaster->CastSpell(pCreatureTarget, SPELL_SUMMON_HAISHULUD, true);
                        break;
                    }
                    case 1:
                    {
                        for (int i = 0; i < 2; ++i)
                        {
                            if (Creature* pSandGnome = pCaster->SummonCreature(NPC_SAND_GNOME, pCreatureTarget->GetPositionX(), pCreatureTarget->GetPositionY(), pCreatureTarget->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_OOC_DESPAWN, 30000))
                                pSandGnome->AI()->AttackStart(pCaster);
                        }
                        break;
                    }
                    case 2:
                    {
                        for (int i = 0; i < 2; ++i)
                        {
                            if (Creature* pMatureBoneSifter = pCaster->SummonCreature(NPC_MATURE_BONE_SIFTER, pCreatureTarget->GetPositionX(), pCreatureTarget->GetPositionY(), pCreatureTarget->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_OOC_DESPAWN, 30000))
                                pMatureBoneSifter->AI()->AttackStart(pCaster);
                        }
                        break;
                    }
                }
                pCreatureTarget->ForcedDespawn();
            }
            return true;
        }
        case SPELL_AHUNAES_KNIFE:
        {
            if (uiEffIndex == EFFECT_INDEX_0)
            {
                if (pCaster->GetTypeId() != TYPEID_PLAYER)
                    return true;

                ((Player*)pCaster)->KilledMonsterCredit(NPC_SCALPS_KILL_CREDIT_BUNNY);
                pCreatureTarget->ForcedDespawn();
                return true;
            }
            return true;
        }
        case SPELL_TAILS_UP_GENDER_MASTER:
        {
            if (uiEffIndex == EFFECT_INDEX_0)
            {
                bool isMale = urand(0, 1);
                Player* pPlayer = pCreatureTarget->GetLootRecipient();

                if (isMale)
                    DoScriptText(SAY_ITS_MALE, pCreatureTarget, pPlayer);
                else
                    DoScriptText(SAY_ITS_FEMALE, pCreatureTarget, pPlayer);

                switch (pCreatureTarget->GetEntry())
                {
                    case NPC_FROST_LEOPARD:
                    {
                        if (isMale)
                            pCreatureTarget->CastSpell(pCreatureTarget, SPELL_TAILS_UP_AURA, true);
                        else
                        {
                            pPlayer->KilledMonsterCredit(NPC_LEOPARD_KILL_CREDIT, pCreatureTarget->GetObjectGuid());
                            pCreatureTarget->CastSpell(pPlayer, SPELL_FORCE_LEOPARD_SUMMON, true);
                            pCreatureTarget->ForcedDespawn();
                        }

                        break;
                    }
                    case NPC_ICEPAW_BEAR:
                    {
                        if (isMale)
                            pCreatureTarget->CastSpell(pCreatureTarget, SPELL_TAILS_UP_AURA, true);
                        else
                        {
                            pPlayer->KilledMonsterCredit(NPC_BEAR_KILL_CREDIT, pCreatureTarget->GetObjectGuid());
                            pCreatureTarget->CastSpell(pPlayer, SPELL_FORCE_BEAR_SUMMON, true);
                            pCreatureTarget->ForcedDespawn();
                        }

                        break;
                    }
                }
                return true;
            }
            return true;
        }
        case SPELL_THROW_GORDAWG_BOULDER:
        {
            if (uiEffIndex == EFFECT_INDEX_0)
            {
                for (int i = 0; i < 3; ++i)
                {
                    if (irand(i, 2))                        // 2-3 summons
                        pCreatureTarget->SummonCreature(NPC_MINION_OF_GUROK, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_CORPSE_DESPAWN, 5000);
                }

                if (pCreatureTarget->getVictim())
                {
                    pCaster->DealDamage(pCreatureTarget, pCreatureTarget->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
                    return true;
                }

                // If not in combat, no xp or loot
                pCreatureTarget->SetDeathState(JUST_DIED);
                pCreatureTarget->SetHealth(0);
                return true;
            }
            return true;
        }
        case SPELL_HIT_APPLE:
        {
            if (uiEffIndex == EFFECT_INDEX_0)
            {
                if (pCaster->GetTypeId() == TYPEID_PLAYER)
                    ((Player*)pCaster)->KilledMonsterCredit(pCreatureTarget->GetEntry(), pCreatureTarget->GetObjectGuid());

                pCreatureTarget->CastSpell(pCreatureTarget, SPELL_APPLE_FALLS_TO_GROUND, false);

                if (Creature* pLuckyWilhelm = GetClosestCreatureWithEntry(pCreatureTarget, NPC_LUCKY_WILHELM, 2 * INTERACTION_DISTANCE))
                    DoScriptText(SAY_LUCKY_HIT_APPLE, pLuckyWilhelm);
            }
            return true;
        }
        case SPELL_MISS_APPLE:
        {
            if (uiEffIndex == EFFECT_INDEX_0)
            {
                switch (urand(1, 3))
                {
                    case 1: DoScriptText(SAY_LUCKY_HIT_1, pCreatureTarget); break;
                    case 2: DoScriptText(SAY_LUCKY_HIT_2, pCreatureTarget); break;
                    case 3: DoScriptText(SAY_LUCKY_HIT_3, pCreatureTarget); break;
                }

                if (Creature* pDrostan = GetClosestCreatureWithEntry(pCreatureTarget, NPC_DROSTAN, 4 * INTERACTION_DISTANCE))
                    DoScriptText(urand(0, 1) ? SAY_DROSTAN_GOT_LUCKY_1 : SAY_DROSTAN_GOT_LUCKY_2, pDrostan);
            }
            return true;
        }
        case SPELL_MISS_APPLE_HIT_BIRD:
        {
            if (uiEffIndex == EFFECT_INDEX_0)
            {
                if (Creature* pDrostan = GetClosestCreatureWithEntry(pCreatureTarget, NPC_DROSTAN, 5 * INTERACTION_DISTANCE))
                    DoScriptText(urand(0, 1) ? SAY_DROSTAN_HIT_BIRD_1 : SAY_DROSTAN_HIT_BIRD_2, pDrostan);

                pCreatureTarget->DealDamage(pCreatureTarget, pCreatureTarget->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
            }
            return true;
        }
        case SPELL_LURIELLES_PENDANT:
        {
            if (uiEffIndex == EFFECT_INDEX_0)
            {
                if (pCreatureTarget->GetEntry() != NPC_CHILL_NYMPH || pCaster->GetTypeId() != TYPEID_PLAYER)
                    return true;

                switch (urand(0, 2))
                {
                    case 0: DoScriptText(SAY_FREE_1, pCreatureTarget); break;
                    case 1: DoScriptText(SAY_FREE_2, pCreatureTarget); break;
                    case 2: DoScriptText(SAY_FREE_3, pCreatureTarget); break;
                }

                ((Player*)pCaster)->KilledMonsterCredit(NPC_LURIELLE);
                pCreatureTarget->SetFactionTemporary(FACTION_FRIENDLY, TEMPFACTION_RESTORE_RESPAWN);
                pCreatureTarget->DeleteThreatList();
                pCreatureTarget->AttackStop(true);
                pCreatureTarget->GetMotionMaster()->MoveFleeing(pCaster, 7);
                pCreatureTarget->ForcedDespawn(7 * IN_MILLISECONDS);
            }
            return true;
        }
        case SPELL_SAMPLING_ENERGY:
        {
            if (uiEffIndex == EFFECT_INDEX_0)
            {
                if (pCaster->GetTypeId() != TYPEID_PLAYER)
                    return true;

                ((Player*)pCaster)->KilledMonsterCredit(pCreatureTarget->GetEntry());
            }
            return true;
        }
        case SPELL_EXPOSE_RAZORTHORN_ROOT:
        {
            if (uiEffIndex == EFFECT_INDEX_0)
            {
                if (pCreatureTarget->GetEntry() != NPC_RAZORTHORN_RAVAGER)
                    return true;

                if (GameObject* pMound = GetClosestGameObjectWithEntry(pCreatureTarget, GO_RAZORTHORN_DIRT_MOUND, 20.0f))
                {
                    if (pMound->GetRespawnTime() != 0)
                        return true;

                    pCreatureTarget->CastSpell(pCreatureTarget, SPELL_SUMMON_RAZORTHORN_ROOT, true);
                    pMound->SetLootState(GO_JUST_DEACTIVATED);
                }
            }
            return true;
        }
        case SPELL_MELODIOUS_RAPTURE:
        {
            if (uiEffIndex == EFFECT_INDEX_0)
            {
                if (pCaster->GetTypeId() != TYPEID_PLAYER && pCreatureTarget->GetEntry() != NPC_DEEPRUN_RAT)
                    return true;

                pCreatureTarget->UpdateEntry(NPC_ENTHRALLED_DEEPRUN_RAT);
                pCreatureTarget->CastSpell(pCreatureTarget, SPELL_MELODIOUS_RAPTURE_VISUAL, false);
                pCreatureTarget->GetMotionMaster()->MoveFollow(pCaster, frand(0.5f, 3.0f), frand(M_PI_F * 0.8f, M_PI_F * 1.2f));

                ((Player*)pCaster)->KilledMonsterCredit(NPC_ENTHRALLED_DEEPRUN_RAT);
            }
            return true;
        }
    }

    return false;
}
Exemplo n.º 21
0
SpellEntry const* ScriptedAI::SelectSpell(Unit* pTarget, int32 uiSchool, int32 uiMechanic, SelectTargetType selectTargets, uint32 uiPowerCostMin, uint32 uiPowerCostMax, float fRangeMin, float fRangeMax, SelectEffect selectEffects)
{
    //No target so we can't cast
    if (!pTarget)
        return false;

    //Silenced so we can't cast
    if (m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED))
        return false;

    //Using the extended script system we first create a list of viable spells
    SpellEntry const* apSpell[CREATURE_MAX_SPELLS];
    memset(apSpell, 0, sizeof(SpellEntry*)*CREATURE_MAX_SPELLS);

    uint32 uiSpellCount = 0;

    SpellEntry const* pTempSpell;
    SpellRangeEntry const* pTempRange;

    //Check if each spell is viable(set it to null if not)
    for (uint32 i = 0; i < CREATURE_MAX_SPELLS; i++)
    {
        pTempSpell = GetSpellStore()->LookupEntry(m_creature->m_spells[i]);

        //This spell doesn't exist
        if (!pTempSpell)
            continue;

        // Targets and Effects checked first as most used restrictions
        //Check the spell targets if specified
        if (selectTargets && !(SpellSummary[m_creature->m_spells[i]].Targets & (1 << (selectTargets-1))))
            continue;

        //Check the type of spell if we are looking for a specific spell type
        if (selectEffects && !(SpellSummary[m_creature->m_spells[i]].Effects & (1 << (selectEffects-1))))
            continue;

        //Check for school if specified
        if (uiSchool >= 0 && pTempSpell->SchoolMask & uiSchool)
            continue;

        //Check for spell mechanic if specified
        if (uiMechanic >= 0 && pTempSpell->Mechanic != uiMechanic)
            continue;

        //Make sure that the spell uses the requested amount of power
        if (uiPowerCostMin && pTempSpell->manaCost < uiPowerCostMin)
            continue;

        if (uiPowerCostMax && pTempSpell->manaCost > uiPowerCostMax)
            continue;

        //Continue if we don't have the mana to actually cast this spell
        if (pTempSpell->manaCost > m_creature->GetPower((Powers)pTempSpell->powerType))
            continue;

        //Get the Range
        pTempRange = GetSpellRangeStore()->LookupEntry(pTempSpell->rangeIndex);

        //Spell has invalid range store so we can't use it
        if (!pTempRange)
            continue;

        //Check if the spell meets our range requirements
        if (fRangeMin && m_creature->GetSpellMinRangeForTarget(pTarget, pTempRange) < fRangeMin)
            continue;
        if (fRangeMax && m_creature->GetSpellMaxRangeForTarget(pTarget, pTempRange) > fRangeMax)
            continue;

        //Check if our target is in range
         if (m_creature->IsWithinDistInMap(pTarget, m_creature->GetSpellMinRangeForTarget(pTarget, pTempRange)) || !m_creature->IsWithinDistInMap(pTarget, m_creature->GetSpellMaxRangeForTarget(pTarget, pTempRange)))
            continue;

        //All good so lets add it to the spell list
        apSpell[uiSpellCount] = pTempSpell;
        ++uiSpellCount;
    }

    //We got our usable spells so now lets randomly pick one
    if (!uiSpellCount)
        return NULL;

    return apSpell[rand()%uiSpellCount];
}
Exemplo n.º 22
0
    void UpdateAI(const uint32 uiDiff)
    {
        if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
            return;

        if(m_uiDoorTimer < uiDiff && !bIsDoorClosed)
        {
            if (GameObject* pForceBarrier = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(DATA_GO_FORCEFIELD)))
                pForceBarrier->SetGoState(GO_STATE_READY);
            if (GameObject* pWallA = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(DATA_KALECGOS_FIGHT_GATE_A)))
                pWallA->SetGoState(GO_STATE_READY);
            if (GameObject* pWallB = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(DATA_KALECGOS_FIGHT_GATE_B)))
                pWallB->SetGoState(GO_STATE_READY);
            bIsDoorClosed = true;
        }m_uiDoorTimer -= uiDiff;

        if (m_creature->HasAura(SPELL_BANISH))
        {
            if (m_pInstance && m_pInstance->GetData(DATA_SATHROVARR_EVENT) == DONE)
                m_creature->RemoveAurasDueToSpell(SPELL_BANISH);

            if (m_pInstance && m_pInstance->GetData(DATA_KALECGOS_EVENT) == NOT_STARTED)
            {
                m_creature->RemoveAurasDueToSpell(SPELL_BANISH);
                ((boss_kalecgosAI*)m_creature->AI())->Reset();
                m_creature->AI()->EnterEvadeMode();
            }
            return;
        }

        /* Banish at 1% hp working */
        if (!bBanished && (m_creature->GetHealthPercent() < 1.0f))
        {
            if (m_pInstance)
                m_pInstance->SetData(DATA_KALECGOS_EVENT, DONE);
            DoCast(m_creature, SPELL_BANISH, true);
            bBanished = true;
        }

        //Mising VMAPS workarroud, ANTY BUG :D
        if (Unit* pSpectral = m_creature->GetMap()->GetUnit(m_uiNormalGUID))
            if (m_creature->GetHealthPercent() > 1.0f)
                if (!m_creature->IsInRange(pSpectral, 0.0f, 50.0f, true))
                {
                    m_creature->GetMap()->CreatureRelocation(m_creature, m_creature->GetPositionX(), m_creature->GetPositionY(), DRAGON_REALM_Z, m_creature->GetOrientation());
                    ((boss_kalecgosAI*)m_creature->AI())->Reset();
                    m_creature->AI()->EnterEvadeMode();
                }

        Unit* pWho = m_creature->getVictim();
        if(pWho && !pWho->IsInRange(m_creature, 0.0f, 50.0f, true))
        {
            m_creature->AddThreat(pWho, -100000.0f);
            if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1))
            {
                m_creature->AddThreat(pTarget, 100000.0f);
                m_creature->AI()->AttackStart(pTarget);
            }
        }
        //END 

        //Enrage at 10% both bosses
        if (!bEnraged)
        {
            if (m_pInstance && m_pInstance->GetData(DATA_SATHROVARR_EVENT) == SPECIAL)
            {
                if (Unit* pSathrovarr = m_creature->GetMap()->GetUnit(m_pInstance->GetData64(DATA_SATHROVARR)))
                {
                    if (pSathrovarr->isAlive())
                        pSathrovarr->CastSpell(pSathrovarr, SPELL_CRAZED_RAGE, true);
                }
                m_uiNextEnrageTimer = 10000;
                bEnraged = true;
            }

        if (m_creature->GetHealthPercent() < 10.0f)
            {
                if (m_pInstance) 
                    m_pInstance->SetData(DATA_SATHROVARR_EVENT,SPECIAL);
                DoCast(m_creature, SPELL_CRAZED_RAGE, true);
                m_uiNextEnrageTimer = 10000;
                bEnraged = true;
            }
        } 
        else if (m_uiNextEnrageTimer < uiDiff)
        {
            DoCast(m_creature, SPELL_CRAZED_RAGE, true);
            m_uiNextEnrageTimer = 10000;
        }else m_uiNextEnrageTimer -= uiDiff;

        //Simple Spelss
        if (m_uiArcaneBuffetTimer < uiDiff)
        {
            if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_ARCANE_BUFFET) == CAST_OK)
            {

                m_uiArcaneBuffetTimer = 20000;
            }
        }
        else
            m_uiArcaneBuffetTimer -= uiDiff;

        if (m_uiFrostBreathTimer < uiDiff)
        {
            if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_FROST_BREATH) == CAST_OK)
            {
                if (!urand(0, 1))
                DoScriptText(SAY_EVIL_SPELL2, m_creature);

            m_uiFrostBreathTimer = 25000;
            }
        }
        else
            m_uiFrostBreathTimer -= uiDiff;

        if (m_uiTailLashTimer < uiDiff)
        {
            if (m_creature->getVictim())
                DoCast(m_creature->getVictim(), SPELL_TAIL_LASH);
            m_uiTailLashTimer = urand(25000, 40000);
        }else m_uiTailLashTimer -= uiDiff;

        if (m_uiWildMagicTimer < uiDiff)
        {
            CastWildMagic();
        }else m_uiWildMagicTimer -= uiDiff;
        //end of simple spells

        DoMeleeAttackIfReady();

        //Teleport To Spectral Realm
        if (m_uiSpectralBlastTimer < uiDiff)
        {
            ThreatList const& m_threatlist = m_creature->getThreatManager().getThreatList();
            if (m_threatlist.empty())
            {
                m_uiSpectralBlastTimer = 1000;
                return;
            }

            std::list<Unit*> targetList;
            for(ThreatList::const_iterator itr = m_threatlist.begin(); itr!= m_threatlist.end(); ++itr)
                if((*itr)->getTarget() && (*itr)->getTarget()->GetTypeId() == TYPEID_PLAYER && (*itr)->getTarget()->GetGUID() && !(*itr)->getTarget()->HasAura(SPELL_SPECTRAL_EXHAUSTION) && (*itr)->getTarget()->IsInRange(m_creature, 0.0f, 50.0f, true))
                    targetList.push_back((*itr)->getTarget());
            if(targetList.empty())
            {
                m_uiSpectralBlastTimer = 1000;
                return;
            }
        
            std::list<Unit*>::iterator i = targetList.begin();
            advance(i, rand()%targetList.size());
            if((*i))
            {
                if(m_pInstance && m_pInstance->GetData(DATA_KALECGOS_EVENT) == SPECIAL)
                {
                    m_uiSpectralBlastTimer = urand(20000, 25000);
                }
                else
                {
                    if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO, 0))
                        if ( pTarget == (*i))
                            return; 

                    m_creature->AddThreat((*i), -100000.0f);
                    (*i)->InterruptNonMeleeSpells(true);
                    SpellEntry* pTempSpell = (SpellEntry*)GetSpellStore()->LookupEntry(SPELL_SPECTRAL_BLAST);
                    if (pTempSpell)
                    {
                        pTempSpell->Effect[EFFECT_INDEX_2] = 0;
                        (*i)->CastSpell((*i), pTempSpell, true);
                    }
                    (*i)->CastSpell((*i), SPELL_SPECTRAL_EXHAUSTION,true);
                    ((Player*)(*i))->TeleportTo((*i)->GetMapId(), (*i)->GetPositionX(), (*i)->GetPositionY(), DEMON_REALM_Z, (*i)->GetOrientation());
                }
                m_uiSpectralBlastTimer = urand(20000, 25000);    
            }else m_uiSpectralBlastTimer = 1000;                
        }else m_uiSpectralBlastTimer -= uiDiff;

        if (m_uiSathrovarrTimer < uiDiff && !bSathrospawnd)
        {
            if (m_pInstance)
                if (Creature* pSath = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_SATHROVARR)))
                {
                    pSath->SetVisibility(VISIBILITY_ON);
                    pSath->setFaction(14);
                    bSathrospawnd = true;
                    if(pSath->AI())
                        pSath->AI()->AttackStart(m_creature->getVictim());
                }
        }else m_uiSathrovarrTimer -= uiDiff;
    }
Exemplo n.º 23
0
void PlayerbotShamanAI::LoadSpells() {
    PlayerbotAI *ai = GetAI();
    if (!ai) return;
    #pragma region SpellId Fill
    //totems
    HEALING_STREAM_TOTEM = ai->getSpellIdExact("Healing Stream Totem");
    MANA_SPRING_TOTEM = ai->getSpellIdExact("Mana Spring Totem");
    MANA_TIDE_TOTEM = ai->getSpellIdExact("Mana Tide Totem");
    CLEANSING_TOTEM = ai->getSpellIdExact("Cleansing Totem");
    FIRE_RESISTANCE_TOTEM = ai->getSpellIdExact("Fire Resistance Totem");

    WINDFURY_TOTEM = ai->getSpellIdExact("Windfury Totem");
    WRATH_OF_AIR_TOTEM = ai->getSpellIdExact("Wrath of Air Totem");
    GROUNDING_TOTEM = ai->getSpellIdExact("Grounding Totem");
    NATURE_RESISTANCE_TOTEM = ai->getSpellIdExact("Nature Resistance Totem");

    STRENGTH_OF_EARTH_TOTEM = ai->getSpellIdExact("Strength of Earth Totem");
    EARTHBIND_TOTEM = ai->getSpellIdExact("Earthbind Totem");
    STONESKIN_TOTEM = ai->getSpellIdExact("Stoneskin Totem");
    STONECLAW_TOTEM = ai->getSpellIdExact("Stoneclaw Totem");
    TREMOR_TOTEM = ai->getSpellIdExact("Tremor Totem");
    EARTH_ELEMENTAL_TOTEM = ai->getSpellIdExact("Earth Elemental Totem");

    FLAMETONGUE_TOTEM = ai->getSpellIdExact("Flametongue Totem");
    TOTEM_OF_WRATH = ai->getSpellIdExact("Totem of Wrath");
    SEARING_TOTEM = ai->getSpellIdExact("Searing Totem");
    MAGMA_TOTEM = ai->getSpellIdExact("Magma Totem");
    FIRE_ELEMENTAL_TOTEM = ai->getSpellIdExact("Fire Elemental Totem");
    FROST_RESISTANCE_TOTEM = ai->getSpellIdExact("Frost Resistance Totem");

    TOTEMIC_RECALL = ai->getSpellIdExact("Totemic Recall");
    CALL_OF_THE_ELEMENTS = ai->getSpellIdExact("Call of the Elements");
    CALL_OF_THE_ANCESTORS = ai->getSpellIdExact("Call of the Ancestors");
    CALL_OF_THE_SPIRITS = ai->getSpellIdExact("Call of the Spirits");

    //restoration
    HEAL = ai->getSpellIdExact("Healing Wave");
    LESSER_HEAL = ai->getSpellIdExact("Lesser Healing Wave");
    CHAIN_HEAL = ai->getSpellIdExact("Chain Heal");
    RIPTIDE = ai->getSpellIdExact("Riptide");
    ANCESTRAL_SPIRIT = ai->getSpellIdExact("Ancestral Spirit");
    CLEANSE_SPIRIT = ai->getSpellIdExact("Cleanse Spirit");
    if (CLEANSE_SPIRIT) CLEANSE_SPIRIT = ai->getSpellIdExact("Cure Toxins");

    //offensive spells
    LIGHTNING_BOLT = ai->getSpellIdExact("Lightning Bolt");
    CHAIN_LIGHTNING = ai->getSpellIdExact("Chain Lightning");
    FIRE_NOVA = ai->getSpellIdExact("Fire Nova");
    THUNDERSTORM = ai->getSpellIdExact("Thunderstorm");
    LAVA_BURST = ai->getSpellIdExact("Lava Burst");
    EARTH_SHOCK = ai->getSpellIdExact("Earth Shock");
    WIND_SHEAR = ai->getSpellIdExact("Wind Shear");
    FLAME_SHOCK = ai->getSpellIdExact("Flame Shock");
    FROST_SHOCK = ai->getSpellIdExact("Frost Shock");
    PURGE = ai->getSpellIdExact("Purge");
    HEX  = ai->getSpellIdExact("Hex");

    //buffs
    LIGHTNING_SHIELD = ai->getSpellIdExact("Lightning Shield");
    WATER_SHIELD = ai->getSpellIdExact("Water Shield");
    EARTH_SHIELD = ai->getSpellIdExact("Earth Shield");
    HEROISM = ai->getSpellIdExact("Heroism");
    if (HEROISM) HEROISM = ai->getSpellIdExact("Bloodlust");
    ELEMENTAL_MASTERY = ai->getSpellIdExact("Elemental Mastery");
    NATURES_SWIFTNESS = ai->getSpellIdExact("Nature's Swiftness");

    WINDFURY_WEAPON = ai->getSpellIdExact("Windfury Weapon");
    FLAMETONGUE_WEAPON = ai->getSpellIdExact("Flametongue Weapon");
    FROSTBRAND_WEAPON = ai->getSpellIdExact("Frostbrand Weapon");
    ROCKBITER_WEAPON = ai->getSpellIdExact("Rockbiter Weapon");
    EARTHLIVING_WEAPON = ai->getSpellIdExact("Earthliving Weapon");

    WATER_BREATHING = ai->getSpellIdExact("Water Breathing");
    WATER_WALKING = ai->getSpellIdExact("Water Walking");

    //melee
    LAVA_LASH = ai->getSpellIdExact("Lava Lash");
    STORMSTRIKE = ai->getSpellIdExact("Stormstrike");
    SHAMANISTIC_RAGE = ai->getSpellIdExact("Shamanistic Rage");
    FERAL_SPIRIT = ai->getSpellIdExact("Feral Spirit");

    GHOST_WOLF = ai->getSpellIdExact("Ghost Wolf");

    EXHAUSTION = 57723; // heroism debuff
    SATED = 57724; // bloodlust debuff
    //MAELSTROM_WEAPON = 0; // We want the triggered aura, not the talent spell
    uint32 mwtrigger = ai->getSpellIdExact("Maelstrom Weapon",true);
    if (mwtrigger)
    {
        SpellEntry const *mwtSpell = GetSpellStore()->LookupEntry(mwtrigger);
        if (mwtSpell && mwtSpell->EffectTriggerSpell[0] > 0) MAELSTROM_WEAPON = mwtSpell->EffectTriggerSpell[0];
    }

    TALENT_ELEMENTAL = ELEMENTAL_MASTERY;
    TALENT_ENHANCEMENT = STORMSTRIKE;
    TALENT_RESTO = EARTH_SHIELD;

    uint8 talentCounter = 0;
    if (TALENT_ELEMENTAL) talentCounter++;
    if (TALENT_ENHANCEMENT) talentCounter++;
    if (TALENT_RESTO) talentCounter++;
    //if (talentCounter > 1) { TALENT_ELEMENTAL = 0; TALENT_ENHANCEMENT = 0; TALENT_RESTO = 0; } //Unreliable Talent detection.
    #pragma endregion
}
Exemplo n.º 24
0
bool PlayerbotShamanAI::ChangeWeaponEnchants()
{
    uint32 mhEnch = 0, ohEnch = 0;

    PlayerbotAI *ai = GetAI();
    if(!ai) return false;
    Player *m_bot = GetPlayerBot();
    if(!m_bot || m_bot->isDead()) return false;


    // Choose Weapon Enchant
    if (TALENT_RESTO) { mhEnch = EARTHLIVING_WEAPON; }
    else if (TALENT_ELEMENTAL){ mhEnch = FLAMETONGUE_WEAPON; }
    else
    {
        if (WINDFURY_WEAPON)
        {
            mhEnch = WINDFURY_WEAPON;
            if (m_bot->haveOffhandWeapon())
            {
                if (LAVA_LASH) ohEnch = FLAMETONGUE_WEAPON;
                else ohEnch = WINDFURY_WEAPON;
            }
		}
    else if (FLAMETONGUE_WEAPON)
    {
        mhEnch = FLAMETONGUE_WEAPON;
        if (m_bot->haveOffhandWeapon()) ohEnch = FLAMETONGUE_WEAPON;
    }

    }

    Item* weap;
    uint32 enchant_id = 0;
    SpellEntry const *tSpell;
    bool castedsomething = false;

    if (mhEnch)
    {
        weap = m_bot->GetWeaponForAttack(BASE_ATTACK);
        if (weap)
        {
            tSpell = GetSpellStore()->LookupEntry(mhEnch);
            if (tSpell && tSpell->EffectMiscValue[0] > 0)
            {
                enchant_id = (uint32) tSpell->EffectMiscValue[0];
                if (enchant_id && weap->GetEnchantmentId(TEMP_ENCHANTMENT_SLOT) != enchant_id && sSpellItemEnchantmentStore.LookupEntry(enchant_id))
                {
                    m_bot->ApplyEnchantment(weap,TEMP_ENCHANTMENT_SLOT, false); //Remove old enchantment effect
                    weap->SetEnchantment(TEMP_ENCHANTMENT_SLOT, enchant_id, 1800 * 1000, 0); //Add for 30 mins
                    m_bot->ApplyEnchantment(weap, TEMP_ENCHANTMENT_SLOT, true); //Add new effect
                    castedsomething = true;
                }
            }
        }
    }

    if (ohEnch)
    {
        weap = m_bot->GetWeaponForAttack(OFF_ATTACK);
        if (weap)
        {
            tSpell = GetSpellStore()->LookupEntry(ohEnch);
            if (tSpell && tSpell->EffectMiscValue[0] > 0)
            {
                enchant_id = (uint32) tSpell->EffectMiscValue[0];
                if (enchant_id && weap->GetEnchantmentId(TEMP_ENCHANTMENT_SLOT) != enchant_id && sSpellItemEnchantmentStore.LookupEntry(enchant_id))
                {
                    m_bot->ApplyEnchantment(weap,TEMP_ENCHANTMENT_SLOT, false); //Remove old enchantment effect
                    weap->SetEnchantment(TEMP_ENCHANTMENT_SLOT, enchant_id, 1800 * 1000, 0); //Add for 30 mins
                    m_bot->ApplyEnchantment(weap, TEMP_ENCHANTMENT_SLOT, true); //Add new effect
                    castedsomething = true;
                }
            }
        }
    }
    return castedsomething;

}
Exemplo n.º 25
0
bool BSWScriptedAI::_doAura(uint32 SpellID, Unit* pTarget, SpellEffectIndex index, int32 basepoint, bool isStack)
{
    if (!pTarget || !pTarget->IsInMap(m_creature) || !pTarget->isAlive())
    {
        error_log("BSW: FAILED adding aura of spell number %u - no target or target not in map or target is dead",SpellID);
        return false;
    }

    if (_hasAura(SpellID,pTarget))
         debug_log("BSW: adding aura stack from spell %u index %u",SpellID, index);
    else debug_log("BSW: adding new aura from spell %u index %u",SpellID, index);

    SpellEntry const *spell = (SpellEntry *)GetSpellStore()->LookupEntry(SpellID);

    if (spell)
    {
        if (IsSpellAppliesAura(spell, (1 << EFFECT_INDEX_0) | (1 << EFFECT_INDEX_1) | (1 << EFFECT_INDEX_2)) || IsSpellHaveEffect(spell, SPELL_EFFECT_PERSISTENT_AREA_AURA))
        {
            int32 _basepoint = basepoint ?  basepoint - 1 : spell->EffectBasePoints[index] + 1;

            bool addedToExisting = true;

            SpellAuraHolderPtr holder = pTarget->GetSpellAuraHolder(SpellID, pTarget->GetObjectGuid());

            Aura* aura = NULL;

            if (!holder)
            {
                holder = CreateSpellAuraHolder(spell, pTarget, pTarget);
                addedToExisting = false;
            }


            if (aura = holder->GetAuraByEffectIndex(index))
            {
                if (isStack)
                    holder->ModStackAmount(1);
            }
            else
            {
                aura = holder->CreateAura(spell, index, &_basepoint, holder, pTarget, m_creature, NULL);
                holder->SetAuraDuration(aura->GetAuraMaxDuration());
            }

            if (addedToExisting)
            {
                pTarget->AddAuraToModList(aura);
                holder->SetInUse(true);
                aura->ApplyModifier(true,true);
                holder->SetInUse(false);
            }
            else
                pTarget->AddSpellAuraHolder(holder);

            return true;
        }
    }

    error_log("BSW: FAILED adding aura from spell %u index %u",SpellID, index);

    return false;
};
Exemplo n.º 26
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)
{
    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;
};
Exemplo n.º 28
0
bool PlayerbotClassAI::castSelfCCBreakers (uint32 castList[])
{
    uint32 dispelSpell = 0;
    Player *dTarget = GetPlayerBot();


            /* dispelSpell = (uint32) R_ESCAPE_ARTIST; // this is script effect,
            Unit::AuraMap const& auras = dTarget->GetOwnedAuras();
            for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); itr++)
            {
                Aura * aura = itr->second;
                AuraApplication * aurApp = aura->GetApplicationOfTarget(dTarget->GetGUID());
                if (!aurApp)
                    continue;

                if ( ( aura->GetSpellProto()->Mechanic == MECHANIC_SNARE ) || ( aura->GetSpellProto()->Mechanic == MECHANIC_ROOT ) )
                {
                    if(aura->GetSpellProto()->Dispel == DISPEL_MAGIC)
                    {
                        bool positive = aurApp->IsPositive() ? (!(aura->GetSpellProto()->AttributesEx & SPELL_ATTR0_UNK7)) : false;

                        // do not remove positive auras if friendly target
                        //               negative auras if non-friendly target
                        if(positive == dTarget->IsFriendlyTo(caster))
                            continue;
                    }
                    return castSpell(dispelSpell, dTarget);
                }
            }
            return false;  */

        // racial abilities
    /*  if( GetPlayerBot()->getRace() == RACE_BLOODELF && !pTarget->HasAura( ARCANE_TORRENT,0 ) && castSpell( ARCANE_TORRENT,pTarget ) ) {
         //GetPlayerBot()->Say("Arcane Torrent!", LANG_UNIVERSAL);
    } else if( GetPlayerBot()->getRace() == RACE_HUMAN && (GetPlayerBot()->HasUnitState( UNIT_STAT_STUNNED ) || GetPlayerBot()->HasAuraType( SPELL_AURA_MOD_FEAR ) || GetPlayerBot()->HasAuraType( SPELL_AURA_MOD_DECREASE_SPEED ) || GetPlayerBot()->HasAuraType( SPELL_AURA_MOD_CHARM )) && castSpell( EVERY_MAN_FOR_HIMSELF, GetPlayerBot() ) ) {
        //GetPlayerBot()->Say("EVERY MAN FOR HIMSELF!", LANG_UNIVERSAL);
    } else if( GetPlayerBot()->getRace() == RACE_UNDEAD_PLAYER && (GetPlayerBot()->HasAuraType( SPELL_AURA_MOD_FEAR ) || GetPlayerBot()->HasAuraType( SPELL_AURA_MOD_CHARM )) && castSpell( WILL_OF_THE_FORSAKEN, GetPlayerBot() ) ) {
       // GetPlayerBot()->Say("WILL OF THE FORSAKEN!", LANG_UNIVERSAL);
    } else if( GetPlayerBot()->getRace() == RACE_DWARF && GetPlayerBot()->HasAuraState( AURA_STATE_DEADLY_POISON ) && castSpell( STONEFORM, GetPlayerBot() ) ) {
        //GetPlayerBot()->Say("STONEFORM!", LANG_UNIVERSAL);
    } else if( GetPlayerBot()->getRace() == RACE_GNOME && (GetPlayerBot()->HasUnitState( UNIT_STAT_STUNNED ) || GetPlayerBot()->HasAuraType( SPELL_AURA_MOD_DECREASE_SPEED )) && castSpell( ESCAPE_ARTIST, GetPlayerBot() ) ) {
       // GetPlayerBot()->Say("ESCAPE ARTIST!", LANG_UNIVERSAL);
    } */

    for (uint8 j = 0; j <  sizeof (castList); j++)
    {
        dispelSpell = castList[j];
        if (dispelSpell == 0 || !dTarget->HasSpell(dispelSpell) || !CanCast(dispelSpell, dTarget, true)) continue;
        SpellEntry const *dSpell = GetSpellStore()->LookupEntry(dispelSpell);
        if (!dSpell) continue;

        for (uint8 i = 0 ; i < MAX_SPELL_EFFECTS ; ++i)
        {
            if (dSpell->Effect[i] != (uint32)SPELL_EFFECT_DISPEL && dSpell->Effect[i] != (uint32)SPELL_EFFECT_APPLY_AURA) continue;
            if (dSpell->Effect[i] == (uint32)SPELL_EFFECT_APPLY_AURA && (
                (dSpell->EffectApplyAuraName[i] != (uint32) SPELL_AURA_MECHANIC_IMMUNITY) ||
                (dSpell->EffectApplyAuraName[i] != (uint32) SPELL_AURA_DISPEL_IMMUNITY)
                )) continue;

            Unit::AuraMap const& auras = dTarget->GetOwnedAuras();
            for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); itr++)
            {
                Aura * aura = itr->second;
                AuraApplication * aurApp = aura->GetApplicationOfTarget(dTarget->GetGUID());
                if (!aurApp) continue;

                if (aura->GetSpellProto() && (
                    (dSpell->Effect[i] == (uint32)SPELL_EFFECT_DISPEL  && ((1<<aura->GetSpellProto()->Dispel) & GetDispellMask(DispelType(dSpell->EffectMiscValue[i]))) )
                    || (dSpell->EffectApplyAuraName[i] == (uint32) SPELL_AURA_MECHANIC_IMMUNITY && ( GetAllSpellMechanicMask(aura->GetSpellProto()) & ( 1 << dSpell->EffectMiscValue[i]) ) )
                    || (dSpell->EffectApplyAuraName[i] == (uint32) SPELL_AURA_DISPEL_IMMUNITY && ( (1<<aura->GetSpellProto()->Dispel) & GetDispellMask(DispelType(dSpell->EffectMiscValue[i])) ) )
                    ) )
                {
                    if(aura->GetSpellProto()->Dispel == DISPEL_MAGIC)
                    {
                        bool positive = aurApp->IsPositive() ? (!(aura->GetSpellProto()->AttributesEx & SPELL_ATTR0_UNK7)) : false;
                        if(positive)continue;
                    }
                    return CastSpell(dispelSpell, dTarget, false);
                }
            }
        }
    }
    return false;
}
Exemplo n.º 29
0
void ScriptMgr::FillSpellSummary()
{
    SpellSummary = new TSpellSummary[GetSpellStore()->GetNumRows()];

    SpellEntry const* pTempSpell;

    for (uint32 i = 0; i < GetSpellStore()->GetNumRows(); ++i)
    {
        SpellSummary[i].Effects = 0;
        SpellSummary[i].Targets = 0;

        pTempSpell = GetSpellStore()->LookupEntry(i);
        //This spell doesn't exist
        if (!pTempSpell)
            continue;

        for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
        {
            //Spell targets self
            if (pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_CASTER)
                SpellSummary[i].Targets |= 1 << (SELECT_TARGET_SELF-1);

            //Spell targets a single enemy
            if (pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_TARGET_ENEMY ||
                pTempSpell->EffectImplicitTargetA[j] == TARGET_DST_TARGET_ENEMY)
                SpellSummary[i].Targets |= 1 << (SELECT_TARGET_SINGLE_ENEMY-1);

            //Spell targets AoE at enemy
            if (pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_AREA_ENEMY_SRC ||
                pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_AREA_ENEMY_DST ||
                pTempSpell->EffectImplicitTargetA[j] == TARGET_SRC_CASTER ||
                pTempSpell->EffectImplicitTargetA[j] == TARGET_DEST_DYNOBJ_ENEMY)
                SpellSummary[i].Targets |= 1 << (SELECT_TARGET_AOE_ENEMY-1);

            //Spell targets an enemy
            if (pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_TARGET_ENEMY ||
                pTempSpell->EffectImplicitTargetA[j] == TARGET_DST_TARGET_ENEMY ||
                pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_AREA_ENEMY_SRC ||
                pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_AREA_ENEMY_DST ||
                pTempSpell->EffectImplicitTargetA[j] == TARGET_SRC_CASTER ||
                pTempSpell->EffectImplicitTargetA[j] == TARGET_DEST_DYNOBJ_ENEMY)
                SpellSummary[i].Targets |= 1 << (SELECT_TARGET_ANY_ENEMY-1);

            //Spell targets a single friend(or self)
            if (pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_CASTER ||
                pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_TARGET_ALLY ||
                pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_TARGET_PARTY)
                SpellSummary[i].Targets |= 1 << (SELECT_TARGET_SINGLE_FRIEND-1);

            //Spell targets aoe friends
            if (pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_PARTY_CASTER ||
                pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_PARTY_TARGET ||
                pTempSpell->EffectImplicitTargetA[j] == TARGET_SRC_CASTER)
                SpellSummary[i].Targets |= 1 << (SELECT_TARGET_AOE_FRIEND-1);

            //Spell targets any friend(or self)
            if (pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_CASTER ||
                pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_TARGET_ALLY ||
                pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_TARGET_PARTY ||
                pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_PARTY_CASTER ||
                pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_PARTY_TARGET ||
                pTempSpell->EffectImplicitTargetA[j] == TARGET_SRC_CASTER)
                SpellSummary[i].Targets |= 1 << (SELECT_TARGET_ANY_FRIEND-1);

            //Make sure that this spell includes a damage effect
            if (pTempSpell->Effect[j] == SPELL_EFFECT_SCHOOL_DAMAGE ||
                pTempSpell->Effect[j] == SPELL_EFFECT_INSTAKILL ||
                pTempSpell->Effect[j] == SPELL_EFFECT_ENVIRONMENTAL_DAMAGE ||
                pTempSpell->Effect[j] == SPELL_EFFECT_HEALTH_LEECH)
                SpellSummary[i].Effects |= 1 << (SELECT_EFFECT_DAMAGE-1);

            //Make sure that this spell includes a healing effect (or an apply aura with a periodic heal)
            if (pTempSpell->Effect[j] == SPELL_EFFECT_HEAL ||
                pTempSpell->Effect[j] == SPELL_EFFECT_HEAL_MAX_HEALTH ||
                pTempSpell->Effect[j] == SPELL_EFFECT_HEAL_MECHANICAL ||
                (pTempSpell->Effect[j] == SPELL_EFFECT_APPLY_AURA  && pTempSpell->EffectApplyAuraName[j] == 8))
                SpellSummary[i].Effects |= 1 << (SELECT_EFFECT_HEALING-1);

            //Make sure that this spell applies an aura
            if (pTempSpell->Effect[j] == SPELL_EFFECT_APPLY_AURA)
                SpellSummary[i].Effects |= 1 << (SELECT_EFFECT_AURA-1);
        }
    }
}
Exemplo n.º 30
0
SpellEntry const* ScriptedAI::SelectSpell(Unit* target, int32 school, int32 mechanic, SelectTarget selectTargets, uint32 powerCostMin, uint32 powerCostMax, float rangeMin, float rangeMax, SelectEffect selectEffects)
{
    // No target so we can't cast
    if (!target)
        return nullptr;

    // Silenced so we can't cast
    if (m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED))
        return nullptr;

    // Using the extended script system we first create a list of viable spells
    SpellEntry const* spellInfos[4];
    memset(spellInfos, 0, sizeof(SpellEntry*) * 4);

    uint32 spellCount = 0;

    SpellEntry const* tempSpellInfo;
    SpellRangeEntry const* tempRange;

    // Check if each spell is viable(set it to null if not)
    for (uint8 i = 0; i < 4; ++i)
    {
        tempSpellInfo = GetSpellStore()->LookupEntry<SpellEntry>(m_creature->m_spells[i]);

        // This spell doesn't exist
        if (!tempSpellInfo)
            continue;

        // Targets and Effects checked first as most used restrictions
        // Check the spell targets if specified
        if (selectTargets && !(SpellSummary[m_creature->m_spells[i]].Targets & (1 << (selectTargets - 1))))
            continue;

        // Check the type of spell if we are looking for a specific spell type
        if (selectEffects && !(SpellSummary[m_creature->m_spells[i]].Effects & (1 << (selectEffects - 1))))
            continue;

        // Check for school if specified
        if (school >= 0 && tempSpellInfo->SchoolMask & school)
            continue;

        // Check for spell mechanic if specified
        if (mechanic >= 0 && tempSpellInfo->Mechanic != (uint32)mechanic)
            continue;

        // Make sure that the spell uses the requested amount of power
        if (powerCostMin &&  tempSpellInfo->manaCost < powerCostMin)
            continue;

        if (powerCostMax && tempSpellInfo->manaCost > powerCostMax)
            continue;

        // Continue if we don't have the mana to actually cast this spell
        if (tempSpellInfo->manaCost > m_creature->GetPower((Powers)tempSpellInfo->powerType))
            continue;

        // Get the Range
        tempRange = GetSpellRangeStore()->LookupEntry(tempSpellInfo->rangeIndex);

        // Spell has invalid range store so we can't use it
        if (!tempRange)
            continue;

        // Check if the spell meets our range requirements
        if (rangeMin && tempRange->maxRange < rangeMin)
            continue;

        if (rangeMax && tempRange->maxRange > rangeMax)
            continue;

        // Check if our target is in range
        if (m_creature->IsWithinDistInMap(target, tempRange->minRange) || !m_creature->IsWithinDistInMap(target, tempRange->maxRange))
            continue;

        // All good so lets add it to the spell list
        spellInfos[spellCount] = tempSpellInfo;
        ++spellCount;
    }

    // We got our usable spells so now lets randomly pick one
    if (!spellCount)
        return nullptr;

    return spellInfos[urand(0, spellCount - 1)];
}