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 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);
	int i = 1;
	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)) {
			// zhang hong chao
			member->SetUnitMovementFlags(m_leader->GetUnitMovementFlags());
			if (m_leader->GetDefaultMovementType() == RANDOM_MOTION_TYPE &&
				m_leader->GetMotionMaster()->GetCurrentMovementGeneratorType() == RANDOM_MOTION_TYPE) {
				member->SetWalk(true);
			}
			else {
				member->SetWalk(m_leader->IsWalking());
			}
		}
		else {
			member->SetWalk(false);
		}
		member->GetMotionMaster()->MovePoint(0, dx, dy, dz);
		member->SetHomePosition(dx, dy, dz, pathangle);
		
    }
}
    void UpdateAI(const uint32 uiDiff) override
    {
        if (m_uiStartTimer)
        {
            // Start collecting after some delay
            if (m_uiStartTimer <= uiDiff)
            {
                Creature* pSelectedOrb = m_creature->GetMap()->GetCreature(m_selectedOrbGuid);
                if (!pSelectedOrb)
                    return;

                // Orb is pulled fast
                pSelectedOrb->SetWalk(false);

                // Move orb to the collector
                float fX, fY, fZ;;
                pSelectedOrb->GetMotionMaster()->MoveIdle();
                m_creature->GetContactPoint(pSelectedOrb, fX, fY, fZ);
                pSelectedOrb->GetMotionMaster()->MovePoint(0, fX, fY, fZ);

                m_bOrbPulled = true;
                m_uiStartTimer = 0;
            }
            else
                m_uiStartTimer -= uiDiff;
        }
    }
Beispiel #4
0
void WaypointMovementGenerator<Creature>::StartMove(Creature& creature)
{
    if (!i_path || i_path->empty())
        return;

    if (Stopped(creature))
        return;

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

    if (m_isArrivalDone)
        i_currentNode = (i_currentNode + 1) % i_path->size();

    m_isArrivalDone = false;

    creature.addUnitState(UNIT_STAT_ROAMING_MOVE);

    const WaypointNode& node = i_path->at(i_currentNode);
    Movement::MoveSplineInit init(creature);
    init.MoveTo(node.x, node.y, node.z, true);

    if (node.orientation != 100 && node.delay != 0)
        init.SetFacing(node.orientation);
    creature.SetWalk(!creature.hasUnitState(UNIT_STAT_RUNNING_STATE) && !creature.IsLevitating(), false);
    init.Launch();
}
void ChaseMovementGenerator<Creature>::Initialize(Creature& owner)
{
    owner.SetWalk(false);                            // Chase movement is running
    owner.AddUnitState(UNIT_STATE_CHASE);                    // _MOVE set in _SetTargetLocation after required checks
    _setTargetLocation(owner, true);
    m_evadeTimer = urand(4000, 8000);
}
    bool OnTrigger(Player* player, AreaTriggerEntry const* /* trigger */)
    {
        if (player->GetQuestStatus(QUEST_THE_LONESOME_WATCHER) != QUEST_STATUS_INCOMPLETE)
            return false;

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

        Creature* stormforgedEradictor = Creature::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::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, TEMPSUMMON_DEAD_DESPAWN, 0))
                {
                    pSummon->SetWalk(false);
                    pSummon->GetMotionMaster()->MovePoint(1, aEventSecondAmbushLocations[i].fMoveX, aEventSecondAmbushLocations[i].fMoveY, aEventSecondAmbushLocations[i].fMoveZ);
                }
            }
        }
    }
}
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 UpdateAI(const uint32 uiDiff) override
    {
        if (m_uiStartTimer)
        {
            if (m_uiStartTimer <= uiDiff)
            {
                // get all the ogres in range
                std::list<Creature*> lOgreList;
                for (uint8 i = 0; i < countof(aOgreEntries); ++i)
                    GetCreatureListWithEntryInGrid(lOgreList, m_creature,  aOgreEntries[i], 30.0f);

                if (lOgreList.empty())
                {
                    m_uiStartTimer = 5000;
                    return;
                }

                // sort by distance and get only the closest
                lOgreList.sort(ObjectDistanceOrder(m_creature));

                std::list<Creature*>::const_iterator ogreItr = lOgreList.begin();
                Creature* pOgre = NULL;

                do
                {
                    if ((*ogreItr)->isAlive() && !(*ogreItr)->HasAura(SPELL_INTOXICATION))
                        pOgre = *ogreItr;

                    ++ogreItr;
                }
                while (!pOgre && ogreItr != lOgreList.end());

                if (!pOgre)
                {
                    m_uiStartTimer = 5000;
                    return;
                }

                // Move ogre to the point
                float fX, fY, fZ;
                pOgre->GetMotionMaster()->MoveIdle();
                pOgre->SetWalk(false, true);
                m_creature->GetContactPoint(pOgre, fX, fY, fZ);
                pOgre->GetMotionMaster()->MovePoint(0, fX, fY, fZ);

                switch (urand(0, 2))
                {
                    case 0: DoScriptText(SAY_BREW_1, pOgre); break;
                    case 1: DoScriptText(SAY_BREW_2, pOgre); break;
                    case 2: DoScriptText(SAY_BREW_3, pOgre); break;
                }

                m_selectedOgreGuid = pOgre->GetObjectGuid();
                m_uiStartTimer = 0;
                m_bHasValidOgre = true;
            }
            else
                m_uiStartTimer -= uiDiff;
        }
    }
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);                    // _MOVE set in _SetTargetLocation after required checks
    _setTargetLocation(owner, true);

    i_target->GetPosition(m_prevTargetPos.x, m_prevTargetPos.y, m_prevTargetPos.z);
}
void ChaseMovementGenerator<Creature>::Initialize(Creature &owner)
{
    owner.SetWalk(false);
    owner.addUnitState(UNIT_STAT_CHASE|UNIT_STAT_CHASE_MOVE);
    _setTargetLocation(owner);

    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));
}
Beispiel #14
0
void HomeMovementGenerator<Creature>::Finalize(Creature& owner)
{
    if (arrived)
    {
        owner.ClearUnitState(UNIT_STATE_EVADE);
        owner.SetWalk(true);
        owner.LoadCreaturesAddon(true);
        owner.AI()->JustReachedHome();
    }
}
void ChaseMovementGenerator<Creature>::Initialize(Creature &owner)
{
    owner.StopMoving();
    owner.SetWalk(false);
    owner.addUnitState(UNIT_STAT_CHASE);
    _setTargetLocation(owner);

    if (owner.IsAIEnabled)
        owner.AI()->MovementInform(CHASE_MOTION_TYPE, 1);
}
    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(CREATURE_SORCERER, X, Y, Z_SPAWN, 0, TEMPSUMMON_DEAD_DESPAWN, 0);
            if (Sorcerer)
            {
                CAST_AI(mob_ashtongue_sorcererAI, Sorcerer->AI())->ShadeGUID = me->GetGUID();
                Sorcerer->SetWalk(false);
                Sorcerer->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ());
                Sorcerer->SetUInt64Value(UNIT_FIELD_TARGET, me->GetGUID());
                Sorcerers.push_back(Sorcerer->GetGUID());
                --DeathCount;
                ++SorcererCount;
            }
        }
        //else
        //{
        for (uint8 pos = 0; pos < 2; ++pos)
        {
            X = SpawnLocations[pos].x;
            Y = SpawnLocations[pos].y;

            for (uint8 i = 0; i < 3; ++i)
            {
                Creature* Spawn = me->SummonCreature(spawnEntries[i], X, Y, Z_SPAWN, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                if (Spawn)
                {
                    Spawn->SetWalk(false);
                    Spawn->GetMotionMaster()->MovePoint(0, AGGRO_X, AGGRO_Y, AGGRO_Z);
                    Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 1);
                    Spawn->AI()->AttackStart(pTarget);
                    DoZoneInCombat(Spawn);
                }
            }
        }
        //}
    }
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);
}
Beispiel #18
0
    void UpdateAI(const uint32 uiDiff) override
    {
        if (m_uiStartTimer)
        {
            if (m_uiStartTimer <= uiDiff)
            {
                // get all the bats list in range; note: this will compare the 2D distance
                std::list<Creature*> lBatsList;
                GetCreatureListWithEntryInGrid(lBatsList, m_creature, NPC_DARKCLAW_BAT, 10.0f);

                if (lBatsList.empty())
                {
                    m_uiStartTimer = 5000;
                    return;
                }

                // sort by distance and get only the closest
                lBatsList.sort(ObjectDistanceOrder(m_creature));

                std::list<Creature*>::const_iterator batItr = lBatsList.begin();
                Creature* pBat = NULL;

                do
                {
                    // check for alive and out of combat only
                    if ((*batItr)->isAlive() && !(*batItr)->getVictim())
                        pBat = *batItr;

                    ++batItr;
                }
                while (!pBat && batItr != lBatsList.end());

                if (!pBat)
                {
                    m_uiStartTimer = 5000;
                    return;
                }

                // Move bat to the point
                float fX, fY, fZ;
                pBat->SetWalk(false);
                pBat->GetMotionMaster()->Clear();
                m_creature->GetContactPoint(pBat, fX, fY, fZ);
                pBat->GetMotionMaster()->MovePoint(0, fX, fY, fZ);

                m_selectedBatGuid = pBat->GetObjectGuid();
                m_uiStartTimer = 0;
                m_bHasValidBat = true;
            }
            else
                m_uiStartTimer -= uiDiff;
        }
    }
void HomeMovementGenerator<Creature>::Finalize(Creature& owner)
{
    if (arrived)
    {
        if (owner.GetTemporaryFactionFlags() & TEMPFACTION_RESTORE_REACH_HOME)
            owner.ClearTemporaryFaction();

        owner.SetWalk(true);
        owner.LoadCreatureAddon(true);
        owner.AI()->JustReachedHome();
    }
}
Beispiel #20
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();
    }
}
Beispiel #21
0
void CreatureGroup::LeaderMoveTo(float x, float y, float z)
{
    m_movingUnits = 0;
    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 = m_leader->GetMap()->GetCreature(itr->first);
        if (!member || member == m_leader || !member->isAlive() || member->getVictim())
            continue;

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

        // if follow distance is 0 then don't follow leader
        if (!dist)
            continue;

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

        Hellground::NormalizeMapCoord(dx);
        Hellground::NormalizeMapCoord(dy);

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

        if (member->IsWithinDistInMap(m_leader, dist + MAX_DESYNC))
        {
            uint32 moveFlags = m_leader->GetUnitMovementFlags();
            if (!member->m_movementInfo.HasMovementFlag(MOVEFLAG_SPLINE_ENABLED))
                moveFlags &= ~MOVEFLAG_SPLINE_ENABLED;

            member->SetUnitMovementFlags(moveFlags);
        }
        else
        {
            // jak sie za bardzo rozjada xO
            if (!member->IsWithinDistInMap(m_leader, 40.0f))
                member->NearTeleportTo(m_leader->GetPositionX(), m_leader->GetPositionY(), m_leader->GetPositionZ(), 0.0f);
            else
                member->SetWalk(false);
        }

        member->GetMotionMaster()->MovePoint(0, dx, dy, dz, true, true, UNIT_ACTION_HOME);
        member->SetHomePosition(m_leader->GetPositionX(), m_leader->GetPositionY(), m_leader->GetPositionZ(), pathangle);
        m_movingUnits++;
    }
}
Beispiel #22
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;
    }
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;
    }
}
        // Function that spawns Arthas on demand
        void DoSpawnArthasIfNeeded(Unit* pSummoner)
        {
            if (!pSummoner)
                return;

            Creature* pArthas = GetSingleCreatureFromStorage(NPC_ARTHAS, true);
            if (pArthas && pArthas->IsAlive())
                return;

            uint8 uiPosition = GetInstancePosition();
            if (uiPosition && uiPosition <= MAX_ARTHAS_SPAWN_POS)
                pSummoner->SummonCreature(NPC_ARTHAS, m_aArthasSpawnLocs[uiPosition - 1].m_fX, m_aArthasSpawnLocs[uiPosition - 1].m_fY, m_aArthasSpawnLocs[uiPosition - 1].m_fZ, m_aArthasSpawnLocs[uiPosition - 1].m_fO, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000, true);

            // no gossip flag in the following positions
            if (uiPosition == POS_ARTHAS_INTRO || uiPosition == POS_ARTHAS_WAVES)
            {
                if (Creature* pArthas = GetSingleCreatureFromStorage(NPC_ARTHAS))
                    pArthas->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
            }

            // summon the other intro actors
            if (uiPosition == POS_ARTHAS_INTRO)
            {
                // start intro event by dbscripts
                if (Creature* pArthas = GetSingleCreatureFromStorage(NPC_ARTHAS))
                {
                    pArthas->SetWalk(false);
                    pArthas->GetMotionMaster()->MoveWaypoint();
                }

                // spawn Jaina and Uther
                if (Creature* pJaina = pSummoner->SummonCreature(NPC_JAINA_PROUDMOORE, m_aIntroActorsSpawnLocs[0].m_fX, m_aIntroActorsSpawnLocs[0].m_fY, m_aIntroActorsSpawnLocs[0].m_fZ, m_aIntroActorsSpawnLocs[0].m_fO, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000))
                    pJaina->GetMotionMaster()->MoveWaypoint();
                if (Creature* pUther = pSummoner->SummonCreature(NPC_UTHER_LIGHTBRINGER, m_aIntroActorsSpawnLocs[1].m_fX, m_aIntroActorsSpawnLocs[1].m_fY, m_aIntroActorsSpawnLocs[1].m_fZ, m_aIntroActorsSpawnLocs[1].m_fO, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000))
                {
                    pUther->SetWalk(false);
                    pUther->GetMotionMaster()->MoveWaypoint();

                    // spawn the knights
                    if (Creature* pKnight = pSummoner->SummonCreature(NPC_KNIGHT_SILVERHAND, m_aIntroActorsSpawnLocs[2].m_fX, m_aIntroActorsSpawnLocs[2].m_fY, m_aIntroActorsSpawnLocs[2].m_fZ, m_aIntroActorsSpawnLocs[2].m_fO, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000))
                        pKnight->GetMotionMaster()->MoveFollow(pUther, pKnight->GetDistance(pUther), 2 * M_PI_F - pKnight->GetAngle(pUther));
                    if (Creature* pKnight = pSummoner->SummonCreature(NPC_KNIGHT_SILVERHAND, m_aIntroActorsSpawnLocs[3].m_fX, m_aIntroActorsSpawnLocs[3].m_fY, m_aIntroActorsSpawnLocs[3].m_fZ, m_aIntroActorsSpawnLocs[3].m_fO, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000))
                        pKnight->GetMotionMaster()->MoveFollow(pUther, pKnight->GetDistance(pUther), 2 * M_PI_F - pKnight->GetAngle(pUther));
                    if (Creature* pKnight = pSummoner->SummonCreature(NPC_KNIGHT_SILVERHAND, m_aIntroActorsSpawnLocs[4].m_fX, m_aIntroActorsSpawnLocs[4].m_fY, m_aIntroActorsSpawnLocs[4].m_fZ, m_aIntroActorsSpawnLocs[4].m_fO, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000))
                        pKnight->GetMotionMaster()->MoveFollow(pUther, pKnight->GetDistance(pUther), 2 * M_PI_F - pKnight->GetAngle(pUther));
                }
            }
            // setup the entrance soldiers in case of reload or intro skip
            else if (uiPosition == POS_ARTHAS_WAVES)
                DoSetupEntranceSoldiers(pSummoner);
        }
bool WaypointMovementGenerator<Creature>::StartMove(Creature &creature)
{
    if (!i_path || i_path->empty())
        return false;
    if (Stopped())
        return true;

    if (m_isArrivalDone)
    {
        if ((i_currentNode == i_path->size() - 1) && !repeating) // If that's our last waypoint
        {
            creature.SetHomePosition(i_path->at(i_currentNode)->x, i_path->at(i_currentNode)->y, i_path->at(i_currentNode)->z, creature.GetOrientation());
            creature.GetMotionMaster()->Initialize();
            return false;
        }

        i_currentNode = (i_currentNode+1) % i_path->size();
    }

    WaypointData const* node = i_path->at(i_currentNode);

    if (!node)
        return false;

    m_isArrivalDone = false;

    creature.AddUnitState(UNIT_STATE_ROAMING_MOVE);

    Movement::MoveSplineInit init(creature);

    init.MoveTo(node->x, node->y, node->z);

    //! Accepts angles such as 0.00001 and -0.00001, 0 must be ignored, default value in waypoint table
    if (node->orientation && node->delay)
        init.SetFacing(node->orientation);

    init.SetWalk(!node->run);
    init.Launch();


    //Call for creature group update
    if (creature.GetFormation() && creature.GetFormation()->getLeader() == &creature)
    {
        creature.SetWalk(!node->run);
        creature.GetFormation()->LeaderMoveTo(node->x, node->y, node->z);
    }

    return true;
}
Beispiel #26
0
void HomeMovementGenerator<Creature>::Finalize(Creature& owner)
{
    if (arrived)
    {
		// Instant regen Health after EvadeMode
		owner.SetFullHealth();
		// Instant regen Mana after EvadeMode
		if (owner.GetPowerType() == POWER_MANA)
			owner.SetPower(POWER_MANA, owner.GetMaxPower(POWER_MANA));
		// Instant Reset Rage after EvadeMode
		if (owner.GetPowerType() == POWER_RAGE)
			owner.SetPower(POWER_RAGE, 0);

		owner.ClearUnitState(UNIT_STATE_EVADE);
        owner.SetWalk(true);
        owner.LoadCreaturesAddon(true);
        owner.AI()->JustReachedHome();
    }
}
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);
    BLIZZLIKE_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;
    }

    return;
}
bool EffectAuraDummy_npc_scourged_flamespitter(const Aura* pAura, bool bApply)
{
    if (pAura->GetId() == SPELL_REINFORCED_NET && pAura->GetEffIndex() == EFFECT_INDEX_0 && bApply)
    {
        Creature* pCreature = (Creature*)pAura->GetTarget();
        Unit* pCaster = pAura->GetCaster();
        if (!pCreature || !pCaster || pCaster->GetTypeId() != TYPEID_PLAYER || pCreature->GetEntry() != NPC_FLAMESPITTER)
            return false;

        // move the flamespitter to the ground level
        pCreature->GetMotionMaster()->Clear();
        pCreature->SetWalk(false);

        float fGroundZ = pCreature->GetMap()->GetHeight(pCreature->GetPhaseMask(), pCreature->GetPositionX(), pCreature->GetPositionY(), pCreature->GetPositionZ());
        pCreature->GetMotionMaster()->MovePoint(1, pCreature->GetPositionX(), pCreature->GetPositionY(), fGroundZ);
        return true;
    }

    return false;
}
Beispiel #30
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 = std::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() || !(itr->second->groupAI & FLAG_IDLE_IN_FORMATION))
            continue;

        if (itr->second->point_1)
            if (m_leader->GetCurrentWaypointID() == itr->second->point_1 - 1 || m_leader->GetCurrentWaypointID() == itr->second->point_2 - 1)
                itr->second->follow_angle = float(M_PI) * 2 - 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);

        if (!member->IsFlying())
            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);
    }
}