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; } }
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)); }
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); }
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(); } }
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 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++; } }
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; }
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; }
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); } }