All pastes #757367 Raw Edit

spellAI 0.1

public cpp v1 · immutable
·published 2007-11-01 07:30 UTC
rendered paste body
enum CreatureSpellIndex{    CREATURE_SPELL_MIN,    CREATURE_SPELL_ATTACK_1 = 0,            //Normal Attack    CREATURE_SPELL_ATTACK_2,    CREATURE_SPELL_ATTACK_3,    CREATURE_SPELL_ATTACK_4,    CREATURE_SPELL_ATTACK_5,    CREATURE_SPELL_ATTACK_MAX,    CREATURE_SPELL_SPEED_1 = 5,         //When target Run Away    CREATURE_SPELL_SPEED_2,    CREATURE_SPELL_SPEED_MAX,    CREATURE_SPELL_STUNT_1 = 7,    CREATURE_SPELL_STUNT_2,             //When target Run Closer    CREATURE_SPELL_STUNT_MAX,    CREATURE_SPELL_HEALING_1 = 9,       //When Less Life Or Friend Target    CREATURE_SPELL_HEALING_2,    CREATURE_SPELL_HEALING_MAX,    CREATURE_SPELL_BUFF_1 = 11,         //When Begin of the fight Or Friend Target    CREATURE_SPELL_BUFF_2,    CREATURE_SPELL_BUFF_MAX,    CREATURE_SPELL_INTERRUPT_1 = 13,    //Select When Target is Casting Channeling Spell    CREATURE_SPELL_INTERRUPT_MAX,    CREATURE_SPELL_MAX = 14};struct CreatureSpellInfo{    CreatureSpellInfo() : id(NULL), recoveryTime(0),     unknow1(0),buffDuration(0),cost(0),    targets(0), usingDBC(false)     {        range[0] = 0.0f;        range[1] = 0.0f;    }    uint8 targets,effects;    uint32 id,recoveryTime,unknow1,buffDuration,cost;    float range[2];    bool usingDBC, isDelayed;};typedef std::map<uint8,CreatureSpellInfo> CreatureSpellInfoMap;struct CreatureSpellBook{     // +1 is to create Global Cool at the End of spellbook.    CreatureSpellBook() : entry(0), globalCoolDown(0)    {        info.clear();    }    uint32 entry;    CreatureSpellInfoMap info;    uint64 globalCoolDown;    bool hasHealing()    {        CreatureSpellInfoMap::iterator spellItr;        for(uint8 i = CREATURE_SPELL_HEALING_1; i < CREATURE_SPELL_HEALING_MAX; ++i)        {            spellItr = info.find(i);            if( spellItr != info.end() && spellItr->second.id)                return true;        }        return false;    }};void Creature::LoadSpellInfo(){    if(m_creatureSpellBook)        delete m_creatureSpellBook;    QueryResult* _result = sDatabase.PQuery("SELECT * FROM creature_spellbook WHERE entry=%u",GetEntry());    if(_result)    {        Field *_spellInfo = _result->Fetch();        char* _spellId = NULL;        m_creatureSpellBook = new CreatureSpellBook();        //spellId, recoveryTime, castingTime, buffDuration, cost, rangeMin, rangeMax        for(uint8 itr = CREATURE_SPELL_MIN; itr < CREATURE_SPELL_MAX; ++itr)        {            const char*  rawSpellInfo = _spellInfo[itr+1].GetString();            _spellId = strtok((char*)rawSpellInfo, " ");             if( _spellId )            {                uint32 spellId = m_creatureSpellBook->info[itr].id = atoi(_spellId);                char* _recoveryTime = strtok(NULL, " ");                if(_recoveryTime)                    m_creatureSpellBook->info[itr].recoveryTime = atoi(_recoveryTime);                char* _castingTime = strtok(NULL, " ");                if(_castingTime)                     m_creatureSpellBook->info[itr].unknow1 = atoi(_castingTime);                char* _buffDuration = strtok(NULL, " ");                if(_buffDuration)                     m_creatureSpellBook->info[itr].buffDuration = atoi(_buffDuration);                char* _cost = strtok(NULL, " ");                if(_cost)                     m_creatureSpellBook->info[itr].cost = atoi(_cost);                char* _rangeMin = strtok(NULL, " ");                if(_rangeMin)                     m_creatureSpellBook->info[itr].range[0] = atof(_rangeMin);                char* _rangeMax = strtok(NULL, " ");                if(_rangeMax)                     m_creatureSpellBook->info[itr].range[1] = atof(_rangeMax);            }        }        delete _result;    }}void ScriptedAI::SetSpellAddon(CreatureSpellCasting *spellCasting){    SpellEntry const* dbcSpell;    SpellRangeEntry const *dbcRange;    SpellDurationEntry const * dbcDuration;    SpellCastTimesEntry const *dbcCastTime;    CreatureSpellInfoMap::iterator itr = spellCasting->spellBook->info.begin();    if(itr == spellCasting->spellBook->info.end())        return;        for(; itr != spellCasting->spellBook->info.end(); ++itr)    {        dbcSpell = GetSpellStore()->LookupEntry(itr->second.id);        if( !dbcSpell )            continue;        dbcRange = GetSpellRangeStore()->LookupEntry(dbcSpell->rangeIndex);        dbcDuration = GetSpellDurationStore()->LookupEntry(dbcSpell->DurationIndex);        dbcCastTime = GetCastTimesStore()->LookupEntry(dbcSpell->CastingTimeIndex);        for (int j=0; j<3; j++)        {            //Spell targets self            if ( dbcSpell->EffectImplicitTargetA[j] == TARGET_SELF )                itr->second.targets |= 1 << (SELECT_TARGET_SELF-1);            //Spell targets a single enemy            if ( dbcSpell->EffectImplicitTargetA[j] == TARGET_CHAIN_DAMAGE ||                 dbcSpell->EffectImplicitTargetA[j] == TARGET_CURRENT_SELECTED_ENEMY )                itr->second.targets |= 1 << (SELECT_TARGET_SINGLE_ENEMY-1);            //Spell targets AoE at enemy            if ( dbcSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA ||                 dbcSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA_INSTANT ||                 dbcSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA_CHANNELED )                itr->second.targets |= 1 << (SELECT_TARGET_AOE_ENEMY-1);            //Spell targets an enemy            if ( dbcSpell->EffectImplicitTargetA[j] == TARGET_CHAIN_DAMAGE ||                 dbcSpell->EffectImplicitTargetA[j] == TARGET_CURRENT_SELECTED_ENEMY ||                 dbcSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA ||                 dbcSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA_INSTANT ||                 dbcSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA_CHANNELED )                itr->second.targets |= 1 << (SELECT_TARGET_ANY_ENEMY-1);            //Spell targets a single friend(or self)            if ( dbcSpell->EffectImplicitTargetA[j] == TARGET_SELF ||                 dbcSpell->EffectImplicitTargetA[j] == TARGET_SINGLE_FRIEND ||                 dbcSpell->EffectImplicitTargetA[j] == TARGET_SINGLE_PARTY )                itr->second.targets |= 1 << (SELECT_TARGET_SINGLE_FRIEND-1);            //Spell targets aoe friends            if ( dbcSpell->EffectImplicitTargetA[j] == TARGET_ALL_PARTY_AROUND_CASTER ||                 dbcSpell->EffectImplicitTargetA[j] == TARGET_AREAEFFECT_PARTY )                itr->second.targets |= 1 << (SELECT_TARGET_AOE_FRIEND-1);            //Spell targets any friend(or self)            if ( dbcSpell->EffectImplicitTargetA[j] == TARGET_SELF ||                 dbcSpell->EffectImplicitTargetA[j] == TARGET_SINGLE_FRIEND ||                 dbcSpell->EffectImplicitTargetA[j] == TARGET_SINGLE_PARTY ||                 dbcSpell->EffectImplicitTargetA[j] == TARGET_ALL_PARTY_AROUND_CASTER ||                 dbcSpell->EffectImplicitTargetA[j] == TARGET_AREAEFFECT_PARTY )                itr->second.targets |= 1 << (SELECT_TARGET_ANY_FRIEND-1);            //Make sure that this spell includes a damage effect            if ( dbcSpell->Effect[j] == SPELL_EFFECT_SCHOOL_DAMAGE ||                  dbcSpell->Effect[j] == SPELL_EFFECT_INSTAKILL ||                  dbcSpell->Effect[j] == SPELL_EFFECT_ENVIRONMENTAL_DAMAGE ||                  dbcSpell->Effect[j] == SPELL_EFFECT_HEALTH_LEECH )                itr->second.effects |= 1 << (SELECT_EFFECT_DAMAGE-1);            //Make sure that this spell includes a healing effect            if ( dbcSpell->Effect[j] == SPELL_EFFECT_HEAL ||                  dbcSpell->Effect[j] == SPELL_EFFECT_HEAL_MAX_HEALTH ||                  dbcSpell->Effect[j] == SPELL_EFFECT_HEAL_MECHANICAL )                itr->second.effects |= 1 << (SELECT_EFFECT_HEALING-1);            //Make sure that this spell applies an aura            if( dbcSpell->Effect[j] == SPELL_EFFECT_APPLY_AURA )                itr->second.effects |= 1 << (SELECT_EFFECT_AURA-1);                        // Buff Duration            if( dbcDuration && itr->second.buffDuration < dbcDuration->Duration[j] )//DBC Info Not Good                itr->second.buffDuration = dbcDuration->Duration[j];        }                //We use powerCost from SQL on missing DBC value        if( dbcSpell->manaCost )        {            itr->second.usingDBC = true;            itr->second.cost = dbcSpell->manaCost;        }        //CoolDown        if( !itr->second.recoveryTime && dbcSpell->RecoveryTime )            itr->second.recoveryTime = dbcSpell->RecoveryTime;        if(dbcRange)        {            //Range Min            if( !itr->second.range[0] )                itr->second.range[0] = dbcRange->minRange;            //Range Max            if( !itr->second.range[1] )//DBC Info Not Good                itr->second.range[1] = dbcRange->maxRange;        }                //Casttime        if(dbcCastTime && dbcCastTime->CastTime)            itr->second.isDelayed = true;    }}    void UpdateAI(const uint32 diff)    {        if( m_creature->isDead() )            return;        //Spell Casting        if(spellCasting->spellIndex > -1)        {                Unit *target = m_creature->GetUnit( (*m_creature),m_creature->GetUInt64Value(UNIT_FIELD_TARGET) );            Unit *spellTarget = NULL;            if( spellCasting->targetGUID != m_creature->GetGUID() )                spellTarget = m_creature->GetUnit((*m_creature),spellCasting->targetGUID );            else               spellTarget = ((Unit*)m_creature);            bool dynamicTarget = false;            if(spellCasting->targetGUID != m_creature->GetGUID() && spellCasting->targetGUID != m_creature->GetUInt64Value(UNIT_FIELD_TARGET))                dynamicTarget = true;                        if(spellTarget)            {                if( !spellCasting->reached )                {                    if(dynamicTarget)                    {                        if( m_creature->IsWithinDistInMap(spellTarget, spellCasting->range) )                            spellCasting->reached = true;                        else                        {                            spellCasting->reset();                            return;                        }                      }                    else                    {                        if( spellTarget->GetGUID() == m_creature->GetGUID() || m_creature->IsWithinDistInMap(spellTarget, spellCasting->range) )                            spellCasting->reached = true;                        else                        {                            spellCasting->runningTimer += diff;                            if(spellCasting->runningTimer > irand(1000*CREATURE_WAIT_REACH_RATE,2000*CREATURE_WAIT_REACH_RATE) )                            {                                DoDoSay("Too Long To Reach Target, IsStopped:%u ",m_creature->IsStopped()); //Hack                                spellCasting->runningTimer = 0;                                /*AICast()*/                            }                            return;                        }                    }                      //if( !spellCasting->reached && m_creature->IsStopped() ) // Hack                        //AIMotionTarget(target,1.0f);                                     }                if( spellCasting->reached )                {                    if(!spellCasting->started)                    {                        if(!m_creature->IsStopped() && spellCasting->spellBook->info[spellCasting->spellIndex].castingTime)                            m_creature->StopMoving();                        AICast(spellCasting);                    }                    else if(!m_creature->m_currentSpells[CURRENT_CHANNELED_SPELL])//Spell Finish                    {                        lastAction = getMSTime();                        if(!dynamicTarget && target && target->isAlive() && m_creature->hasUnitState(UNIT_STAT_FOLLOW))                            AIMotionTarget(target);                        spellCasting->reset();                    }                }            }            else if(dynamicTarget)      //Bad dynamicTarget Target                 spellCasting->reset();            else                        //Bad Target                spellCasting->reset(true);            return;        }        //If we are within range melee the target, we try to swing it with our melee weapon.        if( !AICheckFriendTarget() && m_creature->SelectHostilTarget() && m_creature->isAttackReady() && m_creature->IsWithinDistInMap(m_creature->getVictim(), float(ATTACK_DISTANCE/2)) )        {            m_creature->AttackerStateUpdate(m_creature->getVictim());            m_creature->resetAttackTimer();            lastAction = getMSTime();        }        //Choses a Spell To Cast        if( spellCasting->spellIndex < 0 && m_creature->GetUInt64Value(UNIT_FIELD_TARGET) )            AISelectSpell( spellCasting );        //Wait Time Reset Action Selected        if(lastAction+irand(5000*CREATURE_WAIT_RATE,7000*CREATURE_WAIT_RATE) < getMSTime() && m_creature->GetUInt64Value(UNIT_FIELD_TARGET))        {            if( spellCasting->spellIndex > -1)                spellCasting->reset();            if(AICheckFriendTarget())            {                Unit* friendTarget = m_creature->GetUnit((*m_creature), m_creature->GetUInt64Value(UNIT_FIELD_TARGET));                if(friendTarget && friendTarget->getVictim())                    AISelectSpell(spellCasting,friendTarget->getVictim());                else                    m_creature->SelectHostilTarget();                     }            else            {                Unit *target = m_creature->GetUnit( (*m_creature), m_creature->GetUInt64Value(UNIT_FIELD_TARGET) );                if(target && target->isAlive())                    AIMotionTarget(target);                else                    m_creature->SelectHostilTarget();            }            lastAction = getMSTime();        }    }};void  ScriptedAI::AISelectSpell(CreatureSpellCasting *spellCasting, Unit *dynamicTarget, bool special){    uint16 chosenSpellId;    std::list<uint8> spellIndexFound;    spellIndexFound.clear();    if(spellCasting->spellIndex > -1 || !spellCasting->spellBook || m_creature->HasSpellCooldown() )        return;    /*if(special && m_creature->m_spellsCoolDown[CREATURE_SPELL_SPECIAL_1] < 1 )    {            spellCasting->spellId = m_creature->spellBook->spells[CREATURE_SPELL_SPECIAL_1];        if(spellCasting->spellId && AICheckTakePower(spellCasting->spellId))        {            Unit *creatureTarget = m_creature->GetUnit(*m_creature, m_creature->GetUInt64Value(UNIT_FIELD_TARGET));            if(spellAddon[spellCasting->spellId].targets != TARGET_SELF && creatureTarget)                    AIMotionTarget(creatureTarget,AIFollowRange(spellCasting->spellId));            spellCasting->castingTimer = spellAddon[spellCasting->spellId].castTime;            return;        }        return; // Cause Special case        //AICast(m_creature->getVictim(), spellId, CREATURE_SPELL_SPECIAL_1, waitDuration);    }*/        Unit *enemyTarget = NULL;    Unit *friendTarget = NULL;    if(dynamicTarget)    {        if(m_creature->IsHostileTo(dynamicTarget))            enemyTarget = dynamicTarget;        else            friendTarget = dynamicTarget;      }    else if(AICheckFriendTarget())        friendTarget = m_creature->GetUnit(*m_creature, m_creature->GetUInt64Value(UNIT_FIELD_TARGET));    else if(AICheckVictimTarget())        enemyTarget = m_creature->getVictim();            if( friendTarget )    {        if( friendTarget->isAlive() )        {            //heal Friend            spellIndexFound.clear();            for(uint8 i = CREATURE_SPELL_HEALING_1; i < CREATURE_SPELL_HEALING_MAX; i++)            {                CreatureSpellInfo *spellInfo = &spellCasting->spellBook->info[i];                if( spellInfo->id && !m_creature->HasSpellCooldown(spellInfo->id) && AICheckTakePower(i) )                    spellIndexFound.push_front(i);            }            if( spellIndexFound.size() > 0 && AIHPPercent(friendTarget) < 70)            {                chosenSpellId = 0;                std::list<uint8>::iterator itr = spellIndexFound.begin();                for (uint8 randomIndex = irand(0,spellIndexFound.size()-1); 0 < randomIndex; --randomIndex)++itr;                spellCasting->spellIndex = (*itr);                chosenSpellId = spellCasting->spellBook->info[(*itr)].id;                //DoDoSay("Healing(Friend): %u",chosenSpellId);                spellCasting->targetGUID = friendTarget->GetGUID();                SetSpellMaxRange(spellCasting);                if(!dynamicTarget)                    AIMotionTarget(friendTarget,rand_norm()*spellCasting->range);                return;            }            //Buff Friend            spellIndexFound.clear();            for(uint8 i = CREATURE_SPELL_BUFF_1; i < CREATURE_SPELL_BUFF_MAX; i++)            {                    CreatureSpellInfo *spellInfo = &spellCasting->spellBook->info[i];                if( spellInfo->id && !m_creature->HasSpellCooldown(spellInfo->id) && AICheckTakePower(i) )                    spellIndexFound.push_front(i);            }            if( spellIndexFound.size() > 0 )            {                chosenSpellId = 0;                std::list<uint8>::iterator itr = spellIndexFound.begin();                for (uint8 randomIndex = irand(0,spellIndexFound.size()-1); 0 < randomIndex; --randomIndex)++itr;                spellCasting->spellIndex = (*itr);                chosenSpellId = spellCasting->spellBook->info[(*itr)].id;                //DoDoSay("Buff Friend: %u",chosenSpellId);                spellCasting->targetGUID = friendTarget->GetGUID();                SetSpellMaxRange(spellCasting);                if(!dynamicTarget)                    AIMotionTarget(friendTarget,rand_norm()*spellCasting->range);                return;            }        }    }    else if(enemyTarget)    {        if(!dynamicTarget)        {            float distance = sqrt(m_creature->GetDistance2dSq(enemyTarget));            if( !spellCasting->oldTargetRange )                spellCasting->oldTargetRange = distance;            // Target Is Running Away, try speed-up to get to her.            if( distance > spellCasting->oldTargetRange && (enemyTarget->hasUnitState(UNIT_STAT_MOVING) || !enemyTarget->IsStopped()))            {                spellCasting->oldTargetRange = distance;                spellIndexFound.clear();                for(uint8 i = CREATURE_SPELL_SPEED_1; i < CREATURE_SPELL_SPEED_MAX; i++)                {                        CreatureSpellInfo *spellInfo = &spellCasting->spellBook->info[i];                    if( spellInfo->id && !m_creature->HasSpellCooldown(spellInfo->id) && AICheckTakePower(i) )                        spellIndexFound.push_front(i);                }                if( spellIndexFound.size() > 0 )                {                    chosenSpellId = 0;                    std::list<uint8>::iterator itr = spellIndexFound.begin();                    for (uint8 randomIndex = irand(0,spellIndexFound.size()-1); 0 < randomIndex; --randomIndex)++itr;                    spellCasting->spellIndex = (*itr);                    chosenSpellId = spellCasting->spellBook->info[(*itr)].id;                                        DoDoSay("Speed: %u",chosenSpellId);                    SetSpellMaxRange(spellCasting);                    if( !(spellCasting->spellBook->info[(*itr)].targets & (1 << (SELECT_TARGET_ANY_FRIEND-1))) )                    {                            spellCasting->targetGUID = m_creature->GetGUID();                        AICast(spellCasting);                        spellCasting->reset();                        //AIMotionTarget(enemyTarget);                    }                    else                    {                        AIMotionTarget(enemyTarget);                        spellCasting->targetGUID = enemyTarget->GetGUID();                    }                    //spellCasting->spellBook->castingTimer = spellCasting->spellBook->info[(*itr)].castingTime;                                        return;                }            }            //Potentiel Charge, but for sure Target is comming to Us            if( distance - spellCasting->oldTargetRange < -8.0f /*&& !enemyTarget->IsStopped()*/)            {                spellCasting->oldTargetRange = distance;                spellIndexFound.clear();                for(uint8 i = CREATURE_SPELL_STUNT_1; i < CREATURE_SPELL_STUNT_MAX; i++)                {                        CreatureSpellInfo *spellInfo = &spellCasting->spellBook->info[i];                    if( spellInfo->id && !m_creature->HasSpellCooldown(spellInfo->id) && AICheckTakePower(i) )                        spellIndexFound.push_front(i);                }                if( spellIndexFound.size() > 0 )                {                    chosenSpellId = 0;                    std::list<uint8>::iterator itr = spellIndexFound.begin();                    for (uint8 randomIndex = irand(0,spellIndexFound.size()-1); 0 < randomIndex; --randomIndex)++itr;                    spellCasting->spellIndex = (*itr);                    chosenSpellId = spellCasting->spellBook->info[(*itr)].id;                                        //DoDoSay("Stun: %u",chosenSpellId);                    SetSpellMaxRange(spellCasting);                    if( !(spellCasting->spellBook->info[chosenSpellId].targets & (1 << (SELECT_TARGET_SELF-1))) )                        spellCasting->targetGUID = m_creature->GetGUID();                    else                    {                            AIMotionTarget(enemyTarget,rand_norm()*spellCasting->range);                        spellCasting->targetGUID = enemyTarget->GetGUID();                    }                    //spellCasting->spellBook->castingTimer = spellCasting->spellBook->info[(*itr)].castingTime;                    spellCasting->targetGUID = enemyTarget->GetGUID();                    return;                }            }        }        //Healing        if( AIHPPercent(m_creature) < 70 )        {            spellIndexFound.clear();            for(uint8 i = CREATURE_SPELL_HEALING_1; i < CREATURE_SPELL_HEALING_MAX; i++)            {                    CreatureSpellInfo *spellInfo = &spellCasting->spellBook->info[i];                if( spellInfo->id && !m_creature->HasSpellCooldown(spellInfo->id) && AICheckTakePower(i) )                    spellIndexFound.push_front(i);            }            if( spellIndexFound.size() > 0 )            {                chosenSpellId = 0;                std::list<uint8>::iterator itr = spellIndexFound.begin();                for (uint8 randomIndex = irand(0,spellIndexFound.size()-1); 0 < randomIndex; --randomIndex)++itr;                spellCasting->spellIndex = (*itr);                chosenSpellId = spellCasting->spellBook->info[(*itr)].id;                //DoDoSay("Healing: %u",chosenSpellId);                //spellCasting->spellBook->castingTimer = spellCasting->spellBook->info[(*itr)].castingTime;                spellCasting->targetGUID = m_creature->GetGUID();                SetSpellMaxRange(spellCasting);                return;            }        }        else //Buff        {            spellIndexFound.clear();            for(uint8 i = CREATURE_SPELL_BUFF_1; i < CREATURE_SPELL_BUFF_MAX; i++)            {                    CreatureSpellInfo *spellInfo = &spellCasting->spellBook->info[i];                if( spellInfo->id && !m_creature->HasSpellCooldown(spellInfo->id) && AICheckTakePower(i) )                    spellIndexFound.push_front(i);            }            if( spellIndexFound.size() > 0 )            {                chosenSpellId = 0;                std::list<uint8>::iterator itr = spellIndexFound.begin();                for (uint8 randomIndex = irand(0,spellIndexFound.size()-1); 0 < randomIndex; --randomIndex)++itr;                spellCasting->spellIndex = (*itr);                chosenSpellId = spellCasting->spellBook->info[(*itr)].id;                //DoDoSay("Buff: %u",chosenSpellId);                //spellCasting->spellBook->castingTimer = spellCasting->spellBook->info[(*itr)].castingTime;                spellCasting->targetGUID = m_creature->GetGUID();                SetSpellMaxRange(spellCasting);                return;            }        }        //Attack Spell        spellIndexFound.clear();        for(uint8 i = CREATURE_SPELL_ATTACK_1; i < CREATURE_SPELL_ATTACK_MAX; i++)        {                CreatureSpellInfo *spellInfo = &spellCasting->spellBook->info[i];            if( spellInfo->id && !m_creature->HasSpellCooldown(spellInfo->id) && AICheckTakePower(i) )                spellIndexFound.push_front(i);        }        if( spellIndexFound.size() )        {            chosenSpellId = 0;            std::list<uint8>::iterator itr = spellIndexFound.begin();            for (uint8 randomIndex = irand(0,spellIndexFound.size()-1); 0 < randomIndex; --randomIndex)++itr;            spellCasting->spellIndex = (*itr);            chosenSpellId = spellCasting->spellBook->info[(*itr)].id;                        //DoDoSay("Attack: %u",chosenSpellId);            //spellCasting->spellBook->castingTimer = spellCasting->spellBook->info[(*itr)].castingTime;            spellCasting->targetGUID = enemyTarget->GetGUID();            SetSpellMaxRange(spellCasting);            if(!dynamicTarget)                AIMotionTarget(enemyTarget);            return;        }        /*if(!dynamicTarget)  //Debug, got to be removed...             AIMotionTarget(enemyTarget,rand_norm()*1.5f);*/    }}void  ScriptedAI::AICast(CreatureSpellCasting *spellCasting){    Unit *target = m_creature->GetUnit((*m_creature),spellCasting->targetGUID);    if( !target || !AICheckTakePower(spellCasting->spellIndex, true) )    {        spellCasting->reset();        return;    }    m_creature->CastSpell(target, spellCasting->spellBook->info[spellCasting->spellIndex].id, false);    spellCasting->started = true;}