void SpellColdflameSpellScript::SelectTarget(std::list<WorldObject*>& targets)
{
    targets.clear();

    // select any unit but not the tank (by owners threatlist)
    Unit* target = GetCaster()->GetAI()->SelectTarget(SELECT_TARGET_RANDOM, 1, -GetCaster()->GetObjectSize(), true, -SPELL_IMPALED);
    if (!target)
        target = GetCaster()->GetAI()->SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true); // or the tank if its solo

    if (!target)
        return;

    Creature* dummy = GetCaster()->SummonCreature(NPC_COLDFLAME_TARGET_STALKER, *GetCaster(), TEMPSUMMON_TIMED_DESPAWN, 10000);
    dummy->SetOrientation(GetCaster()->GetAngle(target));

    if (!GetCaster()->HasAura(SPELL_BONE_STORM))
    {
        Position pos;
        dummy->GetNearPosition(pos, GetCaster()->GetObjectSize(), 0);
        dummy->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), dummy->GetPositionZ(), dummy->GetOrientation());
    }

    GetCaster()->GetAI()->SetGUID(dummy->GetGUID(), DATA_COLDFLAME_GUID);
    targets.push_back(target);
}
            void DoAction(int32 actionId) override
            {
                if (actionId == ACTION_OUTRO)
                {
                    Creature* tyrannusPtr = ObjectAccessor::GetCreature(*me, _instanceScript->GetGuidData(DATA_TYRANNUS_EVENT));
                    if (tyrannusPtr)
                        tyrannusPtr->NearTeleportTo(outroPos[1].GetPositionX(), outroPos[1].GetPositionY(), outroPos[1].GetPositionZ(), outroPos[1].GetOrientation());
                    else
                        tyrannusPtr = me->SummonCreature(NPC_TYRANNUS_EVENTS, outroPos[1], TEMPSUMMON_MANUAL_DESPAWN);

                    tyrannusPtr->SetCanFly(true);
                    me->GetMotionMaster()->MovePoint(POINT_KRICK_INTRO, outroPos[0].GetPositionX(), outroPos[0].GetPositionY(), outroPos[0].GetPositionZ());
                    tyrannusPtr->SetFacingToObject(me);
                }
            }
void instance_stratholme::Update(uint32 uiDiff)
{
    // Loop over the two Gate traps, each one has up to three timers (trap reset, gate opening delay, critters spawning delay)
    for (uint8 i = 0; i < 2; i++)
    {
        // Check that the trap is not on cooldown, if so check if player/pet is in range
        if (m_uiGateTrapTimers[i][0])
        {
            m_uiGateTrapTimers[i][0] -= uiDiff;
            if (m_uiGateTrapTimers[i][0] <= uiDiff)
            {
                debug_log("SD2: Instance Stratholme - Rat Trap reseted %u.", i);
                m_uiGateTrapTimers[i][0] = 0;
            }
        }
        else
        {
            Map::PlayerList const& players = instance->GetPlayers();
            for (const auto& player : players)
            {
                if (Player* pPlayer = player.getSource())
                {
                    if (!pPlayer->isGameMaster() && pPlayer->IsWithinDist2d(aGateTrap[i].m_fX, aGateTrap[i].m_fY, 5.5f))
                        DoGateTrap(i);

                    Pet* pet = pPlayer->GetPet();
                    if (!pPlayer->isGameMaster() && pet && pet->IsWithinDist2d(aGateTrap[i].m_fX, aGateTrap[i].m_fY, 5.5f))
                        DoGateTrap(i);
                }
            }
        }
        // Timer to reopen the gates
        if (m_uiGateTrapTimers[i][1])
        {
            if (m_uiGateTrapTimers[i][1] <= uiDiff)
            {
                DoUseDoorOrButton(aGates[2 * i]);
                DoUseDoorOrButton(aGates[2 * i + 1]);
                m_uiGateTrapTimers[i][1] = 0;
            }
            else
                m_uiGateTrapTimers[i][1] -= uiDiff;
        }
        // Delay timer to spawn the plagued critters once the gate are closing
        if (m_uiGateTrapTimers[i][2])
        {
            if (m_uiGateTrapTimers[i][2] <= uiDiff)
            {
                if (Player* pPlayer = GetPlayerInMap())
                    DoSpawnPlaguedCritters(i, pPlayer);
                m_uiGateTrapTimers[i][2] = 0;
            }
            else
                m_uiGateTrapTimers[i][2] -= uiDiff;
        }
    }

    // Timer to send the Black Guard Sentries out of the Slaughterhouse before Baron Rivendare
    if (m_uiBlackGuardsTimer)
    {
        if (m_uiBlackGuardsTimer <= uiDiff)
        {
            // Open the Slaughterhouse door and set a timer to close it after 10 sec to let some time to the 5 Black Guards to move out
            DoOpenSlaughterhouseDoor(true);
            m_uiSlaughterDoorTimer = 10000;

            for (GuidList::const_iterator itr = m_luiGuardGUIDs.begin(); itr != m_luiGuardGUIDs.end(); ++itr)
            {
                Creature* pGuard = instance->GetCreature(*itr);
                if (pGuard && pGuard->isAlive() && !pGuard->isInCombat())
                {
                    float fX, fY, fZ;
                    pGuard->GetRandomPoint(aStratholmeLocation[5].m_fX, aStratholmeLocation[5].m_fY, aStratholmeLocation[5].m_fZ, 10.0f, fX, fY, fZ);
                    pGuard->GetMotionMaster()->MovePoint(0, fX, fY, fZ);
                }
            }
            m_uiBlackGuardsTimer = 0;
        }
        else
            m_uiBlackGuardsTimer -= uiDiff;
    }
    // Timer to close the gate of the Slaughterhouse before Baron Rivendare after Ramstein/Black Guards moved out
    if (m_uiSlaughterDoorTimer)
    {
        if (m_uiSlaughterDoorTimer <= uiDiff)
        {
            DoOpenSlaughterhouseDoor(false);
            m_uiSlaughterDoorTimer = 0;
        }
        else
            m_uiSlaughterDoorTimer -= uiDiff;
    }
    // Timer to teleport Barthilas
    if (m_uiBarthilasRunTimer)
    {
        if (m_uiBarthilasRunTimer <= uiDiff)
        {
            Creature* pBarthilas = GetSingleCreatureFromStorage(NPC_BARTHILAS);
            if (pBarthilas && pBarthilas->isAlive() && !pBarthilas->isInCombat())
                pBarthilas->NearTeleportTo(aStratholmeLocation[1].m_fX, aStratholmeLocation[1].m_fY, aStratholmeLocation[1].m_fZ, aStratholmeLocation[1].m_fO);

            SetData(TYPE_BARTHILAS_RUN, DONE);
            m_uiBarthilasRunTimer = 0;
        }
        else
            m_uiBarthilasRunTimer -= uiDiff;
    }

    // Timer to summon Aurius into the Slaughter House once Baron is engaged
    if (m_uiAuriusSummonTimer)
    {
        if (m_uiAuriusSummonTimer <= uiDiff)
        {
            // Teleport Aurius from the Chapel and spawn it in the Slaughter House to engage Baron
            Creature* pAurius = GetSingleCreatureFromStorage(NPC_AURIUS);
            if (pAurius && pAurius->isAlive() && !pAurius->isInCombat())
            {
                if (Creature* pBaron = GetSingleCreatureFromStorage(NPC_BARON))
                {
                    float fX, fY, fZ;
                    pBaron->GetRandomPoint(pBaron->GetPositionX(), pBaron->GetPositionY(), pBaron->GetPositionZ(), 4.0f, fX, fY, fZ);
                    pAurius->NearTeleportTo(fX, fY, fZ, pAurius->GetOrientation());
                    pAurius->SetRespawnCoord(fX, fY, fZ, pAurius->GetOrientation());
                    DoScriptText(SAY_AURIUS_AGGRO, pAurius);
                    pAurius->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER | UNIT_NPC_FLAG_GOSSIP);
                    pAurius->AI()->AttackStart(pBaron);
                }
            }
            m_uiAuriusSummonTimer = 0;
        }
        else
            m_uiAuriusSummonTimer -= uiDiff;
    }

    // Check changes for Baron ultimatum timer only if Baron is not already in combat
    if (m_uiBaronRunTimer && GetData(TYPE_BARON) != IN_PROGRESS)
    {
        if (m_uiYellCounter == 0 && m_uiBaronRunTimer <= 10 * MINUTE * IN_MILLISECONDS)
        {
            DoOrSimulateScriptTextForThisInstance(SAY_ANNOUNCE_RUN_10_MIN, NPC_BARON);
            ++m_uiYellCounter;
        }
        else if (m_uiYellCounter == 1 && m_uiBaronRunTimer <= 5 * MINUTE * IN_MILLISECONDS)
        {
            DoOrSimulateScriptTextForThisInstance(SAY_ANNOUNCE_RUN_5_MIN, NPC_BARON);
            ++m_uiYellCounter;
        }
        // Used to create a delay of 10s between Baron speech and Ysida's answer
        else if (m_uiYellCounter == 2 && m_uiBaronRunTimer <= (5 * MINUTE - 10) * IN_MILLISECONDS)
        {
            DoOrSimulateScriptTextForThisInstance(SAY_YSIDA_RUN_5_MIN, NPC_YSIDA);
            ++m_uiYellCounter;
        }

        if (m_uiBaronRunTimer <= uiDiff)
        {
            if (GetData(TYPE_BARON_RUN) != FAIL)
            {
                SetData(TYPE_BARON_RUN, FAIL);

                // Open the cage and let Ysida face her doom
                if (Creature* pYsida = GetSingleCreatureFromStorage(NPC_YSIDA))
                {
                    pYsida->GetMotionMaster()->MovePoint(0, aStratholmeLocation[8].m_fX, aStratholmeLocation[8].m_fY, aStratholmeLocation[8].m_fZ);
                    DoUseDoorOrButton(GO_YSIDA_CAGE);
                }

                DoOrSimulateScriptTextForThisInstance(SAY_ANNOUNCE_RUN_FAIL, NPC_BARON);

                m_uiBaronRunTimer = 8000;  // We reset the timer so the speech of Ysida is not said at the same time than the Baron's one
            }
            else
            {
                // Baron ultimatum failed: let the Baron kill her
                if (Creature* pYsida = GetSingleCreatureFromStorage(NPC_YSIDA))
                {
                    if (Creature* pBaron = GetSingleCreatureFromStorage(NPC_BARON))
                        pBaron->CastSpell(pYsida, SPELL_BARON_SOUL_DRAIN, TRIGGERED_NONE);
                }

                DoOrSimulateScriptTextForThisInstance(SAY_YSIDA_RUN_FAIL, NPC_YSIDA);

                m_uiBaronRunTimer = 0;  // event done for good, no more speech
                debug_log("SD2: Instance Stratholme: Baron run event reached end. Event has state %u.", GetData(TYPE_BARON_RUN));
            }
        }
        else
            m_uiBaronRunTimer -= uiDiff;
    }

    if (m_uiMindlessSummonTimer)
    {
        if (m_uiMindlessCount < 30)
        {
            if (m_uiMindlessSummonTimer <= uiDiff)
            {
                if (Creature* pBaron = GetSingleCreatureFromStorage(NPC_BARON))
                {
                    // Summon mindless skeletons and move them to random point in the center of the square
                    if (Creature* pTemp = pBaron->SummonCreature(NPC_MINDLESS_UNDEAD, aStratholmeLocation[4].m_fX, aStratholmeLocation[4].m_fY, aStratholmeLocation[4].m_fZ, aStratholmeLocation[4].m_fO, TEMPSPAWN_DEAD_DESPAWN, 0))
                    {
                        float fX, fY, fZ;
                        pBaron->GetRandomPoint(aStratholmeLocation[5].m_fX, aStratholmeLocation[5].m_fY, aStratholmeLocation[5].m_fZ, 20.0f, fX, fY, fZ);
                        pTemp->SetWalk(false);
                        pTemp->GetMotionMaster()->MovePoint(0, fX, fY, fZ);
                        m_luiUndeadGUIDs.push_back(pTemp->GetObjectGuid());
                        ++m_uiMindlessCount;
                    }
                }
                m_uiMindlessSummonTimer = 400;
            }
            else
                m_uiMindlessSummonTimer -= uiDiff;
        }
        else
            m_uiMindlessSummonTimer = 0;
    }

    if (m_uiSlaugtherSquareTimer)
    {
        if (m_uiSlaugtherSquareTimer <= uiDiff)
        {
            // Call next Abomnations
            for (auto itr : m_sAbomnationGUID)
            {
                Creature* pAbom = instance->GetCreature(itr);
                // Skip killed and already walking Abomnations
                if (!pAbom || !pAbom->isAlive() || pAbom->GetMotionMaster()->GetCurrentMovementGeneratorType() == POINT_MOTION_TYPE)
                    continue;

                // Let Move to somewhere in the middle
                if (!pAbom->isInCombat())
                {
                    if (GameObject* pDoor = GetSingleGameObjectFromStorage(GO_PORT_SLAUGTHER))
                    {
                        float fX, fY, fZ;
                        pAbom->GetRandomPoint(pDoor->GetPositionX(), pDoor->GetPositionY(), pDoor->GetPositionZ(), 10.0f, fX, fY, fZ);
                        pAbom->GetMotionMaster()->MovePoint(0, fX, fY, fZ);
                    }
                }
                break;
            }

            // TODO - how fast are they called?
            m_uiSlaugtherSquareTimer = urand(30000, 45000);
        }
        else
            m_uiSlaugtherSquareTimer -= uiDiff;
    }
}