void HomeMovementGenerator<Creature>::_setTargetLocation(Creature & owner) { if (!&owner) return; if (owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED)) return; CreatureTraveller traveller(owner); uint32 travel_time; float myx,myy,myz,x,y,z; if(sWorld.getConfig(CONFIG_MOVEMAP_ENABLE) == 1) { owner.GetPosition(myx,myy,myz); owner.GetPosition(x,y,z); Position travelto = owner.GetMap()->getNextPositionOnPathToLocation(myx,myy,myz,x,y,z); travel_time = i_destinationHolder.SetDestination(traveller, travelto.m_positionX, travelto.m_positionY, travelto.m_positionZ); } else owner.GetPosition(x,y,z); travel_time = i_destinationHolder.SetDestination(traveller, x, y, z); modifyTravelTime(travel_time); owner.clearUnitState(UNIT_STAT_ALL_STATE); }
void UpdateAI(uint32 const diff) { if (pInstance && pInstance->GetData(TYPE_IONAR) != IN_PROGRESS) { me->DespawnOrUnsummon(); return; } if (uiArcWeldTimer <= diff) { DoCast(me, SPELL_ARC_WELD); uiArcWeldTimer = 500; } else uiArcWeldTimer -= diff; if (uiCheckTimer <= diff) { if (pInstance) { Creature* pIonar = pInstance->instance->GetCreature(pInstance->GetData64(DATA_IONAR)); if (pIonar && pIonar->isAlive()) { if (me->GetDistance(pIonar) > DATA_MAX_SPARK_DISTANCE) { Position pos; pIonar->GetPosition(&pos); me->SetSpeed(MOVE_RUN, 2.0f); me->GetMotionMaster()->Clear(); me->GetMotionMaster()->MovePoint(DATA_POINT_CALLBACK, pos); } } else me->DespawnOrUnsummon(); } uiCheckTimer = 2*IN_MILLISECONDS; } else uiCheckTimer -= diff; }
void WorldSession::HandleBattlemasterHelloOpcode(WorldPacket& recvData) { ObjectGuid guid; recvData >> guid; TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_BATTLEMASTER_HELLO Message from %s", guid.ToString().c_str()); Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_BATTLEMASTER); if (!unit) return; // Stop the npc if moving unit->PauseMovement(sWorld->getIntConfig(CONFIG_CREATURE_STOP_FOR_PLAYER)); unit->SetHomePosition(unit->GetPosition()); BattlegroundTypeId bgTypeId = sBattlegroundMgr->GetBattleMasterBG(unit->GetEntry()); if (!_player->GetBGAccessByLevel(bgTypeId)) { // temp, must be gossip message... SendNotification(LANG_YOUR_BG_LEVEL_REQ_ERROR); return; } SendBattleGroundList(guid, bgTypeId); }
void UpdateAI(const uint32 uiDiff) { // Despawn if the encounter is not running if (pInstance && pInstance->GetData(TYPE_IONAR) != IN_PROGRESS) { me->ForcedDespawn(); return; } // Prevent them to follow players through the whole instance if (uiCheckTimer <= uiDiff) { if (pInstance) { Creature* pIonar = pInstance->instance->GetCreature( pInstance->GetData64(DATA_IONAR)); if (pIonar && pIonar->isAlive()) { if (me->GetDistance(pIonar) > DATA_MAX_SPARK_DISTANCE) { Position pos; pIonar->GetPosition(&pos); me->SetSpeed(MOVE_RUN, 2.0f); me->GetMotionMaster()->Clear(); me->GetMotionMaster()->MovePoint( DATA_POINT_CALLBACK, pos); } } else me->ForcedDespawn(); } uiCheckTimer = 2 * IN_MILLISECONDS; } else uiCheckTimer -= uiDiff; // No melee attack at all! }
void UpdateAI(const uint32 diff) { if (uiCheckTimer <= diff) { if (pInstance) { Creature* pBronjham = Unit::GetCreature(*me, pInstance->GetData64(DATA_BRONJAHM)); if (pBronjham && pBronjham->isAlive()) { if (me->IsWithinMeleeRange(pBronjham)) { pBronjham->CastSpell(pBronjham, SPELL_CONSUME_SOUL, true); me->ForcedDespawn(); } else { Position pos; pBronjham->GetPosition(&pos); me->GetMotionMaster()->Clear(); me->GetMotionMaster()->MovePoint(0, pos); } } else me->ForcedDespawn(); } uiCheckTimer = 500; } else uiCheckTimer -= diff; }
void UpdateAI(uint32 uiDiff) override { // Despawn if the encounter is not running if (instance->GetBossState(DATA_IONAR) != IN_PROGRESS) { me->DespawnOrUnsummon(); return; } // Prevent them to follow players through the whole instance if (uiCheckTimer <= uiDiff) { Creature* ionar = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_IONAR)); if (ionar && ionar->IsAlive()) { if (me->GetDistance(ionar) > DATA_MAX_SPARK_DISTANCE) { Position pos = ionar->GetPosition(); me->SetSpeed(MOVE_RUN, 2.0f); me->GetMotionMaster()->Clear(); me->GetMotionMaster()->MovePoint(DATA_POINT_CALLBACK, pos); } } else me->DespawnOrUnsummon(); uiCheckTimer = 2*IN_MILLISECONDS; } else uiCheckTimer -= uiDiff; // No melee attack at all! }
bool RandomMovementGenerator<Creature>::GetResetPosition(Creature &creature, float& x, float& y, float& z) { float radius; creature.GetRespawnPosition(x, y, z, NULL, &radius); // use current if in range if (creature.IsWithinDist2d(x, y, radius)) creature.GetPosition(x, y, z); return true; }
bool RandomMovementGenerator<Creature>::GetResetPosition(Creature& c, float& x, float& y, float& z) { float radius; c.GetRespawnCoord(x, y, z, NULL, &radius); // use current if in range if (c.IsInRange2d(x,y, 0, radius)) c.GetPosition(x,y,z); return true; }
void HandleAfterCast() { Unit* caster = GetCaster(); if (!caster->IsInCombat() || roll_chance_i(50)) return; std::list<Creature*> triggers; caster->GetCreatureListWithEntryInGrid(triggers, NPC_VIAL_BUNNY, 100.0f); Creature* trigger = Trinity::Containers::SelectRandomContainerElement(triggers); caster->GetMotionMaster()->MovePoint(0, trigger->GetPosition()); }
void JustDied(Unit* Killer) { DoScriptText(YELL_DEATH, me); if (pInstance) { pInstance->SetData(DATA_BRUTALLUS_EVENT, DONE); float x,y,z; Creature *Madrigosa = Unit::GetCreature(*me, pInstance ? pInstance->GetData64(DATA_MADRIGOSA) : 0); Madrigosa->CastSpell(Madrigosa, 44885, true); Madrigosa->GetPosition(x,y,z); Madrigosa->SetVisibility(VISIBILITY_OFF); me->SummonCreature(FELMYST, x,y, z+30, me->GetOrientation(), TEMPSUMMON_MANUAL_DESPAWN, 0); } }
bool RandomMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff) { if (creature.hasUnitState(UNIT_STAT_NOT_MOVE)) { i_nextMoveTime.Update(i_nextMoveTime.GetExpiry()); // Expire the timer creature.clearUnitState(UNIT_STAT_ROAMING_MOVE); return true; } i_nextMoveTime.Update(diff); if (i_destinationHolder.HasArrived() && !creature.IsStopped() && !creature.canFly()) creature.clearUnitState(UNIT_STAT_ROAMING_MOVE); if (!i_destinationHolder.HasArrived() && creature.IsStopped()) creature.addUnitState(UNIT_STAT_ROAMING_MOVE); CreatureTraveller traveller(creature); if (i_destinationHolder.UpdateTraveller(traveller, diff, false, true)) { if (!IsActive(creature)) // force stop processing (movement can move out active zone with cleanup movegens list) return true; // not expire now, but already lost if (i_nextMoveTime.Passed()) { float x,y,z; if(i_destinationHolder.HasDestination()) i_destinationHolder.GetLocationNowNoMicroMovement(x,y,z); else creature.GetPosition(x,y,z); if (creature.canFly() && !(creature.canWalk() && creature.IsAtGroundLevel(x,y,z))) creature.AddSplineFlag(SPLINEFLAG_UNKNOWN7); else creature.AddSplineFlag(SPLINEFLAG_WALKMODE); _setRandomLocation(creature); } else if (creature.isPet() && creature.GetOwner() && !creature.IsWithinDist(creature.GetOwner(), PET_FOLLOW_DIST+2.5f)) { creature.AddSplineFlag(SPLINEFLAG_WALKMODE); _setRandomLocation(creature); } } return true; }
void KillHostage(uint8 index) { if(!HostagesGUID[index]) return; Creature *hostage = (Creature*)(instance->GetUnit(HostagesGUID[index])); if(!hostage) return; WorldLocation wLoc; hostage->GetPosition(wLoc); Creature *corpse = hostage->SummonCreature(HostageInfo[index].deadnpc, wLoc.coord_x, wLoc.coord_y, wLoc.coord_z, wLoc.orientation, TEMPSUMMON_MANUAL_DESPAWN, 0); if(corpse) { corpse->SetStandState(UNIT_STAND_STATE_DEAD); // TODO: add some burn effect } hostage->Kill(hostage, false); hostage->RemoveCorpse(); }
void OnActivate(Player* player) { QuestLogEntry* qle = player->GetQuestLogForEntry(9582); if (qle == nullptr) return; LocationVector pos = player->GetPosition(); // What is this ? :O To remove ? Creature* reaver = player->GetMapMgr()->GetInterface()->GetCreatureNearestCoords(pos.x, pos.y, pos.z, 17556); if (reaver) { LocationVector pos2 = reaver->GetPosition(); reaver->Despawn(1, 5 * 60 * 1000); Creature* reaver2 = player->GetMapMgr()->GetInterface()->SpawnCreature(17556, pos2.x, pos2.y, pos2.z, pos2.o, true, false, 0, 0); if (reaver2 != nullptr) reaver2->Despawn(5 * 60 * 1000, 0); } }
bool HomeMovementGenerator<Creature>::Update(Creature &owner, const uint32& time_diff) { CreatureTraveller traveller(owner); i_destinationHolder.UpdateTraveller(traveller, time_diff); if (time_diff > i_travel_timer) { float x, y, z; owner.GetRespawnCoord(x, y, z); float myx, myy, myz; owner.GetPosition(myx, myy, myz); if (x != myx || y != myy || z != myz) { Position travelto = owner.GetMap()->getNextPositionOnPathToLocation(myx,myy,myz,x,y,z); uint32 travel_time = i_destinationHolder.SetDestination(traveller, travelto.m_positionX, travelto.m_positionY, travelto.m_positionZ); modifyTravelTime(travel_time); return true; } owner.AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); // restore orientation of not moving creature at returning to home if (owner.GetDefaultMovementType() == IDLE_MOTION_TYPE) { //sLog.outDebug("Entering HomeMovement::GetDestination(z,y,z)"); owner.SetOrientation(ori); WorldPacket packet; owner.BuildHeartBeatMsg(&packet); owner.SendMessageToSet(&packet, false); } owner.clearUnitState(UNIT_STAT_EVADE); owner.AI()->JustReachedHome(); return false; } i_travel_timer -= time_diff; return true; }
Creature* Tower::SearchNearestCreature(std::list<Creature*>& p_creatureList) { Creature* targetCreature = NULL; float targetDistance = -1; std::list<Creature*>::iterator creatureIt; std::list<Creature*>::iterator creatureItEnd = p_creatureList.end(); Creature* creatureCurrent = NULL; float creatureDistance; for (creatureIt = p_creatureList.begin(); creatureIt != creatureItEnd; ++creatureIt) { creatureCurrent = (*creatureIt); creatureDistance = GetPosition().getDistanceFrom(creatureCurrent->GetPosition()); if (targetDistance == -1 || creatureDistance < targetDistance) { targetDistance = creatureDistance; targetCreature = creatureCurrent; } } return targetCreature; }
void ChargeMovementGenerator<Creature>::Initialize(Creature &creature) { if (!creature.isAlive()) return; creature.addUnitState(UNIT_STAT_ROAMING|UNIT_STAT_ROAMING_MOVE); if (m_start == m_end) { float dist = creature.GetDistance(m_path[m_end].x, m_path[m_end].y, m_path[m_end].z); float angle = creature.GetAngle(m_path[m_end].x, m_path[m_end].y); bool outdoor = creature.GetTerrain()->IsOutdoors(m_path[m_end].x, m_path[m_end].y, m_path[m_end].z); Coords pos = creature.GetPosition(); float itr = 1; if(m_pointTime > 1000) { while(float(m_pointTime)/(float(dist+itr)/itr) <= 1000 && itr < dist) itr+=0.3f; } else itr = dist; for(float i = 1; i < dist; i+=itr) { m_path.resize(m_path.size()+1); m_path.set(m_end+1, m_path[m_end]); pos.x += cos(angle)*itr; pos.y += sin(angle)*itr; creature.UpdateGroundPositionZ(pos.x, pos.y, pos.z, outdoor ? 10.0f : 3.0f); m_path.set(m_end, pos); ++m_end; } m_pointTime = float(m_pointTime)/float((m_end - m_start) + 1); i_nextMoveTime.Reset(m_pointTime); } }
void RandomCircleMovementGenerator<Creature>::fillSplineWayPoints(Creature &creature) { m_splineMap.clear(); float spawnX, spawnY, spawnZ, spawnO, spawnDist, x, y, z; creature.GetRespawnCoord(spawnX, spawnY, spawnZ, &spawnO, &spawnDist); creature.GetPosition(x,y,z); //Add first waypoint /* SplineWayPointInfo *firstwp = new SplineWayPointInfo(); firstwp->x = x; firstwp->y = y; firstwp->z = z; m_splineMap.insert(std::make_pair<uint32, SplineWayPointInfo*>(0, firstwp)); */ //calculate other ones float m_fDistance = creature.GetDistance2d(spawnX, spawnY); float m_fLenght = 2*M_PI_F*m_fDistance; float m_fAngle = (M_PI_F - ((2*M_PI_F) / m_fLenght)) / 2; if (m_bClockWise) m_fAngle += ((2*M_PI_F) / m_fLenght) + creature.GetAngle(spawnX, spawnY); else m_fAngle = creature.GetAngle(spawnX, spawnY) - m_fAngle - ((2*M_PI_F) / m_fLenght); //because it cant be lower than 0 or bigger than 2*PI m_fAngle = (m_fAngle >= 0) ? m_fAngle : 2 * M_PI_F + m_fAngle; m_fAngle = (m_fAngle <= 2*M_PI_F) ? m_fAngle : m_fAngle - 2 * M_PI_F; float creature_speed = creature.GetSpeed(MOVE_FLIGHT) / 2; float lastx = x; float lasty = y; for(uint32 wpId = 0; wpId < 30; ++wpId) { bool canIncerase = true; bool canDecerase = true; if (m_fDistance > spawnDist) canIncerase = false; if (m_fDistance < 1) canDecerase = false; uint8 tmp = urand(0,2); // 0 nothing, 1 incerase, 2 decerase if (tmp == 1 && canIncerase) m_fDistance += 0.5f; else if (tmp == 2 && canDecerase) m_fDistance -= 0.5f; m_fLenght = 2*M_PI_F*m_fDistance; float m_fRotateAngle = ((2*M_PI_F) / m_fLenght); // Moving by half of speed every 500ms if (m_bClockWise) m_fAngle -= m_fRotateAngle; else m_fAngle += m_fRotateAngle; //because it cant be lower than 0 or bigger than 2*PI m_fAngle = (m_fAngle >= 0) ? m_fAngle : 2 * M_PI_F + m_fAngle; m_fAngle = (m_fAngle <= 2*M_PI_F) ? m_fAngle : m_fAngle - 2 * M_PI_F; lastx += cos(m_fAngle)*creature_speed; lasty += sin(m_fAngle)*creature_speed; MaNGOS::NormalizeMapCoord(lastx); MaNGOS::NormalizeMapCoord(lasty); Position *wp = new Position(); wp->x = lastx; wp->y = lasty; wp->z = z; wp->o = m_fAngle; m_splineMap.insert(std::make_pair<uint32, Position*>(wpId, wp)); } i_nextMoveTime.Reset(500); }
//============================================================================== void GameServer::HandleUse_(const QVariantMap& request, QVariantMap& response) { auto sid = request["sid"].toByteArray(); Player* p = sidToPlayer_[sid]; if (!request["id"].toInt()) { WriteResult_(response, EFEMPResult::BAD_ID); return; } int id = request["id"].toInt(); Item* item = dynamic_cast<Item*>(idToActor_[request["id"].toInt()]); if (item) { if (request.find("x") == request.end() && request.find("y") == request.end()) { if (item->GetSubtype() != "consumable") { WriteResult_(response, EFEMPResult::BAD_ID); return; } else { p->SetHealth(p->GetHealth() + item->bonuses[EStatConst::HP]["value"].toFloat()); WriteResult_(response, EFEMPResult::OK); return; } } if ((item != p->GetSlot(left_hand) || item != p->GetSlot(right_hand)) && (p->GetSlot(left_hand) != 0 || p->GetSlot(right_hand)!= 0 ) && id != FistId_) { WriteResult_(response, EFEMPResult::BAD_SLOT); return; } WriteResult_ (response, EFEMPResult::OK); return; } if (!request["x"].toFloat() || !request["y"].toFloat()) { WriteResult_(response, EFEMPResult::BAD_PLACING); return; } for (Actor* actor : actors_) { if (actor->GetType() != EActorType::ITEM && actor->GetType() != EActorType::PROJECTILE) { Creature* target = static_cast<Creature*>(actor); if ((p->GetId() != target->GetId()) && (target->GetHealth() > 0)) { Vector2 player_pos = p->GetPosition(); Vector2 target_pos = target->GetPosition(); float distance2 = Sqr(player_pos.x - target_pos.x) + Sqr(player_pos.y - target_pos.y); if (distance2 <= Sqr(pickUpRadius_)) { QVariantMap a = p->atack(target, id); events_ << a; if (target->GetHealth() <= 0) { GetItems(target); p->SetExperience(p->GetExperience () + 300); int lev = p->GetLevel(); p->SetLevel (p->GetExperience() / 1000); if (lev < p->GetLevel()) { p->AddStat (); p->UpdateStat(); } } else { a = target->atack(p); events_ << a; } WriteResult_(response, EFEMPResult::OK); return; } } } } }
//============================================================================== void GameServer::tick() { /*float dt = (time_.elapsed() - lastTime_) * 0.001f;*/ lastTime_ = time_.elapsed(); /*if (actors_.size() < 100 && !testingStageActive_) { GenMonsters_(); }*/ auto collideWithGrid = [=](Actor* actor, EActorDirection direction) { auto& p = *actor; float x = p.GetPosition().x; float y = p.GetPosition().y; bool collided = false; if ((levelMap_.GetCell(x + 0.49f, y - 0.51f) != '.' || levelMap_.GetCell(x + 0.49f, y + 0.49f) != '.') && levelMap_.GetCell(x - slideThreshold_+ 0.5f, y) == '.' && (direction == EActorDirection::NORTH || direction == EActorDirection::SOUTH)) { p.SetPosition(Vector2(x - slideThreshold_+ 0.0001f, p.GetPosition().y)); } if (levelMap_.GetCell(x + slideThreshold_- 0.5f, y) == '.' &&((levelMap_.GetCell(x - 0.5f, y - 0.51f) != '.' || levelMap_.GetCell(x - 0.5f, y + 0.49f) != '.') && (direction == EActorDirection::NORTH || direction == EActorDirection::SOUTH))) { p.SetPosition(Vector2(x + slideThreshold_- 0.0001f, p.GetPosition().y)); } if (levelMap_.GetCell(x, y - slideThreshold_ + 0.5f) == '.' && (levelMap_.GetCell(x - 0.51f, y + 0.49f) != '.' || levelMap_.GetCell(x + 0.49f, y + 0.49f) != '.') && (direction == EActorDirection::EAST || direction == EActorDirection::WEST)) { p.SetPosition(Vector2(p.GetPosition().x, y - slideThreshold_+ 0.0001f)); } if ((levelMap_.GetCell(x + 0.49f, y - 0.5f) != '.' || levelMap_.GetCell(x - 0.51f, y - 0.5f) != '.') && levelMap_.GetCell(x, y + slideThreshold_- 0.5f) == '.' && (direction == EActorDirection::EAST || direction == EActorDirection::WEST)) { p.SetPosition(Vector2(p.GetPosition().x, y + slideThreshold_ - 0.001f)); } if (levelMap_.GetCell(x + 0.5f, y) != '.') { p.SetPosition(Vector2(round(x + 0.5f) - 0.5f, p.GetPosition().y)); collided = true; } if (levelMap_.GetCell(x - 0.51f, y) != '.') { p.SetPosition(Vector2(round(x - 0.5f) + 0.5f, p.GetPosition().y)); collided = true; } if (levelMap_.GetCell(x, y + 0.5f) != '.') { p.SetPosition(Vector2(p.GetPosition().x, round(y + 0.5f) - 0.5f)); collided = true; } if (levelMap_.GetCell(x, y - 0.51f) != '.') { p.SetPosition(Vector2(p.GetPosition().x, round(y - 0.5f) + 0.5f)); collided = true; } if (collided) { actor->OnCollideWorld(); } }; for (Actor* actor: actors_) { if (actor->GetType() == EActorType::MONSTER) { Monster* monster = dynamic_cast<Monster*>(actor); Creature* target = monster->target; float distance2; Vector2 m_pos = actor->GetPosition(); if (target && target != nullptr) { Vector2 t_pos = target->GetPosition(); distance2 = Sqr(m_pos.x - t_pos.x) + Sqr(m_pos.y - t_pos.y); if (distance2 < 25) { if (abs(m_pos.x - t_pos.x - 1.0f) < playerVelocity_ && m_pos.x - t_pos.x - 1.0f != 0) { monster->SetPosition(Vector2(t_pos.x + 1.0f, m_pos.y)); monster->SetDirection(EActorDirection::NONE); } if (abs(m_pos.y - t_pos.y + 1.0f) < playerVelocity_ && m_pos.y - t_pos.y + 1.0f != 0) { monster->SetPosition(Vector2(m_pos.x, t_pos.y - 1.0f)); monster->SetDirection(EActorDirection::NONE); } if (m_pos.x < t_pos.x - 1.0f) { monster->SetDirection(EActorDirection::EAST); } else if (m_pos.x > t_pos.x + 1.0f) { monster->SetDirection(EActorDirection::WEST); } else if (m_pos.y < t_pos.y - 1.0f) { monster->SetDirection(EActorDirection::SOUTH); } else if (m_pos.y > t_pos.y + 1.0f) { monster->SetDirection(EActorDirection::NORTH); } } } if (!target || target == nullptr || distance2 >= 5) { for (Actor* tar : actors_) { if (tar != monster) { bool b = false; if (tar->GetType() != EActorType::ITEM && tar->GetType () != EActorType::PROJECTILE) { Creature* m = dynamic_cast<Creature*>(tar); QStringList str = monster->Flags.filter("HATE"); for (QString hate: str) { if (Hates[hate] == m->GetRace()) { b = true; break; } } if (b) { Vector2 t_pos = tar->GetPosition(); distance2 = Sqr(m_pos.x - t_pos.x) + Sqr(m_pos.y - t_pos.y); // Dasha told 5^2 is a protocol defined const if (distance2 < 25) { monster->target = m; break; } } } } } } } if (actor->GetType() == EActorType::MONSTER || actor->GetType() == EActorType::PLAYER) { Creature* monster = dynamic_cast<Creature*>(actor); if (monster->GetHealth() <= 0) { KillActor_(actor); break; } } } for (Actor* actor: actors_) { if (!actor || actor == nullptr) { break; } auto v = directionToVector[static_cast<unsigned>(actor->GetDirection())] ; actor->SetVelocity(v); float dt = playerVelocity_; Vector2 old_pos = actor->GetPosition(); Vector2 new_pos = old_pos + v * (dt + 0.001); Vector2 old_pos2 = old_pos + v * 0.51; levelMap_.RemoveActor(actor); EActorDirection d = actor->GetDirection(); float x = new_pos.x; float y = new_pos.y; if (levelMap_.GetCell(old_pos2.x, old_pos2.y) != '#' && d != EActorDirection::NONE && (((levelMap_.GetCell(x - slideThreshold_+ 0.5f, y) == '.' && levelMap_.GetCell(x + slideThreshold_- 0.5f, y) == '.') && (d == EActorDirection::NORTH || d == EActorDirection::SOUTH)) || ((levelMap_.GetCell(x, y - slideThreshold_+ 0.5f) == '.' && levelMap_.GetCell(x, y + slideThreshold_- 0.5f) == '.') && (d == EActorDirection::EAST || d == EActorDirection::WEST)))) { if (levelMap_.GetCell(new_pos.x, new_pos.y) == '.') { if (!actor->Update(dt) && actor->GetType () == EActorType::PROJECTILE) { static_cast<Projectile*>(actor)->death = true; } collideWithGrid(actor, d); } else if (levelMap_.GetCell(x , y) != '.' && playerVelocity_ >= 1) { bool b = false; for (float i = 0.01; i <= dt; i += 0.01) { new_pos = old_pos + v * i + v * 0.5f; if (levelMap_.GetCell(new_pos.x, new_pos.y) == '#' && !b) { actor->Update(i - 0.01); b = true; } } } else { if (actor->GetType () == EActorType::PROJECTILE) { static_cast<Projectile*>(actor)->death = true; } } } else { if (actor && actor != nullptr) { if (actor->GetType () == EActorType::PROJECTILE) { static_cast<Projectile*>(actor)->death = true; } else { actor->OnCollideWorld(); } } } if (actor->GetType() == EActorType::PLAYER) { Player* player = dynamic_cast<Player*>(actor); if (player->GetHealth() < player->GetMaxHealth()) { player->SetHealth(player->GetHealth() + 1); } } if (actor->GetType() == EActorType::MONSTER) { Monster* monster = dynamic_cast<Monster*>(actor); Creature* target = monster->target; if (target && target->GetHealth() > 0) { Vector2 m_pos = actor->GetPosition(); Vector2 t_pos = target->GetPosition(); float distance2 = Sqr(m_pos.x - t_pos.x) + Sqr(m_pos.y - t_pos.y); if (distance2 <= Sqr(pickUpRadius_)) { events_ << monster->atack(target); events_ << target->atack(monster); } } } for (Actor* neighbour : actors_) { if (actor == nullptr || neighbour == nullptr || actor == neighbour || neighbour->GetType() == EActorType::ITEM || (actor->GetType() == EActorType::PROJECTILE && neighbour->GetType() == EActorType::PROJECTILE)) { break; } Box box0(neighbour->GetPosition(), 0.9f, 0.9f); Box box1(actor->GetPosition(), 0.9f, 0.9f); if (box0.Intersect(box1)) { actor->OnCollideActor(neighbour); neighbour->OnCollideActor(actor); if (actor->GetType() == EActorType::PROJECTILE) { static_cast<Projectile*>(actor)->death = true; if (neighbour->GetType () == EActorType::MONSTER) { Monster* monster = dynamic_cast<Monster*>(neighbour); if (monster->GetHealth () <= 0) { GetItems(monster); } } } else if (neighbour->GetType() == EActorType::PROJECTILE) { static_cast<Projectile*>(neighbour)->death = true; if (actor->GetType() == EActorType::MONSTER) { Monster* monster = dynamic_cast<Monster*>(actor); if (monster->GetHealth () <= 0) { GetItems(monster); } } } else if (neighbour->GetType() != EActorType::ITEM) { actor->SetPosition(old_pos); } } } if (actor->GetType() == EActorType::PROJECTILE && static_cast<Projectile*>(actor)->death) { QVariantMap ans1; ans1["radius"] = 1.0f; ans1["x"] = actor->GetPosition ().x; ans1["y"] = actor->GetPosition ().y; QVariantMap ans; ans["explode"] = ans1; events_ << ans; idToActor_.erase(actor->GetId()); actors_.erase(std::remove(actors_.begin(), actors_.end(), actor), actors_.end()); delete actor; actor = nullptr; } else { levelMap_.IndexActor(actor); } } QVariantMap tickMessage; tickMessage["tick"] = tick_; tickMessage["events"] = events_; events_.clear(); emit broadcastMessage(QString(QJsonDocument::fromVariant(tickMessage).toJson())); tick_++; }
void WorldSession::SendListInventory(ObjectGuid vendorGuid) { Creature* vendor = GetPlayer()->GetNPCIfCanInteractWith(vendorGuid, UNIT_NPC_FLAG_VENDOR); if (!vendor) { TC_LOG_DEBUG("network", "WORLD: SendListInventory - %s not found or you can not interact with him.", vendorGuid.ToString().c_str()); _player->SendSellError(SELL_ERR_CANT_FIND_VENDOR, nullptr, ObjectGuid::Empty, 0); return; } // remove fake death if (GetPlayer()->HasUnitState(UNIT_STATE_DIED)) GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); // Stop the npc if moving vendor->PauseMovement(sWorld->getIntConfig(CONFIG_CREATURE_STOP_FOR_PLAYER)); vendor->SetHomePosition(vendor->GetPosition()); VendorItemData const* items = vendor->GetVendorItems(); if (!items) { WorldPacket data(SMSG_LIST_INVENTORY, 8 + 1 + 1); data << uint64(vendorGuid); data << uint8(0); // count == 0, next will be error code data << uint8(0); // "Vendor has no inventory" SendPacket(&data); return; } uint8 itemCount = items->GetItemCount(); uint8 count = 0; WorldPacket data(SMSG_LIST_INVENTORY, 8 + 1 + itemCount * 8 * 4); data << uint64(vendorGuid); size_t countPos = data.wpos(); data << uint8(count); float discountMod = _player->GetReputationPriceDiscount(vendor); for (uint8 slot = 0; slot < itemCount; ++slot) { if (VendorItem const* item = items->GetItem(slot)) { if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(item->item)) { if (!(itemTemplate->AllowableClass & _player->getClassMask()) && itemTemplate->Bonding == BIND_WHEN_PICKED_UP && !_player->IsGameMaster()) continue; // Only display items in vendor lists for the team the // player is on. If GM on, display all items. if (!_player->IsGameMaster() && ((itemTemplate->Flags2 & ITEM_FLAG2_FACTION_HORDE && _player->GetTeam() == ALLIANCE) || (itemTemplate->Flags2 == ITEM_FLAG2_FACTION_ALLIANCE && _player->GetTeam() == HORDE))) continue; // Items sold out are not displayed in list uint32 leftInStock = !item->maxcount ? 0xFFFFFFFF : vendor->GetVendorItemCurrentCount(item); if (!_player->IsGameMaster() && !leftInStock) continue; if (!sConditionMgr->IsObjectMeetingVendorItemConditions(vendor->GetEntry(), item->item, _player, vendor)) { TC_LOG_DEBUG("condition", "SendListInventory: conditions not met for creature entry %u item %u", vendor->GetEntry(), item->item); continue; } // reputation discount int32 price = item->IsGoldRequired(itemTemplate) ? uint32(floor(itemTemplate->BuyPrice * discountMod)) : 0; data << uint32(slot + 1); // client expects counting to start at 1 data << uint32(item->item); data << uint32(itemTemplate->DisplayInfoID); data << int32(leftInStock); data << uint32(price); data << uint32(itemTemplate->MaxDurability); data << uint32(itemTemplate->BuyCount); data << uint32(item->ExtendedCost); if (++count >= MAX_VENDOR_ITEMS) break; } } } if (count == 0) { data << uint8(0); SendPacket(&data); return; } data.put<uint8>(countPos, count); SendPacket(&data); }
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 UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) { if (Phase == PHASE_INTRO) { if (m_uiEventTimer <= uiDiff) { switch(subevent) { case 0: if (lInitiates.size() < SUMMONS_NUMBER) SpawnAdds(lInitiates, NPC_TWILIGHT_INITIATE); else ++subevent; m_uiEventTimer = 1500; break; case 1: case 2: case 3: case 4: case 5: DoScriptText(SayPreaching[subevent], m_creature); m_uiEventTimer = 10000; ++subevent; break; case 6: if (!lInitiates.empty()) for (GuidList::iterator itr = lInitiates.begin(); itr != lInitiates.end(); ++itr) { if (Unit* pUnit = m_creature->GetMap()->GetUnit(*itr)) pUnit->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); } subevent = 0; Phase = PHASE_AFTER_INTRO; m_uiEventTimer = 1500; break; default: break; } } else m_uiEventTimer -= uiDiff; } return; } if (Phase == PHASE_SACRIFICE_SEQUENCE) { if (m_uiEventTimer <= uiDiff) { if (!m_pInstance) { // this should not happen! Phase = PHASE_READY_TO_ATTACK; return; } Creature* pController = m_pInstance->GetSingleCreatureFromStorage(NPC_JEDOGA_CONTROLLER); if (!pController) { // this should not happen! Phase = PHASE_READY_TO_ATTACK; return; } switch(subevent) { case 0: MoveToPosition(true); ++subevent; break; case 1: if (lVolunteers.size() < SUMMONS_NUMBER) SpawnAdds(lVolunteers, NPC_TWILIGHT_VOLUNTEER); else { DoScriptText(urand(0, 1) ? SAY_VOLUNTEER_CHOOSEN : SAY_VOLUNTEER_SACRIFICED, m_creature); ++subevent; } break; case 2: pController->CastSpell(pController, SPELL_SACRIFICE_VISUAL, false); DoCastSpellIfCan(m_creature, SPELL_SACRIFICE_BEAM); ++subevent; break; case 3: { GuidList::iterator itr = lVolunteers.begin(); advance(itr, (rand()% (lVolunteers.size()))); if (Creature* pVolunteer = m_creature->GetMap()->GetCreature(*itr)) { pVolunteer->RemoveAurasDueToSpell(SPELL_VOLUNTEER_SPHERE); float x, y, z; pController->GetPosition(x, y, z); pVolunteer->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); pVolunteer->GetMotionMaster()->MovePoint(7, SpawnNode[8][0], SpawnNode[8][1], SpawnNode[8][2],false); DoScriptText(SAY_VOLUNTEER_CHOOSEN, pVolunteer); } ++subevent; } break; case 4: if (m_creature->HasAura(SPELL_GIFT_OF_THE_HERALD)) m_bSacrifice = true; if (m_bSacrifice) { pController->RemoveAurasDueToSpell(SPELL_SACRIFICE_VISUAL); MoveToPosition(false); Phase = PHASE_READY_TO_ATTACK; subevent = 0; return; } break; default: break; } m_uiEventTimer = 1500; } else m_uiEventTimer -= uiDiff; return; } if(!m_bSacrifice && m_creature->GetHealthPercent() < 50.0f) { Phase = PHASE_SACRIFICE_SEQUENCE; return; } if(m_uiCycloneStrikeTimer < uiDiff) { DoCastSpellIfCan(m_creature->getVictim(), m_bIsRegularMode ? SPELL_CYCLONE_STRIKE : SPELL_CYCLONE_STRIKE_H); m_uiCycloneStrikeTimer = urand(10000, 20000); } else m_uiCycloneStrikeTimer -= uiDiff; if(m_uiLightningBoltTimer < uiDiff) { if(Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) DoCastSpellIfCan(pTarget, m_bIsRegularMode ? SPELL_LIGHTNING_BOLT : SPELL_LIGHTNING_BOLT_H); m_uiLightningBoltTimer = urand(3000, 8000); } else m_uiLightningBoltTimer -= uiDiff; if(m_uiThundershockTimer < uiDiff) { if(Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) DoCastSpellIfCan(pTarget, m_bIsRegularMode ? SPELL_THUNDERSHOCK : SPELL_THUNDERSHOCK_H); m_uiThundershockTimer = urand(8000, 16000); } else m_uiThundershockTimer -= uiDiff; DoMeleeAttackIfReady(); }
void npc_toc_announcerAI::UpdateAI(const uint32 /*diff*/) { // custom event step handling if (SpellTimer* stepTimer = m_TimerMgr->GetState(TIMER_PHASE_HANDLING)) { uint32 cooldown = 0; ++encounterStage; switch(currentEncounter) { case TYPE_BEASTS: { switch(encounterStage) { case 1: DoScriptText(SAY_STAGE_0_01, m_pInstance->GetCreature(NPC_TIRION)); cooldown = 22000; break; case 2: DoScriptText(SAY_STAGE_0_02, m_pInstance->GetCreature(NPC_TIRION)); cooldown = 4000; break; case 3: SummonToCBoss(NPC_GORMOK, 0, 100); cooldown = 1000; break; case 4: if (encounterCreature) encounterCreature->AI()->AttackStart(m_pInstance->GetRandomPlayerInMap()); cooldown = 5000; break; case 5: if (m_pInstance->GetInstanceSide() == INSTANCE_SIDE_ALI) DoScriptText(SAY_STAGE_0_03a, m_pInstance->GetCreature(NPC_WRYNN)); else DoScriptText(SAY_STAGE_0_03h, m_pInstance->GetCreature(NPC_GARROSH)); cooldown = isHeroic ? 174000 : REALLY_BIG_COOLDOWN; break; case 6: SummonToCBoss(NPC_DREADSCALE, NULL, 5100); DoScriptText(SAY_STAGE_0_04, m_pInstance->GetCreature(NPC_TIRION)); cooldown = 6000; break; case 7: if (encounterCreature) encounterCreature->AI()->AttackStart(m_pInstance->GetRandomPlayerInMap()); cooldown = 4000; break; case 8: { Player* randPlr = m_pInstance->GetRandomPlayerInMap(); if (!randPlr) break; encounterCreature2 = DoSpawnTocBoss(NPC_ACIDMAW, randPlr->GetPosition(), 0); if (!encounterCreature2) break; encounterCreature2->CastSpell(encounterCreature2, SPELL_EMERGE_ACIDMAW, false); cooldown = isHeroic ? 170000 + stepTimer->GetCustomValue() : REALLY_BIG_COOLDOWN; break; } case 9: SummonToCBoss(NPC_ICEHOWL, NULL, 3100); DoScriptText(SAY_STAGE_0_05, m_pInstance->GetCreature(NPC_TIRION)); cooldown = 4000; case 10: if (encounterCreature) encounterCreature->AI()->AttackStart(m_pInstance->GetRandomPlayerInMap()); cooldown = isHeroic ? 176000 + stepTimer->GetCustomValue() : REALLY_BIG_COOLDOWN; break; case 11: if (encounterCreature) encounterCreature->GetTimerMgr()->AddSpellToQueue(SPELL_BERSERK_NB); cooldown = REALLY_BIG_COOLDOWN; break; case 51: // outro DoScriptText(SAY_STAGE_0_06, m_pInstance->GetCreature(NPC_TIRION)); break; } break; } case TYPE_JARAXXUS: { switch(encounterStage) { case 1: { encounterCreature2 = m_pInstance->GetCreature(NPC_JARAXXUS); if (encounterCreature2 && m_pInstance->GetData(TYPE_JARAXXUS) == FAIL) { encounterCreature2->RemoveAurasDueToSpell(SPELL_JARAXXUS_CHAINS); encounterCreature2->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); encounterCreature2->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE); encounterCreature2->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE); ((ScriptedAI*)encounterCreature2->AI())->EnableAttack(true); DoScriptText(SAY_STAGE_1_AGGRO, encounterCreature2); encounterCreature2->AI()->AttackStart(m_pInstance->GetRandomPlayerInMap()); m_pInstance->SetData(TYPE_JARAXXUS, IN_PROGRESS); cooldown = REALLY_BIG_COOLDOWN; } else { DoScriptText(SAY_STAGE_1_01, m_pInstance->GetCreature(NPC_TIRION)); SummonToCBoss(NPC_FIZZLEBANG); cooldown = 2000; } break; } case 2: { if (!encounterCreature) break; encounterCreature->AddSplineFlag(SPLINEFLAG_WALKMODE); encounterCreature->GetMotionMaster()->MovePoint(POINT_MOVE, SpawnLoc[LOC_FIZZLE_END], false); uint32 timeToPoint = uint32(encounterCreature->GetPosition().GetDistance2d(SpawnLoc[LOC_FIZZLE_END])/0.0025f); m_TimerMgr->Cooldown(TIMER_DOOR_HANDLER, timeToPoint); cooldown = timeToPoint + 1000; break; } case 3: DoScriptText(SAY_STAGE_1_02, encounterCreature); cooldown = 11000; break; case 4: { DoScriptText(SAY_STAGE_1_03, encounterCreature); Coords sumPos = SpawnLoc[LOC_CENTER]; encounterCreature->SummonCreature(NPC_WILFRED_PORTAL_GROUND, sumPos, 1.5f*M_PI_F, TEMPSUMMON_TIMED_DESPAWN, 8000); cooldown = 2000; break; } case 5: { Coords sumPos = SpawnLoc[LOC_CENTER]; sumPos.z += 5.f; if (!(encounterCreature2 = encounterCreature->SummonCreature(NPC_TRIGGER, sumPos, 1.5f*M_PI_F, TEMPSUMMON_TIMED_DESPAWN, 6000))) break; encounterCreature2->SetFloatValue(OBJECT_FIELD_SCALE_X, 2.f); encounterCreature2->CastSpell(encounterCreature2, SPELL_WILFRED_PORTAL, false); cooldown = 3500; break; } case 6: DoScriptText(SAY_STAGE_1_04, encounterCreature); if (!(encounterCreature2 = DoSpawnTocBoss(NPC_JARAXXUS, encounterCreature2->GetPosition(), encounterCreature->GetOrientation()))) break; cooldown = 500; break; case 7: encounterCreature2->GetMotionMaster()->MovePoint(0, SpawnLoc[LOC_JAROXXUS_END]); cooldown = 2300; break; case 8: encounterCreature2->SetFacingToObject(encounterCreature); encounterCreature2->SetSummonPoint(encounterCreature->GetPositionX(), encounterCreature->GetPositionY(), encounterCreature->GetPositionZ(), encounterCreature->GetOrientation()); ((ScriptedAI*)encounterCreature2->AI())->SetCombatMovement(false); cooldown = 8500; break; case 9: DoScriptText(SAY_STAGE_1_05, encounterCreature2); cooldown = 7000; break; case 10: DoScriptText(SAY_STAGE_1_06, encounterCreature); cooldown = 800; break; case 11: encounterCreature2->CastSpell(encounterCreature, SPELL_FEL_LIGHTNING_IK, false); cooldown = 2000; break; case 12: DoScriptText(SAY_STAGE_1_07, m_pInstance->GetCreature(NPC_TIRION)); ((ScriptedAI*)encounterCreature2->AI())->SetCombatMovement(true); cooldown = 5000; break; case 13: encounterCreature2->RemoveAurasDueToSpell(SPELL_JARAXXUS_CHAINS); encounterCreature2->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); encounterCreature2->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE); encounterCreature2->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE); ((ScriptedAI*)encounterCreature2->AI())->EnableAttack(true); m_pInstance->SetData(TYPE_JARAXXUS, IN_PROGRESS); DoScriptText(SAY_STAGE_1_AGGRO, encounterCreature2); encounterCreature2->AI()->AttackStart(m_pInstance->GetRandomPlayerInMap()); cooldown = REALLY_BIG_COOLDOWN; break; case 51: //outro DoScriptText(SAY_STAGE_1_08, m_pInstance->GetCreature(NPC_TIRION)); cooldown = 15000; break; case 52: DoScriptText(SAY_STAGE_1_09, m_pInstance->GetCreature(NPC_GARROSH)); cooldown = 10000; break; case 53: DoScriptText(SAY_STAGE_1_10, m_pInstance->GetCreature(NPC_WRYNN)); cooldown = 7000; break; case 54: DoScriptText(SAY_STAGE_1_11, m_pInstance->GetCreature(NPC_TIRION)); cooldown = 5000; break; case 55: break; } break; } case TYPE_CRUSADERS: { switch(encounterStage) { case 1: DoScriptText(SAY_STAGE_2_01, m_pInstance->GetCreature(NPC_TIRION)); cooldown = 9000; break; case 2: if (m_pInstance->GetInstanceSide() == INSTANCE_SIDE_ALI) DoScriptText(SAY_STAGE_2_02h, m_pInstance->GetCreature(NPC_GARROSH)); else DoScriptText(SAY_STAGE_2_02a, m_pInstance->GetCreature(NPC_WRYNN)); cooldown = 17000; break; case 3: DoScriptText(SAY_STAGE_2_03, m_pInstance->GetCreature(NPC_TIRION)); cooldown = 5000; break; case 4: { uint32 spawnMask = 0; if (!(spawnMask = m_pInstance->GetData(TYPE_CHAMPION_SPAWN_MASK))) { typedef std::list<uint8> ChampionList; ChampionList healerList, dpsList, finalList; for(uint8 i = 0; i < CHAMPION_COUNT; ++i) { if (i == CHAMPION_R_DRUID || i == CHAMPION_H_PALADIN || i == CHAMPION_R_SHAMAN || i == CHAMPION_D_PRIEST) healerList.push_back(i); else dpsList.push_back(i); } for(uint8 h = 0; h < 2; ++h) { uint8 neededCount = h ? (is10Man ? 2 : 3) : (is10Man ? 4 : 7); ChampionList& refList = h ? healerList : dpsList; for (uint8 i = 0; i < neededCount; ++i) { ChampionList::iterator itr = refList.begin(); std::advance(itr, urand(0, refList.size()-1)); finalList.push_back(*itr); refList.erase(itr); } } for(ChampionList::iterator itr = finalList.begin(); itr != finalList.end(); ++itr) spawnMask |= (1 << *itr); m_pInstance->SetData(TYPE_CHAMPION_SPAWN_MASK, spawnMask); } encounterCreature = NULL; encounterCreature2 = NULL; AddNonCastTimer(TIMER_CUSTOM, 500, 2000); cooldown = REALLY_BIG_COOLDOWN; break; } case 5: { uint32 textId, npcId, faction; if (m_pInstance->GetInstanceSide() == INSTANCE_SIDE_ALI) { textId = SAY_STAGE_2_04h; npcId = NPC_GARROSH; faction = FACTION_HORDE; } else { textId = SAY_STAGE_2_04a; npcId = NPC_WRYNN; faction = FACTION_ALLIANCE; } DoScriptText(textId, m_pInstance->GetCreature(npcId)); CreatureList ChampionList; for(uint8 i = 0; i < CHAMPION_COUNT; ++i) GetCreatureListWithEntryInGrid(ChampionList, m_creature, FChampIDs[i][faction], DEFAULT_VISIBILITY_INSTANCE); stepTimer->SetValue(TIMER_VALUE_CUSTOM, 0); for(CreatureList::iterator itr = ChampionList.begin(); itr != ChampionList.end(); ++itr) { Creature* champ = *itr; if (!champ) continue; champ->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); ((ScriptedAI*)champ->AI())->EnableAttack(true); } cooldown = REALLY_BIG_COOLDOWN; break; } case 51: // outro DoScriptText(SAY_STAGE_2_06, m_pInstance->GetCreature(NPC_TIRION)); cooldown = 5000; break; case 52: { uint32 chestId = 0; m_pInstance->DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, SPELL_CHAMPIONS); if (getMSTimeDiff(stepTimer->GetCustomValue(), getMSTime() < 73000)) // kill under 60 seconds m_pInstance->DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, SPELL_CHAMPIONS_MINUTE); switch(m_dDifficulty) { case RAID_DIFFICULTY_10MAN_NORMAL: chestId = GO_CRUSADERS_CACHE_10; break; case RAID_DIFFICULTY_25MAN_NORMAL: chestId = GO_CRUSADERS_CACHE_25; break; case RAID_DIFFICULTY_10MAN_HEROIC: chestId = GO_CRUSADERS_CACHE_10_H; break; case RAID_DIFFICULTY_25MAN_HEROIC: chestId = GO_CRUSADERS_CACHE_25_H; break; default: break; } if (chestId) m_creature->SummonGameobject(chestId, SpawnLoc[LOC_CENTER], M_PI_F*1.5f, 604800); break; } } break; } case TYPE_VALKIRIES: { switch(encounterStage) { case 1: DoScriptText(SAY_STAGE_3_01, m_pInstance->GetCreature(NPC_TIRION)); cooldown = 12000; break; case 2: SummonToCBoss(NPC_LIGHTBANE, NPC_DARKBANE); for(uint8 i = 0; i < 4; ++i) DoSpawnTocBoss(i/2 ? NPC_LIGHT_ESSENCE : NPC_DARK_ESSENCE, SpawnLoc[LOC_D_ESSENCE_1+i], 0); cooldown = 2000; break; case 3: { if (!encounterCreature || !encounterCreature2) break; DoScriptText(SAY_STAGE_3_02, m_pInstance->GetCreature(NPC_TIRION)); uint32 travelTime[2]; for(uint8 second = 0; second < 2; ++second) { Creature* crt = second ? encounterCreature2 : encounterCreature; ((ScriptedAI*)crt->AI())->EnableAttack(false); PointPath path; path.resize(3); path.set(0, crt->GetPosition()); path.set(1, second ? SpawnLoc[LOC_D_VALKYR_1] : SpawnLoc[LOC_L_VALKYR_1]); path.set(2, second ? SpawnLoc[LOC_D_VALKYR_2] : SpawnLoc[LOC_L_VALKYR_2]); //path.set(3, second ? SpawnLoc[LOC_D_VALKYR_3] : SpawnLoc[LOC_L_VALKYR_3]); travelTime[second] = path.GetTotalLength()/(crt->GetSpeed(MOVE_RUN)*0.001f); crt->GetMotionMaster()->Clear(false, true); crt->ChargeMonsterMove(path, SPLINETYPE_FACINGANGLE, crt->GetSplineFlags(), travelTime[second], M_PI_F*1.5f); } cooldown = (travelTime[0] > travelTime[1] ? travelTime[0] : travelTime[1]) + 5000; break; } case 4: { for(uint8 second = 0; second < 2; ++second) { Creature* crt = second ? encounterCreature2 : encounterCreature; ((ScriptedAI*)crt->AI())->EnableAttack(true); crt->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); } cooldown = REALLY_BIG_COOLDOWN; break; } case 51: // outro if (m_pInstance->GetInstanceSide() == INSTANCE_SIDE_ALI) DoScriptText(SAY_STAGE_3_03a, m_pInstance->GetCreature(NPC_WRYNN)); else DoScriptText(SAY_STAGE_3_03h, m_pInstance->GetCreature(NPC_GARROSH)); cooldown = 5000; break; case 52: break; } break; } case TYPE_LICH_KING: { switch(encounterStage) { case 1: DoScriptText(SAY_STAGE_4_01, m_pInstance->GetCreature(NPC_TIRION)); cooldown = 19000; break; case 2: encounterCreature = DoSpawnTocBoss(NPC_LICH_KING, SpawnLoc[LOC_BACKDOOR], M_PI_F*1.5f); encounterCreature->SetFloatValue(OBJECT_FIELD_SCALE_X, 0.1f); encounterCreature->SetVisibility(VISIBILITY_OFF); m_pInstance->SetData(TYPE_LICH_KING, IN_PROGRESS); cooldown = 500; break; case 3: DoScriptText(SAY_STAGE_4_02, encounterCreature); cooldown = 7000; break; case 4: if (!(encounterCreature2 = DoSpawnTocBoss(NPC_TRIGGER, SpawnLoc[LOC_LICH_KING_S], M_PI_F*1.5f, false))) break; encounterCreature2->SetFloatValue(OBJECT_FIELD_SCALE_X, 1.8f); encounterCreature2->CastSpell(encounterCreature2, SPELL_LK_GATE, false); cooldown = 4000; break; case 5: encounterCreature->SetFloatValue(OBJECT_FIELD_SCALE_X, 1.f); m_pInstance->instance->CreatureRelocation(encounterCreature, SpawnLoc[LOC_LICH_KING_S], M_PI_F*1.5f); cooldown = 500; break; case 6: { PointPath path; path.resize(2); path.set(0, SpawnLoc[LOC_LICH_KING_S]); path.set(1, SpawnLoc[LOC_LICH_KING_E]); encounterCreature->GetMotionMaster()->Clear(false, true); encounterCreature->GetMotionMaster()->MoveIdle(); encounterCreature->ChargeMonsterMove(path, SPLINETYPE_NORMAL, SPLINEFLAG_WALKMODE, path.GetTotalLength()/0.0025f); cooldown = 3000; break; } case 7: DoScriptText(SAY_STAGE_4_03, m_pInstance->GetCreature(NPC_TIRION)); cooldown = 8000; break; case 8: DoScriptText(SAY_STAGE_4_04, encounterCreature); encounterCreature->HandleEmote(EMOTE_ONESHOT_LAUGH); cooldown = 13000; break; case 9: encounterCreature->HandleEmote(EMOTE_ONESHOT_EXCLAMATION); cooldown = 3000; break; case 10: encounterCreature->HandleEmote(EMOTE_ONESHOT_KNEEL); cooldown = 1000; break; case 11: encounterCreature->CastSpell(encounterCreature, SPELL_LK_NOVA, false); cooldown = 500; break; case 12: { encounterCreature->SetVisibility(VISIBILITY_OFF); m_pInstance->instance->CreatureRelocation(encounterCreature, SpawnLoc[LOC_BACKDOOR], M_PI_F*1.5f); encounterCreature->SendMonsterMove(SpawnLoc[LOC_BACKDOOR].x, SpawnLoc[LOC_BACKDOOR].y, SpawnLoc[LOC_BACKDOOR].z, SPLINETYPE_NORMAL, encounterCreature->GetSplineFlags(), 1); Map::PlayerList const &PlayerList = m_pInstance->instance->GetPlayers(); if (!PlayerList.isEmpty()) for (Map::PlayerList::const_iterator iter = PlayerList.begin(); iter != PlayerList.end(); ++iter) if (Player* plr = iter->getSource()) plr->KnockBackFrom(plr, 2, 25); if (GameObject* pFloor = m_pInstance->GetGameObject(GO_ARGENT_COLISEUM_FLOOR)) { pFloor->TakenDamage(100, m_creature); pFloor->TakenDamage(100, m_creature); } cooldown = 2000; break; } case 13: DoScriptText(SAY_STAGE_4_05, encounterCreature); cooldown = 10000; break; case 14: { m_pInstance->SetData(TYPE_LICH_KING, DONE); encounterCreature->ForcedDespawn(); if (GameObject* pFloor = m_pInstance->GetGameObject(GO_ARGENT_COLISEUM_FLOOR)) pFloor->Rebuild(m_creature); break; } } break; } case TYPE_ANUBARAK: { switch(encounterStage) { case 51: if (!(encounterCreature = DoSpawnTocBoss(NPC_OUTRO_TIRION, SpawnLoc[LOC_O_TIRION_S], 0))) break; if (!(encounterCreature2 = DoSpawnTocBoss(NPC_OUTRO_ARGENT_MAGE, SpawnLoc[LOC_O_MAGE_S], 0))) break; encounterCreature->GetMotionMaster()->MovePoint(0, SpawnLoc[LOC_O_TIRION_E], false); encounterCreature2->GetMotionMaster()->MovePoint(0, SpawnLoc[LOC_O_MAGE_E], false); cooldown = 10000; break; case 52: DoScriptText(SAY_STAGE_4_06, encounterCreature); cooldown = 15000; break; case 53: if (!isHeroic || m_pInstance->GetData(TYPE_COUNTER) >= 50) break; DoScriptText(SAY_STAGE_4_07, encounterCreature); cooldown = 5000; break; case 54: { uint32 chestId = 0; uint32 attempts = m_pInstance->GetData(TYPE_COUNTER); if (isInRange(1, attempts, 24)) chestId = is10Man ? GO_TRIBUTE_CHEST_10H_1 : GO_TRIBUTE_CHEST_25H_1; else if (isInRange(25, attempts, 44)) chestId = is10Man ? GO_TRIBUTE_CHEST_10H_25 : GO_TRIBUTE_CHEST_25H_25; else if (isInRange(45, attempts, 49)) chestId = is10Man ? GO_TRIBUTE_CHEST_10H_45 : GO_TRIBUTE_CHEST_25H_45; else if (attempts == 50) chestId = is10Man ? GO_TRIBUTE_CHEST_10H_50 : GO_TRIBUTE_CHEST_25H_50; if (chestId) m_creature->SummonGameobject(chestId, SpawnLoc[LOC_UNDERGROUND], 0, 604800); break; } } break; } default: break; } cat_log("toc_announcer: Phase updating: Handling current encounter %u in encounter stage %u and setting cooldown to %u", currentEncounter, encounterStage, cooldown); if (cooldown) stepTimer->Cooldown(cooldown); else Reset(); } // open and closes doors if (SpellTimer* doorTimer = m_TimerMgr->GetState(TIMER_DOOR_HANDLER)) { uint64 doorGuid = m_pInstance->GetData64(GO_MAIN_GATE_DOOR); if (!doorTimer->GetCustomValue()) { m_pInstance->OpenDoor(doorGuid); doorTimer->SetValue(TIMER_VALUE_CUSTOM, true); } else { m_pInstance->CloseDoor(doorGuid); doorTimer->SetValue(TIMER_VALUE_DELETE_AT_FINISH, true); } } // runaway of announcer if (SpellTimer* runawayTimer = m_TimerMgr->GetState(TIMER_RUNAWAY)) { if (GameObject* go = m_pInstance->GetGameObject(GO_GATE_EAST)) { Coords coord = go->GetPosition(); m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE); m_creature->SetSpeedRate(MOVE_RUN, 1.2f, true); m_creature->GetMotionMaster()->MovePoint(POINT_MOVE, coord.x, coord.y, coord.z, false); } runawayTimer->SetValue(TIMER_VALUE_DELETE_AT_FINISH, true); } // handling of custom timer in the event if (SpellTimer* customTimer = m_TimerMgr->GetState(TIMER_CUSTOM)) { if (currentEncounter == TYPE_CRUSADERS) { uint32 timerCustom = customTimer->GetCustomValue(); uint32 spawnMask = m_pInstance->GetData(TYPE_CHAMPION_SPAWN_MASK); uint8 faction = m_pInstance->GetInstanceSide() == INSTANCE_SIDE_ALI ? FACTION_HORDE : FACTION_ALLIANCE; const Coords Spawn1 = faction == FACTION_ALLIANCE ? SpawnLoc[LOC_FCH_A_SPAWN_1] : SpawnLoc[LOC_FCH_H_SPAWN_1]; const Coords Spawn2 = faction == FACTION_ALLIANCE ? SpawnLoc[LOC_FCH_A_SPAWN_2] : SpawnLoc[LOC_FCH_H_SPAWN_2]; const Coords Jump1 = faction == FACTION_ALLIANCE ? SpawnLoc[LOC_FCH_A_JUMP_1] : SpawnLoc[LOC_FCH_H_JUMP_1]; const Coords Jump2 = faction == FACTION_ALLIANCE ? SpawnLoc[LOC_FCH_A_JUMP_2] : SpawnLoc[LOC_FCH_H_JUMP_2]; Coords Location = faction == FACTION_ALLIANCE ? SpawnLoc[LOC_FCH_A_MOVE] : SpawnLoc[LOC_FCH_H_MOVE]; if (encounterCreature2) { int32 champOrder = customValue-2; int32 x_coef = champOrder%2 ? 1 : -1; int32 y_coef = champOrder/2 - (is10Man ? 1 : 2); if (faction == FACTION_HORDE) { x_coef *= -1; y_coef *= -1; } Location.x += x_coef*2.5f; Location.y += y_coef*5.f; PointPath path; path.resize(2); //path.set(0, champOrder%2 ? Jump2 : Jump1); path.set(0, encounterCreature2->GetPosition()); path.set(1, Location); uint32 travelTime = path.GetTotalLength()/0.0025f; encounterCreature2->GetMotionMaster()->Clear(false, true); encounterCreature2->ChargeMonsterMove(path, SPLINETYPE_FACINGANGLE, SPLINEFLAG_WALKMODE, travelTime, faction == FACTION_ALLIANCE ? M_PI_F : 0); encounterCreature2 = NULL; // if is last one set phase handler to travelTime if (timerCustom == CHAMPION_COUNT && !encounterCreature) { customTimer->SetValue(TIMER_VALUE_DELETE_AT_FINISH, true); m_TimerMgr->Cooldown(TIMER_PHASE_HANDLING, travelTime); return; } } if (encounterCreature) { uint32 champOrder = customValue-1; const Coords& jump = champOrder%2 ? Jump2 : Jump1; encounterCreature->GetMotionMaster()->Clear(false, true); encounterCreature->GetMotionMaster()->MoveIdle(); encounterCreature->TrajMonsterMove(jump.x, jump.y, jump.z, false, 80, 1000); encounterCreature2 = encounterCreature; encounterCreature = NULL; } for(uint8 i = timerCustom; i < CHAMPION_COUNT; ++i) { customTimer->SetValue(TIMER_VALUE_CUSTOM, i+1); if (spawnMask & (1 << i)) { const Coords& spawn = customValue%2 ? Spawn2 : Spawn1; encounterCreature = DoSpawnTocBoss(FChampIDs[i][faction], spawn, 0); ((ScriptedAI*)encounterCreature->AI())->EnableAttack(false); break; } } ++customValue; } else customTimer->SetValue(TIMER_VALUE_DELETE_AT_FINISH, true); } }
void DoIntro() { Creature *pMadrigosa = (Creature*)me->GetUnit(pInstance->GetData64(DATA_MADRIGOSA)); if (!pMadrigosa) return; switch (IntroPhase) { case 0: DoScriptText(YELL_MADR_ICE_BARRIER, pMadrigosa); pMadrigosa->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); for (uint8 i = 0; i < 8; ++i) pMadrigosa->SetSpeed(UnitMoveType(i), 2.5); pMadrigosa->GetMotionMaster()->MovePoint(1, MADRI_FLY_X, MADRI_FLY_Y, MADRI_FLY_Z); IntroPhaseTimer = 6500; ++IntroPhase; break; case 1: pInstance->SetData(DATA_BRUTALLUS_INTRO_EVENT, IN_PROGRESS); pMadrigosa->SetLevitate(false); pMadrigosa->SetWalk(true); pMadrigosa->HandleEmoteCommand(EMOTE_ONESHOT_LAND); IntroPhaseTimer = 2500; ++IntroPhase; break; case 2: pMadrigosa->SendHeartBeat(); DoScriptText(YELL_MADR_INTRO, pMadrigosa); IntroPhaseTimer = 5000; ++IntroPhase; break; case 3: float x, y, z; pMadrigosa->GetMap()->CreatureRelocation((Creature*)pMadrigosa, MADRI_FLY_X, MADRI_FLY_Y, MADRI_FLY_Z, me->GetOrientation()); me->SetInFront(pMadrigosa); pMadrigosa->SetInFront(me); DoScriptText(YELL_INTRO, me); IntroPhaseTimer = 6000; ++IntroPhase; break; case 4: pMadrigosa->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); DoStartMovement(pMadrigosa); pMadrigosa->GetMotionMaster()->MoveChase(me); me->Attack(pMadrigosa, true); pMadrigosa->Attack(me, true); IntroPhaseTimer = 7000; ++IntroPhase; break; case 5: pMadrigosa->CastSpell(me, SPELL_INTRO_FROST_BREATH, false); me->CastSpell(me, SPELL_INTRO_FROST_BREATH, true); IntroPhaseTimer = 2500; ++IntroPhase; break; case 6: me->GetMotionMaster()->MoveIdle(); pMadrigosa->SetLevitate(true); pMadrigosa->GetPosition(x, y, z); pMadrigosa->GetMotionMaster()->MovePoint(2, x, y, z+15); pMadrigosa->setHover(true); IntroPhaseTimer = 4500; ++IntroPhase; case 7: pMadrigosa->SetInFront(me); pMadrigosa->CastSpell(me, SPELL_INTRO_FROST_BLAST, false); me->CastSpell(me, SPELL_INTRO_FROST_BLAST, true); DoScriptText(YELL_MADR_ICE_BLOCK, pMadrigosa); IntroFrostBoltTimer = 500; IntroPhaseTimer = 10000; ++IntroPhase; break; case 8: DoScriptText(YELL_INTRO_BREAK_ICE, me); IntroPhaseTimer = 2000; ++IntroPhase; break; case 9: me->GetMotionMaster()->MoveIdle(); me->AttackStop(); pMadrigosa->setHover(false); pMadrigosa->SetLevitate(false); pMadrigosa->SetWalk(true); pMadrigosa->HandleEmoteCommand(EMOTE_ONESHOT_LAND); pMadrigosa->SendHeartBeat(); IntroPhaseTimer = 1000; ++IntroPhase; break; case 10: pMadrigosa->GetMotionMaster()->MoveIdle(); IntroPhaseTimer = 2500; ++IntroPhase; break; case 11: pMadrigosa->GetMap()->CreatureRelocation((Creature*)pMadrigosa, MADRI_FLY_X, MADRI_FLY_Y, MADRI_FLY_Z, me->GetOrientation()); pMadrigosa->GetMotionMaster()->MoveIdle(); IntroPhaseTimer = 2000; ++IntroPhase; break; case 12: me->GetMotionMaster()->MoveIdle(); pMadrigosa->CastSpell(me, SPELL_INTRO_ENCAPSULATE, false); DoScriptText(YELL_MADR_TRAP, pMadrigosa); IntroPhaseTimer = 1000; ++IntroPhase; break; case 13: me->GetPosition(x, y, z); me->GetMotionMaster()->MovePoint(1, x-6, y-15, z+10); me->SetInFront(pMadrigosa); IntroPhaseTimer = 8000; ++IntroPhase; break; case 14: me->RemoveAurasDueToSpell(44883); pMadrigosa->InterruptNonMeleeSpells(false); pMadrigosa->GetMotionMaster()->MoveIdle(); DoScriptText(YELL_INTRO_CHARGE, me); me->SetInFront(pMadrigosa); me->GetPosition(x, y, z); me->GetMotionMaster()->MoveFall(); IntroPhaseTimer = 3500; ++IntroPhase; break; case 15: for(uint8 i = 0; i < 8; ++i) me->SetSpeed(UnitMoveType(i), 10.0); me->GetMotionMaster()->MoveCharge(MADRI_FLY_X-5, MADRI_FLY_Y-15, MADRI_FLY_Z); AddSpellToCast((Unit*)NULL, SPELL_INTRO_CHARGE); IntroPhaseTimer = 1000; ++IntroPhase; break; case 16: DoScriptText(YELL_MADR_DEATH, pMadrigosa); pMadrigosa->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH); pMadrigosa->SetFlag(UNIT_DYNAMIC_FLAGS, (UNIT_DYNFLAG_DEAD | UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_PACIFIED)); pMadrigosa->CombatStop(); pMadrigosa->DeleteThreatList(); pMadrigosa->setFaction(35); me->CombatStop(); me->RemoveFlag(UNIT_FIELD_FLAGS, (UNIT_FLAG_PET_IN_COMBAT | UNIT_FLAG_PVP_ATTACKABLE)); IntroPhaseTimer = 4000; ++IntroPhase; break; case 17: if(pInstance) me->SetFacingToObject(GameObject::GetGameObject(*me, pInstance->GetData64(DATA_BRUTALLUS_TRIGGER))); for(uint8 i = 0; i < 8; ++i) me->SetSpeed(UnitMoveType(i), 2.0); IntroPhaseTimer = 6000; ++IntroPhase; break; case 18: DoScriptText(YELL_INTRO_KILL_MADRIGOSA, me); IntroPhaseTimer = 8000; ++IntroPhase; break; case 19: DoScriptText(YELL_INTRO_TAUNT, me); AddSpellToCast(me, SPELL_INTRO_BREAK_ICE); if(pInstance) pInstance->SetData(DATA_BRUTALLUS_INTRO_EVENT, DONE); else return; if(Unit *pTrigger = me->GetUnit(pInstance->GetData64(DATA_BRUTALLUS_TRIGGER))) pTrigger->CastSpell((Unit*)NULL, SPELL_INTRO_BREAK_ICE_KNOCKBACK, false); IntroPhaseTimer = 2000; ++IntroPhase; break; case 20: EnterEvadeMode(); ++IntroPhase; break; } }