Example #1
1
 void HandleEffectApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
 {
     Unit* target = GetTarget();
     if (!target->HasAura(DK_SPELL_BLOOD_PRESENCE) && !target->HasAura(DK_SPELL_IMPROVED_BLOOD_PRESENCE_TRIGGERED))
     {
         int32 basePoints1 = aurEff->GetAmount();
         target->CastCustomSpell(target, 63611, NULL, &basePoints1, NULL, true, 0, aurEff);
     }
 }
Example #2
1
 void HandleEffectApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
 {
     Unit* target = GetTarget();
     if (target->HasAura(DK_SPELL_UNHOLY_PRESENCE) && !target->HasAura(DK_SPELL_IMPROVED_UNHOLY_PRESENCE_TRIGGERED))
     {
         // Not listed as any effect, only base points set in dbc
         int32 basePoints0 = aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue();
         target->CastCustomSpell(target, DK_SPELL_IMPROVED_UNHOLY_PRESENCE_TRIGGERED, &basePoints0, &basePoints0, &basePoints0, true, 0, aurEff);
     }
 }
Example #3
1
        void NeedCheckCubeStatus()
        {
            uint32 ClickerNum = 0;
            // now checking if every clicker has debuff from manticron(it is dispelable atm rev 6110 : S)
            // if not - apply mind exhaustion and delete from clicker's list
            for (CubeMap::iterator i = Cube.begin(); i != Cube.end(); ++i)
            {
                Unit *clicker = Unit::GetUnit(*me, (*i).second);
                if (!clicker || !clicker->HasAura(SPELL_SHADOW_GRASP))
                {
                    DebuffClicker(clicker);
                    (*i).second = 0;
                }
                else
                    ++ClickerNum;
            }

            // if 5 clickers from other cubes apply shadow cage
            if (ClickerNum >= CLICKERS_COUNT && !me->HasAura(SPELL_SHADOW_CAGE))
            {
                DoScriptText(SAY_BANISH, me);
                DoCast(me, SPELL_SHADOW_CAGE, true);
            }
            else if (ClickerNum < CLICKERS_COUNT && me->HasAura(SPELL_SHADOW_CAGE))
                me->RemoveAurasDueToSpell(SPELL_SHADOW_CAGE);

            if (!ClickerNum)
                NeedCheckCube = false;
        }
Example #4
1
 void SonicBoomEffect()
 {
     ThreatContainer::StorageType const &t_list = me->getThreatManager().getThreatList();
     for (ThreatContainer::StorageType::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr)
     {
         Unit* target = Unit::GetUnit(*me, (*itr)->getUnitGuid());
         if (target && target->GetTypeId() == TYPEID_PLAYER)
         {
             //Not do anything without aura, spell can be resisted!
             if (target->HasAura(SPELL_SONIC_BOOM_CAST) && me->IsWithinDistInMap(target, 34.0f))
             {
                 //This will be wrong calculation. Also, comments suggest it must deal damage
                 target->SetHealth(target->CountPctFromMaxHealth(20));
             }
         }
     }
 }
        void UpdateAI(uint32 diff)
        {
            if (!instance)
                return;

            if (CheckTimer <= diff)
            {
                Unit* vashj = Unit::GetUnit(*me, instance->GetData64(DATA_LADYVASHJ));

                if (vashj && vashj->isAlive())
                {
                    // start visual channel
                    if (!Casted || !vashj->HasAura(SPELL_MAGIC_BARRIER))
                    {
                        DoCast(vashj, SPELL_MAGIC_BARRIER, true);
                        Casted = true;
                    }
                }
                CheckTimer = 1000;
            } else CheckTimer -= diff;
        }
Example #6
1
 void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
 {
     Unit* target = GetTarget();
     if (!target->HasAura(DK_SPELL_BLOOD_PRESENCE))
         target->RemoveAura(DK_SPELL_IMPROVED_BLOOD_PRESENCE_TRIGGERED);
 }
Example #7
1
    void UpdateAI(const uint32 uiDiff)
    {
        if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
            return;

        //Fearsome Roar
        if (FearsomeRoar_Timer < uiDiff)
        {
            DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_FEARSOME_ROAR : H_SPELL_FEARSOME_ROAR, true);
            FearsomeRoar_Timer = 15000;
        } else FearsomeRoar_Timer -= uiDiff;

        //Piercing Slash
        if (PiercingSlash_Timer < uiDiff)
        {
            DoCast(m_creature->getVictim(), SPELL_PIERCING_SLASH, true);
            PiercingSlash_Timer = urand(20000, 25000);
        } else PiercingSlash_Timer -= uiDiff;

        //Mangling Slash
        if (ManglingSlash_Timer < uiDiff)
        {
            DoCast(m_creature->getVictim(), SPELL_MANGLING_SLASH, true);
            ManglingSlash_Timer = urand(20000, 25000);
        } else ManglingSlash_Timer -= uiDiff;

        //Mangling Slash
        if (GrievousBite_Timer < uiDiff)
        {
            DoCast(m_creature->getVictim(), SPELL_GRIEVOUS_BITE, true);
            GrievousBite_Timer = urand(20000, 25000);
        } else GrievousBite_Timer -= uiDiff;

        //Grievous Bite remove
        if (Check_Timer < uiDiff)
        {
            Unit* pPlayer = m_creature->getVictim();
            if (pPlayer->GetHealth() == pPlayer->GetMaxHealth())
                if (pPlayer->HasAura(SPELL_GRIEVOUS_BITE))
                    pPlayer->RemoveAura(SPELL_GRIEVOUS_BITE, EFFECT_INDEX_0);
            Check_Timer = 1000;
        } else Check_Timer -= uiDiff;

        //Bellowing Roar
        if (BellowingRoar_Timer < uiDiff)
        {
            DoCast(m_creature, SPELL_BELLOWING_ROAR);
            BellowingRoar_Timer = 60000;
        } else BellowingRoar_Timer -= uiDiff;

        //Call For Raptor - spell
        if (CallForRaptor_Timer < uiDiff)
        {
            DoScriptText(SAY_CALL_FOR_RAPTOR, m_creature);
            m_creature->CastSpell(m_creature, SAY_CALL_FOR_RAPTOR, true);
            CallForRaptor_Timer = 25000;
            CallForRaptorSpawnCheck();
        } else CallForRaptor_Timer -= uiDiff;

        //Call For Raptor - spawn
        if (CallForRaptorSpawn_Timer < uiDiff && CallForRaptorSpawn_Check == 1)
        {
            switch (urand(0, 1))
            {
            case 0:
            {
                if (Creature* pRaptor1 = m_creature->SummonCreature(NPC_DRAKKARI_GUTRIPPER, PosSummon1[0], PosSummon1[1], PosSummon1[2], 0 , TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 240000))
                    pRaptor1->AI()->AttackStart(m_creature->getVictim());
            }
            case 1:
            {
                if (Creature* pRaptor2 = m_creature->SummonCreature(NPC_DRAKKARI_SCYTHECLAW, PosSummon1[0], PosSummon1[1], PosSummon1[2], 0 , TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 240000))
                    pRaptor2->AI()->AttackStart(m_creature->getVictim());
            }
            }
            CallForRaptorSpawn_Check = 0;
        } else CallForRaptorSpawn_Timer -= uiDiff;

        DoMeleeAttackIfReady();
    }
Example #8
1
void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32 rnd, uint32 eventId, Unit* actionInvoker)
{
    switch (action.type)
    {
    case ACTION_T_TEXT:
    {
        if (!action.text.TextId1)
            return;

        int32 temp = action.text.TextId1;

        if (action.text.TextId2 && action.text.TextId3)
            temp = RAND(action.text.TextId1, action.text.TextId2, action.text.TextId3);
        else if (action.text.TextId2 && urand(0, 1))
            temp = action.text.TextId2;

        if (temp)
        {
            Unit* target = NULL;

            if (actionInvoker)
            {
                if (actionInvoker->GetTypeId() == TYPEID_PLAYER)
                    target = actionInvoker;
                else if (Unit* owner = actionInvoker->GetOwner())
                {
                    if (owner->GetTypeId() == TYPEID_PLAYER)
                        target = owner;
                }
            }
            else
            {
                target = me->getVictim();
                if (target && target->GetTypeId() != TYPEID_PLAYER)
                    if (Unit* owner = target->GetOwner())
                        if (owner->GetTypeId() == TYPEID_PLAYER)
                            target = owner;
            }

            DoScriptText(temp, me, target);
        }
        break;
    }
    case ACTION_T_SET_FACTION:
    {
        if (action.set_faction.factionId)
            me->setFaction(action.set_faction.factionId);
        else
        {
            if (CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(me->GetEntry()))
            {
                //if no id provided, assume reset and then use default
                if (me->getFaction() != ci->faction_A)
                    me->setFaction(ci->faction_A);
            }
        }
        break;
    }
    case ACTION_T_MORPH_TO_ENTRY_OR_MODEL:
    {
        if (action.morph.creatureId || action.morph.modelId)
        {
            //set model based on entry from creature_template
            if (action.morph.creatureId)
            {
                if (CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(action.morph.creatureId))
                {
                    uint32 display_id = sObjectMgr->ChooseDisplayId(0, ci);
                    me->SetDisplayId(display_id);
                }
            }
            //if no param1, then use value from param2 (modelId)
            else
                me->SetDisplayId(action.morph.modelId);
        }
        else
            me->DeMorph();
        break;
    }
    case ACTION_T_SOUND:
        me->PlayDirectSound(action.sound.soundId);
        break;
    case ACTION_T_EMOTE:
        me->HandleEmoteCommand(action.emote.emoteId);
        break;
    case ACTION_T_RANDOM_SOUND:
    {
        int32 temp = GetRandActionParam(rnd, action.random_sound.soundId1, action.random_sound.soundId2, action.random_sound.soundId3);
        if (temp >= 0)
            me->PlayDirectSound(temp);
        break;
    }
    case ACTION_T_RANDOM_EMOTE:
    {
        int32 temp = GetRandActionParam(rnd, action.random_emote.emoteId1, action.random_emote.emoteId2, action.random_emote.emoteId3);
        if (temp >= 0)
            me->HandleEmoteCommand(temp);
        break;
    }
    case ACTION_T_CAST:
    {
        Unit* target = GetTargetByType(action.cast.target, actionInvoker);
        Unit* caster = me;

        if (!target)
            return;

        if (action.cast.castFlags & CAST_FORCE_TARGET_SELF)
            caster = target;

        //Allowed to cast only if not casting (unless we interrupt ourself) or if spell is triggered
        bool canCast = !caster->IsNonMeleeSpellCasted(false) || (action.cast.castFlags & (CAST_TRIGGERED | CAST_INTERRUPT_PREVIOUS));

        // If cast flag CAST_AURA_NOT_PRESENT is active, check if target already has aura on them
        if (action.cast.castFlags & CAST_AURA_NOT_PRESENT)
        {
            if (target->HasAura(action.cast.spellId))
                return;
        }

        if (canCast)
        {
            const SpellInfo* tSpell = sSpellMgr->GetSpellInfo(action.cast.spellId);

            //Verify that spell exists
            if (tSpell)
            {
                //Check if cannot cast spell
                if (!(action.cast.castFlags & (CAST_FORCE_TARGET_SELF | CAST_FORCE_CAST)) &&
                        !CanCast(target, tSpell, (action.cast.castFlags & CAST_TRIGGERED)))
                {
                    //Melee current victim if flag not set
                    switch(me->GetMotionMaster()->GetCurrentMovementGeneratorType())
                    {
                    case CHASE_MOTION_TYPE:
                    case FOLLOW_MOTION_TYPE:
                        m_AttackDistance = 0.0f;
                        m_AttackAngle = 0.0f;

                        me->GetMotionMaster()->Clear(false);
                        break;
                    }
                }
                else
                {
                    //Interrupt any previous spell
                    if (caster->IsNonMeleeSpellCasted(false) && action.cast.castFlags & CAST_INTERRUPT_PREVIOUS)
                        caster->InterruptNonMeleeSpells(false);

                    caster->CastSpell(target, action.cast.spellId, (action.cast.castFlags & CAST_TRIGGERED));
                }
            }
            else
                sLog->outErrorDb("CreatureEventAI: event %d creature %d attempt to cast spell that doesn't exist %d", eventId, me->GetEntry(), action.cast.spellId);
        }
        break;
    }
    case ACTION_T_SUMMON:
    {
        Unit* target = GetTargetByType(action.summon.target, actionInvoker);

        Creature* creature = NULL;

        if (action.summon.duration)
            creature = me->SummonCreature(action.summon.creatureId, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, action.summon.duration);
        else
            creature = me->SummonCreature(action.summon.creatureId, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0);

        if (!creature)
            sLog->outErrorDb("CreatureEventAI: failed to spawn creature %u. Spawn event %d is on creature %d", action.summon.creatureId, eventId, me->GetEntry());
        else if (action.summon.target != TARGET_T_SELF && target)
            creature->AI()->AttackStart(target);
        break;
    }
    case ACTION_T_THREAT_SINGLE_PCT:
        if (Unit* target = GetTargetByType(action.threat_single_pct.target, actionInvoker))
            me->getThreatManager().modifyThreatPercent(target, action.threat_single_pct.percent);
        break;
    case ACTION_T_THREAT_ALL_PCT:
    {
        std::list<HostileReference*>& threatList = me->getThreatManager().getThreatList();
        for (std::list<HostileReference*>::iterator i = threatList.begin(); i != threatList.end(); ++i)
            if (Unit* Temp = Unit::GetUnit(*me, (*i)->getUnitGuid()))
                me->getThreatManager().modifyThreatPercent(Temp, action.threat_all_pct.percent);
        break;
    }
    case ACTION_T_QUEST_EVENT:
        if (Unit* target = GetTargetByType(action.quest_event.target, actionInvoker))
            if (target->GetTypeId() == TYPEID_PLAYER)
                target->ToPlayer()->AreaExploredOrEventHappens(action.quest_event.questId);
        break;
    case ACTION_T_CAST_EVENT:
        if (Unit* target = GetTargetByType(action.cast_event.target, actionInvoker))
            if (target->GetTypeId() == TYPEID_PLAYER)
                target->ToPlayer()->CastedCreatureOrGO(action.cast_event.creatureId, me->GetGUID(), action.cast_event.spellId);
        break;
    case ACTION_T_SET_UNIT_FIELD:
    {
        Unit* target = GetTargetByType(action.set_unit_field.target, actionInvoker);

        // not allow modify important for integrity object fields
        if (action.set_unit_field.field < OBJECT_END || action.set_unit_field.field >= UNIT_END)
            return;

        if (target)
            target->SetUInt32Value(action.set_unit_field.field, action.set_unit_field.value);

        break;
    }
    case ACTION_T_SET_UNIT_FLAG:
        if (Unit* target = GetTargetByType(action.unit_flag.target, actionInvoker))
            target->SetFlag(UNIT_FIELD_FLAGS, action.unit_flag.value);
        break;
    case ACTION_T_REMOVE_UNIT_FLAG:
        if (Unit* target = GetTargetByType(action.unit_flag.target, actionInvoker))
            target->RemoveFlag(UNIT_FIELD_FLAGS, action.unit_flag.value);
        break;
    case ACTION_T_AUTO_ATTACK:
        m_MeleeEnabled = action.auto_attack.state != 0;
        break;
    case ACTION_T_COMBAT_MOVEMENT:
        // ignore no affect case
        if (m_CombatMovementEnabled == (action.combat_movement.state != 0))
            return;

        m_CombatMovementEnabled = action.combat_movement.state != 0;

        //Allow movement (create new targeted movement gen only if idle)
        if (m_CombatMovementEnabled)
        {
            Unit* victim = me->getVictim();
            if (me->isInCombat() && victim)
            {
                if (action.combat_movement.melee)
                {
                    me->AddUnitState(UNIT_STATE_MELEE_ATTACKING);
                    me->SendMeleeAttackStart(victim);
                }
                if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == IDLE_MOTION_TYPE)
                    me->GetMotionMaster()->MoveChase(victim, m_AttackDistance, m_AttackAngle); // Targeted movement generator will start melee automatically, no need to send it explicitly
            }
        }
        else
        {
            if (me->isInCombat())
            {
                Unit* victim = me->getVictim();
                if (action.combat_movement.melee && victim)
                {
                    me->ClearUnitState(UNIT_STATE_MELEE_ATTACKING);
                    me->SendMeleeAttackStop(victim);
                }
                if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == CHASE_MOTION_TYPE)
                    me->GetMotionMaster()->MoveIdle();
            }
        }
        break;
    case ACTION_T_SET_PHASE:
        m_Phase = action.set_phase.phase;
        break;
    case ACTION_T_INC_PHASE:
    {
        int32 new_phase = int32(m_Phase)+action.set_inc_phase.step;
        if (new_phase < 0)
        {
            sLog->outErrorDb("CreatureEventAI: Event %d decrease m_Phase under 0. CreatureEntry = %d", eventId, me->GetEntry());
            m_Phase = 0;
        }
        else if (new_phase >= MAX_PHASE)
        {
            sLog->outErrorDb("CreatureEventAI: Event %d incremented m_Phase above %u. m_Phase mask cannot be used with phases past %u. CreatureEntry = %d", eventId, MAX_PHASE-1, MAX_PHASE-1, me->GetEntry());
            m_Phase = MAX_PHASE-1;
        }
        else
            m_Phase = new_phase;

        break;
    }
    case ACTION_T_EVADE:
        EnterEvadeMode();
        break;
    case ACTION_T_FLEE_FOR_ASSIST:
        me->DoFleeToGetAssistance();
        break;
    case ACTION_T_QUEST_EVENT_ALL:
        if (actionInvoker && actionInvoker->GetTypeId() == TYPEID_PLAYER)
        {
            if (Unit* Temp = Unit::GetUnit(*me, actionInvoker->GetGUID()))
                if (Temp->GetTypeId() == TYPEID_PLAYER)
                    Temp->ToPlayer()->GroupEventHappens(action.quest_event_all.questId, me);
        }
        break;
    case ACTION_T_CAST_EVENT_ALL:
    {
        std::list<HostileReference*>& threatList = me->getThreatManager().getThreatList();
        for (std::list<HostileReference*>::iterator i = threatList.begin(); i != threatList.end(); ++i)
            if (Unit* Temp = Unit::GetUnit(*me, (*i)->getUnitGuid()))
                if (Temp->GetTypeId() == TYPEID_PLAYER)
                    Temp->ToPlayer()->CastedCreatureOrGO(action.cast_event_all.creatureId, me->GetGUID(), action.cast_event_all.spellId);
        break;
    }
    case ACTION_T_REMOVEAURASFROMSPELL:
        if (Unit* target = GetTargetByType(action.remove_aura.target, actionInvoker))
            target->RemoveAurasDueToSpell(action.remove_aura.spellId);
        break;
    case ACTION_T_RANGED_MOVEMENT:
        m_AttackDistance = (float)action.ranged_movement.distance;
        m_AttackAngle = action.ranged_movement.angle/180.0f*M_PI;

        if (m_CombatMovementEnabled)
        {
            me->GetMotionMaster()->MoveChase(me->getVictim(), m_AttackDistance, m_AttackAngle);
        }
        break;
    case ACTION_T_RANDOM_PHASE:
        m_Phase = GetRandActionParam(rnd, action.random_phase.phase1, action.random_phase.phase2, action.random_phase.phase3);
        break;
    case ACTION_T_RANDOM_PHASE_RANGE:
        if (action.random_phase_range.phaseMin <= action.random_phase_range.phaseMax)
            m_Phase = urand(action.random_phase_range.phaseMin, action.random_phase_range.phaseMax);
        else
            sLog->outErrorDb("CreatureEventAI: ACTION_T_RANDOM_PHASE_RANGE cannot have Param2 < Param1. Event = %d. CreatureEntry = %d", eventId, me->GetEntry());
        break;
    case ACTION_T_SUMMON_ID:
    {
        Unit* target = GetTargetByType(action.summon_id.target, actionInvoker);

        CreatureEventAI_Summon_Map::const_iterator i = sEventAIMgr->GetCreatureEventAISummonMap().find(action.summon_id.spawnId);
        if (i == sEventAIMgr->GetCreatureEventAISummonMap().end())
        {
            sLog->outErrorDb("CreatureEventAI: failed to spawn creature %u. Summon map index %u does not exist. EventID %d. CreatureID %d", action.summon_id.creatureId, action.summon_id.spawnId, eventId, me->GetEntry());
            return;
        }

        Creature* creature = NULL;
        if ((*i).second.SpawnTimeSecs)
            creature = me->SummonCreature(action.summon_id.creatureId, (*i).second.position_x, (*i).second.position_y, (*i).second.position_z, (*i).second.orientation, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, (*i).second.SpawnTimeSecs);
        else
            creature = me->SummonCreature(action.summon_id.creatureId, (*i).second.position_x, (*i).second.position_y, (*i).second.position_z, (*i).second.orientation, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0);

        if (!creature)
            sLog->outErrorDb("CreatureEventAI: failed to spawn creature %u. EventId %d.Creature %d", action.summon_id.creatureId, eventId, me->GetEntry());
        else if (action.summon_id.target != TARGET_T_SELF && target)
            creature->AI()->AttackStart(target);

        break;
    }
    case ACTION_T_KILLED_MONSTER:
        //first attempt player who tapped creature
        if (Player* player = me->GetLootRecipient())
            player->RewardPlayerAndGroupAtEvent(action.killed_monster.creatureId, player);    // player as param is a hacky solution not to use GUID
        else
        {
            //if not available, use actionInvoker
            if (Unit* target = GetTargetByType(action.killed_monster.target, actionInvoker))
                if (Player* player2 = target->GetCharmerOrOwnerPlayerOrPlayerItself())
                    player2->RewardPlayerAndGroupAtEvent(action.killed_monster.creatureId, player2);
        }
        break;
    case ACTION_T_SET_INST_DATA:
    {
        InstanceScript* instance = (InstanceScript*)me->GetInstanceScript();
        if (!instance)
        {
            sLog->outErrorDb("CreatureEventAI: Event %d attempt to set instance data without instance script. Creature %d", eventId, me->GetEntry());
            return;
        }

        instance->SetData(action.set_inst_data.field, action.set_inst_data.value);
        break;
    }
    case ACTION_T_SET_INST_DATA64:
    {
        Unit* target = GetTargetByType(action.set_inst_data64.target, actionInvoker);
        if (!target)
        {
            sLog->outErrorDb("CreatureEventAI: Event %d attempt to set instance data64 but Target == NULL. Creature %d", eventId, me->GetEntry());
            return;
        }

        InstanceScript* instance = (InstanceScript*)me->GetInstanceScript();
        if (!instance)
        {
            sLog->outErrorDb("CreatureEventAI: Event %d attempt to set instance data64 without instance script. Creature %d", eventId, me->GetEntry());
            return;
        }

        instance->SetData64(action.set_inst_data64.field, target->GetGUID());
        break;
    }
    case ACTION_T_UPDATE_TEMPLATE:
        if (me->GetEntry() == action.update_template.creatureId)
        {
            sLog->outErrorDb("CreatureEventAI: Event %d ACTION_T_UPDATE_TEMPLATE call with param1 == current entry. Creature %d", eventId, me->GetEntry());
            return;
        }

        me->UpdateEntry(action.update_template.creatureId, action.update_template.team ? HORDE : ALLIANCE);
        break;
    case ACTION_T_DIE:
        if (me->isDead())
        {
            sLog->outErrorDb("CreatureEventAI: Event %d ACTION_T_DIE on dead creature. Creature %d", eventId, me->GetEntry());
            return;
        }
        me->Kill(me);
        break;
    case ACTION_T_ZONE_COMBAT_PULSE:
    {
        me->SetInCombatWithZone();
        break;
    }
    case ACTION_T_CALL_FOR_HELP:
    {
        me->CallForHelp((float)action.call_for_help.radius);
        break;
    }
    break;

    case ACTION_T_MOVE_RANDOM_POINT: //dosen't work in combat
    {
        float x, y, z;
        me->GetClosePoint(x, y, z, me->GetObjectSize() / 3, (float)action.raw.param1);
        me->GetMotionMaster()->MovePoint(0, x, y, z);
        break;
    }
    case ACTION_T_SET_STAND_STATE:
        me->SetStandState(UnitStandStateType(action.raw.param1));
        break;
    case ACTION_T_SET_PHASE_MASK:
        me->SetPhaseMask(action.raw.param1, true);
        break;
    case ACTION_T_SET_VISIBILITY:
        me->SetVisible(bool(action.raw.param1));
        break;
    case ACTION_T_SET_ACTIVE:
        me->setActive(action.raw.param1 ? true : false);
        break;
    case ACTION_T_SET_AGGRESSIVE:
        me->SetReactState(ReactStates(action.raw.param1));
        break;
    case ACTION_T_ATTACK_START_PULSE:
        AttackStart(me->SelectNearestTarget((float)action.raw.param1));
        break;
    case ACTION_T_SUMMON_GO:
    {
        GameObject* object = NULL;

        float x, y, z;
        me->GetPosition(x, y, z);
        object = me->SummonGameObject(action.raw.param1, x, y, z, 0, 0, 0, 0, 0, action.raw.param2);
        if (!object)
        {
            sLog->outErrorDb("TSCR: EventAI failed to spawn object %u. Spawn event %d is on creature %d", action.raw.param1, eventId, me->GetEntry());
        }
        break;
    }

    case ACTION_T_SET_SHEATH:
    {
        me->SetSheath(SheathState(action.set_sheath.sheath));
        break;
    }
    case ACTION_T_FORCE_DESPAWN:
    {
        me->DespawnOrUnsummon(action.forced_despawn.msDelay);
        break;
    }
    case ACTION_T_SET_INVINCIBILITY_HP_LEVEL:
    {
        if (action.invincibility_hp_level.is_percent)
            m_InvinceabilityHpLevel = me->CountPctFromMaxHealth(action.invincibility_hp_level.hp_level);
        else
            m_InvinceabilityHpLevel = action.invincibility_hp_level.hp_level;
        break;
    }
    case ACTION_T_MOUNT_TO_ENTRY_OR_MODEL:
    {
        if (action.mount.creatureId || action.mount.modelId)
        {
            // set model based on entry from creature_template
            if (action.mount.creatureId)
            {
                if (CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(action.mount.creatureId))
                {
                    uint32 display_id = sObjectMgr->ChooseDisplayId(0, cInfo);
                    me->Mount(display_id);
                }
            }
            //if no param1, then use value from param2 (modelId)
            else
                me->Mount(action.mount.modelId);
        }
        else
            me->Dismount();

        break;
    }
    }
}
        void UpdateAI(uint32 diff)
        {
            if (!CanAttack && Intro)
            {
                if (AggroTimer <= diff)
                {
                    CanAttack = true;
                    me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                    AggroTimer=19000;
                }
                else
                {
                    AggroTimer-=diff;
                    return;
                }
            }
            // to prevent abuses during phase 2
            if (Phase == 2 && !me->getVictim() && me->isInCombat())
            {
                EnterEvadeMode();
                return;
            }
            // Return since we have no target
            if (!UpdateVictim())
                return;

            if (Phase == 1 || Phase == 3)
            {
                // ShockBlastTimer
                if (ShockBlastTimer <= diff)
                {
                    // Shock Burst
                    // Randomly used in Phases 1 and 3 on Vashj's target, it's a Shock spell doing 8325-9675 nature damage and stunning the target for 5 seconds, during which she will not attack her target but switch to the next person on the aggro list.
                    DoCast(me->getVictim(), SPELL_SHOCK_BLAST);
                    me->TauntApply(me->getVictim());

                    ShockBlastTimer = 1000+rand()%14000;       // random cooldown
                } else ShockBlastTimer -= diff;

                // StaticChargeTimer
                if (StaticChargeTimer <= diff)
                {
                    // Static Charge
                    // Used on random people (only 1 person at any given time) in Phases 1 and 3, it's a debuff doing 2775 to 3225 Nature damage to the target and everybody in about 5 yards around it, every 1 seconds for 30 seconds. It can be removed by Cloak of Shadows, Iceblock, Divine Shield, etc, but not by Cleanse or Dispel Magic.
                    Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 200, true);
                    if (target && !target->HasAura(SPELL_STATIC_CHARGE_TRIGGER))
                        DoCast(target, SPELL_STATIC_CHARGE_TRIGGER); // cast Static Charge every 2 seconds for 20 seconds

                    StaticChargeTimer = 10000+rand()%20000;
                } else StaticChargeTimer -= diff;

                // EntangleTimer
                if (EntangleTimer <= diff)
                {
                    if (!Entangle)
                    {
                        // Entangle
                        // Used in Phases 1 and 3, it casts Entangling Roots on everybody in a 15 yard radius of Vashj, immobilzing them for 10 seconds and dealing 500 damage every 2 seconds. It's not a magic effect so it cannot be dispelled, but is removed by various buffs such as Cloak of Shadows or Blessing of Freedom.
                        DoCast(me->getVictim(), SPELL_ENTANGLE);
                        Entangle = true;
                        EntangleTimer = 10000;
                    }
                    else
                    {
                        CastShootOrMultishot();
                        Entangle = false;
                        EntangleTimer = 20000+rand()%5000;
                    }
                } else EntangleTimer -= diff;

                // Phase 1
                if (Phase == 1)
                {
                    // Start phase 2
                    if (HealthBelowPct(70))
                    {
                        // Phase 2 begins when Vashj hits 70%. She will run to the middle of her platform and surround herself in a shield making her invulerable.
                        Phase = 2;

                        me->GetMotionMaster()->Clear();
                        DoTeleportTo(MIDDLE_X, MIDDLE_Y, MIDDLE_Z);

                        for (uint8 i = 0; i < 4; ++i)
                            if (Creature* creature = me->SummonCreature(SHIED_GENERATOR_CHANNEL, ShieldGeneratorChannelPos[i][0],  ShieldGeneratorChannelPos[i][1],  ShieldGeneratorChannelPos[i][2],  ShieldGeneratorChannelPos[i][3], TEMPSUMMON_CORPSE_DESPAWN, 0))
                                ShieldGeneratorChannel[i] = creature->GetGUID();

                        Talk(SAY_PHASE2);
                    }
                }
                // Phase 3
                else
                {
                    // SummonSporebatTimer
                    if (SummonSporebatTimer <= diff)
                    {
                        if (Creature* sporebat = me->SummonCreature(TOXIC_SPOREBAT, SPOREBAT_X, SPOREBAT_Y, SPOREBAT_Z, SPOREBAT_O, TEMPSUMMON_CORPSE_DESPAWN, 0))
                            if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
                                sporebat->AI()->AttackStart(target);

                        // summon sporebats faster and faster
                        if (SummonSporebatStaticTimer > 1000)
                            SummonSporebatStaticTimer -= 1000;

                        SummonSporebatTimer = SummonSporebatStaticTimer;

                        if (SummonSporebatTimer < 5000)
                            SummonSporebatTimer = 5000;

                    } else SummonSporebatTimer -= diff;
                }

                // Melee attack
                DoMeleeAttackIfReady();

                // CheckTimer - used to check if somebody is in melee range
                if (CheckTimer <= diff)
                {
                    bool inMeleeRange = false;
                    std::list<HostileReference*> t_list = me->getThreatManager().getThreatList();
                    for (std::list<HostileReference*>::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr)
                    {
                        Unit* target = Unit::GetUnit(*me, (*itr)->getUnitGuid());
                        if (target && target->IsWithinDistInMap(me, 5)) // if in melee range
                        {
                            inMeleeRange = true;
                            break;
                        }
                    }

                    // if nobody is in melee range
                    if (!inMeleeRange)
                        CastShootOrMultishot();

                    CheckTimer = 5000;
                } else CheckTimer -= diff;
            }
            // Phase 2
            else
            {
                // ForkedLightningTimer
                if (ForkedLightningTimer <= diff)
                {
                    // Forked Lightning
                    // Used constantly in Phase 2, it shoots out completely randomly targeted bolts of lightning which hit everybody in a roughtly 60 degree cone in front of Vashj for 2313-2687 nature damage.
                    Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0);

                    if (!target)
                        target = me->getVictim();

                    DoCast(target, SPELL_FORKED_LIGHTNING);

                    ForkedLightningTimer = 2000+rand()%6000;
                } else ForkedLightningTimer -= diff;

                // EnchantedElementalTimer
                if (EnchantedElementalTimer <= diff)
                {
                    me->SummonCreature(ENCHANTED_ELEMENTAL, ElementPos[EnchantedElementalPos][0], ElementPos[EnchantedElementalPos][1], ElementPos[EnchantedElementalPos][2], ElementPos[EnchantedElementalPos][3], TEMPSUMMON_CORPSE_DESPAWN, 0);

                    if (EnchantedElementalPos == 7)
                        EnchantedElementalPos = 0;
                    else
                        ++EnchantedElementalPos;

                    EnchantedElementalTimer = 10000+rand()%5000;
                } else EnchantedElementalTimer -= diff;

                // TaintedElementalTimer
                if (TaintedElementalTimer <= diff)
                {
                    uint32 pos = rand()%8;
                    me->SummonCreature(TAINTED_ELEMENTAL, ElementPos[pos][0], ElementPos[pos][1], ElementPos[pos][2], ElementPos[pos][3], TEMPSUMMON_DEAD_DESPAWN, 0);

                    TaintedElementalTimer = 120000;
                } else TaintedElementalTimer -= diff;

                // CoilfangEliteTimer
                if (CoilfangEliteTimer <= diff)
                {
                    uint32 pos = rand()%3;
                    Creature* coilfangElite = me->SummonCreature(COILFANG_ELITE, CoilfangElitePos[pos][0], CoilfangElitePos[pos][1], CoilfangElitePos[pos][2], CoilfangElitePos[pos][3], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    if (coilfangElite)
                    {
                        if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
                            coilfangElite->AI()->AttackStart(target);
                        else if (me->getVictim())
                            coilfangElite->AI()->AttackStart(me->getVictim());
                    }
                    CoilfangEliteTimer = 45000+rand()%5000;
                } else CoilfangEliteTimer -= diff;

                // CoilfangStriderTimer
                if (CoilfangStriderTimer <= diff)
                {
                    uint32 pos = rand()%3;
                    if (Creature* CoilfangStrider = me->SummonCreature(COILFANG_STRIDER, CoilfangStriderPos[pos][0], CoilfangStriderPos[pos][1], CoilfangStriderPos[pos][2], CoilfangStriderPos[pos][3], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000))
                    {
                        if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
                            CoilfangStrider->AI()->AttackStart(target);
                        else if (me->getVictim())
                            CoilfangStrider->AI()->AttackStart(me->getVictim());
                    }
                    CoilfangStriderTimer = 60000+rand()%10000;
                } else CoilfangStriderTimer -= diff;

                // CheckTimer
                if (CheckTimer <= diff)
                {
                    // Start Phase 3
                    if (instance && instance->GetData(DATA_CANSTARTPHASE3))
                    {
                        // set life 50%
                        me->SetHealth(me->CountPctFromMaxHealth(50));

                        me->RemoveAurasDueToSpell(SPELL_MAGIC_BARRIER);

                        Talk(SAY_PHASE3);

                        Phase = 3;

                        // return to the tank
                        me->GetMotionMaster()->MoveChase(me->getVictim());
                    }
                    CheckTimer = 1000;
                } else CheckTimer -= diff;
            }
        }
Example #10
0
CombatManeuverReturns PlayerbotRogueAI::DoNextCombatManeuver(Unit *pTarget)
{
    if (!pTarget) return RETURN_NO_ACTION_ERROR;
    if (!m_ai)    return RETURN_NO_ACTION_ERROR;
    if (!m_bot)   return RETURN_NO_ACTION_ERROR;

    switch (m_ai->GetScenarioType())
    {
    case PlayerbotAI::SCENARIO_DUEL:
    {
        if (SINISTER_STRIKE > 0)
        {
            m_ai->CastSpell(SINISTER_STRIKE);
            return RETURN_CONTINUE;
        }

        return RETURN_NO_ACTION_UNKNOWN;
    }
    default:
        break;
    }

    Unit* pVictim = pTarget->getVictim();
    float fTargetDist = m_bot->GetCombatDistance(pTarget);

    // TODO: make this work better...
    /*if (pVictim)
       {
        if( pVictim!=m_bot && !m_bot->hasUnitState(UNIT_STAT_FOLLOW) && !pTarget->isInBackInMap(m_bot,10) ) {
            m_ai->TellMaster( "getting behind target" );
            m_bot->GetMotionMaster()->Clear( true );
            m_bot->GetMotionMaster()->MoveFollow( pTarget, 1, 2*M_PI );
        }
        else if( pVictim==m_bot && m_bot->hasUnitState(UNIT_STAT_FOLLOW) )
        {
            m_ai->TellMaster( "chasing attacking target" );
            m_bot->GetMotionMaster()->Clear( true );
            m_bot->GetMotionMaster()->MoveChase( pTarget );
        }
       }*/

    //Rouge like behaviour. ^^
    /*    if (VANISH > 0 && GetMaster()->isDead()) { //Causes the server to crash :( removed for now.
            m_bot->AttackStop();
            m_bot->RemoveAllAttackers();
            m_ai->CastSpell(VANISH);
       //        m_bot->RemoveAllSpellCooldown();
            m_ai->TellMaster("AttackStop, CombatStop, Vanish");
        }*/

    // decide what to do:
    if (pVictim == m_bot && CLOAK_OF_SHADOWS > 0 && pVictim->HasAura(SPELL_AURA_PERIODIC_DAMAGE) && !m_bot->HasAura(CLOAK_OF_SHADOWS, EFFECT_INDEX_0) && m_ai->CastSpell(CLOAK_OF_SHADOWS))
    {
        if (m_ai->GetManager()->m_confDebugWhisper)
            m_ai->TellMaster("CoS!");
        return RETURN_CONTINUE;
    }
    else if (m_bot->HasAura(STEALTH, EFFECT_INDEX_0))
        SpellSequence = RogueStealth;
    else if (pTarget->IsNonMeleeSpellCasted(true))
        SpellSequence = RogueSpellPreventing;
    else if (pVictim == m_bot && m_ai->GetHealthPercent() < 40)
        SpellSequence = RogueThreat;
    else
        SpellSequence = RogueCombat;

    // we fight in melee, target is not in range, skip the next part!
    if (fTargetDist > ATTACK_DISTANCE)
        return RETURN_CONTINUE;

    std::ostringstream out;
    switch (SpellSequence)
    {
    case RogueStealth:
        if (PICK_POCKET > 0 && (pTarget->GetCreatureTypeMask() & CREATURE_TYPEMASK_HUMANOID_OR_UNDEAD) != 0 &&
                !((Creature *) pTarget)->lootForPickPocketed && m_ai->CastSpell(PICK_POCKET, *pTarget))
            return RETURN_CONTINUE;
        else if (PREMEDITATION > 0 && m_ai->CastSpell(PREMEDITATION, *pTarget))
            return RETURN_CONTINUE;
        else if (AMBUSH > 0 && m_ai->GetEnergyAmount() >= 60 && m_ai->CastSpell(AMBUSH, *pTarget))
            return RETURN_CONTINUE;
        else if (CHEAP_SHOT > 0 && !pTarget->HasAura(CHEAP_SHOT, EFFECT_INDEX_0) && m_ai->GetEnergyAmount() >= 60 && m_ai->CastSpell(CHEAP_SHOT, *pTarget))
            return RETURN_CONTINUE;
        else if (GARROTE > 0 && m_ai->GetEnergyAmount() >= 50 && m_ai->CastSpell(GARROTE, *pTarget))
            return RETURN_CONTINUE;

        // No appropriate action found, remove stealth
        m_bot->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
        return RETURN_CONTINUE;

    case RogueThreat:
        if (GOUGE > 0 && m_ai->GetEnergyAmount() >= 45 && !pTarget->HasAura(GOUGE, EFFECT_INDEX_0) && m_ai->CastSpell(GOUGE, *pTarget))
            return RETURN_CONTINUE;
        else if (EVASION > 0 && m_ai->GetHealthPercent() <= 35 && !m_bot->HasAura(EVASION, EFFECT_INDEX_0) && m_ai->CastSpell(EVASION))
            return RETURN_CONTINUE;
        else if (BLIND > 0 && m_ai->GetHealthPercent() <= 30 && !pTarget->HasAura(BLIND, EFFECT_INDEX_0) && m_ai->GetEnergyAmount() >= 30 && m_ai->CastSpell(BLIND, *pTarget))
            return RETURN_CONTINUE;
        else if (FEINT > 0 && m_ai->GetHealthPercent() <= 25 && m_ai->GetEnergyAmount() >= 20 && m_ai->CastSpell(FEINT))
            return RETURN_CONTINUE;
        else if (VANISH > 0 && m_ai->GetHealthPercent() <= 20 && !m_bot->HasAura(FEINT, EFFECT_INDEX_0) && m_ai->CastSpell(VANISH))
            return RETURN_CONTINUE;
        else if (PREPARATION > 0 && m_ai->CastSpell(PREPARATION))
            return RETURN_CONTINUE;
        else if (m_bot->getRace() == RACE_NIGHTELF && m_ai->GetHealthPercent() <= 15 && !m_bot->HasAura(SHADOWMELD, EFFECT_INDEX_0) && m_ai->CastSpell(SHADOWMELD, *m_bot))
            return RETURN_CONTINUE;
        break;

    case RogueSpellPreventing:
        if (KIDNEY_SHOT > 0 && m_ai->GetEnergyAmount() >= 25 && m_bot->GetComboPoints() >= 2 && m_ai->CastSpell(KIDNEY_SHOT, *pTarget))
            return RETURN_CONTINUE;
        else if (KICK > 0 && m_ai->GetEnergyAmount() >= 25  && m_ai->CastSpell(KICK, *pTarget))
            return RETURN_CONTINUE;
    // break; // No action? Go combat!

    case RogueCombat:
    default:
        if (m_bot->GetComboPoints() >= 5)
        {
            // wait for energy
            if ( (m_ai->GetEnergyAmount() < 25 && (KIDNEY_SHOT || SLICE_DICE || EXPOSE_ARMOR))
                    || (m_ai->GetEnergyAmount() < 35 && EVISCERATE) )
                return RETURN_NO_ACTION_OK;

            switch (pTarget->getClass())
            {
            case CLASS_SHAMAN:
                if (KIDNEY_SHOT > 0 && m_ai->CastSpell(KIDNEY_SHOT, *pTarget)) // 25 energy (checked above)
                    return RETURN_CONTINUE;
                break;

            case CLASS_WARLOCK:
            case CLASS_HUNTER:
                if (SLICE_DICE > 0 && m_ai->CastSpell(SLICE_DICE, *pTarget)) // 25 energy (checked above)
                    return RETURN_CONTINUE;
                break;

            case CLASS_WARRIOR:
            case CLASS_PALADIN:
            case CLASS_DEATH_KNIGHT:
                if (EXPOSE_ARMOR > 0 && !pTarget->HasAura(EXPOSE_ARMOR, EFFECT_INDEX_0) && m_ai->CastSpell(EXPOSE_ARMOR, *pTarget)) // 25 energy (checked above)
                    return RETURN_CONTINUE;
                break;


            case CLASS_MAGE:
            case CLASS_PRIEST:
                if (RUPTURE > 0 && m_ai->CastSpell(RUPTURE, *pTarget)) // 25 energy (checked above)
                    return RETURN_CONTINUE;
                break;

            case CLASS_ROGUE:
            case CLASS_DRUID:
            default:
                break; // fall through to below
            }

            // default combo action for rogue/druid or if other combo action is unavailable/failed
            if (EVISCERATE > 0 && m_ai->CastSpell(EVISCERATE, *pTarget))
                return RETURN_CONTINUE;

            // failed for some (non-energy related) reason, fall through to normal attacks to maximize DPS
        }

        if (SHADOW_DANCE > 0 && !m_bot->HasAura(SHADOW_DANCE, EFFECT_INDEX_0) && m_ai->CastSpell(SHADOW_DANCE, *m_bot))
            return RETURN_CONTINUE;
        else if (CHEAP_SHOT > 0 && m_bot->HasAura(SHADOW_DANCE, EFFECT_INDEX_0) && !pTarget->HasAura(CHEAP_SHOT, EFFECT_INDEX_0) && m_ai->GetEnergyAmount() >= 60 && m_ai->CastSpell(CHEAP_SHOT, *pTarget))
            return RETURN_CONTINUE;
        else if (AMBUSH > 0 && m_bot->HasAura(SHADOW_DANCE, EFFECT_INDEX_0) && m_ai->GetEnergyAmount() >= 60 && m_ai->CastSpell(AMBUSH, *pTarget))
            return RETURN_CONTINUE;
        else if (GARROTE > 0 && m_bot->HasAura(SHADOW_DANCE, EFFECT_INDEX_0) && m_ai->GetEnergyAmount() >= 50 && m_ai->CastSpell(GARROTE, *pTarget))
            return RETURN_CONTINUE;
        else if (BACKSTAB > 0 && pTarget->isInBackInMap(m_bot, 1) && m_ai->GetEnergyAmount() >= 60 && m_ai->CastSpell(BACKSTAB, *pTarget))
            return RETURN_CONTINUE;
        else if (MUTILATE > 0 && m_ai->GetEnergyAmount() >= 60 && m_ai->CastSpell(MUTILATE, *pTarget))
            return RETURN_CONTINUE;
        else if (SINISTER_STRIKE > 0 && m_ai->GetEnergyAmount() >= 45 && m_ai->CastSpell(SINISTER_STRIKE, *pTarget))
            return RETURN_CONTINUE;
        else if (GHOSTLY_STRIKE > 0 && m_ai->GetEnergyAmount() >= 40 && m_ai->CastSpell(GHOSTLY_STRIKE, *pTarget))
            return RETURN_CONTINUE;
        else if (HEMORRHAGE > 0 && m_ai->GetEnergyAmount() >= 35 && m_ai->CastSpell(HEMORRHAGE, *pTarget))
            return RETURN_CONTINUE;
        else if (DISMANTLE > 0 && !pTarget->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISARMED) && m_ai->GetEnergyAmount() >= 25 && m_ai->CastSpell(DISMANTLE, *pTarget))
            return RETURN_CONTINUE;
        else if (SHADOWSTEP > 0 && m_ai->GetEnergyAmount() >= 10 && m_ai->CastSpell(SHADOWSTEP, *pTarget))
            return RETURN_CONTINUE;
        else if (m_bot->getRace() == RACE_BLOODELF && !pTarget->HasAura(ARCANE_TORRENT, EFFECT_INDEX_0) && m_ai->CastSpell(ARCANE_TORRENT, *pTarget))
            return RETURN_CONTINUE;
        else if ((m_bot->getRace() == RACE_HUMAN && m_bot->hasUnitState(UNIT_STAT_STUNNED)) || m_bot->HasAuraType(SPELL_AURA_MOD_FEAR) || m_bot->HasAuraType(SPELL_AURA_MOD_DECREASE_SPEED) || (m_bot->HasAuraType(SPELL_AURA_MOD_CHARM) && m_ai->CastSpell(EVERY_MAN_FOR_HIMSELF, *m_bot)))
            return RETURN_CONTINUE;
        else if ((m_bot->getRace() == RACE_UNDEAD && m_bot->HasAuraType(SPELL_AURA_MOD_FEAR)) || (m_bot->HasAuraType(SPELL_AURA_MOD_CHARM) && m_ai->CastSpell(WILL_OF_THE_FORSAKEN, *m_bot)))
            return RETURN_CONTINUE;
        else if (m_bot->getRace() == RACE_DWARF && m_bot->HasAuraState(AURA_STATE_DEADLY_POISON) && m_ai->CastSpell(STONEFORM, *m_bot))
            return RETURN_CONTINUE;
        else if ((m_bot->getRace() == RACE_GNOME && m_bot->hasUnitState(UNIT_STAT_STUNNED)) || (m_bot->HasAuraType(SPELL_AURA_MOD_DECREASE_SPEED) && m_ai->CastSpell(ESCAPE_ARTIST, *m_bot)))
            return RETURN_CONTINUE;
        else if (m_bot->getRace() == RACE_ORC && !m_bot->HasAura(BLOOD_FURY, EFFECT_INDEX_0) && m_ai->CastSpell(BLOOD_FURY, *m_bot))
            return RETURN_CONTINUE;
        else if (m_bot->getRace() == RACE_TROLL && !m_bot->HasAura(BERSERKING, EFFECT_INDEX_0) && m_ai->CastSpell(BERSERKING, *m_bot))
            return RETURN_CONTINUE;
        break;
    }
    if (m_ai->GetManager()->m_confDebugWhisper)
        m_ai->TellMaster(out.str().c_str());

    return RETURN_NO_ACTION_UNKNOWN;
}
Example #11
0
    void UpdateAI(const uint32 uiDiff)
    {
        if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
            return;

        if(m_uiIntroTimer < uiDiff)
        {
            if(m_bIsIntroNow)
            {
                m_creature->StopMoving();
                m_creature->GetMotionMaster()->Clear();
                m_creature->GetMotionMaster()->MoveIdle();

                switch(m_uiIntroCount)
                {
                case 0:
                    DoPlaySoundToSet(m_creature, SOUND_MADR_ICE_BARRIER);
                    m_uiIntroTimer = 6000;
                    break;
                case 1:
                    DoPlaySoundToSet(m_creature, SOUND_MADR_INTRO);
                    m_uiIntroTimer = 5000;
                    break;
                case 2:
                    DoPlaySoundToSet(m_creature, SOUND_INTRO);
                    m_uiIntroTimer = 6000;
                    break;
                case 3:
                    DoPlaySoundToSet(m_creature, SOUND_MADR_ICE_BLOCK);
                    m_uiIntroTimer = 4000;
                    break;
                case 4:
                    DoPlaySoundToSet(m_creature, SOUND_INTRO_BREAK_ICE);
                    m_uiIntroTimer = 5000;
                    break;
                case 5:
                    DoPlaySoundToSet(m_creature, SOUND_MADR_TRAP);
                    m_uiIntroTimer = 5000;
                    break;
                case 6:
                    DoPlaySoundToSet(m_creature, SOUND_INTRO_CHARGE);
                    m_uiIntroTimer = 5000;
                    break;
                case 7:
                    DoPlaySoundToSet(m_creature, SOUND_MADR_DEATH);
                    m_uiIntroTimer = 5000;
                    break;
                case 8:
                    DoPlaySoundToSet(m_creature, SOUND_INTRO_KILL_MADRIGOSA);
                    m_uiIntroTimer = 6000;
                    break;
                case 9:
                    DoPlaySoundToSet(m_creature, SOUND_INTRO_TAUNT);
                    m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
                    m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                    m_uiBerserkTimer = 360000;
                    m_bIsIntroNow = false;
                    break;
                }
                ++m_uiIntroCount;
            }
        } else m_uiIntroTimer -= uiDiff;

        if(m_bIsIntroNow)
            return;

        if (m_uiBurnCheckTimer < uiDiff)
        {
            std::list<HostileReference *> t_list = m_creature->getThreatManager().getThreatList();
            for(std::list<HostileReference *>::iterator itr = t_list.begin(); itr!= t_list.end(); ++itr)
            {
                Unit *BurnedPlayer = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid());
                if (BurnedPlayer && BurnedPlayer->GetTypeId() == TYPEID_PLAYER && BurnedPlayer->HasAura(SPELL_BURN_AURA))
                {
                    std::list<HostileReference *> t_list = m_creature->getThreatManager().getThreatList();
                    for(std::list<HostileReference *>::iterator itr = t_list.begin(); itr!= t_list.end(); ++itr)
                    {
                        Unit *TargetedPlayer = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid());
                        if (TargetedPlayer && TargetedPlayer->GetTypeId() == TYPEID_PLAYER && TargetedPlayer->IsWithinDistInMap(BurnedPlayer, 6) && !TargetedPlayer->HasAura(SPELL_BURN_AURA))
                            TargetedPlayer->CastSpell(TargetedPlayer,SPELL_BURN_AURA,true);
                    }
                }
            }
            m_uiBurnCheckTimer = 1000;
        } else m_uiBurnCheckTimer -= uiDiff;

        if (m_uiLoveTimer < uiDiff)
        {
            switch(urand(0, 2))
            {
            case 0:
                DoScriptText(YELL_LOVE1, m_creature);
                break;
            case 1:
                DoScriptText(YELL_LOVE2, m_creature);
                break;
            case 2:
                DoScriptText(YELL_LOVE3, m_creature);
                break;
            }
            m_uiLoveTimer = urand(15000, 23000);
        }
        else
            m_uiLoveTimer -= uiDiff;

        if (m_uiSlashTimer < uiDiff)
        {
            if (Unit* pTarget = m_creature->getVictim())
                DoCast(pTarget,SPELL_METEOR_SLASH);
            m_uiSlashTimer = 11000;
        } else m_uiSlashTimer -= uiDiff;

        if (m_uiStompTimer < uiDiff)
        {
            if (Unit* pTarget = m_creature->getVictim())
            {
                DoCast(pTarget,SPELL_STOMP);

                if (pTarget->HasAura(SPELL_BURN_AURA))
                    pTarget->RemoveAurasDueToSpell(SPELL_BURN_AURA);
            }
            m_uiStompTimer = 30000;
        }
        else
            m_uiStompTimer -= uiDiff;

        if (m_uiBurnTimer < uiDiff)
        {
            if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0))
            {
                DoCast(target,SPELL_BURN);
                target->CastSpell(target,SPELL_BURN_AURA, true);
            }
            m_uiBurnTimer = 60000;
        }
        else m_uiBurnTimer -= uiDiff;

        if (m_uiBerserkTimer < uiDiff)
        {
            DoScriptText(YELL_BERSERK, m_creature);
            DoCast(m_creature,SPELL_BERSERK);
            m_uiBerserkTimer = 20000;
        }
        else
            m_uiBerserkTimer -= uiDiff;

        DoMeleeAttackIfReady();
    }