예제 #1
0
        void UpdateAI(uint32 diff) override
        {
            if (!UpdateVictim())
                return;

            DoMeleeAttackIfReady();

            if (ChaseTimer <= diff)
            {
                if (!IsChasing)
                {
                    if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
                    {
                        Talk(SAY_WOLF_HOOD);
                        DoCast(target, SPELL_LITTLE_RED_RIDING_HOOD, true);
                        TempThreat = GetThreat(target);
                        if (TempThreat)
                            ModifyThreatByPercent(target, -100);
                        HoodGUID = target->GetGUID();
                        AddThreat(target, 1000000.0f);
                        ChaseTimer = 20000;
                        IsChasing = true;
                    }
                }
                else
                {
                    IsChasing = false;

                    if (Unit* target = ObjectAccessor::GetUnit(*me, HoodGUID))
                    {
                        HoodGUID.Clear();
                        if (GetThreat(target))
                            ModifyThreatByPercent(target, -100);
                        AddThreat(target, TempThreat);
                        TempThreat = 0;
                    }

                    ChaseTimer = 40000;
                }
            } else ChaseTimer -= diff;

            if (IsChasing)
                return;

            if (FearTimer <= diff)
            {
                DoCastVictim(SPELL_TERRIFYING_HOWL);
                FearTimer = urand(25000, 35000);
            } else FearTimer -= diff;

            if (SwipeTimer <= diff)
            {
                DoCastVictim(SPELL_WIDE_SWIPE);
                SwipeTimer = urand(25000, 30000);
            } else SwipeTimer -= diff;
        }
예제 #2
0
파일: ai_map.cpp 프로젝트: vgck/opendr2
  //
  // Evaluate enemy threat to the given defense table
  //
  U32 Map::Cluster::EvaluateThreat(Team *team, Relation relation, U32 armourClass)
  {
    U32 threat = 0;

    // Enumerate the enemy teams
    for (List<Team>::Iterator t(&team->RelatedTeams(relation)); *t; ++t)
    {
      threat += GetThreat((*t)->GetId(), armourClass);
    }
    return (threat);
  }
예제 #3
0
double MapAnalysis::GetThreatRank(const CityData * city) const
{
    Assert(city);
    PLAYER_INDEX owner = city->GetOwner();
    sint32 threat = GetThreat(owner, city->GetHomeCity().RetPos());

    if ((m_maxCityThreat[owner] - m_minCityThreat[owner]) > 0)
        return ((double)(threat - m_minCityThreat[owner]) /
        (double)(m_maxCityThreat[owner] - m_minCityThreat[owner]));

    return 0.0;
}
예제 #4
0
파일: ai_map.cpp 프로젝트: vgck/opendr2
  //
  // Evaluate enemy threat to the given defense table
  //
  U32 Map::Cluster::EvaluateThreat(Team *team, Relation relation, U32 *defenses)
  {
    U32 threat = 0;

    // Enumerate the enemy teams
    for (List<Team>::Iterator t(&team->RelatedTeams(relation)); *t; ++t)
    {
      for (U32 a = 0; a < ArmourClass::NumClasses(); a++)
      {
        if (defenses[a])
        {
          threat += GetThreat((*t)->GetId(), a) * defenses[a];
        }
      }
    }
    return (threat);
  }
        void UpdateAI(uint32 diff) override
        {
            if (!UpdateVictim())
                return;

            events.Update(diff);

            while (uint32 eventId = events.ExecuteEvent())
            {
                switch (eventId)
                {
                    case EVENT_CLEAVE:
                        DoCastVictim(SPELL_CLEAVE);
                        events.ScheduleEvent(EVENT_CLEAVE, 7s);
                        break;
                    case EVENT_BLASTWAVE:
                        DoCastVictim(SPELL_BLASTWAVE);
                        events.ScheduleEvent(EVENT_BLASTWAVE, 8s, 16s);
                        break;
                    case EVENT_MORTALSTRIKE:
                        DoCastVictim(SPELL_MORTALSTRIKE);
                        events.ScheduleEvent(EVENT_MORTALSTRIKE, 25s, 35s);
                        break;
                    case EVENT_KNOCKBACK:
                        DoCastVictim(SPELL_KNOCKBACK);
                        if (GetThreat(me->GetVictim()))
                            ModifyThreatByPercent(me->GetVictim(), -50);
                        events.ScheduleEvent(EVENT_KNOCKBACK, 15s, 30s);
                        break;
                    case EVENT_CHECK:
                        if (me->GetDistance(me->GetHomePosition()) > 150.0f)
                        {
                            Talk(SAY_LEASH);
                            EnterEvadeMode(EVADE_REASON_BOUNDARY);
                        }
                        events.ScheduleEvent(EVENT_CHECK, 1s);
                        break;
                }
            }

            DoMeleeAttackIfReady();
        }
예제 #6
0
double MapAnalysis::CityAtRiskRatio(const Unit city, const PLAYER_INDEX opponentId) const
{
    Assert(city.IsValid());
    PLAYER_INDEX playerId = city.GetOwner();

    Player * player_ptr = g_player[playerId];
    if (player_ptr == NULL)
        return 0.0;

    if (opponentId != PLAYER_UNASSIGNED && g_player[opponentId] == NULL)
        return 0.0;

    MapPoint pos;
    city.GetPos(pos);


    sint32  player_threat   = m_threatGrid[playerId].GetGridValue(pos);
    sint32  opponent_threat = (PLAYER_UNASSIGNED == opponentId) // In that case no opponent there, so it is the right way to calculate it?
                              ? GetThreat(playerId, pos)
                              : m_threatGrid[opponentId].GetGridValue(pos);

    double ratio;
    if (player_threat > 0)
	{
		ratio = ((double) opponent_threat / (double) player_threat) * 0.2;
        if (ratio > 1.0)
            ratio = 1.0;
        else if (ratio < 0.0)
            ratio = 0.0;
	}
	else if (opponent_threat <= 0)
	{
		ratio  = 0.0;
	}
	else 
	{
		ratio = 1.0;
	}

	return ratio;
}
        void UpdateAI(uint32 diff) override
        {
            //Return since we have no target
            if (!UpdateVictim())
                return;

            //Charge_Timer
            if (Charge_Timer <= diff)
            {
                if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
                {
                    DoCast(target, SPELL_CHARGE);
                    //me->SendMonsterMove(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, true, 1);
                    AttackStart(target);
                }

                Charge_Timer = urand(8000, 16000);
            } else Charge_Timer -= diff;

            //KnockBack_Timer
            if (KnockBack_Timer <= diff)
            {
                DoCastVictim(SPELL_KNOCKBACK);
                if (GetThreat(me->GetVictim()))
                    ModifyThreatByPercent(me->GetVictim(), -80);
                KnockBack_Timer = urand(15000, 25000);
            } else KnockBack_Timer -= diff;

            //Enrage_Timer
            if (!Enraged && Enrage_Timer <= diff)
            {
                DoCast(me, SPELL_ENRAGE);
                Enraged = true;
            } else Charge_Timer -= diff;

            DoMeleeAttackIfReady();
        }
예제 #8
0
        void UpdateAI(uint32 diff) override
        {
            if (!UpdateVictim())
                return;

            events.Update(diff);

            if (me->HasUnitState(UNIT_STATE_CASTING))
                return;

            while (uint32 eventId = events.ExecuteEvent())
            {
                switch (eventId)
                {
                    case EVENT_SHADOWFLAME:
                        DoCastVictim(SPELL_SHADOWFLAME);
                        events.ScheduleEvent(EVENT_SHADOWFLAME, urand(10000, 20000));
                        break;
                    case EVENT_WINGBUFFET:
                        DoCastVictim(SPELL_WINGBUFFET);
                        if (GetThreat(me->GetVictim()))
                            ModifyThreatByPercent(me->GetVictim(), -75);
                        events.ScheduleEvent(EVENT_WINGBUFFET, 30000);
                        break;
                    case EVENT_FRENZY:
                        Talk(EMOTE_FRENZY);
                        DoCast(me, SPELL_FRENZY);
                        events.ScheduleEvent(EVENT_FRENZY, urand(8000, 10000));
                        break;
                }

                if (me->HasUnitState(UNIT_STATE_CASTING))
                    return;
            }

            DoMeleeAttackIfReady();
        }
            void DoAction(int32 actionId) override
            {
                if (actionId == ACTION_STORE_OLD_TARGET)
                {
                    if (Unit* victim = me->GetVictim())
                    {
                        _oldTargetGUID = victim->GetGUID();
                        _tempThreat = GetThreat(victim);
                    }
                }
                else if (actionId == ACTION_RESET_THREAT)
                {
                    if (Unit* oldTarget = ObjectAccessor::GetUnit(*me, _oldTargetGUID))
                    {
                        if (Unit* current = me->GetVictim())
                            ModifyThreatByPercent(current, -100);

                        AddThreat(oldTarget, _tempThreat);
                        AttackStart(oldTarget);
                        _oldTargetGUID.Clear();
                        _tempThreat = 0.0f;
                    }
                }
            }
예제 #10
0
            void UpdateAI(uint32 diff) override
            {
                if (!UpdateVictim())
                    return;

                events.Update(diff);

                if (me->HasUnitState(UNIT_STATE_CASTING))
                    return;

                while (uint32 eventId = events.ExecuteEvent())
                {
                    switch (eventId)
                    {
                        case EVENT_BRAIN_WASH_TOTEM:
                            DoCast(me, SPELL_BRAIN_WASH_TOTEM);
                            events.ScheduleEvent(EVENT_BRAIN_WASH_TOTEM, 18s, 26s);
                            break;
                        case EVENT_POWERFULL_HEALING_WARD:
                            DoCast(me, SPELL_POWERFULL_HEALING_WARD);
                            events.ScheduleEvent(EVENT_POWERFULL_HEALING_WARD, 14s, 20s);
                            break;
                        case EVENT_HEX:
                            if (Unit* target = me->GetVictim())
                            {
                                DoCast(target, SPELL_HEX, true);
                                if (GetThreat(target))
                                    ModifyThreatByPercent(target, -80);
                            }
                            events.ScheduleEvent(EVENT_HEX, 12s, 20s);
                            break;
                        case EVENT_DELUSIONS_OF_JINDO:
                            // Casting the delusion curse with a shade so shade will attack the same target with the curse.
                            if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
                            {
                                DoCast(target, SPELL_SHADE_OF_JINDO, true);
                                DoCast(target, SPELL_DELUSIONS_OF_JINDO);
                            }
                            events.ScheduleEvent(EVENT_DELUSIONS_OF_JINDO, 4s, 12s);
                            break;
                        case EVENT_TELEPORT:
                            // Teleports a random player and spawns 9 Sacrificed Trolls to attack player
                            if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
                            {
                                DoTeleportPlayer(target, TeleportLoc.GetPositionX(), TeleportLoc.GetPositionY(), TeleportLoc.GetPositionZ(), TeleportLoc.GetOrientation());
                                if (GetThreat(me->GetVictim()))
                                    ModifyThreatByPercent(target, -100);

                                // Summon a formation of trolls
                                for (uint8 i = 0; i < 10; ++i)
                                    if (Creature* SacrificedTroll = me->SummonCreature(NPC_SACRIFICED_TROLL, Formation[i].GetPositionX(), Formation[i].GetPositionY(), Formation[i].GetPositionZ(), Formation[i].GetOrientation(), TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000))
                                        SacrificedTroll->AI()->AttackStart(target);
                            }
                            events.ScheduleEvent(EVENT_TELEPORT, 15s, 23s);
                            break;
                        default:
                            break;
                    }

                    if (me->HasUnitState(UNIT_STATE_CASTING))
                        return;
                }

                DoMeleeAttackIfReady();
            }
            void UpdateAI(uint32 diff) override
            {
                if (!UpdateVictim())
                    return;

                //Invisible_Timer
                if (Invisible_Timer <= diff)
                {
                    me->InterruptSpell(CURRENT_GENERIC_SPELL);

                    SetEquipmentSlots(false, EQUIP_UNEQUIP, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
                    me->SetDisplayId(11686);

                    me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                    Invisible = true;

                    Invisible_Timer = urand(15000, 30000);
                } else Invisible_Timer -= diff;

                if (Invisible)
                {
                    if (Ambush_Timer <= diff)
                    {
                        if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
                        {
                            DoTeleportTo(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ());
                            DoCast(target, SPELL_AMBUSH);
                        }

                        Ambushed = true;
                        Ambush_Timer = 3000;
                    } else Ambush_Timer -= diff;
                }

                if (Ambushed)
                {
                    if (Visible_Timer <= diff)
                    {
                        me->InterruptSpell(CURRENT_GENERIC_SPELL);

                        me->SetDisplayId(15268);
                        SetEquipmentSlots(false, EQUIP_ID_MAIN_HAND, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);

                        me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                        Invisible = false;

                        Visible_Timer = 4000;
                    } else Visible_Timer -= diff;
                }

                //Resetting some aggro so he attacks other gamers
                if (!Invisible)
                {
                    if (Aggro_Timer <= diff)
                    {
                        if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
                        {
                            if (GetThreat(me->GetVictim()))
                                ModifyThreatByPercent(me->GetVictim(), -50);
                            AttackStart(target);
                        }

                        Aggro_Timer = urand(7000, 20000);
                    } else Aggro_Timer -= diff;

                    if (ThousandBlades_Timer <= diff)
                    {
                        DoCastVictim(SPELL_THOUSANDBLADES);
                        ThousandBlades_Timer = urand(7000, 12000);
                    } else ThousandBlades_Timer -= diff;
                }

                DoMeleeAttackIfReady();
            }
예제 #12
0
void MapAnalysis::BeginTurn()
{
    MapPoint pos;
    Army army;
    Unit city;
    Unit unit;
    sint32 i;

    m_piracyIncomeMatrix.assign(m_piracyIncomeMatrix.size(), 0);

    m_cityOnContinent.Reset(FALSE);
    m_armyOnContinent.Reset(FALSE);

    m_worldPopulation = 0;

    ComputeHandicapRatios();

    size_t player;
    for (player = 0; player < m_threatGrid.size(); ++player)
    {
        m_threatGrid       [player].Clear();
        m_attackGrid       [player].Clear();
        m_defenseGrid      [player].Clear();
        m_rangedGrid       [player].Clear();
        m_bombardLandGrid  [player].Clear();
        m_bombardSeaGrid   [player].Clear();
        m_bombardAirGrid   [player].Clear();
        m_valueGrid        [player].Clear();
        m_tradeAtRiskGrid  [player].Clear();
        m_piracyLossGrid   [player].Clear();

        m_minCityThreat    [player] = std::numeric_limits<sint32>::max();
        m_maxCityThreat    [player] = std::numeric_limits<sint32>::min();

        m_movementTypeUnion[player] = 0x0;

        m_nuclearWeapons   [player] = 0;
        m_bioWeapons       [player] = 0;
        m_nanoWeapons      [player] = 0;
        m_specialAttackers [player] = 0;
        m_continentSize    [player] = 0;

        m_totalPopulation  [player] = 0;
        m_landArea         [player] = 0;
        m_totalTrade       [player] = 0;

        Player * player_ptr = g_player[player];
        if (player_ptr == NULL)
            continue;

        RecalcCityRanks(player);

        m_projectedScience[player] =
            player_ptr->m_advances->GetProjectedScience();

        m_totalPopulation[player] = static_cast<sint16>(player_ptr->GetTotalPopulation());
        m_landArea[player] = static_cast<sint16>(player_ptr->GetLandArea());
        m_worldPopulation += m_totalPopulation[player];

        sint32 num_units = player_ptr->m_all_units->Num();
        for (i = 0; i < num_units; i++)
        {
            unit = player_ptr->m_all_units->Access(i);
            Assert(unit.IsValid());

            if (    unit.IsValid()
                 && unit.GetDBRec()
                 && unit.GetDBRec()->GetNumSpecialAttacks() > 0
               )
            {
                m_specialAttackers[player]++;
            }
        }

        sint32 num_armies = player_ptr->m_all_armies->Num();
        for (i = 0; i < num_armies; i++)
        {
            army = player_ptr->m_all_armies->Access(i);
            Assert(army.IsValid());
            army->GetPos(pos);

            sint8 defense_count;
            sint8 ranged_count;
            float attack_strength;
            float defense_strength;
            float ranged_strength;
            float bombard_land_strength;
            float bombard_sea_strength;
            float bombard_air_strength;
            float total_value;
			army->ComputeStrength(attack_strength,
			                      defense_strength,
			                      ranged_strength,
			                      defense_count,
			                      ranged_count,
			                      bombard_land_strength,
			                      bombard_sea_strength,
			                      bombard_air_strength,
			                      total_value,
			                      false
			                     );

			Assert(total_value >= 0);

			m_nuclearWeapons[player] += army->CountNuclearUnits();
			m_bioWeapons[player]     += army->CountBioUnits();
			m_nanoWeapons[player]    += army->CountNanoUnits();

			if(m_empireCenter[player] == MapPoint())
			{
				CalcEmpireCenter(player);
			}

			if(!m_empireBoundingRect[player].IsValid())
			{
				UpdateBoundingRectangle(army);
			}

			m_threatGrid      [player].AddValue(pos, static_cast<sint32>(attack_strength + ranged_strength));
			m_attackGrid      [player].AddValue(pos, static_cast<sint32>(attack_strength));
			m_defenseGrid     [player].AddValue(pos, static_cast<sint32>(defense_strength));
			m_rangedGrid      [player].AddValue(pos, static_cast<sint32>(ranged_strength));
			m_bombardLandGrid [player].AddValue(pos, static_cast<sint32>(bombard_land_strength));
			m_bombardSeaGrid  [player].AddValue(pos, static_cast<sint32>(bombard_sea_strength));
			m_bombardAirGrid  [player].AddValue(pos, static_cast<sint32>(bombard_air_strength));
			m_valueGrid       [player].AddValue(pos, static_cast<sint32>(total_value));

			bool    is_land;
			sint16  cont;
			g_theWorld->GetContinent(pos, cont, is_land);

			if(is_land)
			{
				bool is_military = (attack_strength > 0 || ranged_strength > 0)
				                && !army->IsCivilian();
				if(is_military)
				{
					m_armyOnContinent.Set(player, cont, TRUE);
				}
			}

            m_movementTypeUnion[player] |= army.GetMovementType();

            Assert(m_threatGrid      [player].GetTotalValue()  >= 0);
            Assert(m_attackGrid      [player].GetTotalValue()  >= 0);
            Assert(m_defenseGrid     [player].GetTotalValue()  >= 0);
            Assert(m_rangedGrid      [player].GetTotalValue()  >= 0);
            Assert(m_bombardLandGrid [player].GetTotalValue()  >= 0);
            Assert(m_bombardSeaGrid  [player].GetTotalValue()  >= 0);
            Assert(m_bombardAirGrid  [player].GetTotalValue()  >= 0);
            Assert(m_valueGrid       [player].GetTotalValue()  >= 0);
            Assert(m_nuclearWeapons  [player]                  >= 0);
            Assert(m_bioWeapons      [player]                  >= 0);
            Assert(m_nanoWeapons     [player]                  >= 0);
            Assert(m_specialAttackers[player]                  >= 0);
            Assert(m_continentSize   [player]                  >= 0);
            Assert(m_totalPopulation [player]                  >= 0);
            Assert(m_landArea        [player]                  >= 0);
            Assert(m_totalTrade      [player]                  >= 0);
        }

        sint32 num_cities = player_ptr->m_all_cities->Num();
        for (i = 0; i < num_cities; i++)
        {
            city = player_ptr->m_all_cities->Access(i);
            Assert(city.IsValid() && city->GetCityData());
            city.GetPos(pos);
            sint32 total_value = city->GetCityData()->GetValue();

            m_totalTrade[player] += city->GetCityData()->GetGoldFromTradeRoutes();

            m_valueGrid[player].AddValue(pos, total_value);

            TradeDynamicArray * trade_routes = city.CD()->GetTradeSourceList();
            Assert(trade_routes != NULL);

            sint32 tradeRouteCount  = trade_routes ? trade_routes->Num() : 0;
            for (sint32 j = 0; j < tradeRouteCount; j++)
            {
                sint32 route_value = trade_routes->Get(j)->GetValue();
                Army pirate_army = trade_routes->Get(j)->GetPiratingArmy();
                if (pirate_army.IsValid())
                {
                    m_piracyLossGrid[player].
                    AddValue(pirate_army->RetPos(), route_value);

                    AddPiracyIncome(pirate_army.GetOwner(), player, static_cast<sint16>(route_value));

                    m_valueGrid[pirate_army.GetOwner()].
                    AddValue(pirate_army->RetPos(), route_value);
                }

                const DynamicArray < MapPoint > * path = trade_routes->Get(j)->GetPath();
                sint32 per_cell_value =
                            (sint32)(((double)route_value / path->Num()) * 1000.0);
                for (sint32 k = 0; k < path->Num(); k++)
                {
                    m_tradeAtRiskGrid[player].AddValue(path->Get(k),
                    per_cell_value);
                }
            }

            bool    is_land;
            sint16  cont;
            g_theWorld->GetContinent(pos, cont, is_land);
            if (is_land)
            {
                m_cityOnContinent.Set(player, cont, TRUE);

                m_continentSize[player] += g_theWorld->GetLandContinentSize(cont) / num_cities;
            }

        }
    }

    DPRINTF(k_DBG_MAPANALYSIS, ("BEFORE RELAX:\n"));
    DebugLog();
    DPRINTF(k_DBG_MAPANALYSIS, ("\n"));

    const sint8 cycles = 1;
    const float coef = 0.95f;
    for (player = 0; player < m_threatGrid.size(); player++)
    {
        m_threatGrid      [player].Relax(cycles, coef);
        m_attackGrid      [player].Relax(cycles, coef);
        m_defenseGrid     [player].Relax(cycles, coef);
        m_rangedGrid      [player].Relax(cycles, coef);
        m_bombardLandGrid [player].Relax(cycles, coef);
        m_bombardSeaGrid  [player].Relax(cycles, coef);
        m_bombardAirGrid  [player].Relax(cycles, coef);
        m_valueGrid       [player].Relax(cycles, coef);
    }

	for (player = 0; player < m_threatGrid.size(); player++)
	{
		if(Diplomat::HasDiplomat(player))
		{
			Diplomat::GetDiplomat(player).ComputeAllDesireWarWith();
			Diplomat::GetDiplomat(player).ComputeIncursionPermission();
		}
	}

    for (player = 0; player < m_threatGrid.size(); player++)
    {
        Player * player_ptr = g_player[player];
        if (player_ptr == NULL)
            continue;

        sint32 num_cities = player_ptr->m_all_cities->Num();
        for (i = 0; i < num_cities; i++)
        {
            city = player_ptr->m_all_cities->Access(i);
            // Threat has to be calculated after relax
            sint32 threat = GetThreat(player, city.RetPos());

            if (threat < m_minCityThreat[player])
                m_minCityThreat[player] = threat;

            if (threat > m_maxCityThreat[player])
                m_maxCityThreat[player] = threat;
        }
    }

    DPRINTF(k_DBG_MAPANALYSIS, ("RELAXED:\n"));
    DebugLog();
    DPRINTF(k_DBG_MAPANALYSIS, ("\n"));
}
예제 #13
0
            void UpdateAI(uint32 diff) override
            {
                if (!UpdateVictim())
                    return;

                //SweepingStrikes_Timer
                if (SweepingStrikes_Timer <= diff)
                {
                    DoCastVictim(SPELL_SWEEPINGSTRIKES);
                    SweepingStrikes_Timer = 22000 + rand32() % 4000;
                } else SweepingStrikes_Timer -= diff;

                //SinisterStrike_Timer
                if (SinisterStrike_Timer <= diff)
                {
                    DoCastVictim(SPELL_SINISTERSTRIKE);
                    SinisterStrike_Timer = 8000 + rand32() % 8000;
                } else SinisterStrike_Timer -= diff;

                //Gouge_Timer
                if (Gouge_Timer <= diff)
                {
                    DoCastVictim(SPELL_GOUGE);

                    if (GetThreat(me->GetVictim()))
                        ModifyThreatByPercent(me->GetVictim(), -100);

                    Gouge_Timer = 17000 + rand32() % 10000;
                } else Gouge_Timer -= diff;

                //Kick_Timer
                if (Kick_Timer <= diff)
                {
                    DoCastVictim(SPELL_KICK);
                    Kick_Timer = 15000 + rand32() % 10000;
                } else Kick_Timer -= diff;

                //Blind_Timer
                if (Blind_Timer <= diff)
                {
                    DoCastVictim(SPELL_BLIND);
                    Blind_Timer = 10000 + rand32() % 10000;
                } else Blind_Timer -= diff;

                //Check_Timer for the death of LorKhan and Zath.
                if (!FakeDeath && Check_Timer <= diff)
                {
                    if (instance->GetBossState(DATA_LORKHAN) == SPECIAL)
                    {
                        //Resurrect LorKhan
                        if (Unit* pLorKhan = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_LORKHAN)))
                        {
                            pLorKhan->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
                            pLorKhan->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                            pLorKhan->SetFaction(14);
                            pLorKhan->SetFullHealth();
                        }
                    }

                    if (instance->GetBossState(DATA_THEKAL) == SPECIAL)
                    {
                        //Resurrect Thekal
                        if (Unit* pThekal = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_THEKAL)))
                        {
                            pThekal->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
                            pThekal->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                            pThekal->SetFaction(14);
                            pThekal->SetFullHealth();
                        }
                    }

                    Check_Timer = 5000;
                } else Check_Timer -= diff;

                if (!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->SetFaction(35);
                    me->AttackStop();

                    instance->SetBossState(DATA_ZATH, SPECIAL);

                    FakeDeath = true;
                }

                DoMeleeAttackIfReady();
            }