Example #1
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;
    }
    }
}
Example #2
0
        void UpdateAI(const uint32 diff)
        {
            if(!UpdateVictim())
                return;

            //Check_Timer for the death of LorKhan and Zath.
            if(!WasDead && Check_Timer <= diff)
            {
                if(pInstance)
                {
                    if(pInstance->GetData(DATA_LORKHAN) == SPECIAL)
                    {
                        //Resurrect LorKhan
                        if(Unit* pLorKhan = Unit::GetUnit((*me), pInstance->GetData64(DATA_LORKHAN)))
                        {
                            pLorKhan->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
                            pLorKhan->setFaction(14);
                            pLorKhan->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                            pLorKhan->SetFullHealth();

                            pInstance->SetData(DATA_LORKHAN, DONE);
                        }
                    }

                    if(pInstance->GetData(DATA_ZATH) == SPECIAL)
                    {
                        //Resurrect Zath
                        Unit* pZath = Unit::GetUnit((*me), pInstance->GetData64(DATA_ZATH));
                        if(pZath)
                        {
                            pZath->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
                            pZath->setFaction(14);
                            pZath->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                            pZath->SetFullHealth();

                            pInstance->SetData(DATA_ZATH, DONE);
                        }
                    }
                }

                Check_Timer = 5000;
            } else Check_Timer -= diff;

            if(!PhaseTwo && MortalCleave_Timer <= diff)
            {
                DoCast(me->getVictim(), SPELL_MORTALCLEAVE);
                MortalCleave_Timer = 15000 + rand()%5000;
            } else MortalCleave_Timer -= diff;

            if(!PhaseTwo && Silence_Timer <= diff)
            {
                DoCast(me->getVictim(), SPELL_SILENCE);
                Silence_Timer = 20000 + rand()%5000;
            } else Silence_Timer -= diff;

            if(!PhaseTwo && !WasDead && !HealthAbovePct(5))
            {
                me->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE_PERCENT);
                me->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
                me->RemoveAurasByType(SPELL_AURA_PERIODIC_LEECH);
                me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                me->SetStandState(UNIT_STAND_STATE_SLEEP);
                me->AttackStop();

                if(pInstance)
                    pInstance->SetData(DATA_THEKAL, SPECIAL);

                WasDead=true;
            }

            //Thekal will transform to Tiger if he died and was not resurrected after 10 seconds.
            if(!PhaseTwo && WasDead)
            {
                if(Resurrect_Timer <= diff)
                {
                    DoCast(me, SPELL_TIGER_FORM);
                    me->SetFloatValue(OBJECT_FIELD_SCALE_X, 2.00f);
                    me->SetStandState(UNIT_STAND_STATE_STAND);
                    me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                    me->SetFullHealth();
                    const CreatureTemplate *cinfo = me->GetCreatureInfo();
                    me->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg +((cinfo->mindmg/100) * 40)));
                    me->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg +((cinfo->maxdmg/100) * 40)));
                    me->UpdateDamagePhysical(BASE_ATTACK);
                    DoResetThreat();
                    PhaseTwo = true;
                } else Resurrect_Timer -= diff;
            }

            if(me->IsFullHealth() && WasDead)
            {
                WasDead = false;
            }

            if(PhaseTwo)
            {
                if(Charge_Timer <= diff)
                {
                    if(Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
                    {
                        DoCast(target, SPELL_CHARGE);
                        DoResetThreat();
                        AttackStart(target);
                    }

                    Charge_Timer = 15000 + rand()%7000;
                } else Charge_Timer -= diff;

                if(Frenzy_Timer <= diff)
                {
                    DoCast(me, SPELL_FRENZY);
                    Frenzy_Timer = 30000;
                } else Frenzy_Timer -= diff;

                if(ForcePunch_Timer <= diff)
                {
                    DoCast(me->getVictim(), SPELL_SILENCE);
                    ForcePunch_Timer = 16000 + rand()%5000;
                } else ForcePunch_Timer -= diff;

                if(SummonTigers_Timer <= diff)
                {
                    DoCast(me->getVictim(), SPELL_SUMMONTIGERS);
                    SummonTigers_Timer = 10000 + rand()%4000;
                } else SummonTigers_Timer -= diff;

                if(HealthBelowPct(11) && !Enraged)
                {
                    DoCast(me, SPELL_ENRAGE);
                    Enraged = true;
                }
            }

            DoMeleeAttackIfReady();

        }