All pastes #762708 Raw Edit

Unnamed

public cpp v1 · immutable
·published 2007-11-05 21:12 UTC
rendered paste body
#include "config.h"#include "ScriptMgr.h"#include "../../shared/WorldPacket.h"#include "../../game/Player.h"#include "../../game/ObjectMgr.h"#include "../../game/GameObject.h"#include "../../game/GossipDef.h"#include "../../game/QuestDef.h"#include "../../game/TargetedMovementGenerator.h"#include "../../shared/Database/DBCStores.h"#include "../../mangosd/Master.h"#include "../../game/Spell.h"uint8 loglevel = 0;int nrscripts;Script *m_scripts[MAX_SCRIPTS];//Spells Addons System//Spell Information on Exclusive script spells.void SetSpellAddon();// Spell summary for ScriptedAI::SelectSpellstruct TSpellSummary {    uint8 Targets;    // set of enum SelectTarget    uint8 Effects;    // set of enum SelectEffect } *SpellSummary;extern void AddSC_npc_generic_creature();MANGOS_DLL_EXPORTvoid ScriptsFree(){       for(int i=0;i<nrscripts;i++)        delete m_scripts[i];    nrscripts = 0;}MANGOS_DLL_EXPORTvoid ScriptsInit(){    nrscripts = 0;    for(int i=0;i<MAX_SCRIPTS;i++)        m_scripts[i]=NULL;    // -- Inicialize the Scripts to be Added --    AddSC_npc_generic_creature();}//*********************************//*** Functions used internally ***Script* GetScriptByName(std::string Name){    for(int i=0;i<MAX_SCRIPTS;i++)    {        if( m_scripts[i] && m_scripts[i]->Name == Name )            return m_scripts[i];    }    return NULL;}//********************************//*** Functions to be Exported ***MANGOS_DLL_EXPORTbool GossipHello ( Player * player, Creature *_Creature ){    Script *tmpscript = NULL;    tmpscript = GetScriptByName(_Creature->GetCreatureInfo()->ScriptName);    if(!tmpscript || !tmpscript->pGossipHello) return false;    player->PlayerTalkClass->ClearMenus();    return tmpscript->pGossipHello(player,_Creature);}MANGOS_DLL_EXPORTbool GossipSelect( Player *player, Creature *_Creature,uint32 sender, uint32 action ){    Script *tmpscript = NULL;    printf("action: %d\n",action);    tmpscript = GetScriptByName(_Creature->GetCreatureInfo()->ScriptName);    if(!tmpscript || !tmpscript->pGossipSelect) return false;    player->PlayerTalkClass->ClearMenus();    return tmpscript->pGossipSelect(player,_Creature,sender,action);}MANGOS_DLL_EXPORTbool GossipSelectWithCode( Player *player, Creature *_Creature, uint32 sender, uint32 action, char* sCode ){    Script *tmpscript = NULL;    tmpscript = GetScriptByName(_Creature->GetCreatureInfo()->ScriptName);    if(!tmpscript || !tmpscript->pGossipSelectWithCode) return false;    player->PlayerTalkClass->ClearMenus();    return tmpscript->pGossipSelectWithCode(player,_Creature,sender,action,sCode);}MANGOS_DLL_EXPORTbool QuestAccept( Player *player, Creature *_Creature, Quest *_Quest ){    Script *tmpscript = NULL;    tmpscript = GetScriptByName(_Creature->GetCreatureInfo()->ScriptName);    if(!tmpscript || !tmpscript->pQuestAccept) return false;    player->PlayerTalkClass->ClearMenus();    return tmpscript->pQuestAccept(player,_Creature,_Quest);}MANGOS_DLL_EXPORTbool QuestSelect( Player *player, Creature *_Creature, Quest *_Quest ){    Script *tmpscript = NULL;    tmpscript = GetScriptByName(_Creature->GetCreatureInfo()->ScriptName);    if(!tmpscript || !tmpscript->pQuestSelect) return false;    player->PlayerTalkClass->ClearMenus();    return tmpscript->pQuestSelect(player,_Creature,_Quest);}MANGOS_DLL_EXPORTbool QuestComplete( Player *player, Creature *_Creature, Quest *_Quest ){    Script *tmpscript = NULL;    tmpscript = GetScriptByName(_Creature->GetCreatureInfo()->ScriptName);    if(!tmpscript || !tmpscript->pQuestComplete) return false;    player->PlayerTalkClass->ClearMenus();    return tmpscript->pQuestComplete(player,_Creature,_Quest);}MANGOS_DLL_EXPORTbool ChooseReward( Player *player, Creature *_Creature, Quest *_Quest, uint32 opt ){    Script *tmpscript = NULL;    tmpscript = GetScriptByName(_Creature->GetCreatureInfo()->ScriptName);    if(!tmpscript || !tmpscript->pChooseReward) return false;    player->PlayerTalkClass->ClearMenus();    return tmpscript->pChooseReward(player,_Creature,_Quest,opt);}MANGOS_DLL_EXPORTuint32 NPCDialogStatus( Player *player, Creature *_Creature ){    Script *tmpscript = NULL;    tmpscript = GetScriptByName(_Creature->GetCreatureInfo()->ScriptName);    if(!tmpscript || !tmpscript->pNPCDialogStatus) return 100;    player->PlayerTalkClass->ClearMenus();    return tmpscript->pNPCDialogStatus(player,_Creature);}MANGOS_DLL_EXPORTbool ItemHello( Player *player, Item *_Item, Quest *_Quest ){    Script *tmpscript = NULL;    tmpscript = GetScriptByName(_Item->GetProto()->ScriptName);    if(!tmpscript || !tmpscript->pItemHello) return false;    player->PlayerTalkClass->ClearMenus();    return tmpscript->pItemHello(player,_Item,_Quest);}MANGOS_DLL_EXPORTbool ItemQuestAccept( Player *player, Item *_Item, Quest *_Quest ){    Script *tmpscript = NULL;    tmpscript = GetScriptByName(_Item->GetProto()->ScriptName);    if(!tmpscript || !tmpscript->pItemQuestAccept) return false;    player->PlayerTalkClass->ClearMenus();    return tmpscript->pItemQuestAccept(player,_Item,_Quest);}MANGOS_DLL_EXPORTbool GOHello( Player *player, GameObject *_GO ){    Script *tmpscript = NULL;    tmpscript = GetScriptByName(_GO->GetGOInfo()->ScriptName);    if(!tmpscript || !tmpscript->pGOHello) return false;    player->PlayerTalkClass->ClearMenus();    return tmpscript->pGOHello(player,_GO);}MANGOS_DLL_EXPORTbool GOQuestAccept( Player *player, GameObject *_GO, Quest *_Quest ){    Script *tmpscript = NULL;    tmpscript = GetScriptByName(_GO->GetGOInfo()->ScriptName);    if(!tmpscript || !tmpscript->pGOQuestAccept) return false;    player->PlayerTalkClass->ClearMenus();    return tmpscript->pGOQuestAccept(player,_GO,_Quest);}MANGOS_DLL_EXPORTbool GOChooseReward( Player *player, GameObject *_GO, Quest *_Quest, uint32 opt ){    Script *tmpscript = NULL;    tmpscript = GetScriptByName(_GO->GetGOInfo()->ScriptName);    if(!tmpscript || !tmpscript->pGOChooseReward) return false;    player->PlayerTalkClass->ClearMenus();    return tmpscript->pGOChooseReward(player,_GO,_Quest,opt);}MANGOS_DLL_EXPORTbool AreaTrigger      ( Player *player, Quest *_Quest, uint32 triggerID ){    Script *tmpscript = NULL;    // TODO: load a script name for the areatriggers    //tmpscript = GetScriptByName();    if(!tmpscript || !tmpscript->pAreaTrigger) return false;    player->PlayerTalkClass->ClearMenus();    return tmpscript->pAreaTrigger(player,_Quest,triggerID);}MANGOS_DLL_EXPORTCreatureAI* GetAI(Creature *_Creature){    Script *tmpscript = GetScriptByName(_Creature->GetCreatureInfo()->ScriptName);    if(!tmpscript || !tmpscript->GetAI) return NULL;    return tmpscript->GetAI(_Creature);}MANGOS_DLL_EXPORTbool ItemUse( Player *player, Item* _Item, SpellCastTargets const& targets){    Script *tmpscript = NULL;    tmpscript = GetScriptByName(_Item->GetProto()->ScriptName);    if(!tmpscript || !tmpscript->pItemUse) return false;    return tmpscript->pItemUse(player,_Item,targets);}MANGOS_DLL_EXPORTbool ReceiveEmote( Player *player, Creature *_Creature, uint32 emote ){    Script *tmpscript = NULL;    tmpscript = GetScriptByName(_Creature->GetCreatureInfo()->ScriptName);    if(!tmpscript || !tmpscript->pReceiveEmote) return false;    return tmpscript->pReceiveEmote(player, _Creature, emote);}MANGOS_DLL_EXPORTInstanceData* CreateInstanceData(Map *map){    Script *tmpscript = NULL;    tmpscript = GetScriptByName(map->GetScript());    if(!tmpscript || !tmpscript->GetInstanceData) return false;    return tmpscript->GetInstanceData(map);}bool ScriptedAI::IsVisible(Unit* who) const{    if (!who)        return false;    return m_creature->IsWithinDistInMap(who, VISIBLE_RANGE) && who->isVisibleForOrDetect(m_creature,true);}void ScriptedAI::AttackStart(Unit* who){    if (!who)        return;    if (who->isTargetableForAttack())    {        //Begin attack        DoStartMeleeAttack(who);    }}void ScriptedAI::UpdateAI(const uint32 diff){    //Check if we have a current target    if( m_creature->isAlive() && m_creature->SelectHostilTarget() && m_creature->getVictim())    {        //If we are within range melee the target        if( m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE))        {            if( m_creature->isAttackReady() )            {                m_creature->AttackerStateUpdate(m_creature->getVictim());                m_creature->resetAttackTimer();            }        }    }}void ScriptedAI::EnterEvadeMode(){    m_creature->RemoveAllAuras();    m_creature->DeleteThreatList();    m_creature->CombatStop();    DoGoHome();}void ScriptedAI::DoStartMeleeAttack(Unit* victim){    if (!victim)        return;    if ( m_creature->Attack(victim) )    {        m_creature->addUnitState(UNIT_STAT_FOLLOW);        //m_creature->GetMotionMaster()->MovementExpired();        m_creature->GetMotionMaster()->Mutate(new TargetedMovementGenerator<Creature>(*victim));        m_creature->AddThreat(victim, 0.0f);        m_creature->resetAttackTimer();        if (victim->GetTypeId() == TYPEID_PLAYER)            m_creature->SetLootRecipient((Player*)victim);    }}void ScriptedAI::DoMeleeAttackIfReady(){    //If we are within range melee the target    if( m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE))    {        //Make sure our attack is ready and we arn't currently casting        if( m_creature->isAttackReady() && !m_creature->IsNonMeleeSpellCasted(false))        {            m_creature->AttackerStateUpdate(m_creature->getVictim());            m_creature->resetAttackTimer();        }    }}void ScriptedAI::DoStartRangedAttack(Unit* victim){    if (!victim)        return;    if (m_creature->Attack(victim))    {        m_creature->AddThreat(victim, 0.0f);        m_creature->resetAttackTimer();        if (victim->GetTypeId() == TYPEID_PLAYER)            m_creature->SetLootRecipient((Player*)victim);    }}void ScriptedAI::DoStopAttack(){    if( m_creature->getVictim() != NULL )    {        m_creature->AttackStop();    }}void ScriptedAI::DoCast(Unit* victim, uint32 spelId){    if (!victim || m_creature->IsNonMeleeSpellCasted(false))        return;    m_creature->StopMoving();    m_creature->CastSpell(victim, spelId, false);}void ScriptedAI::DoCastSpell(Unit* who,SpellEntry const *spellInfo){    if (!who || m_creature->IsNonMeleeSpellCasted(false))        return;    m_creature->StopMoving();    m_creature->CastSpell(who, spellInfo, false);}void ScriptedAI::DoSay(const char* text, uint32 language, Unit* target){    if (target)m_creature->Say(text, language, target->GetGUID());    else m_creature->Say(text, language, 0);}void ScriptedAI::DoDoSay(const char *text,...){    va_list ap;    char str [1024];    va_start(ap, text);    vsnprintf(str,1024,text, ap );    va_end(ap);    DoSay(str,LANG_UNIVERSAL,NULL);}void ScriptedAI::DoYell(const char* text, uint32 language, Unit* target){    if (target)m_creature->Yell(text, language, target->GetGUID());    else m_creature->Yell(text, language, 0);}void ScriptedAI::DoTextEmote(const char* text, Unit* target){    if (target)m_creature->TextEmote(text, target->GetGUID());    else m_creature->TextEmote(text, 0);}void ScriptedAI::DoGoHome(){    if( m_creature->isAlive() )    {        float x,y,z,d;        m_creature->GetRespawnCoord(x,y,z);        m_creature->GetRespawnDist(d);        if( m_creature->GetDistanceSq(x,y,z) > (d*d) )        {            m_creature->clearUnitState(UNIT_STAT_FOLLOW);            m_creature->GetMotionMaster()->TargetedHome();        }    }}void ScriptedAI::DoPlaySoundToSet(Unit* unit, uint32 sound){    if (!unit)        return;    WorldPacket data(4);    data.SetOpcode(SMSG_PLAY_SOUND);    data << uint32(sound);    unit->SendMessageToSet(&data,false);}void ScriptedAI::DoFaceTarget(Unit *unit){    if (!unit)        return;    //Face target    m_creature->SetInFront(unit);}Creature* ScriptedAI::DoSpawnCreature(uint32 id, float x, float y, float z, float angle, uint32 type, uint32 despawntime){    return m_creature->SummonCreature(id,m_creature->GetPositionX() + x,m_creature->GetPositionY() + y,m_creature->GetPositionZ() + z, angle, (TempSummonType)type, despawntime);}/*Unit* ScriptedAI::SelectUnit(SelectAggroTarget target, uint32 position){    //ThreatList m_threatlist;    std::list<HostilReference*>& m_threatlist = m_creature->getThreatManager().getThreatList();    std::list<HostilReference*>::iterator i = m_threatlist.begin();    std::list<HostilReference*>::reverse_iterator r = m_threatlist.rbegin();    if (position >= m_threatlist.size() || !m_threatlist.size())        return NULL;    switch (target)    {    case SELECT_TARGET_RANDOM:        advance ( i , rand()%m_threatlist.size());        return Unit::GetUnit((*m_creature),(*i)->getUnitGuid());        break;    case SELECT_TARGET_TOPAGGRO:        advance ( i , position);        return Unit::GetUnit((*m_creature),(*i)->getUnitGuid());        break;    case SELECT_TARGET_BOTTOMAGGRO:        advance ( r , position);        return Unit::GetUnit((*m_creature),(*r)->getUnitGuid());        break;    }    return NULL;}*//*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->School != 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];}*/bool ScriptedAI::CanCast(Unit* Target, SpellEntry const *Spell){    //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;    //Check for power    if (m_creature->GetPower((Powers)Spell->powerType) < Spell->manaCost)        return false;    SpellRangeEntry const *TempRange = NULL;    TempRange = GetSpellRangeStore()->LookupEntry(Spell->rangeIndex);    //Spell has invalid range store so we can't use it    if (!TempRange)        return false;    //Unit is out of range of this spell    if (m_creature->GetDistanceSq(Target) > TempRange->maxRange*TempRange->maxRange || m_creature->GetDistanceSq(Target) < TempRange->minRange*TempRange->minRange)        return false;    return true;}//New AI System/*void  ScriptedAI::AISelectAction(Unit* who){    //Special Check on NULL, Called Only If Creature Do Nothing    if(!who)    {        if( AICheckFriendTarget())        {            srand(time(0));            if(!irand(0,10))            {                    srand(time(0));                Unit *copain = m_creature->GetUnit((*m_creature),m_creature->GetUInt64Value(UNIT_FIELD_TARGET));                if(copain->getVictim() && AIHPPercent(copain) > AIHPPercent(copain->getVictim()))                    AIAttackStart( copain->getVictim() );                else if(!irand(0,20))                    AIMotionTarget(copain,5.0f);            }            return;        }           if( AICheckVictimTarget() )        {            srand(time(0));            if( !irand(0,10) )                AIMotionTarget(m_creature->getVictim(),1.0f);            return;         }        //EnterEvadeMode();        return;    }    float attackRadius = m_creature->GetAttackDistance(who);    //MoveInLineOfSight Normal    if( !AICheckVictimTarget() && !AICheckFriendTarget()        && m_creature->IsHostileTo(who)        && who->isInAccessablePlaceFor(m_creature)        && m_creature->IsWithinLOSInMap(who) )    {        if( m_creature->IsWithinDistInMap(who, attackRadius) )        {            if(who->HasStealthAura())                who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);            AIAttackStart(who);            return;        }    }        //MoveInLineOfSight Normal, Who Is Maybe A friend    if(!AICheckVictimTarget() && !AICheckFriendTarget() )    {        if( m_creature->IsWithinDistInMap(who,RANGE_ASSIST ) && m_creature->IsFriendlyTo(who)             && m_creature->IsWithinLOSInMap(who) )        {            Unit *victimTarget = who->getVictim();            if( victimTarget && !m_creature->IsFriendlyTo(victimTarget) )            {                if( AIHasHealing() && AIManaPercent(m_creature) > 10)                    m_creature->SetUInt64Value( UNIT_FIELD_TARGET, who->GetGUID() );                else                    AIAttackStart(victimTarget);            }        }    }}*/void  ScriptedAI::AISelectSpell(CreatureSpellCasting *spellCasting, Unit *dynamicTarget, uint8 specialCase){    uint16 chosenSpellId;    std::list<uint8> spellIndexFound;    spellIndexFound.clear();    if(spellCasting->spellIndex > -1 || !spellCasting->spellBook || m_creature->HasSpellCooldown() )        return;    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();            switch( specialCase )    {        case SELECTSPELL_NONE:            break;        case SELECTSPELL_SPEED:        {            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();                else                    spellCasting->targetGUID = enemyTarget->GetGUID();            }        }return;        case SELECTSPELL_INTERRUPT:        {            spellIndexFound.clear();            CreatureSpellInfo *spellInfo = &spellCasting->spellBook->info[CREATURE_SPELL_INTERRUPT_1];            if( spellInfo->id && !m_creature->HasSpellCooldown(spellInfo->id) && AICheckTakePower(CREATURE_SPELL_INTERRUPT_1) )            {                spellCasting->spellIndex = CREATURE_SPELL_INTERRUPT_1;                chosenSpellId = spellInfo->id;                SetSpellMaxRange(spellCasting);                spellCasting->targetGUID = enemyTarget->GetGUID();            }        }return;    }    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)+1.0f);                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 )            {                srand(getMSTime());                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)+1.0f);                return;            }        }    }    else if(enemyTarget)    {        if(!dynamicTarget)        {            float distance = sqrt(m_creature->GetDistance2dSq(enemyTarget));            if( !spellCasting->oldTargetRange )                spellCasting->oldTargetRange = distance;            // Target Is Casting a Channeled Spell            if( enemyTarget->HasSpellChannelActiveTimer() )            {                //Cast Intterupted Spell if we have available            }            // Target Is Running Away, try speed-up to get to her.            // Far from what i wan... Need to correct that situation            //Potentiel Charge, but for sure Target is comming to Us            // Far from what i wan... Need to correct that situation            if( distance < spellCasting->oldTargetRange /*&& !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 )                {                    srand(getMSTime());                    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)+1.0f);                        spellCasting->targetGUID = enemyTarget->GetGUID();                    }                    //spellCasting->spellBook->castingTimer = spellCasting->spellBook->info[(*itr)].castingTime;                    spellCasting->targetGUID = enemyTarget->GetGUID();                    return;                }            }        }        //Healing        if( AIHPPercent(m_creature) < irand(40,90) )        {            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 )            {                srand(getMSTime());                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 )            {                srand(getMSTime());                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() )        {            srand(getMSTime());            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->targetGUID = enemyTarget->GetGUID();            SetSpellMaxRange(spellCasting);            if(!dynamicTarget)                AIMotionTarget(enemyTarget,spellCasting->range/1.1f);            return;        }        if(!dynamicTarget && m_creature->IsStopped())  //Debug, got to be removed...             AIMotionTarget(enemyTarget,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;}void  ScriptedAI::AIMotionTarget(Unit *target, float offSet){    bool exist = false;    MotionMaster* creatureMM = m_creature->GetMotionMaster();    float angle = m_creature->IsHostileTo(target) ? NULL : target->GetOrientation() + (rand_norm()*M_PI);    if(creatureMM->top()->GetMovementGeneratorType() == TARGETED_MOTION_TYPE)    {        TargetedMovementGenerator<Creature>* targetMV = static_cast<TargetedMovementGenerator<Creature>*> (creatureMM->top());        if( targetMV && targetMV->GetTarget() )        {            if( targetMV->GetTarget()->GetGUID() != target->GetGUID() )            {                if( !m_creature->hasUnitState(UNIT_STAT_FOLLOW) )                    m_creature->addUnitState(UNIT_STAT_FOLLOW);                else                    creatureMM->MovementExpired();                creatureMM->Mutate(new TargetedMovementGenerator<Creature>(*target,offSet,angle));            }            else if(targetMV->GetOffSet() != offSet)                targetMV->SetOffSet(offSet);        }    }    else    {         m_creature->addUnitState(UNIT_STAT_FOLLOW);        //Add Home, Confuse and Then Targeted        m_creature->GetMotionMaster()->Mutate(new TargetedMovementGenerator<Creature>(*target,offSet,angle));    }}bool  ScriptedAI::AICheckFriendTarget(){    //friend target not found so we reset Status of Friend Follow.    if( !m_creature->getVictim() && m_creature->GetUInt64Value(UNIT_FIELD_TARGET) )    {        Unit* friendTarget = m_creature->GetUnit( *m_creature, m_creature->GetUInt64Value(UNIT_FIELD_TARGET) );        if( friendTarget && friendTarget->isAlive() && friendTarget->isInCombat() && !m_creature->IsHostileTo(friendTarget) && m_creature->IsWithinDistInMap(friendTarget,35.0f))            return true;        else        {            if(friendTarget)                friendTarget->m_hasHealer = false;            m_creature->clearUnitState(UNIT_STAT_FOLLOW);            m_creature->SetUInt64Value(UNIT_FIELD_TARGET,0);        }    }    return false;}bool  ScriptedAI::AICheckVictimTarget(){    //Check if we have a current target    if( m_creature->getVictim() )    {        if( m_creature->GetUInt64Value(UNIT_FIELD_TARGET) != m_creature->getVictim()->GetGUID() )            m_creature->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->getVictim()->GetGUID());        if( m_creature->getVictim()->isTargetableForAttack() && m_creature->isAlive())            return true;    }    return false;}bool  ScriptedAI::AICheckTakePower(uint8 spellIndex, bool take){    uint32 currentPowerValue;    // Don't take SpellAddon PowerType, Because can be missing, so is up to us    // to not put spell for mage on a warrior.    Powers creaturePowerType = m_creature->getPowerType();    switch( creaturePowerType )    {        case POWER_RAGE: currentPowerValue = m_creature->GetPower(POWER_RAGE)/10; break;        case POWER_MANA: currentPowerValue = m_creature->GetPower(POWER_MANA); break;        case POWER_FOCUS: currentPowerValue = m_creature->GetPower(POWER_FOCUS); break;        case POWER_ENERGY: currentPowerValue = m_creature->GetPower(POWER_ENERGY); break;        case POWER_HAPPINESS: currentPowerValue = m_creature->GetPower(POWER_HAPPINESS); break;    }    if( m_creature->m_creatureSpellBook->info[spellIndex].cost > currentPowerValue )        return false;    if( take && !m_creature->m_creatureSpellBook->info[spellIndex].usingDBC )        switch(POWER_MANA) //We Only use this one for The Moment        {            case POWER_RAGE:                m_creature->SetPower(creaturePowerType, (currentPowerValue - m_creature->m_creatureSpellBook->info[spellIndex].cost)*10 );break;            case POWER_MANA:                m_creature->SetPower(creaturePowerType, (currentPowerValue - m_creature->m_creatureSpellBook->info[spellIndex].cost) );break;            case POWER_FOCUS:                 m_creature->SetPower(creaturePowerType, (currentPowerValue - m_creature->m_creatureSpellBook->info[spellIndex].cost) );break;            case POWER_ENERGY:                m_creature->SetPower(creaturePowerType, (currentPowerValue - m_creature->m_creatureSpellBook->info[spellIndex].cost) );break;            case POWER_HAPPINESS:                m_creature->SetPower(creaturePowerType, (currentPowerValue - m_creature->m_creatureSpellBook->info[spellIndex].cost) );break;        }    return true;}float  ScriptedAI::SetSpellMaxRange(CreatureSpellCasting *spellCasting){    // Not OK ...     float _rangeMax = spellCasting->spellBook->info[spellCasting->spellIndex].range[1] - 2.0f;    spellCasting->range  = _rangeMax < 5.5f ? 5.5f : _rangeMax;    return spellCasting->range;}uint8 ScriptedAI::AICombatRating(Unit* unit){    uint32 rating = 0;        //3 point at each 10Level, so level 56, got 15 Point    rating += unit->getLevel()/10;         //1 point for each 1000HP    rating += unit->GetMaxHealth()/1000 > 50 ? 50 : unit->GetMaxHealth()/1000;        rating += 100-AIHPPercent(unit);        return uint8(rating);}//Init Functionvoid 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;    }}