Example #1
0
 void SummonCreature()
 {
     uint32 random = rand()%2;
     float X = SpawnLocations[random].x;
     float Y = SpawnLocations[random].y;
     // max of 6 sorcerers can be summoned
     if ((rand()%3 == 0) && (DeathCount > 0) && (SorcererCount < 7))
     {
         Creature* Sorcerer = me->SummonCreature(NPC_SORCERER, X, Y, Z_SPAWN, 0, TEMPSUMMON_DEAD_DESPAWN, 0);
         if (Sorcerer)
         {
             CAST_AI(npc_ashtongue_sorcerer::npc_ashtongue_sorcererAI, Sorcerer->AI())->ShadeGUID = me->GetGUID();
             Sorcerer->SetWalk(false);
             Sorcerer->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ());
             Sorcerer->SetTarget(me->GetGUID());
             Sorcerers.push_back(Sorcerer->GetGUID());
             --DeathCount;
             ++SorcererCount;
         }
     }
     else
     {
         for (uint8 i = 0; i < 3; ++i)
         {
             Creature* Spawn = me->SummonCreature(spawnEntries[i], X, Y, Z_SPAWN, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 25000);
             if (Spawn)
             {
                 Spawn->SetWalk(false);
                 Spawn->GetMotionMaster()->MovePoint(0, AGGRO_X, AGGRO_Y, AGGRO_Z);
                 Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1);
                 Spawn->AI()->AttackStart(target);
             }
         }
     }
 }
void instance_pit_of_saron::OnCreatureEnterCombat(Creature* pCreature)
{
    if (pCreature->GetEntry() == NPC_YMIRJAR_DEATHBRINGER)
    {
        ++m_uiAmbushAggroCount;

        // Summon the rest of the mobs at the 2nd ambush
        if (m_uiAmbushAggroCount == 2)
        {
            Creature* pTyrannus = GetSingleCreatureFromStorage(NPC_TYRANNUS_INTRO);
            if (!pTyrannus)
                return;

            DoScriptText(SAY_TYRANNUS_AMBUSH_2, pTyrannus);
            pTyrannus->SetWalk(false);
            pTyrannus->GetMotionMaster()->MovePoint(0, afTyrannusMovePos[2][0], afTyrannusMovePos[2][1], afTyrannusMovePos[2][2]);

            // Spawn Mobs
            for (uint8 i = 0; i < countof(aEventSecondAmbushLocations); ++i)
            {
                if (Creature* pSummon = pTyrannus->SummonCreature(aEventSecondAmbushLocations[i].uiEntryHorde, aEventSecondAmbushLocations[i].fX, aEventSecondAmbushLocations[i].fY,
                                        aEventSecondAmbushLocations[i].fZ, aEventSecondAmbushLocations[i].fO, TEMPSPAWN_DEAD_DESPAWN, 0))
                {
                    pSummon->SetWalk(false);
                    pSummon->GetMotionMaster()->MovePoint(1, aEventSecondAmbushLocations[i].fMoveX, aEventSecondAmbushLocations[i].fMoveY, aEventSecondAmbushLocations[i].fMoveZ);
                }
            }
        }
    }
}
    bool OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/, bool /*entered*/) override
    {
        if (player->GetQuestStatus(QUEST_THE_LONESOME_WATCHER) != QUEST_STATUS_INCOMPLETE)
            return false;

        Creature* stormforgedMonitor = ObjectAccessor::GetCreature(*player, stormforgedMonitorGUID);
        if (stormforgedMonitor)
            return false;

        Creature* stormforgedEradictor = ObjectAccessor::GetCreature(*player, stormforgedEradictorGUID);
        if (stormforgedEradictor)
            return false;

        stormforgedMonitor = player->SummonCreature(NPC_STORMFORGED_MONITOR, stormforgedMonitorPosition, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000);
        if (stormforgedMonitor)
        {
            stormforgedMonitorGUID = stormforgedMonitor->GetGUID();
            stormforgedMonitor->SetWalk(false);
            /// The npc would search an alternative way to get to the last waypoint without this unit state.
            stormforgedMonitor->AddUnitState(UNIT_STATE_IGNORE_PATHFINDING);
            stormforgedMonitor->GetMotionMaster()->MovePath(NPC_STORMFORGED_MONITOR * 100, false);
        }

        stormforgedEradictor = player->SummonCreature(NPC_STORMFORGED_ERADICTOR, stormforgedEradictorPosition, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000);
        if (stormforgedEradictor)
        {
            stormforgedEradictorGUID = stormforgedEradictor->GetGUID();
            stormforgedEradictor->GetMotionMaster()->MovePath(NPC_STORMFORGED_ERADICTOR * 100, false);
        }

        return true;
    }
void instance_pit_of_saron::OnCreatureDeath(Creature* pCreature)
{
    switch (pCreature->GetEntry())
    {
        case NPC_YMIRJAR_DEATHBRINGER:
        case NPC_YMIRJAR_WRATHBRINGER:
        case NPC_YMIRJAR_FLAMEBEARER:
        case NPC_FALLEN_WARRIOR:
        case NPC_COLDWRAITH:
            // Check for tunnel event end - these mobs are not summoned
            if (pCreature->IsTemporarySummon())
            {
                m_lAmbushNpcsGuidList.remove(pCreature->GetObjectGuid());

                // If empty start tunnel event
                if (m_lAmbushNpcsGuidList.empty())
                {
                    Creature* pTyrannus = GetSingleCreatureFromStorage(NPC_TYRANNUS_INTRO);
                    if (!pTyrannus)
                        return;

                    DoScriptText(SAY_GAUNTLET, pTyrannus);
                    pTyrannus->SetWalk(false);
                    pTyrannus->GetMotionMaster()->MovePoint(0, afTyrannusMovePos[0][0], afTyrannusMovePos[0][1], afTyrannusMovePos[0][2]);
                    pTyrannus->ForcedDespawn(20000);

                    m_uiIciclesTimer = urand(3000, 5000);
                    SetSpecialAchievementCriteria(TYPE_ACHIEV_DONT_LOOK_UP, true);
                }
            }
            break;
    }
}
void WaypointMovementGenerator<Creature>::StartMove(Creature& creature)
{
    if (!i_path || i_path->empty())
        { return; }

    if (Stopped(creature))
        { return; }

    if (!creature.IsAlive() || creature.hasUnitState(UNIT_STAT_NOT_MOVE))
        { return; }

    WaypointPath::const_iterator currPoint = i_path->find(i_currentNode);
    MANGOS_ASSERT(currPoint != i_path->end());

    if (WaypointBehavior* behavior = currPoint->second.behavior)
    {
        if (behavior->model2 != 0)
            { creature.SetDisplayId(behavior->model2); }
        creature.SetUInt32Value(UNIT_NPC_EMOTESTATE, 0);
    }

    if (m_isArrivalDone)
    {
        bool reachedLast = false;
        ++currPoint;
        if (currPoint == i_path->end())
        {
            reachedLast = true;
            currPoint = i_path->begin();
        }

        // Inform AI
        if (creature.AI() && m_PathOrigin == PATH_FROM_EXTERNAL &&  m_pathId > 0)
        {
            if (!reachedLast)
                creature.AI()->MovementInform(EXTERNAL_WAYPOINT_MOVE_START + m_pathId, currPoint->first);
            else
                creature.AI()->MovementInform(EXTERNAL_WAYPOINT_FINISHED_LAST + m_pathId, currPoint->first);

            if (creature.IsDead() || !creature.IsInWorld()) // Might have happened with above calls
                return;
        }

        i_currentNode = currPoint->first;
    }

    m_isArrivalDone = false;

    creature.addUnitState(UNIT_STAT_ROAMING_MOVE);

    WaypointNode const& nextNode = currPoint->second;;
    Movement::MoveSplineInit init(creature);
    init.MoveTo(nextNode.x, nextNode.y, nextNode.z, true);

    if (nextNode.orientation != 100 && nextNode.delay != 0)
        { init.SetFacing(nextNode.orientation); }
    creature.SetWalk(!creature.hasUnitState(UNIT_STAT_RUNNING_STATE) && !creature.IsLevitating(), false);
    init.Launch();
}
void ChaseMovementGenerator<Creature>::Initialize(Creature& owner)
{
    owner.SetWalk(false, false);                            // Chase movement is running
    owner.addUnitState(UNIT_STAT_CHASE | UNIT_STAT_CHASE_MOVE);
    _setTargetLocation(owner, true);

    if (owner.getVictim() && !owner.hasUnitState(UNIT_STAT_MELEE_ATTACKING))
        owner.Attack(owner.getVictim(), !owner.IsNonMeleeSpellCasted(true));
}
void ChaseMovementGenerator<Creature>::initialize(Creature& owner)
{
    owner.SetWalk(false, false);                            // Chase movement is running
    owner.addUnitState(UNIT_STAT_CHASE | UNIT_STAT_CHASE_MOVE);

    Unit* pVictim = owner.getVictim();
    if (pVictim && !owner.hasUnitState(UNIT_STAT_MELEE_ATTACKING))
        owner.Attack(pVictim, !owner.IsNonMeleeSpellCasted(true));
}
void RandomMovementGenerator<Creature>::Interrupt(Creature &creature)
{
    if (!creature.movespline->Finalized())
    {
        Location loc = creature.movespline->ComputePosition();
        creature.SetPosition(loc.x,loc.y,loc.z,loc.orientation);
        creature.movespline->_Interrupt();
    }
    creature.clearUnitState(UNIT_STAT_ROAMING | UNIT_STAT_ROAMING_MOVE);
    creature.SetWalk(!creature.hasUnitState(UNIT_STAT_RUNNING_STATE), false);
}
Example #9
0
void HomeMovementGenerator<Creature>::Finalize(Creature& owner)
{
    if (arrived)
    {
        if (owner.GetTemporaryFactionFlags() & TEMPFACTION_RESTORE_REACH_HOME)
            owner.ClearTemporaryFaction();

        owner.SetWalk(!owner.hasUnitState(UNIT_STAT_RUNNING_STATE) && !owner.IsLevitating(), false);
        owner.LoadCreatureAddon(true);
        owner.AI()->JustReachedHome();
    }
}
void instance_blackrock_spire::JustDidDialogueStep(int32 iEntry)
{
    switch (iEntry)
    {
        case NPC_BLACKHAND_HANDLER:
            m_uiStadiumEventTimer = 1000;
            // Move the two near the balcony
            if (Creature* pRend = GetSingleCreatureFromStorage(NPC_REND_BLACKHAND))
                pRend->SetFacingTo(aStadiumLocs[5].m_fO);
            if (Creature* pNefarius = GetSingleCreatureFromStorage(NPC_LORD_VICTOR_NEFARIUS))
            {
                pNefarius->GetMotionMaster()->MovePoint(0, aStadiumLocs[5].m_fX, aStadiumLocs[5].m_fY, aStadiumLocs[5].m_fZ);
                // Summon the spectators and move them to the western balcony
                for (uint8 i = 0; i < 12; i++)
                {
                    Creature* pSpectator = pNefarius->SummonCreature(aStadiumSpectators[i], aSpectatorsSpawnLocs[i].m_fX, aSpectatorsSpawnLocs[i].m_fY, aSpectatorsSpawnLocs[i].m_fZ, aSpectatorsSpawnLocs[i].m_fO, TEMPSPAWN_DEAD_DESPAWN, 0);
                    if (pSpectator)
                    {
                        pSpectator->SetFacingTo(aSpectatorsTargetLocs[i].m_fO);
                        pSpectator->SetWalk(false);
                        pSpectator->GetMotionMaster()->MovePoint(0, aSpectatorsTargetLocs[i].m_fX, aSpectatorsTargetLocs[i].m_fY, aSpectatorsTargetLocs[i].m_fZ);
                        m_lStadiumSpectatorsGUIDList.push_back(pSpectator->GetObjectGuid());
                    }
                }
            }
            break;
        case SAY_NEFARIUS_WARCHIEF:
            // Prepare for Gyth
            if (Creature* pRend = GetSingleCreatureFromStorage(NPC_REND_BLACKHAND))
            {
                pRend->ForcedDespawn(5000);
                pRend->SetWalk(false);
                pRend->GetMotionMaster()->MovePoint(0, aStadiumLocs[6].m_fX, aStadiumLocs[6].m_fY, aStadiumLocs[6].m_fZ);
            }
            // Make Lord Nefarius walk back and forth while Rend is preparing Glyth
            if (Creature* pNefarius = GetSingleCreatureFromStorage(NPC_LORD_VICTOR_NEFARIUS))
                pNefarius->GetMotionMaster()->MoveWaypoint(0);
            m_uiStadiumEventTimer = 30000;
            break;
        case SAY_NEFARIUS_VICTORY:
            SetData(TYPE_STADIUM, DONE);
            break;
        case NPC_REND_BLACKHAND:
            // Despawn Nefarius
            if (Creature* pNefarius = GetSingleCreatureFromStorage(NPC_LORD_VICTOR_NEFARIUS))
            {
                pNefarius->ForcedDespawn(5000);
                pNefarius->GetMotionMaster()->MovePoint(0, aStadiumLocs[6].m_fX, aStadiumLocs[6].m_fY, aStadiumLocs[6].m_fZ);
            }
            break;
    }
}
Example #11
0
    int32 NextStep(uint32 Steps)
    {       
        if (uint64 TarethaGUID = pInstance->GetData64(DATA_TARETHA))
        {
            Creature* Taretha = (Unit::GetCreature(*me, TarethaGUID));
            Creature* Image = me->GetMap()->GetCreature(ImageGUID);

            switch (Steps)
            {
                case 1:
                    return 15000;
                case 2:
                    DoScriptText(SAY_TR_GLAD_SAFE, me);
                    return 10000;
                case 3:
                    DoScriptText(SAY_TA_NEVER_MET, Taretha);
                    return 10000;
                case 4:
                    DoScriptText(SAY_TR_THEN_WHO, me);
                    return 5000;
                case 5:
                    me->SummonCreature(NPC_EROZION, 2648.47f, 684.43f, 55.713f, 3.86f, TEMPSUMMON_TIMED_DESPAWN, 300000);
                    return 5000;
                case 6:
                    Image->CastSpell(Image, SPELL_MEMORY_WIPE, false);
                    return 5000;
                case 7:
                    DoScriptText(SAY_WIPE_MEMORY, Image);
                    return 10000;
                case 8:
                    DoScriptText(SAY_ABOUT_TARETHA, Image);
                    return 5000;
                case 9:
                    Image->CastSpell(Image, SPELL_MEMORY_WP_RESUME, false);
                    DoScriptText(SAY_TH_EVENT_COMPLETE, me);
                    return 6000;
                case 10:
                    Taretha->HandleEmoteCommand(EMOTE_ONESHOT_WAVE);
                    DoScriptText(SAY_TA_FAREWELL, Taretha);
                    SetEscortPaused(false);
                    QuestCredit();
                    return 3000;
                case 11:
                    Taretha->SetWalk(true);
                    Taretha->GetMotionMaster()->MovePoint(0, 2639.96f, 703.66f, 56.056f);
                    Taretha->ForcedDespawn(11000);
                default:
                    return 0;
            }
        }
        return true;
    }
Example #12
0
void CreatureGroup::LeaderMoveTo(float x, float y, float z)
{
    //! To do: This should probably get its own movement generator or use WaypointMovementGenerator.
    //! If the leader's path is known, member's path can be plotted as well using formation offsets.
    if (!m_leader)
        return;

    float pathangle = atan2(m_leader->GetPositionY() - y, m_leader->GetPositionX() - x);

    for (CreatureGroupMemberType::iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
    {
        Creature* member = itr->first;
        if (member == m_leader || !member->IsAlive() || member->GetVictim())
            continue;

        if (itr->second->point_1)
        {
            if (m_leader->GetCurrentWaypointID() == itr->second->point_1)
                itr->second->follow_angle = (2 * M_PI) - itr->second->follow_angle;
            if (m_leader->GetCurrentWaypointID() == itr->second->point_2)
                itr->second->follow_angle = (2 * M_PI) + itr->second->follow_angle;
        }

        float angle = itr->second->follow_angle;
        float dist = itr->second->follow_dist;

        float dx = x + std::cos(angle + pathangle) * dist;
        float dy = y + std::sin(angle + pathangle) * dist;
        float dz = z;

        Trinity::NormalizeMapCoord(dx);
        Trinity::NormalizeMapCoord(dy);

        member->UpdateGroundPositionZ(dx, dy, dz);

        if (member->IsWithinDist(m_leader, dist + MAX_DESYNC))
            member->SetUnitMovementFlags(m_leader->GetUnitMovementFlags());
        else
            member->SetWalk(false);

        member->GetMotionMaster()->MovePoint(0, dx, dy, dz);
        member->SetHomePosition(dx, dy, dz, pathangle);
    }
}
void WaypointMovementGenerator<Creature>::StartMove(Creature& creature)
{
    if (!i_path || i_path->empty())
        return;

    if (Stopped(creature))
        return;

    if (!creature.isAlive() || creature.hasUnitState(UNIT_STAT_NOT_MOVE))
        return;

    WaypointPath::const_iterator currPoint = i_path->find(i_currentNode);
    MANGOS_ASSERT(currPoint != i_path->end());

    if (WaypointBehavior* behavior = currPoint->second.behavior)
    {
        if (behavior->model2 != 0)
            creature.SetDisplayId(behavior->model2);
        creature.SetUInt32Value(UNIT_NPC_EMOTESTATE, 0);
    }

    if (m_isArrivalDone)
    {
        ++currPoint;
        if (currPoint == i_path->end())
            currPoint = i_path->begin();

        i_currentNode = currPoint->first;
    }

    m_isArrivalDone = false;

    creature.addUnitState(UNIT_STAT_ROAMING_MOVE);

    WaypointNode const& nextNode = currPoint->second;;
    Movement::MoveSplineInit init(creature);
    init.MoveTo(nextNode.x, nextNode.y, nextNode.z, true);

    if (nextNode.orientation != 100 && nextNode.delay != 0)
        init.SetFacing(nextNode.orientation);
    creature.SetWalk(!creature.hasUnitState(UNIT_STAT_RUNNING_STATE) && !creature.IsLevitating(), false);
    init.Launch();
}
void instance_stratholme::DoMoveBackDefenders(uint8 uiStep, Creature* pCreature)
{
    uint8 uiIndex;
    uint8 uiTreshold = 0;
    uint8 uiFoundGuards = 0;

    switch (uiStep)
    {
        case BARRICADE:
            uiIndex = FIRST_BARRICADES;
            break;
        case STAIRS:
            uiIndex = BARRICADE;
            uiTreshold = 3;
            break;
        default:
            return;     // avoid indexing the following table with a wrong index. Should never happen.
    }

    // Check that there are still defenders to move to the stairs/last barricade
    if (m_suiCrimsonDefendersLowGuids[uiIndex].empty())
        return;
    if (pCreature)
        DoScriptText(ScarletEventYells[uiStep], pCreature);

    for (GuidList::const_iterator itr = m_suiCrimsonDefendersLowGuids[uiIndex].begin(); itr != m_suiCrimsonDefendersLowGuids[uiIndex].end(); ++itr)
    {
        Creature* pGuard = instance->GetCreature(*itr);
        if (pGuard && pGuard->isAlive() && !pGuard->isInCombat())
        {
            pGuard->GetMotionMaster()->MoveIdle();
            pGuard->SetWalk(false);
            pGuard->GetMotionMaster()->MovePoint(0, aScarletLastStand[uiTreshold + uiFoundGuards].m_fX, aScarletLastStand[uiTreshold + uiFoundGuards].m_fY, aScarletLastStand[uiTreshold + uiFoundGuards].m_fZ);
            uiFoundGuards++;
        }

        if (uiFoundGuards == 3)
            return;
    }
}
Example #15
0
    void CallDragon(uint32 uiEntry)
    {
        if (m_pInstance)
        {
            Creature* pTemp = m_pInstance->GetSingleCreatureFromStorage(uiEntry);
            if (pTemp && pTemp->IsAlive())
            {
                if (pTemp->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
                    pTemp->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);

                if (pTemp->getVictim())
                    return;

                pTemp->SetWalk(false);

                int32 iTextId = 0;

                switch (uiEntry)
                {
                    case NPC_TENEBRON:
                        iTextId = SAY_SARTHARION_CALL_TENEBRON;
                        pTemp->GetMotionMaster()->MovePoint(POINT_ID_LAND, m_aTene[1].m_fX, m_aTene[1].m_fY, m_aTene[1].m_fZ);
                        break;
                    case NPC_SHADRON:
                        iTextId = SAY_SARTHARION_CALL_SHADRON;
                        pTemp->GetMotionMaster()->MovePoint(POINT_ID_LAND, m_aShad[1].m_fX, m_aShad[1].m_fY, m_aShad[1].m_fZ);
                        break;
                    case NPC_VESPERON:
                        iTextId = SAY_SARTHARION_CALL_VESPERON;
                        pTemp->GetMotionMaster()->MovePoint(POINT_ID_LAND, m_aVesp[1].m_fX, m_aVesp[1].m_fY, m_aVesp[1].m_fZ);
                        break;
                }

                DoScriptText(iTextId, m_creature);
            }
        }
    }
void WaypointMovementGenerator<Creature>::Interrupt(Creature& creature)
{
    creature.InterruptMoving();
    creature.clearUnitState(UNIT_STAT_ROAMING | UNIT_STAT_ROAMING_MOVE);
    creature.SetWalk(!creature.hasUnitState(UNIT_STAT_RUNNING_STATE), false);
}
Example #17
0
    void DoIntro()
    {
        Creature* Madrigosa = Unit::GetCreature(*me, pInstance ? pInstance->GetData64(DATA_MADRIGOSA) : 0);
        if (!Madrigosa)
            return;

        float x, y, z, ground_Z;
        switch (IntroPhase)
        {
        case 0:
            me->SetFacingToObject(Madrigosa);
            Madrigosa->SetFacingToObject(me);
            IntroPhaseTimer = 1000;
            break;
        case 1:
            DoScriptText(YELL_MADR_ICE_BARRIER, Madrigosa);
            IntroPhaseTimer = 8000;
            break;
        case 2:
            DoScriptText(YELL_MADR_INTRO, Madrigosa, me);
            IntroPhaseTimer = 7000;
            break;
        case 3:
            DoScriptText(YELL_INTRO, me, Madrigosa);
            IntroPhaseTimer = 4000;
            break;
        case 4:
            Madrigosa->CombatStart(me, true);
            IntroAttackTimer = 2000;
            IntroPhaseTimer = 10000;
            break;
        case 5:
            me->AttackStop();
            Madrigosa->AttackStop();
            Madrigosa->SetSpeed(MOVE_RUN, 3.0f, true);
            Madrigosa->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
            IntroPhaseTimer = 500;
            break;
        case 6:
            Madrigosa->GetMotionMaster()->MovePoint(0, Madrigosa->GetPositionX(), Madrigosa->GetPositionY() + 2, Madrigosa->GetPositionZ() + 8);
            IntroPhaseTimer = 2000;
            break;
        case 7:
            Madrigosa->SetInFront(me);
            Madrigosa->SendMovementFlagUpdate();
            IntroAttackTimer = 3500;
            IntroFrostBoltTimer = 3500;
            IntroPhaseTimer = 13000;
            break;
        case 8:
            DoScriptText(YELL_INTRO_BREAK_ICE, me);
            IntroPhaseTimer = 5000;
            break;
        case 9:
            Madrigosa->SetWalk(true);
            Madrigosa->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
            IntroPhaseTimer = 500;
            break;
        case 10:
            Madrigosa->GetPosition(x, y, z);
            ground_Z = me->GetMap()->GetHeight(x, y, MAX_HEIGHT, true);
            Madrigosa->GetMotionMaster()->MovePoint(1, x, y, ground_Z);
            IntroPhaseTimer = 2000;
            break;
        case 11:
            Madrigosa->SetInFront(me);
            Madrigosa->SendMovementFlagUpdate();
            Madrigosa->CastSpell(me, SPELL_INTRO_ENCAPSULATE_CHANELLING, true);
            DoScriptText(YELL_MADR_TRAP, Madrigosa);
            DoCast(me, SPELL_INTRO_ENCAPSULATE);
            me->SetSpeed(MOVE_RUN, 4.0f, true);

            me->GetPosition(x, y, z);
            me->GetMotionMaster()->MovePoint(1, x - 6, y - 15, z + 10);

            IntroAttackTimer = 3000;
            IntroPhaseTimer = 6000;
            break;
        case 12:
            DoScriptText(YELL_INTRO_CHARGE, me);
            me->SetSpeed(MOVE_RUN, 3.0f, true);
            //me->GetMotionMaster()->MovePath(30000, false);
            me->GetPosition(x, y, z);
            ground_Z = me->GetMap()->GetHeight(x, y, MAX_HEIGHT, true);
            me->GetMotionMaster()->MovePoint(2, x + 6, y + 15, ground_Z);
            IntroPhaseTimer = 5000;
            break;
        case 13:
            me->Kill(Madrigosa);
            DoScriptText(YELL_MADR_DEATH, Madrigosa);
            me->SetSpeed(MOVE_RUN, 2.0f, true);
            IntroPhaseTimer = 7000;
            break;
        case 14:
            DoScriptText(YELL_INTRO_KILL_MADRIGOSA, me);
            me->SetSpeed(MOVE_RUN, 1.0f, true);
            Madrigosa->setDeathState(CORPSE);
            IntroPhaseTimer = 8000;
            break;
        case 15:
            DoScriptText(YELL_INTRO_TAUNT, me);
            IntroPhaseTimer = 5000;
            break;
        case 16:
            EndIntro();
            break;
        }
    }
void RandomMovementGenerator<Creature>::Finalize(Creature &creature)
{
    creature.ClearUnitState(UNIT_STATE_ROAMING | UNIT_STATE_ROAMING_MOVE);
    creature.SetWalk(false);
}
void WaypointMovementGenerator<Creature>::Finalize(Creature &creature)
{
    creature.clearUnitState(UNIT_STAT_ROAMING|UNIT_STAT_ROAMING_MOVE);
    creature.SetWalk(false);
}
void instance_stratholme::SetData(uint32 uiType, uint32 uiData)
{
    // TODO: Remove the hard-coded indexes from array accessing
    switch (uiType)
    {
        case TYPE_BARON_RUN:
            switch (uiData)
            {
                case IN_PROGRESS:
                    if (m_auiEncounter[uiType] == IN_PROGRESS || m_auiEncounter[uiType] == FAIL)
                        break;

                    // Baron ultimatum starts: summon Ysida in the cage
                    if (Creature* pBaron = GetSingleCreatureFromStorage(NPC_BARON))
                    {
                        DoOrSimulateScriptTextForThisInstance(SAY_ANNOUNCE_RUN_START, NPC_BARON);
                        if (Creature* pYsida = pBaron->SummonCreature(NPC_YSIDA, aStratholmeLocation[7].m_fX, aStratholmeLocation[7].m_fY, aStratholmeLocation[7].m_fZ, aStratholmeLocation[7].m_fO, TEMPSPAWN_DEAD_DESPAWN, 0))
                            pYsida->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER | UNIT_NPC_FLAG_GOSSIP);
                    }

                    m_uiBaronRunTimer = 45 * MINUTE * IN_MILLISECONDS;
                    debug_log("SD2: Instance Stratholme: Baron run in progress.");
                    break;
                case FAIL:
                    // may add code to remove aura from players, but in theory the time should be up already and removed.
                    break;
                case DONE:
                    m_uiBaronRunTimer = 0;
                    break;
            }
            m_auiEncounter[uiType] = uiData;
            break;
        case TYPE_BARONESS:
        case TYPE_NERUB:
        case TYPE_PALLID:
            m_auiEncounter[uiType] = uiData;
            if (uiData == DONE)
            {
                DoSortZiggurats();
                DoUseDoorOrButton(m_zigguratStorage[uiType - TYPE_BARONESS].m_doorGuid);
            }
            if (uiData == SPECIAL)
                StartSlaugtherSquare();
            break;
        case TYPE_RAMSTEIN:
            if (uiData == SPECIAL)
            {
                if (m_auiEncounter[uiType] != SPECIAL && m_auiEncounter[uiType] != DONE)
                {
                    m_uiSlaugtherSquareTimer = 20000;       // TODO - unknown, also possible that this is not the very correct place..
                    DoUseDoorOrButton(GO_PORT_GAUNTLET);
                }

                uint32 uiCount = m_sAbomnationGUID.size();
                for (GuidSet::iterator itr = m_sAbomnationGUID.begin(); itr != m_sAbomnationGUID.end();)
                {
                    if (Creature* pAbom = instance->GetCreature(*itr))
                    {
                        ++itr;
                        if (!pAbom->isAlive())
                            --uiCount;
                    }
                    else
                    {
                        // Remove obsolete guid from set and decrement count
                        m_sAbomnationGUID.erase(itr++);
                        --uiCount;
                    }
                }

                if (!uiCount)
                {
                    // Open the Slaughterhouse door and set a timer to close it after 10 sec to let some time to Ramstein to move out
                    DoOpenSlaughterhouseDoor(true);
                    m_uiSlaughterDoorTimer = 10000;

                    // No more handlng of Abomnations
                    m_uiSlaugtherSquareTimer = 0;

                    if (Creature* pBaron = GetSingleCreatureFromStorage(NPC_BARON))
                    {
                        DoScriptText(SAY_ANNOUNCE_RAMSTEIN, pBaron);
                        if (Creature* pRamstein = pBaron->SummonCreature(NPC_RAMSTEIN, aStratholmeLocation[2].m_fX, aStratholmeLocation[2].m_fY, aStratholmeLocation[2].m_fZ, aStratholmeLocation[2].m_fO, TEMPSPAWN_DEAD_DESPAWN, 0))
                            pRamstein->GetMotionMaster()->MovePoint(0, aStratholmeLocation[5].m_fX, aStratholmeLocation[5].m_fY, aStratholmeLocation[5].m_fZ);

                        debug_log("SD2: Instance Stratholme - Slaugther event: Ramstein spawned.");
                    }
                }
                else
                    debug_log("SD2: Instance Stratholme - Slaugther event: %u Abomnation left to kill.", uiCount);
            }
            // After fail aggroing Ramstein means wipe on Ramstein, so close door again
            if (uiData == IN_PROGRESS && m_auiEncounter[uiType] == FAIL)
                DoUseDoorOrButton(GO_PORT_GAUNTLET);
            if (uiData == DONE)
            {
                // Open side gate and start summoning skeletons
                DoUseDoorOrButton(GO_PORT_SLAUGHTER_GATE);
                // Close the Slaughterhouse door in case it was open again after a wipe on Ramstein
                DoOpenSlaughterhouseDoor(false);
                // use this timer as a bool just to start summoning
                m_uiMindlessSummonTimer = 500;
                m_uiMindlessCount = 0;
                m_luiUndeadGUIDs.clear();

                // Summon 5 guards
                if (Creature* pBaron = GetSingleCreatureFromStorage(NPC_BARON))
                {
                    for (uint8 i = 0; i < 5; ++i)
                    {
                        float fX, fY, fZ;
                        pBaron->GetRandomPoint(aStratholmeLocation[6].m_fX, aStratholmeLocation[6].m_fY, aStratholmeLocation[6].m_fZ, 5.0f, fX, fY, fZ);
                        if (Creature* pTemp = pBaron->SummonCreature(NPC_BLACK_GUARD, aStratholmeLocation[6].m_fX, aStratholmeLocation[6].m_fY, aStratholmeLocation[6].m_fZ, aStratholmeLocation[6].m_fO, TEMPSPAWN_DEAD_DESPAWN, 0))
                            m_luiGuardGUIDs.push_back(pTemp->GetObjectGuid());
                    }

                    debug_log("SD2: Instance Stratholme - Slaugther event: Summoned 5 guards.");
                }
            }
            // Open Door again and stop Abomnation
            if (uiData == FAIL && m_auiEncounter[uiType] != FAIL)
            {
                DoUseDoorOrButton(GO_PORT_GAUNTLET);
                m_uiSlaugtherSquareTimer = 0;

                // Let already moving Abomnations stop
                for (auto itr : m_sAbomnationGUID)
                {
                    Creature* pAbom = instance->GetCreature(itr);
                    if (pAbom && pAbom->GetMotionMaster()->GetCurrentMovementGeneratorType() == POINT_MOTION_TYPE)
                        pAbom->GetMotionMaster()->MovementExpired();
                }
            }

            m_auiEncounter[uiType] = uiData;
            break;
        case TYPE_BARON:
            if (uiData == IN_PROGRESS)
            {
                // Close Slaughterhouse door if needed
                if (m_auiEncounter[uiType] == FAIL)
                    DoUseDoorOrButton(GO_PORT_GAUNTLET);

                // If Aurius was given the medaillon wait 5s before summoning him
                if (GetData(TYPE_AURIUS) == DONE)
                    m_uiAuriusSummonTimer = 5000;
            }
            else if (uiData == DONE)
            {
                // Players successfully engaged Baron within the time-limit of his ultimatum
                //     Note: UpdateAI() prevents TYPE_BARON_RUN to be marked as FAILED if the
                //     Baron is already engaged (in progress) when the ultimatum timer expires
                if (m_auiEncounter[TYPE_BARON_RUN] == IN_PROGRESS)
                {
                    SetData(TYPE_BARON_RUN, DONE);
                    Map::PlayerList const& players = instance->GetPlayers();

                    for (const auto& player : players)
                    {
                        if (Player* pPlayer = player.getSource())
                        {
                            if (pPlayer->HasAura(SPELL_BARON_ULTIMATUM))
                                pPlayer->RemoveAurasDueToSpell(SPELL_BARON_ULTIMATUM);

                            if (pPlayer->GetQuestStatus(QUEST_DEAD_MAN_PLEA) == QUEST_STATUS_INCOMPLETE)
                                pPlayer->KilledMonsterCredit(NPC_YSIDA);

                            // Argent Dawn reputation reward
                            pPlayer->CastSpell(pPlayer, SPELL_YSIDA_FREED, TRIGGERED_OLD_TRIGGERED);
                        }
                    }

                    // Open cage, finish rescue event
                    if (Creature* pYsida = GetSingleCreatureFromStorage(NPC_YSIDA))
                    {
                        DoScriptText(SAY_EPILOGUE, pYsida);
                        DoUseDoorOrButton(GO_YSIDA_CAGE);
                        pYsida->GetMotionMaster()->MovePoint(0, aStratholmeLocation[8].m_fX, aStratholmeLocation[8].m_fY, aStratholmeLocation[8].m_fZ);
                        pYsida->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER | UNIT_NPC_FLAG_GOSSIP);
                    }
                }

                // If Aurius was spawned to help fight the Baron
                if (GetData(TYPE_AURIUS) == DONE)
                {
                    // Baron killed and Aurius is alive: give him his NPC Flags back, so players can complete the quest and fake his death
                    if (Creature* pAurius = GetSingleCreatureFromStorage(NPC_AURIUS))
                    {
                        if (pAurius->isAlive())
                        {
                            DoScriptText(SAY_AURIUS_DEATH, pAurius);
                            pAurius->StopMoving();
                            pAurius->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER | UNIT_NPC_FLAG_GOSSIP);
                            pAurius->InterruptNonMeleeSpells(true);
                            pAurius->SetHealth(1);
                            pAurius->GetMotionMaster()->MovementExpired();
                            pAurius->GetMotionMaster()->MoveIdle();
                            pAurius->RemoveAllAurasOnDeath();
                            pAurius->SetStandState(UNIT_STAND_STATE_DEAD);
                        }
                    }
                }

                // Open Slaughterhouse door again
                DoUseDoorOrButton(GO_PORT_GAUNTLET);
            }
            else if (uiData == FAIL)
                DoUseDoorOrButton(GO_PORT_GAUNTLET);

            m_auiEncounter[uiType] = uiData;
            break;
        case TYPE_BARTHILAS_RUN:
            if (uiData == IN_PROGRESS)
            {
                Creature* pBarthilas = GetSingleCreatureFromStorage(NPC_BARTHILAS);
                if (pBarthilas && pBarthilas->isAlive() && !pBarthilas->isInCombat())
                {
                    DoScriptText(SAY_WARN_BARON, pBarthilas);
                    pBarthilas->SetWalk(false);
                    pBarthilas->GetMotionMaster()->MovePoint(0, aStratholmeLocation[0].m_fX, aStratholmeLocation[0].m_fY, aStratholmeLocation[0].m_fZ);

                    m_uiBarthilasRunTimer = 8000;
                }
            }
            m_auiEncounter[uiType] = uiData;
            break;
        case TYPE_BLACK_GUARDS:
            // Prevent double action
            if (m_auiEncounter[uiType] == uiData)
                return;

            // Restart after failure, close Gauntlet
            if (uiData == IN_PROGRESS && m_auiEncounter[uiType] == FAIL)
                DoUseDoorOrButton(GO_PORT_GAUNTLET);
            // Wipe case - open gauntlet
            if (uiData == FAIL)
                DoUseDoorOrButton(GO_PORT_GAUNTLET);
            if (uiData == DONE)
            {
                if (Creature* pBaron = GetSingleCreatureFromStorage(NPC_BARON))
                    DoScriptText(SAY_UNDEAD_DEFEAT, pBaron);
                DoOpenSlaughterhouseDoor(true);
                DoUseDoorOrButton(GO_ZIGGURAT_DOOR_5);
            }
            m_auiEncounter[uiType] = uiData;

            // No need to save anything here, so return
            return;
        case TYPE_POSTMASTER:
            m_auiEncounter[uiType] = uiData;
            if (uiData == IN_PROGRESS)
            {
                ++m_uiPostboxesUsed;

                // After the second post box prepare to spawn the Post Master
                if (m_uiPostboxesUsed == 2)
                    SetData(TYPE_POSTMASTER, SPECIAL);
            }
            // No need to save anything here, so return
            return;
        case TYPE_TRUE_MASTERS:
            m_auiEncounter[uiType] = uiData;
            if (uiData == SPECIAL)
            {
                ++m_uiSilverHandKilled;

                // When the 5th paladin is killed set data to DONE in order to give the quest credit for the last paladin
                if (m_uiSilverHandKilled == MAX_SILVERHAND)
                    SetData(TYPE_TRUE_MASTERS, DONE);
            }
            // No need to save anything here, so return
            return;
        case TYPE_AURIUS:
            // Prevent further players to complete the quest in that instance or autocomplete the follow-up quest. the flag will be set back if event is succeed
            if (uiData == DONE)
            {
                if (Creature* pAurius = GetSingleCreatureFromStorage(NPC_AURIUS))
                    pAurius->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
            }
            m_auiEncounter[uiType] = uiData;
            break;
    }

    if (uiData == DONE)
    {
        OUT_SAVE_INST_DATA;

        std::ostringstream saveStream;
        saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " "
                   << m_auiEncounter[3] << " " << m_auiEncounter[4] << " " << m_auiEncounter[5] << " "
                   << m_auiEncounter[6] << " " << m_auiEncounter[7];

        m_strInstData = saveStream.str();

        SaveToDB();
        OUT_SAVE_INST_DATA_COMPLETE;
    }
}
Example #21
0
        void UpdateAI(uint32 diff)
        {
            if (!me->IsInCombat())
                return;

            if (IsBanished)
            {
                // Akama is set in the threatlist so when we reset, we make sure that he is not included in our check
                if (me->getThreatManager().getThreatList().size() < 2)
                {
                    EnterEvadeMode();
                    return;
                }

                if (DefenderTimer <= diff)
                {
                    uint32 ran = rand()%2;
                    Creature* Defender = me->SummonCreature(NPC_DEFENDER, SpawnLocations[ran].x, SpawnLocations[ran].y, Z_SPAWN, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 25000);
                    if (Defender)
                    {
                        Defender->SetWalk(false);
                        bool move = true;
                        if (AkamaGUID)
                        {
                            if (Creature* Akama = Unit::GetCreature(*me, AkamaGUID))
                            {
                                float x, y, z;
                                Akama->GetPosition(x, y, z);
                                // They move towards AKama
                                Defender->GetMotionMaster()->MovePoint(0, x, y, z);
                                Defender->AI()->AttackStart(Akama);
                            } else move = false;
                        } else move = false;
                        if (!move)
                            Defender->GetMotionMaster()->MovePoint(0, AKAMA_X, AKAMA_Y, AKAMA_Z);
                    }
                    DefenderTimer = 15000;
                } else DefenderTimer -= diff;

                if (SummonTimer <= diff)
                {
                    SummonCreature();
                    SummonTimer = 35000;
                } else SummonTimer -= diff;

                if (DeathCount >= 6)
                {
                    if (AkamaGUID)
                    {
                        Creature* Akama = Unit::GetCreature((*me), AkamaGUID);
                        if (Akama && Akama->IsAlive())
                        {
                            IsBanished = false;
                            me->GetMotionMaster()->Clear(false);
                            me->GetMotionMaster()->MoveChase(Akama);
                            Akama->GetMotionMaster()->Clear();
                            // Shade should move to Akama, not the other way around
                            Akama->GetMotionMaster()->MoveIdle();
                            me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                            // Crazy amount of threat
                            me->AddThreat(Akama, 10000000.0f);
                            Akama->AddThreat(me, 10000000.0f);
                            me->Attack(Akama, true);
                            Akama->Attack(me, true);
                        }
                    }
                }
            }
            else                                                // No longer banished, let's fight Akama now
            {
                if (ReduceHealthTimer <= diff)
                {
                    if (AkamaGUID)
                    {
                        Creature* Akama = Unit::GetCreature((*me), AkamaGUID);
                        if (Akama && Akama->IsAlive())
                        {
                            //10 % less health every few seconds.
                            me->DealDamage(Akama, Akama->GetMaxHealth()/10, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
                            ReduceHealthTimer = 12000;
                        }
                    }
                } else ReduceHealthTimer -= diff;

                if (HasKilledAkama)
                {
                    if (!HasKilledAkamaAndReseting)//do not let players kill Shade if Akama is dead and Shade is waiting for ResetTimer!! event would bug
                    {
                        HasKilledAkamaAndReseting = true;
                        me->RemoveAllAuras();
                        me->DeleteThreatList();
                        me->CombatStop();
                        //me->SetFullHealth();
                        me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                        me->GetMotionMaster()->MoveTargetedHome();
                    }
                    if (ResetTimer <= diff)
                    {
                        EnterEvadeMode();// Reset a little while after killing Akama, evade and respawn Akama
                        return;
                    } else ResetTimer -= diff;
                }

                DoMeleeAttackIfReady();
            }
        }
void ChaseMovementGenerator<Creature>::Initialize(Creature &owner)
{
    owner.SetWalk(false, false);                            // Chase movement is running
    owner.addUnitState(UNIT_STAT_CHASE);                    // _MOVE set in _SetTargetLocation after required checks
    _setTargetLocation(owner, true);
}
void ChaseMovementGenerator<Creature>::Initialize(Creature &owner)
{
    owner.SetWalk(false);
    owner.AddUnitState(UNIT_STAT_CHASE|UNIT_STAT_CHASE_MOVE);
    _setTargetLocation(owner);
}
void FleeingMovementGenerator<Creature>::Finalize(Creature& owner) const
{
    owner.SetWalk(!owner.hasUnitState(UNIT_STAT_RUNNING_STATE), false);
    owner.clearUnitState(UNIT_STAT_FLEEING | UNIT_STAT_FLEEING_MOVE);
}
void RandomMovementGenerator<Creature>::Interrupt(Creature &creature)
{
    creature.clearUnitState(UNIT_STAT_ROAMING|UNIT_STAT_ROAMING_MOVE);
    creature.SetWalk(false);
}
void RandomMovementGenerator<Creature>::Finalize(Creature& creature)
{
    creature.clearUnitState(UNIT_STAT_ROAMING | UNIT_STAT_ROAMING_MOVE);
    creature.SetWalk(!creature.hasUnitState(UNIT_STAT_RUNNING_STATE), false);
}