//set spawn dist of creature static bool HandleNpcSetSpawnDistCommand(ChatHandler* handler, const char* args) { if (!*args) return false; float option = (float)(atof((char*)args)); if (option < 0.0f) { handler->SendSysMessage(LANG_BAD_VALUE); return false; } MovementGeneratorType mtype = IDLE_MOTION_TYPE; if (option >0.0f) mtype = RANDOM_MOTION_TYPE; Creature *pCreature = handler->getSelectedCreature(); uint32 u_guidlow = 0; if (pCreature) u_guidlow = pCreature->GetDBTableGUIDLow(); else return false; pCreature->SetRespawnRadius((float)option); pCreature->SetDefaultMovementType(mtype); pCreature->GetMotionMaster()->Initialize(); if (pCreature->isAlive()) // dead creature will reset movement generator at respawn { pCreature->setDeathState(JUST_DIED); pCreature->Respawn(); } WorldDatabase.PExecute("UPDATE creature SET spawndist=%f, MovementType=%i WHERE guid=%u",option,mtype,u_guidlow); handler->PSendSysMessage(LANG_COMMAND_SPAWNDIST,option); return true; }
void NextPhase() { if (currentPhase == PHASE_NONE) { pInstance->SetData(DATA_GORTOK_PALEHOOF_EVENT, IN_PROGRESS); me->SummonCreature(MOB_STASIS_CONTROLLER,moveLocs[5].x,moveLocs[5].y,moveLocs[5].z,0,TEMPSUMMON_CORPSE_DESPAWN); } Phase move = PHASE_NONE; if (AddCount >= DUNGEON_MODE(2,4)) move = PHASE_GORTOK_PALEHOOF; else { //select random not yet defeated add uint8 next = urand(0,3); for (uint8 i=0; i < 16; i++) { if (!DoneAdds[i%4] && next == 0) { move = (Phase)(i%4); break; } else if (!DoneAdds[i%4] && next > 0) --next; } ++AddCount; DoneAdds[move] = true; move = (Phase)(move%4); } //send orb to summon spot Creature *pOrb = Unit::GetCreature((*me), pInstance ? pInstance->GetData64(DATA_MOB_ORB) : 0); if (pOrb && pOrb->isAlive()) { if (currentPhase == PHASE_NONE) pOrb->CastSpell(me,SPELL_ORB_VISUAL,true); pOrb->GetMotionMaster()->MovePoint(move,moveLocs[move].x,moveLocs[move].y,moveLocs[move].z); } currentPhase = move; }
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); m_isArrivalDone = false; creature.AddUnitState(UNIT_STAT_ROAMING_MOVE); Movement::MoveSplineInit init(creature); init.MoveTo(node->x, node->y, node->z, true); init.SetWalk(!node->run); init.Launch(); //Call for creature group update if(creature.GetFormation() && creature.GetFormation()->getLeader() == &creature) creature.GetFormation()->LeaderMoveTo(node->x, node->y, node->z); return true; }
void CreatureGroup::LeaderMoveTo(float x, float y, float z) { //! To do: This should probably get its own movement generator or use WaypointMovementGenerator. //! If the leader's path is known, member's path can be plotted as well using formation offsets. if (!m_leader) return; float pathangle = atan2(m_leader->GetPositionY() - y, m_leader->GetPositionX() - x); for (CreatureGroupMemberType::iterator itr = m_members.begin(); itr != m_members.end(); ++itr) { Creature* member = itr->first; if (member == m_leader || !member->isAlive() || member->getVictim()) continue; float angle = itr->second->follow_angle; float dist = itr->second->follow_dist; float dx = x + std::cos(angle + pathangle) * dist; float dy = y + std::sin(angle + pathangle) * dist; float dz = z; Trinity::NormalizeMapCoord(dx); Trinity::NormalizeMapCoord(dy); member->UpdateGroundPositionZ(dx, dy, dz); if (member->IsWithinDist(m_leader, dist + MAX_DESYNC)) member->SetUnitMovementFlags(m_leader->GetUnitMovementFlags()); else member->SetWalk(false); member->GetMotionMaster()->MovePoint(0, dx, dy, dz); member->SetHomePosition(dx, dy, dz, pathangle); } }
bool GhostOPlasmEventStep(GhostOPlasmEvent& eventData) { if (eventData.despawnTimer > 180000) { for (auto guid : eventData.summonedMagrami) if (Creature* magrami = instance->GetCreature(guid)) if (magrami->isAlive()) // dont despawn corpses with loot magrami->ForcedDespawn(); if (GameObject* go = instance->GetGameObject(eventData.guid)) go->AddObjectToRemoveList(); // TODO: Establish rules for despawning temporary GOs that were used in their lifetime (buttons for example) return false; } if (GameObject* go = instance->GetGameObject(eventData.guid)) { if (eventData.despawnTimer / 15000 >= eventData.phaseCounter) { float x, y, z; go->GetPosition(x, y, z); // do some urand radius shenanigans to spawn it further and make it walk to go using doing X and Y yourself and using function in MAP to get proper Z uint32 random = urand(0, 35); float xR = x + random, yR = y + (40 - random), zR = z; instance->GetHeightInRange(xR, yR, zR); Creature* creature = go->SummonCreature(NPC_MAGRAMI_SPECTRE, xR, yR, zR, 0, TEMPSPAWN_TIMED_OOC_OR_DEAD_DESPAWN, 180000); // add more timed logic here instance->GetReachableRandomPointOnGround(x, y, z, 10.0f); // get position to which spectre will walk eventData.phaseCounter++; eventData.summonedMagrami.push_back(creature->GetObjectGuid()); creature->GetMotionMaster()->MovePoint(1, x, y, z); } return true; } else return false; }
void HandleBugs(uint32 diff) { if (BugsTimer < diff || Abuse_Bug_Timer < diff) { Creature *c = RespawnNearbyBugsAndGetOne(IAmVeklor() ? 15316 : 15317); if (Abuse_Bug_Timer < diff) { if (c) { CastSpellOnBug(c); if (m_creature->getVictim()) { c->Attack(m_creature->getVictim(), false); c->GetMotionMaster()->MoveChase(m_creature->getVictim()); } Abuse_Bug_Timer = urand(10000, 17000); } else { Abuse_Bug_Timer = 1000; } } else { Abuse_Bug_Timer -= diff; } BugsTimer = 2000; } else { BugsTimer -= diff; Abuse_Bug_Timer -= diff; } }
void instance_stratholme::OnCreatureDeath(Creature* pCreature) { switch (pCreature->GetEntry()) { case NPC_BARONESS_ANASTARI: SetData(TYPE_BARONESS, DONE); break; case NPC_MALEKI_THE_PALLID: SetData(TYPE_PALLID, DONE); break; case NPC_NERUBENKAN: SetData(TYPE_NERUB, DONE); break; case NPC_RAMSTEIN: SetData(TYPE_RAMSTEIN, DONE); break; case NPC_BARON: SetData(TYPE_BARON, DONE); break; case NPC_THUZADIN_ACOLYTE: for (uint8 i = 0; i < MAX_ZIGGURATS; ++i) { if (m_alZigguratAcolyteGUID[i].empty()) continue; // nothing to do anymore for this ziggurat m_alZigguratAcolyteGUID[i].remove(pCreature->GetGUID()); if (m_alZigguratAcolyteGUID[i].empty()) { // A random zone yell after one is cleared int32 aAnnounceSay[MAX_ZIGGURATS] = {SAY_ANNOUNCE_ZIGGURAT_1, SAY_ANNOUNCE_ZIGGURAT_2, SAY_ANNOUNCE_ZIGGURAT_3}; if (Creature* pAnnouncer = instance->GetCreature(m_uiAcolyteAnnouncerGUID)) DoScriptText(aAnnounceSay[i], pAnnouncer); // Kill Crystal if (Creature* pCrystal = instance->GetCreature(m_auiCrystalSortedGUID[i])) pCrystal->DealDamage(pCrystal, pCrystal->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); switch (i) { case 0: SetData(TYPE_BARONESS, SPECIAL); break; case 1: SetData(TYPE_NERUB, SPECIAL); break; case 2: SetData(TYPE_PALLID, SPECIAL); break; } } } break; case NPC_ABOM_BILE: case NPC_ABOM_VENOM: // Start Slaughterhouse Event SetData(TYPE_RAMSTEIN, SPECIAL); break; case NPC_MINDLESS_UNDEAD: m_luiUndeadGUIDs.remove(pCreature->GetGUID()); if (m_luiUndeadGUIDs.empty()) { // Let the black Guards move out of the citadel for (std::list<uint64>::const_iterator itr = m_luiGuardGUIDs.begin(); itr != m_luiGuardGUIDs.end(); ++itr) { Creature* pGuard = instance->GetCreature(*itr); if (pGuard && pGuard->isAlive() && !pGuard->isInCombat()) { float fX, fY, fZ; pGuard->GetRandomPoint(sStratholmeLocation[5].m_fX, sStratholmeLocation[5].m_fY, sStratholmeLocation[5].m_fZ, 10.0f, fX, fY, fZ); pGuard->GetMotionMaster()->MovePoint(0, fX, fY, fZ); } } } break; case NPC_BLACK_GUARD: m_luiGuardGUIDs.remove(pCreature->GetGUID()); if (m_luiGuardGUIDs.empty()) { if (Creature* pBaron = instance->GetCreature(m_uiBaronGUID)) DoScriptText(SAY_UNDEAD_DEFEAT, pBaron); DoUseDoorOrButton(m_auiRivendareDoorGUID); } break; } }
void instance_stratholme::SetData(uint32 uiType, uint32 uiData) { // TODO: Remove the hard-coded indexes from array accessing switch(uiType) { case TYPE_BARON_RUN: switch(uiData) { case IN_PROGRESS: if (m_auiEncounter[uiType] == IN_PROGRESS || m_auiEncounter[uiType] == FAIL) break; if (Creature* pBaron = instance->GetCreature(m_uiBaronGUID)) DoScriptText(SAY_ANNOUNCE_RUN_START, pBaron); m_uiBaronRunTimer = 45*MINUTE*IN_MILLISECONDS; debug_log("SD2: Instance Stratholme: Baron run in progress."); break; case FAIL: //may add code to remove aura from players, but in theory the time should be up already and removed. break; case DONE: m_uiBaronRunTimer = 0; break; } m_auiEncounter[uiType] = uiData; break; case TYPE_BARONESS: case TYPE_NERUB: case TYPE_PALLID: m_auiEncounter[uiType] = uiData; if (uiData == DONE) { DoSortZiggurats(); DoUseDoorOrButton(m_auiZigguratGUID[uiType - TYPE_BARONESS]); } if (uiData == SPECIAL) StartSlaugtherSquare(); break; case TYPE_RAMSTEIN: if (uiData == SPECIAL) { if (m_auiEncounter[uiType] != SPECIAL && m_auiEncounter[uiType] != DONE) { m_uiSlaugtherSquareTimer = 20000; // TODO - unknown, also possible that this is not the very correct place.. DoUseDoorOrButton(m_uiPortGauntletGUID); m_bIsSlaughterhouseGateOpened = false; } uint32 uiCount = m_sAbomnationGUID.size(); for(std::set<uint64>::iterator itr = m_sAbomnationGUID.begin(); itr != m_sAbomnationGUID.end();) { if (Creature* pAbom = instance->GetCreature(*itr)) { ++itr; if (!pAbom->isAlive()) --uiCount; } else { // Remove obsolete guid from set and decrement count m_sAbomnationGUID.erase(itr++); --uiCount; } } if (!uiCount) { // Old Comment: a bit itchy, it should close m_auiRamsteinDoorGUID door after 10 secs, but it doesn't. skipping it for now. // However looks like that this door is no more closed DoUseDoorOrButton(m_auiRamsteinDoorGUID); // No more handlng of Abomnations m_uiSlaugtherSquareTimer = 0; if (Creature* pBaron = instance->GetCreature(m_uiBaronGUID)) { DoScriptText(SAY_ANNOUNCE_RAMSTEIN, pBaron); if (Creature* pRamstein = pBaron->SummonCreature(NPC_RAMSTEIN, sStratholmeLocation[2].m_fX, sStratholmeLocation[2].m_fY, sStratholmeLocation[2].m_fZ, sStratholmeLocation[2].m_fO, TEMPSUMMON_DEAD_DESPAWN, 0)) pRamstein->GetMotionMaster()->MovePoint(0, sStratholmeLocation[3].m_fX, sStratholmeLocation[3].m_fY, sStratholmeLocation[3].m_fZ); debug_log("SD2: Instance Stratholme - Slaugther event: Ramstein spawned."); } } else debug_log("SD2: Instance Stratholme - Slaugther event: %u Abomnation left to kill.", uiCount); } // After fail aggroing Ramstein means wipe on Ramstein, so close door again if (uiData == IN_PROGRESS && m_auiEncounter[uiType] == FAIL) { DoUseDoorOrButton(m_uiPortGauntletGUID); m_bIsSlaughterhouseGateOpened = false; } if (uiData == DONE) { // Open side gate and start summoning skeletons DoUseDoorOrButton(m_uiPortSlaughterGateGUID); // use this timer as a bool just to start summoning m_uiMindlessSummonTimer = 500; m_uiMindlessCount = 0; m_luiUndeadGUIDs.clear(); // Summon 5 guards if (Creature* pBaron = instance->GetCreature(m_uiBaronGUID)) { for(uint8 i = 0; i < 5; ++i) { float fX, fY, fZ; pBaron->GetRandomPoint(sStratholmeLocation[6].m_fX, sStratholmeLocation[6].m_fY, sStratholmeLocation[6].m_fZ, 5.0f, fX, fY, fZ); if (Creature* pTemp = pBaron->SummonCreature(NPC_BLACK_GUARD, sStratholmeLocation[6].m_fX, sStratholmeLocation[6].m_fY, sStratholmeLocation[6].m_fZ, sStratholmeLocation[6].m_fO, TEMPSUMMON_DEAD_DESPAWN, 0)) m_luiGuardGUIDs.push_back(pTemp->GetGUID()); } debug_log("SD2: Instance Stratholme - Slaugther event: Summoned 5 guards."); } } // Open Door again and stop Abomnation if (uiData == FAIL && m_auiEncounter[uiType] != FAIL) { DoUseDoorOrButton(m_uiPortGauntletGUID); m_bIsSlaughterhouseGateOpened = true; m_uiSlaugtherSquareTimer = 0; // Let already moving Abomnations stop for (std::set<uint64>::iterator itr = m_sAbomnationGUID.begin(); itr != m_sAbomnationGUID.end(); ++itr) { Creature* pAbom = instance->GetCreature(*itr); if (pAbom && pAbom->GetMotionMaster()->GetCurrentMovementGeneratorType() == POINT_MOTION_TYPE) pAbom->GetMotionMaster()->MovementExpired(); } } m_auiEncounter[uiType] = uiData; break; case TYPE_BARON: if (uiData == IN_PROGRESS) { // Reached the Baron within time-limit if (m_auiEncounter[TYPE_BARON_RUN] == IN_PROGRESS) SetData(TYPE_BARON_RUN, DONE); // Close Slaughterhouse door if needed if (m_bIsSlaughterhouseGateOpened) { DoUseDoorOrButton(m_uiPortGauntletGUID); m_bIsSlaughterhouseGateOpened = false; } } if (uiData == DONE) { if (m_auiEncounter[TYPE_BARON_RUN] == DONE) { Map::PlayerList const& players = instance->GetPlayers(); for(Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) { if (Player* pPlayer = itr->getSource()) { if (pPlayer->HasAura(SPELL_BARON_ULTIMATUM)) pPlayer->RemoveAurasDueToSpell(SPELL_BARON_ULTIMATUM); if (pPlayer->GetQuestStatus(QUEST_DEAD_MAN_PLEA) == QUEST_STATUS_INCOMPLETE) pPlayer->AreaExploredOrEventHappens(QUEST_DEAD_MAN_PLEA); } } // Open cage and finish rescue event if (Creature* pYsidaT = instance->GetCreature(m_uiYsidaTriggerGUID)) { if (Creature* pYsida = pYsidaT->SummonCreature(NPC_YSIDA, pYsidaT->GetPositionX(), pYsidaT->GetPositionY(), pYsidaT->GetPositionZ(), pYsidaT->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN, 1800000)) { DoScriptText(SAY_EPILOGUE, pYsida); pYsida->GetMotionMaster()->MovePoint(0, sStratholmeLocation[7].m_fX, sStratholmeLocation[7].m_fY, sStratholmeLocation[7].m_fZ); } DoUseDoorOrButton(m_uiYsidaCageGUID); } } // Open Slaughterhouse door again DoUseDoorOrButton(m_uiPortGauntletGUID); m_bIsSlaughterhouseGateOpened = true; } if (uiData == FAIL) { DoUseDoorOrButton(m_uiPortGauntletGUID); m_bIsSlaughterhouseGateOpened = true; } // combat door DoUseDoorOrButton(m_auiRivendareDoorGUID); m_auiEncounter[5] = uiData; // TODO break; case TYPE_BARTHILAS_RUN: if (uiData == IN_PROGRESS) { Creature* pBarthilas = instance->GetCreature(m_uiBarthilasGUID); if (pBarthilas && pBarthilas->isAlive() && !pBarthilas->isInCombat()) { DoScriptText(SAY_WARN_BARON, pBarthilas); pBarthilas->RemoveSplineFlag(SPLINEFLAG_WALKMODE); pBarthilas->GetMotionMaster()->MovePoint(0, sStratholmeLocation[0].m_fX, sStratholmeLocation[0].m_fY, sStratholmeLocation[0].m_fZ); m_uiBarthilasRunTimer = 8000; } } m_auiEncounter[6] = uiData; // TODO break; case TYPE_SH_AELMAR: m_bIsSilverHandDead[0] = (uiData) ? true : false; break; case TYPE_SH_CATHELA: m_bIsSilverHandDead[1] = (uiData) ? true : false; break; case TYPE_SH_GREGOR: m_bIsSilverHandDead[2] = (uiData) ? true : false; break; case TYPE_SH_NEMAS: m_bIsSilverHandDead[3] = (uiData) ? true : false; break; case TYPE_SH_VICAR: m_bIsSilverHandDead[4] = (uiData) ? true : false; break; } if (uiData == DONE) { OUT_SAVE_INST_DATA; std::ostringstream saveStream; saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " " << m_auiEncounter[3] << " " << m_auiEncounter[4] << " " << m_auiEncounter[5] << " " << m_auiEncounter[6]; strInstData = saveStream.str(); SaveToDB(); OUT_SAVE_INST_DATA_COMPLETE; } }
bool WaypointMovementGenerator<Creature>::Update(Creature &unit, const uint32 &diff) { if (!&unit) return true; if (!path_id) return false; // Waypoint movement can be switched on/off // This is quite handy for escort quests and other stuff if (unit.HasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED)) return true; // Clear the generator if the path doesn't exist if (!waypoints || !waypoints->size()) return false; Traveller<Creature> traveller(unit); i_nextMoveTime.Update(diff); i_destinationHolder.UpdateTraveller(traveller, diff, true); if (i_nextMoveTime.GetExpiry() < TIMEDIFF_NEXT_WP) { if (unit.IsStopped()) { if (StopedByPlayer) { ASSERT(node); InitTraveller(unit, *node); i_destinationHolder.SetDestination(traveller, node->x, node->y, node->z); i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime()); StopedByPlayer = false; return true; } if (i_currentNode == waypoints->size() - 1) // If that's our last waypoint { if (repeating) // If the movement is repeating i_currentNode = 0; // Start moving all over again else { unit.SetHomePosition(node->x, node->y, node->z, unit.GetOrientation()); unit.GetMotionMaster()->Initialize(); return false; // Clear the waypoint movement } } else ++i_currentNode; node = waypoints->at(i_currentNode); InitTraveller(unit, *node); i_destinationHolder.SetDestination(traveller, node->x, node->y, node->z); i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime()); //Call for creature group update if (unit.GetFormation() && unit.GetFormation()->getLeader() == &unit) unit.GetFormation()->LeaderMoveTo(node->x, node->y, node->z); } else { //Determine waittime if (node->delay) i_nextMoveTime.Reset(node->delay); //note: disable "start" for mtmap if (node->event_id && urand(0,99) < node->event_chance) unit.GetMap()->ScriptsStart(sWaypointScripts, node->event_id, &unit, NULL/*, false*/); i_destinationHolder.ResetTravelTime(); MovementInform(unit); unit.UpdateWaypointID(i_currentNode); unit.ClearUnitState(UNIT_STAT_ROAMING); unit.Relocate(node->x, node->y, node->z); } } else { if (unit.IsStopped() && !i_destinationHolder.HasArrived()) { if (!StopedByPlayer) { i_destinationHolder.IncreaseTravelTime(STOP_TIME_FOR_PLAYER); i_nextMoveTime.Reset(STOP_TIME_FOR_PLAYER); StopedByPlayer = true; } } } return true; }
void StartBossEncounter(uint8 uiBoss, bool bForceRespawn = true) { Creature* pBoss = NULL; switch(uiBoss) { case BOSS_MORAGG: HandleGameObject(uiMoraggCell,bForceRespawn); pBoss = instance->GetCreature(uiMoragg); if (pBoss) pBoss->GetMotionMaster()->MovePoint(0, BossStartMove1); break; case BOSS_EREKEM: HandleGameObject(uiErekemCell, bForceRespawn); HandleGameObject(uiErekemRightGuardCell, bForceRespawn); HandleGameObject(uiErekemLeftGuardCell, bForceRespawn); pBoss = instance->GetCreature(uiErekem); if (pBoss) pBoss->GetMotionMaster()->MovePoint(0, BossStartMove2); if (Creature* pGuard1 = instance->GetCreature(uiErekemGuard[0])) { if (bForceRespawn) pGuard1->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_NON_ATTACKABLE); else pGuard1->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_NON_ATTACKABLE); pGuard1->GetMotionMaster()->MovePoint(0, BossStartMove21); } if (Creature* pGuard2 = instance->GetCreature(uiErekemGuard[1])) { if (bForceRespawn) pGuard2->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_NON_ATTACKABLE); else pGuard2->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_NON_ATTACKABLE); pGuard2->GetMotionMaster()->MovePoint(0, BossStartMove22); } break; case BOSS_ICHORON: HandleGameObject(uiIchoronCell,bForceRespawn); pBoss = instance->GetCreature(uiIchoron); if (pBoss) pBoss->GetMotionMaster()->MovePoint(0, BossStartMove3); break; case BOSS_LAVANTHOR: HandleGameObject(uiLavanthorCell,bForceRespawn); pBoss = instance->GetCreature(uiLavanthor); if (pBoss) pBoss->GetMotionMaster()->MovePoint(0, BossStartMove4); break; case BOSS_XEVOZZ: HandleGameObject(uiXevozzCell,bForceRespawn); pBoss = instance->GetCreature(uiXevozz); if (pBoss) pBoss->GetMotionMaster()->MovePoint(0, BossStartMove5); break; case BOSS_ZURAMAT: HandleGameObject(uiZuramatCell,bForceRespawn); pBoss = instance->GetCreature(uiZuramat); if (pBoss) pBoss->GetMotionMaster()->MovePoint(0, BossStartMove6); break; } // generic boss state changes if (pBoss) { pBoss->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_NON_ATTACKABLE); pBoss->SetReactState(REACT_AGGRESSIVE); if (!bForceRespawn) { if (pBoss->isDead()) { // respawn but avoid to be looted again pBoss->Respawn(); pBoss->RemoveLootMode(1); } pBoss->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_NON_ATTACKABLE); uiWaveCount = 0; } } }
void Update(uint32 diff) override { if (!instance->HavePlayers()) return; // portals should spawn if other portal is dead and doors are closed if (bActive && uiMainEventPhase == IN_PROGRESS) { if (uiActivationTimer < diff) { AddWave(); bActive = false; // 1 minute waiting time after each boss fight uiActivationTimer = (uiWaveCount == 6 || uiWaveCount == 12) ? 60000 : 5000; } else uiActivationTimer -= diff; } // if main event is in progress and players have wiped then reset instance if (uiMainEventPhase == IN_PROGRESS && CheckWipe()) { SetData(DATA_REMOVE_NPC, 1); StartBossEncounter(uiFirstBoss, false); StartBossEncounter(uiSecondBoss, false); SetData(DATA_MAIN_DOOR, GO_STATE_ACTIVE); SetData(DATA_WAVE_COUNT, 0); uiMainEventPhase = NOT_STARTED; for (int i = 0; i < 4; ++i) if (GameObject* crystal = instance->GetGameObject(uiActivationCrystal[i])) crystal->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); if (Creature* sinclari = GetCreature(DATA_SINCLARI)) { sinclari->SetVisible(true); std::list<Creature*> GuardList; sinclari->GetCreatureListWithEntryInGrid(GuardList, NPC_VIOLET_HOLD_GUARD, 40.0f); if (!GuardList.empty()) { for (Creature* guard : GuardList) { guard->SetVisible(true); guard->SetReactState(REACT_AGGRESSIVE); guard->GetMotionMaster()->MovePoint(1, guard->GetHomePosition()); } } sinclari->GetMotionMaster()->MovePoint(1, sinclari->GetHomePosition()); sinclari->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); } } // Cyanigosa is spawned but not tranformed, prefight event Creature* cyanigosa = GetCreature(DATA_CYANIGOSA); if (cyanigosa && !cyanigosa->HasAura(CYANIGOSA_SPELL_TRANSFORM)) { if (uiCyanigosaEventTimer <= diff) { switch (uiCyanigosaEventPhase) { case 1: cyanigosa->CastSpell(cyanigosa, CYANIGOSA_BLUE_AURA, false); cyanigosa->AI()->Talk(CYANIGOSA_SAY_SPAWN); uiCyanigosaEventTimer = 7*IN_MILLISECONDS; ++uiCyanigosaEventPhase; break; case 2: cyanigosa->GetMotionMaster()->MoveJump(MiddleRoomLocation.GetPositionX(), MiddleRoomLocation.GetPositionY(), MiddleRoomLocation.GetPositionZ(), 10.0f, 20.0f); cyanigosa->CastSpell(cyanigosa, CYANIGOSA_BLUE_AURA, false); uiCyanigosaEventTimer = 7*IN_MILLISECONDS; ++uiCyanigosaEventPhase; break; case 3: cyanigosa->RemoveAurasDueToSpell(CYANIGOSA_BLUE_AURA); cyanigosa->CastSpell(cyanigosa, CYANIGOSA_SPELL_TRANSFORM, 0); cyanigosa->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_NON_ATTACKABLE); cyanigosa->SetReactState(REACT_AGGRESSIVE); uiCyanigosaEventTimer = 2*IN_MILLISECONDS; ++uiCyanigosaEventPhase; break; case 4: uiCyanigosaEventPhase = 0; break; } } else uiCyanigosaEventTimer -= diff; } // if there are NPCs in front of the prison door, which are casting the door seal spell and doors are active if (GetData(DATA_NPC_PRESENCE_AT_DOOR) && uiMainEventPhase == IN_PROGRESS) { // if door integrity is > 0 then decrase it's integrity state if (GetData(DATA_DOOR_INTEGRITY)) { if (uiDoorSpellTimer < diff) { SetData(DATA_DOOR_INTEGRITY, GetData(DATA_DOOR_INTEGRITY)-1); uiDoorSpellTimer =2000; } else uiDoorSpellTimer -= diff; } // else set door state to active (means door will open and group have failed to sustain mob invasion on the door) else { SetData(DATA_MAIN_DOOR, GO_STATE_ACTIVE); uiMainEventPhase = FAIL; } } }
void DoWaveSpawnForCreature(Creature* creature) { switch (creature->GetEntry()) { case ENTRY_BNAAR_C_CONSOLE: if (rand()%2) { add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2933.68f, 4162.55f, 164.00f, 1.60f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); if (add) add->GetMotionMaster()->MovePoint(0, 2927.36f, 4212.97f, 164.00f); } else { add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2927.36f, 4212.97f, 164.00f, 4.94f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); if (add) add->GetMotionMaster()->MovePoint(0, 2933.68f, 4162.55f, 164.00f); } Wave_Timer = 30000; break; case ENTRY_CORUU_C_CONSOLE: add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2445.21f, 2765.26f, 134.49f, 3.93f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); if (add) add->GetMotionMaster()->MovePoint(0, 2424.21f, 2740.15f, 133.81f); add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2429.86f, 2731.85f, 134.53f, 1.31f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); if (add) add->GetMotionMaster()->MovePoint(0, 2435.37f, 2766.04f, 133.81f); Wave_Timer = 20000; break; case ENTRY_DURO_C_CONSOLE: add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2986.80f, 2205.36f, 165.37f, 3.74f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); if (add) add->GetMotionMaster()->MovePoint(0, 2985.15f, 2197.32f, 164.79f); add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2952.91f, 2191.20f, 165.32f, 0.22f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); if (add) add->GetMotionMaster()->MovePoint(0, 2060.01f, 2185.27f, 164.67f); Wave_Timer = 15000; break; case ENTRY_ARA_C_CONSOLE: if (rand()%2) { add = me->SummonCreature(ENTRY_ARA_TECH, 4035.11f, 4038.97f, 194.27f, 2.57f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); if (add) add->GetMotionMaster()->MovePoint(0, 4003.42f, 4040.19f, 193.49f); add = me->SummonCreature(ENTRY_ARA_TECH, 4033.66f, 4036.79f, 194.28f, 2.57f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); if (add) add->GetMotionMaster()->MovePoint(0, 4003.42f, 4040.19f, 193.49f); add = me->SummonCreature(ENTRY_ARA_TECH, 4037.13f, 4037.30f, 194.23f, 2.57f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); if (add) add->GetMotionMaster()->MovePoint(0, 4003.42f, 4040.19f, 193.49f); } else { add = me->SummonCreature(ENTRY_ARA_TECH, 3099.59f, 4049.30f, 194.22f, 0.05f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); if (add) add->GetMotionMaster()->MovePoint(0, 4028.01f, 4035.17f, 193.59f); add = me->SummonCreature(ENTRY_ARA_TECH, 3999.72f, 4046.75f, 194.22f, 0.05f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); if (add) add->GetMotionMaster()->MovePoint(0, 4028.01f, 4035.17f, 193.59f); add = me->SummonCreature(ENTRY_ARA_TECH, 3996.81f, 4048.26f, 194.22f, 0.05f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); if (add) add->GetMotionMaster()->MovePoint(0, 4028.01f, 4035.17f, 193.59f); } Wave_Timer = 15000; break; } }
void UpdateAI(uint32 diff) { if (spawnTimer) { spawnTimer += diff; if (spawnTimer >= 21500) { me->SetVisible(true); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); me->SetReactState(REACT_AGGRESSIVE); spawnTimer = 0; } return; } if (!IsInRoom()) return; if (!UpdateVictim()) return; events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) return; switch (events.GetEvent()) { case EVENT_BERSERK: Talk(EMOTE_ENRAGE); me->CastSpell(me, SPELL_BERSERK, true); events.PopEvent(); return; case EVENT_SPELL_CLEAVE: me->CastSpell(me->GetVictim(), SPELL_CLEAVE, false); events.RepeatEvent(10000); return; case EVENT_SPELL_TAIL_SWEEP: me->CastSpell(me, RAID_MODE(SPELL_TAIL_SWEEP_10, SPELL_TAIL_SWEEP_25), false); events.RepeatEvent(10000); return; case EVENT_SPELL_LIFE_DRAIN: me->CastCustomSpell(RAID_MODE(SPELL_LIFE_DRAIN_10, SPELL_LIFE_DRAIN_25), SPELLVALUE_MAX_TARGETS, RAID_MODE(2, 5), me, false); events.RepeatEvent(24000); return; case EVENT_SPELL_BLIZZARD: { Creature* cr; if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 40.0f, true)) cr = me->SummonCreature(NPC_BLIZZARD, *target, TEMPSUMMON_TIMED_DESPAWN, 16000); else cr = me->SummonCreature(NPC_BLIZZARD, *me, TEMPSUMMON_TIMED_DESPAWN, 16000); if (cr) cr->GetMotionMaster()->MoveRandom(40); events.RepeatEvent(RAID_MODE(8000, 6500)); return; } case EVENT_FLIGHT_START: if (me->HealthBelowPct(11)) { events.PopEvent(); return; } events.RepeatEvent(45000); events.DelayEvents(35000); me->SetReactState(REACT_PASSIVE); me->AttackStop(); float x, y, z, o; me->GetHomePosition(x, y, z, o); me->GetMotionMaster()->MovePoint(POINT_CENTER, x, y, z); return; case EVENT_FLIGHT_LIFTOFF: me->GetMotionMaster()->MoveIdle(); me->SendMeleeAttackStop(me->GetVictim()); me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); me->SetDisableGravity(true); currentTarget = 0; events.PopEvent(); events.ScheduleEvent(EVENT_FLIGHT_ICEBOLT, 3000); iceboltCount = RAID_MODE(2, 3); return; case EVENT_FLIGHT_ICEBOLT: { events.PopEvent(); if (currentTarget) if (Unit* target = ObjectAccessor::GetUnit(*me, currentTarget)) me->SummonGameObject(GO_ICE_BLOCK, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), target->GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 0); std::vector<Unit*> targets; ThreatContainer::StorageType::const_iterator i = me->getThreatManager().getThreatList().begin(); for (; i != me->getThreatManager().getThreatList().end(); ++i) if ((*i)->getTarget()->GetTypeId() == TYPEID_PLAYER) { bool inList = false; if (!blockList.empty()) for (std::list<uint64>::const_iterator itr = blockList.begin(); itr != blockList.end(); ++itr) if ((*i)->getTarget()->GetGUID() == *itr) { inList = true; break; } if (!inList) targets.push_back((*i)->getTarget()); } if (!targets.empty() && iceboltCount) { std::vector<Unit*>::iterator itr = targets.begin(); advance(itr, urand(0, targets.size()-1)); me->CastSpell(*itr, SPELL_ICEBOLT_CAST, false); blockList.push_back((*itr)->GetGUID()); currentTarget = (*itr)->GetGUID(); --iceboltCount; events.ScheduleEvent(EVENT_FLIGHT_ICEBOLT, (me->GetExactDist(*itr) / 13.0f)*IN_MILLISECONDS); } else events.ScheduleEvent(EVENT_FLIGHT_BREATH, 1000); return; } case EVENT_FLIGHT_BREATH: currentTarget = 0; Talk(EMOTE_BREATH); me->CastSpell(me, SPELL_FROST_MISSILE, false); events.ScheduleEvent(EVENT_FLIGHT_SPELL_EXPLOSION, 8500); events.PopEvent(); return; case EVENT_FLIGHT_SPELL_EXPLOSION: me->CastSpell(me, SPELL_FROST_EXPLOSION, true); events.PopEvent(); events.ScheduleEvent(EVENT_FLIGHT_START_LAND, 3000); return; case EVENT_FLIGHT_START_LAND: if (!blockList.empty()) for (std::list<uint64>::const_iterator itr = blockList.begin(); itr != blockList.end(); ++itr) if (Unit* block = ObjectAccessor::GetUnit(*me, *itr)) block->RemoveAurasDueToSpell(SPELL_ICEBOLT_TRIGGER); blockList.clear(); me->RemoveAllGameObjects(); events.ScheduleEvent(EVENT_LAND, 1000); events.PopEvent(); return; case EVENT_LAND: me->HandleEmoteCommand(EMOTE_ONESHOT_LAND); me->SetDisableGravity(false); events.PopEvent(); events.ScheduleEvent(EVENT_GROUND, 1500); return; case EVENT_GROUND: me->SetReactState(REACT_AGGRESSIVE); me->SetInCombatWithZone(); events.PopEvent(); return; case EVENT_HUNDRED_CLUB: { Map::PlayerList const& pList = me->GetMap()->GetPlayers(); for(Map::PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr) { if (itr->GetSource()->GetResistance(SPELL_SCHOOL_FROST) > 100 && pInstance) { events.PopEvent(); pInstance->SetData(DATA_HUNDRED_CLUB, 0); return; } } events.RepeatEvent(5000); return; } } DoMeleeAttackIfReady(); }
void instance_stratholme::Update(uint32 uiDiff) { if (m_uiBarthilasRunTimer) { if (m_uiBarthilasRunTimer <= uiDiff) { Creature* pBarthilas = instance->GetCreature(m_uiBarthilasGUID); if (pBarthilas && pBarthilas->isAlive() && !pBarthilas->isInCombat()) pBarthilas->NearTeleportTo(sStratholmeLocation[1].m_fX, sStratholmeLocation[1].m_fY, sStratholmeLocation[1].m_fZ, sStratholmeLocation[1].m_fO); SetData(TYPE_BARTHILAS_RUN, DONE); m_uiBarthilasRunTimer = 0; } else m_uiBarthilasRunTimer -= uiDiff; } if (m_uiBaronRunTimer) { if (m_uiYellCounter == 0 && m_uiBaronRunTimer <= 10*MINUTE*IN_MILLISECONDS) { if (Creature* pBaron = instance->GetCreature(m_uiBaronGUID)) DoScriptText(SAY_ANNOUNCE_RUN_10_MIN, pBaron); ++m_uiYellCounter; } else if (m_uiYellCounter == 1 && m_uiBaronRunTimer <= 5*MINUTE*IN_MILLISECONDS) { if (Creature* pBaron = instance->GetCreature(m_uiBaronGUID)) DoScriptText(SAY_ANNOUNCE_RUN_5_MIN, pBaron); ++m_uiYellCounter; } if (m_uiBaronRunTimer <= uiDiff) { SetData(TYPE_BARON_RUN, FAIL); if (Creature* pBaron = instance->GetCreature(m_uiBaronGUID)) DoScriptText(SAY_ANNOUNCE_RUN_FAIL, pBaron); m_uiBaronRunTimer = 0; debug_log("SD2: Instance Stratholme: Baron run event reached end. Event has state %u.", GetData(TYPE_BARON_RUN)); } else m_uiBaronRunTimer -= uiDiff; } if (m_uiMindlessSummonTimer) { if (m_uiMindlessCount < 30) { if (m_uiMindlessSummonTimer <= uiDiff) { if (Creature* pBaron = instance->GetCreature(m_uiBaronGUID)) { // Summon mindless skeletons and move them to random point in the center of the square if (Creature* pTemp = pBaron->SummonCreature(NPC_MINDLESS_UNDEAD, sStratholmeLocation[4].m_fX, sStratholmeLocation[4].m_fY, sStratholmeLocation[4].m_fZ, sStratholmeLocation[4].m_fO, TEMPSUMMON_DEAD_DESPAWN, 0)) { float fX, fY, fZ; pBaron->GetRandomPoint(sStratholmeLocation[5].m_fX, sStratholmeLocation[5].m_fY, sStratholmeLocation[5].m_fZ, 20.0f, fX, fY, fZ); pTemp->GetMotionMaster()->MovePoint(0, fX, fY, fZ); m_luiUndeadGUIDs.push_back(pTemp->GetGUID()); ++m_uiMindlessCount; } } m_uiMindlessSummonTimer = 400; } else m_uiMindlessSummonTimer -= uiDiff; } else m_uiMindlessSummonTimer = 0; } if (m_uiSlaugtherSquareTimer) { if (m_uiSlaugtherSquareTimer <= uiDiff) { // Call next Abomnations for (std::set<uint64>::iterator itr = m_sAbomnationGUID.begin(); itr != m_sAbomnationGUID.end(); ++itr) { Creature* pAbom = instance->GetCreature(*itr); // Skip killed and already walking Abomnations if (!pAbom || !pAbom->isAlive() || pAbom->GetMotionMaster()->GetCurrentMovementGeneratorType() == POINT_MOTION_TYPE) continue; // Let Move to somewhere in the middle if (!pAbom->isInCombat()) { if (GameObject* pDoor = instance->GetGameObject(m_uiPortSlaugtherGUID)) { float fX, fY, fZ; pAbom->GetRandomPoint(pDoor->GetPositionX(), pDoor->GetPositionY(), pDoor->GetPositionZ(), 10.0f, fX, fY, fZ); pAbom->GetMotionMaster()->MovePoint(0, fX, fY, fZ); } } break; } // TODO - how fast are they called? m_uiSlaugtherSquareTimer = urand(15000, 30000); } else m_uiSlaugtherSquareTimer -= uiDiff; } }
/**HandleNpcSetMoveTypeCommand * Set the movement type for an NPC.<br/> * <br/> * Valid movement types are: * <ul> * <li> stay - NPC wont move </li> * <li> random - NPC will move randomly according to the spawndist </li> * <li> way - NPC will move with given waypoints set </li> * </ul> * additional parameter: NODEL - so no waypoints are deleted, if you * change the movement type */ static bool HandleNpcSetMoveTypeCommand(ChatHandler* handler, const char* args) { if (!*args) return false; // 3 arguments: // GUID (optional - you can also select the creature) // stay|random|way (determines the kind of movement) // NODEL (optional - tells the system NOT to delete any waypoints) // this is very handy if you want to do waypoints, that are // later switched on/off according to special events (like escort // quests, etc) char* guid_str = strtok((char*)args, " "); char* type_str = strtok((char*)NULL, " "); char* dontdel_str = strtok((char*)NULL, " "); bool doNotDelete = false; if (!guid_str) return false; uint32 lowguid = 0; Creature* pCreature = NULL; if (dontdel_str) { //sLog->outError("DEBUG: All 3 params are set"); // All 3 params are set // GUID // type // doNotDEL if (stricmp(dontdel_str, "NODEL") == 0) { //sLog->outError("DEBUG: doNotDelete = true;"); doNotDelete = true; } } else { // Only 2 params - but maybe NODEL is set if (type_str) { sLog->outError("DEBUG: Only 2 params "); if (stricmp(type_str, "NODEL") == 0) { //sLog->outError("DEBUG: type_str, NODEL "); doNotDelete = true; type_str = NULL; } } } if (!type_str) // case .setmovetype $move_type (with selected creature) { type_str = guid_str; pCreature = handler->getSelectedCreature(); if (!pCreature || pCreature->isPet()) return false; lowguid = pCreature->GetDBTableGUIDLow(); } else // case .setmovetype #creature_guid $move_type (with selected creature) { lowguid = atoi((char*)guid_str); /* impossible without entry if (lowguid) pCreature = ObjectAccessor::GetCreature(*handler->GetSession()->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT)); */ // attempt check creature existence by DB data if (!pCreature) { CreatureData const* data = sObjectMgr->GetCreatureData(lowguid); if (!data) { handler->PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid); handler->SetSentErrorMessage(true); return false; } } else { lowguid = pCreature->GetDBTableGUIDLow(); } } // now lowguid is low guid really existed creature // and pCreature point (maybe) to this creature or NULL MovementGeneratorType move_type; std::string type = type_str; if (type == "stay") move_type = IDLE_MOTION_TYPE; else if (type == "random") move_type = RANDOM_MOTION_TYPE; else if (type == "way") move_type = WAYPOINT_MOTION_TYPE; else return false; // update movement type //if (doNotDelete == false) // WaypointMgr.DeletePath(lowguid); if (pCreature) { // update movement type if (doNotDelete == false) pCreature->LoadPath(0); pCreature->SetDefaultMovementType(move_type); pCreature->GetMotionMaster()->Initialize(); if (pCreature->isAlive()) // dead creature will reset movement generator at respawn { pCreature->setDeathState(JUST_DIED); pCreature->Respawn(); } pCreature->SaveToDB(); } if (doNotDelete == false) { handler->PSendSysMessage(LANG_MOVE_TYPE_SET,type_str); } else { handler->PSendSysMessage(LANG_MOVE_TYPE_SET_NODEL,type_str); } return true; }
//move selected creature static bool HandleNpcMoveCommand(ChatHandler* handler, const char* args) { uint32 lowguid = 0; Creature* pCreature = handler->getSelectedCreature(); if (!pCreature) { // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r char* cId = handler->extractKeyFromLink((char*)args,"Hcreature"); if (!cId) return false; lowguid = atoi(cId); /* FIXME: impossible without entry if (lowguid) pCreature = ObjectAccessor::GetCreature(*handler->GetSession()->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT)); */ // Attempting creature load from DB data if (!pCreature) { CreatureData const* data = sObjectMgr->GetCreatureData(lowguid); if (!data) { handler->PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid); handler->SetSentErrorMessage(true); return false; } uint32 map_id = data->mapid; if (handler->GetSession()->GetPlayer()->GetMapId() != map_id) { handler->PSendSysMessage(LANG_COMMAND_CREATUREATSAMEMAP, lowguid); handler->SetSentErrorMessage(true); return false; } } else { lowguid = pCreature->GetDBTableGUIDLow(); } } else { lowguid = pCreature->GetDBTableGUIDLow(); } float x = handler->GetSession()->GetPlayer()->GetPositionX(); float y = handler->GetSession()->GetPlayer()->GetPositionY(); float z = handler->GetSession()->GetPlayer()->GetPositionZ(); float o = handler->GetSession()->GetPlayer()->GetOrientation(); if (pCreature) { if (CreatureData const* data = sObjectMgr->GetCreatureData(pCreature->GetDBTableGUIDLow())) { const_cast<CreatureData*>(data)->posX = x; const_cast<CreatureData*>(data)->posY = y; const_cast<CreatureData*>(data)->posZ = z; const_cast<CreatureData*>(data)->orientation = o; } pCreature->GetMap()->CreatureRelocation(pCreature,x, y, z,o); pCreature->GetMotionMaster()->Initialize(); if (pCreature->isAlive()) // dead creature will reset movement generator at respawn { pCreature->setDeathState(JUST_DIED); pCreature->Respawn(); } } WorldDatabase.PExecute("UPDATE creature SET position_x = '%f', position_y = '%f', position_z = '%f', orientation = '%f' WHERE guid = '%u'", x, y, z, o, lowguid); handler->PSendSysMessage(LANG_COMMAND_CREATUREMOVED); return true; }
//add move for creature static bool HandleNpcAddMoveCommand(ChatHandler* handler, const char* args) { if (!*args) return false; char* guid_str = strtok((char*)args, " "); char* wait_str = strtok((char*)NULL, " "); uint32 lowguid = atoi((char*)guid_str); Creature* pCreature = NULL; /* FIXME: impossible without entry if (lowguid) pCreature = ObjectAccessor::GetCreature(*handler->GetSession()->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT)); */ // attempt check creature existence by DB data if (!pCreature) { CreatureData const* data = sObjectMgr->GetCreatureData(lowguid); if (!data) { handler->PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid); handler->SetSentErrorMessage(true); return false; } } else { // obtain real GUID for DB operations lowguid = pCreature->GetDBTableGUIDLow(); } int wait = wait_str ? atoi(wait_str) : 0; if (wait < 0) wait = 0; //Player* player = handler->GetSession()->GetPlayer(); //WaypointMgr.AddLastNode(lowguid, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetOrientation(), wait, 0); // update movement type WorldDatabase.PExecute("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE,lowguid); if (pCreature && pCreature->GetWaypointPath()) { pCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE); pCreature->GetMotionMaster()->Initialize(); if (pCreature->isAlive()) // dead creature will reset movement generator at respawn { pCreature->setDeathState(JUST_DIED); pCreature->Respawn(true); } pCreature->SaveToDB(); } handler->SendSysMessage(LANG_WAYPOINT_ADDED); return true; }
uint32 NextStep(uint32 Step) { Creature* arca = ObjectAccessor::GetCreature(*me, ArcanagosGUID); Map* map = me->GetMap(); switch (Step) { case 0: return 9999999; case 1: me->Yell(SAY_DIALOG_MEDIVH_1, LANG_UNIVERSAL); return 10000; case 2: if (arca) arca->Yell(SAY_DIALOG_ARCANAGOS_2, LANG_UNIVERSAL); return 20000; case 3: me->Yell(SAY_DIALOG_MEDIVH_3, LANG_UNIVERSAL); return 10000; case 4: if (arca) arca->Yell(SAY_DIALOG_ARCANAGOS_4, LANG_UNIVERSAL); return 20000; case 5: me->Yell(SAY_DIALOG_MEDIVH_5, LANG_UNIVERSAL); return 20000; case 6: if (arca) arca->Yell(SAY_DIALOG_ARCANAGOS_6, LANG_UNIVERSAL); return 10000; case 7: FireArcanagosTimer = 500; return 5000; case 8: FireMedivhTimer = 500; DoCast(me, SPELL_MANA_SHIELD); return 10000; case 9: me->TextEmote(EMOTE_DIALOG_MEDIVH_7); return 10000; case 10: if (arca) DoCast(arca, SPELL_CONFLAGRATION_BLAST, false); return 1000; case 11: if (arca) arca->Yell(SAY_DIALOG_ARCANAGOS_8, LANG_UNIVERSAL); return 5000; case 12: if (arca) { arca->GetMotionMaster()->MovePoint(0, -11010.82f, -1761.18f, 156.47f); arca->setActive(true); arca->InterruptNonMeleeSpells(true); arca->SetSpeed(MOVE_FLIGHT, 2.0f); } return 10000; case 13: me->Yell(SAY_DIALOG_MEDIVH_9, LANG_UNIVERSAL); return 10000; case 14: me->SetVisible(false); me->ClearInCombat(); if (map->IsDungeon()) { InstanceMap::PlayerList const &PlayerList = map->GetPlayers(); for (InstanceMap::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) { if (i->GetSource()->IsAlive()) { if (i->GetSource()->GetQuestStatus(9645) == QUEST_STATUS_INCOMPLETE) i->GetSource()->CompleteQuest(9645); } } } return 50000; case 15: if (arca) arca->DealDamage(arca, arca->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); return 5000; default : return 9999999; } }
void UpdateAI(const uint32 diff) { if (_phase != PHASE_OUTRO) return; _events.Update(diff); while (uint32 eventId = _events.ExecuteEvent()) { switch (eventId) { case EVENT_OUTRO_1: { if (Creature* temp = me->GetCreature(*me, _instanceScript->GetData64(DATA_JAINA_SYLVANAS_1))) temp->DespawnOrUnsummon(); Creature* jainaOrSylvanas = NULL; if (_instanceScript->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) jainaOrSylvanas = me->SummonCreature(NPC_JAINA_PART1, outroPos[2], TEMPSUMMON_MANUAL_DESPAWN); else jainaOrSylvanas = me->SummonCreature(NPC_SYLVANAS_PART1, outroPos[2], TEMPSUMMON_MANUAL_DESPAWN); if (jainaOrSylvanas) { jainaOrSylvanas->GetMotionMaster()->MovePoint(0, outroPos[3]); _outroNpcGUID = jainaOrSylvanas->GetGUID(); } _events.ScheduleEvent(EVENT_OUTRO_2, 6000); break; } case EVENT_OUTRO_2: if (Creature* jainaOrSylvanas = ObjectAccessor::GetCreature(*me, _outroNpcGUID)) { jainaOrSylvanas->SetFacingToObject(me); me->SetFacingToObject(jainaOrSylvanas); if (_instanceScript->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) jainaOrSylvanas->AI()->Talk(SAY_JAYNA_OUTRO_2); else jainaOrSylvanas->AI()->Talk(SAY_SYLVANAS_OUTRO_2); } _events.ScheduleEvent(EVENT_OUTRO_3, 5000); break; case EVENT_OUTRO_3: Talk(SAY_KRICK_OUTRO_3); _events.ScheduleEvent(EVENT_OUTRO_4, 18000); break; case EVENT_OUTRO_4: if (Creature* jainaOrSylvanas = ObjectAccessor::GetCreature(*me, _outroNpcGUID)) { if (_instanceScript->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) jainaOrSylvanas->AI()->Talk(SAY_JAYNA_OUTRO_4); else jainaOrSylvanas->AI()->Talk(SAY_SYLVANAS_OUTRO_4); } _events.ScheduleEvent(EVENT_OUTRO_5, 5000); break; case EVENT_OUTRO_5: Talk(SAY_KRICK_OUTRO_5); _events.ScheduleEvent(EVENT_OUTRO_6, 1000); break; case EVENT_OUTRO_6: if (Creature* tyrannus = me->GetCreature(*me, _instanceScript->GetData64(DATA_TYRANNUS_EVENT))) { tyrannus->SetSpeed(MOVE_FLIGHT, 3.5f, true); tyrannus->GetMotionMaster()->MovePoint(1, outroPos[4]); _tyrannusGUID = tyrannus->GetGUID(); } _events.ScheduleEvent(EVENT_OUTRO_7, 5000); break; case EVENT_OUTRO_7: if (Creature* tyrannus = ObjectAccessor::GetCreature(*me, _tyrannusGUID)) tyrannus->AI()->Talk(SAY_TYRANNUS_OUTRO_7); _events.ScheduleEvent(EVENT_OUTRO_8, 5000); break; case EVENT_OUTRO_8: //! HACK: Creature's can't have MOVEMENTFLAG_FLYING me->AddUnitMovementFlag(MOVEMENTFLAG_FLYING); me->GetMotionMaster()->MovePoint(0, outroPos[5]); DoCast(me, SPELL_STRANGULATING); _events.ScheduleEvent(EVENT_OUTRO_9, 2000); break; case EVENT_OUTRO_9: Talk(SAY_KRICK_OUTRO_8); // TODO: Tyrannus starts killing Krick. // there shall be some visual spell effect if (Creature* tyrannus = ObjectAccessor::GetCreature(*me, _tyrannusGUID)) tyrannus->CastSpell(me, SPELL_NECROMANTIC_POWER, true); //not sure if it's the right spell :/ _events.ScheduleEvent(EVENT_OUTRO_10, 1000); break; case EVENT_OUTRO_10: //! HACK: Creature's can't have MOVEMENTFLAG_FLYING me->RemoveUnitMovementFlag(MOVEMENTFLAG_FLYING); me->AddUnitMovementFlag(MOVEMENTFLAG_FALLING_FAR); me->GetMotionMaster()->MovePoint(0, outroPos[6]); _events.ScheduleEvent(EVENT_OUTRO_11, 2000); break; case EVENT_OUTRO_11: DoCast(me, SPELL_KRICK_KILL_CREDIT); // don't really know if we need it me->SetStandState(UNIT_STAND_STATE_DEAD); me->SetHealth(0); _events.ScheduleEvent(EVENT_OUTRO_12, 3000); break; case EVENT_OUTRO_12: if (Creature* tyrannus = ObjectAccessor::GetCreature(*me, _tyrannusGUID)) tyrannus->AI()->Talk(SAY_TYRANNUS_OUTRO_9); _events.ScheduleEvent(EVENT_OUTRO_13, 2000); break; case EVENT_OUTRO_13: if (Creature* jainaOrSylvanas = ObjectAccessor::GetCreature(*me, _outroNpcGUID)) { if (_instanceScript->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) jainaOrSylvanas->AI()->Talk(SAY_JAYNA_OUTRO_10); else jainaOrSylvanas->AI()->Talk(SAY_SYLVANAS_OUTRO_10); } // End of OUTRO. for now... _events.ScheduleEvent(EVENT_OUTRO_END, 3000); if (Creature* tyrannus = ObjectAccessor::GetCreature(*me, _tyrannusGUID)) tyrannus->GetMotionMaster()->MovePoint(0, outroPos[7]); break; case EVENT_OUTRO_END: if (Creature* tyrannus = ObjectAccessor::GetCreature(*me, _tyrannusGUID)) tyrannus->DespawnOrUnsummon(); me->DisappearAndDie(); break; default: break; } } }
static bool HandleWpLoadCommand(ChatHandler* handler, const char* args) { if (!*args) return false; // optional char* path_number = NULL; if (*args) path_number = strtok((char*) args, " "); uint32 pathid = 0; uint32 guidlow = 0; Creature* target = handler->getSelectedCreature(); // Did player provide a path_id? if (!path_number) return false; if (!target) { handler->SendSysMessage(LANG_SELECT_CREATURE); handler->SetSentErrorMessage(true); return false; } if (target->GetEntry() == 1) { handler->PSendSysMessage("%s%s|r", "|cffff33ff", "You want to load path to a waypoint? Aren't you?"); handler->SetSentErrorMessage(true); return false; } pathid = atoi(path_number); if (!pathid) { handler->PSendSysMessage("%s%s|r", "|cffff33ff", "No valid path number provided."); return true; } guidlow = target->GetDBTableGUIDLow(); QueryResult result = WorldDatabase.PQuery( "SELECT guid FROM creature_addon WHERE guid = '%u'", guidlow); if (result) WorldDatabase.PExecute( "UPDATE creature_addon SET path_id = '%u' WHERE guid = '%u'", pathid, guidlow); else WorldDatabase.PExecute( "INSERT INTO creature_addon(guid, path_id) VALUES ('%u', '%u')", guidlow, pathid); WorldDatabase.PExecute( "UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE, guidlow); target->LoadPath(pathid); target->SetDefaultMovementType(WAYPOINT_MOTION_TYPE); target->GetMotionMaster()->Initialize(); target->MonsterSay("Path loaded.", 0, 0); return true; }
void DoWork() { switch (m_phase) { case 0: // Time: 07/03/2015 11:08:09.619 if (Creature* npc_trigger = me->FindNearestCreature(50373, 20.0f)) if (m_npc = me->SummonCreature(50414, npc_trigger->GetPosition(), TEMPSUMMON_TIMED_DESPAWN, 40000)) { Position pos = me->GetNearPosition(1.5f, 1.72f); m_npc->GetMotionMaster()->MovePoint(0, pos, true); } m_phase = 1; break; case 1: // Time: 07/03/2015 11:08:10.539 Talk(0); m_timer = 3000; m_phase = 2; break; case 2: // Time: 07/03/2015 11:08:13.253 Number: 5796 if (m_npc && m_npc->IsAlive()) { m_npc->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_KNEEL); m_npc->SetFacingToObject(me); } m_timer = 750; m_phase = 3; break; case 3: // Time: 07/03/2015 11:08:14.080 Number: 5805 me->HandleEmoteState(EMOTE_STATE_USE_STANDING); m_timer = 6000; m_phase = 4; break; case 4: // Time: 07/03/2015 11:08:20.133 Number: 5875 me->HandleEmoteState(EMOTE_ONESHOT_NONE); m_timer = 750; m_phase = 5; break; case 5: // Time: 07/03/2015 11:08:21.350 Number: 5891 me->HandleEmote(EMOTE_ONESHOT_POINT); m_timer = 2500; m_phase = 6; break; case 6: // Time: 07/03/2015 11:08:23.908 Number: 5934 Talk(1); m_timer = 250; m_phase = 7; break; case 7: // 07/03/2015 11:08:24.189 Number: 5935 if (m_npc && m_npc->IsAlive()) { m_npc->AddAura(93460, m_npc); m_npc->CastSpell(m_npc, 93460); m_npc->SetDisplayId(36775); m_npc->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_STAND); } m_timer = 2500; m_phase = 8; break; case 8: // Time: 07/03/2015 11:08:26.607 Number: 5967 if (m_npc && m_npc->IsAlive()) { m_npc->HandleEmote(EMOTE_ONESHOT_TALK); m_npc->AI()->Talk(0); } m_timer = 3750; m_phase = 9; break; case 9: // Time: 07/03/2015 11:08:30.257 Number: 6015 if (m_npc && m_npc->IsAlive()) m_npc->HandleEmote(EMOTE_ONESHOT_SALUTE); m_timer = 2500; m_phase = 10; break; case 10: // Time: 07/03/2015 11:08:32.691 Number: 6043 if (m_npc && m_npc->IsAlive()) m_npc->GetMotionMaster()->MovePath(5041401, false); m_timer = 45000; m_phase = 11; break; case 11: // Time: 07/03/2015 11:09:15.139 Number: 6405 if (m_npc && m_npc->IsAlive()) m_npc->DespawnOrUnsummon(); m_timer = urand(15000, 45000);; m_phase = 0; break; } }
void UpdateAI(uint32 diff) { if (!me->IsInCombat()) return; if (IsBanished) { // Akama is set in the threatlist so when we reset, we make sure that he is not included in our check if (me->getThreatManager().getThreatList().size() < 2) { EnterEvadeMode(); return; } if (DefenderTimer <= diff) { uint32 ran = rand()%2; Creature* Defender = me->SummonCreature(NPC_DEFENDER, SpawnLocations[ran].x, SpawnLocations[ran].y, Z_SPAWN, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 25000); if (Defender) { Defender->SetWalk(false); bool move = true; if (AkamaGUID) { if (Creature* Akama = Unit::GetCreature(*me, AkamaGUID)) { float x, y, z; Akama->GetPosition(x, y, z); // They move towards AKama Defender->GetMotionMaster()->MovePoint(0, x, y, z); Defender->AI()->AttackStart(Akama); } else move = false; } else move = false; if (!move) Defender->GetMotionMaster()->MovePoint(0, AKAMA_X, AKAMA_Y, AKAMA_Z); } DefenderTimer = 15000; } else DefenderTimer -= diff; if (SummonTimer <= diff) { SummonCreature(); SummonTimer = 35000; } else SummonTimer -= diff; if (DeathCount >= 6) { if (AkamaGUID) { Creature* Akama = Unit::GetCreature((*me), AkamaGUID); if (Akama && Akama->IsAlive()) { IsBanished = false; me->GetMotionMaster()->Clear(false); me->GetMotionMaster()->MoveChase(Akama); Akama->GetMotionMaster()->Clear(); // Shade should move to Akama, not the other way around Akama->GetMotionMaster()->MoveIdle(); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); // Crazy amount of threat me->AddThreat(Akama, 10000000.0f); Akama->AddThreat(me, 10000000.0f); me->Attack(Akama, true); Akama->Attack(me, true); } } } } else // No longer banished, let's fight Akama now { if (ReduceHealthTimer <= diff) { if (AkamaGUID) { Creature* Akama = Unit::GetCreature((*me), AkamaGUID); if (Akama && Akama->IsAlive()) { //10 % less health every few seconds. me->DealDamage(Akama, Akama->GetMaxHealth()/10, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); ReduceHealthTimer = 12000; } } } else ReduceHealthTimer -= diff; if (HasKilledAkama) { if (!HasKilledAkamaAndReseting)//do not let players kill Shade if Akama is dead and Shade is waiting for ResetTimer!! event would bug { HasKilledAkamaAndReseting = true; me->RemoveAllAuras(); me->DeleteThreatList(); me->CombatStop(); //me->SetFullHealth(); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->GetMotionMaster()->MoveTargetedHome(); } if (ResetTimer <= diff) { EnterEvadeMode();// Reset a little while after killing Akama, evade and respawn Akama return; } else ResetTimer -= diff; } DoMeleeAttackIfReady(); } }
void StartBossEncounter(uint8 uiBoss, bool bForceRespawn = true) { Creature* boss = nullptr; switch (uiBoss) { case BOSS_MORAGG: HandleGameObject(GetObjectGuid(DATA_MORAGG_CELL), bForceRespawn); boss = GetCreature(DATA_MORAGG); if (boss) boss->GetMotionMaster()->MovePoint(0, BossStartMove1); break; case BOSS_EREKEM: HandleGameObject(GetObjectGuid(DATA_EREKEM_CELL), bForceRespawn); HandleGameObject(GetObjectGuid(DATA_EREKEM_LEFT_GUARD_CELL), bForceRespawn); HandleGameObject(GetObjectGuid(DATA_EREKEM_RIGHT_GUARD_CELL), bForceRespawn); boss = GetCreature(DATA_EREKEM); if (boss) boss->GetMotionMaster()->MovePoint(0, BossStartMove2); if (Creature* pGuard1 = instance->GetCreature(uiErekemGuard[0])) { if (bForceRespawn) pGuard1->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NON_ATTACKABLE); else pGuard1->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NON_ATTACKABLE); pGuard1->GetMotionMaster()->MovePoint(0, BossStartMove21); } if (Creature* pGuard2 = instance->GetCreature(uiErekemGuard[1])) { if (bForceRespawn) pGuard2->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NON_ATTACKABLE); else pGuard2->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NON_ATTACKABLE); pGuard2->GetMotionMaster()->MovePoint(0, BossStartMove22); } break; case BOSS_ICHORON: HandleGameObject(GetObjectGuid(DATA_ICHORON_CELL), bForceRespawn); boss = GetCreature(DATA_ICHORON); if (boss) boss->GetMotionMaster()->MovePoint(0, BossStartMove3); break; case BOSS_LAVANTHOR: HandleGameObject(GetObjectGuid(DATA_LAVANTHOR_CELL), bForceRespawn); boss = GetCreature(DATA_LAVANTHOR); if (boss) boss->GetMotionMaster()->MovePoint(0, BossStartMove4); break; case BOSS_XEVOZZ: HandleGameObject(GetObjectGuid(DATA_XEVOZZ_CELL), bForceRespawn); boss = GetCreature(DATA_XEVOZZ); if (boss) boss->GetMotionMaster()->MovePoint(0, BossStartMove5); break; case BOSS_ZURAMAT: HandleGameObject(GetObjectGuid(DATA_ZURAMAT_CELL), bForceRespawn); boss = GetCreature(DATA_ZURAMAT); if (boss) boss->GetMotionMaster()->MovePoint(0, BossStartMove6); break; } // generic boss state changes if (boss) { boss->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_NON_ATTACKABLE); boss->SetReactState(REACT_AGGRESSIVE); if (!bForceRespawn) { if (boss->isDead()) { // respawn but avoid to be looted again boss->Respawn(); boss->RemoveLootMode(1); } boss->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_NON_ATTACKABLE); uiWaveCount = 0; } } }
void UpdateAI(uint32 diff) { if (!EventBegun) return; if (HealthBelowPct(15) && !HasYelledOnce) { Talk(SAY_LOW_HEALTH); HasYelledOnce = true; } if (ShadeGUID && !StartCombat) { Creature* Shade = (Unit::GetCreature((*me), ShadeGUID)); if (Shade && Shade->IsAlive()) { if (CAST_AI(boss_shade_of_akama::boss_shade_of_akamaAI, Shade->AI())->IsBanished) { if (CastSoulRetrieveTimer <= diff) { DoCast(Shade, SPELL_AKAMA_SOUL_CHANNEL); CastSoulRetrieveTimer = 500; } else CastSoulRetrieveTimer -= diff; } else { me->InterruptNonMeleeSpells(false); StartCombat = true; } } } if (ShadeHasDied && (WayPointId == 1)) { if (instance) instance->SetData(DATA_SHADEOFAKAMAEVENT, DONE); me->GetMotionMaster()->MovePoint(WayPointId, AkamaWP[1].x, AkamaWP[1].y, AkamaWP[1].z); ++WayPointId; } if (!ShadeHasDied && StartCombat) { if (CheckTimer <= diff) { if (ShadeGUID) { Creature* Shade = Unit::GetCreature((*me), ShadeGUID); if (Shade && !Shade->IsAlive()) { ShadeHasDied = true; WayPointId = 0; me->SetWalk(true); me->GetMotionMaster()->MovePoint(WayPointId, AkamaWP[0].x, AkamaWP[0].y, AkamaWP[0].z); } if (Shade && Shade->IsAlive()) { if (Shade->getThreatManager().getThreatList().size() < 2) Shade->AI()->EnterEvadeMode(); } } CheckTimer = 5000; } else CheckTimer -= diff; } if (SummonBrokenTimer && BrokenSummonIndex < 4) { if (SummonBrokenTimer <= diff) { for (uint8 i = 0; i < 4; ++i) { float x = BrokenCoords[BrokenSummonIndex].x + (i*5); float y = BrokenCoords[BrokenSummonIndex].y + (1*5); float z = BrokenCoords[BrokenSummonIndex].z; float o = BrokenCoords[BrokenSummonIndex].o; Creature* Broken = me->SummonCreature(NPC_BROKEN, x, y, z, o, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 360000); if (Broken) { float wx = BrokenWP[BrokenSummonIndex].x + (i*5); float wy = BrokenWP[BrokenSummonIndex].y + (i*5); float wz = BrokenWP[BrokenSummonIndex].z; Broken->GetMotionMaster()->MovePoint(0, wx, wy, wz); Broken->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); BrokenList.push_back(Broken->GetGUID()); } } ++BrokenSummonIndex; SummonBrokenTimer = 1000; } else SummonBrokenTimer -= diff; } if (SoulRetrieveTimer) { if (SoulRetrieveTimer <= diff) { switch (EndingTalkCount) { case 0: me->HandleEmoteCommand(EMOTE_ONESHOT_ROAR); ++EndingTalkCount; SoulRetrieveTimer = 2000; SummonBrokenTimer = 1; break; case 1: Talk(SAY_FREE); ++EndingTalkCount; SoulRetrieveTimer = 25000; break; case 2: if (!BrokenList.empty()) { bool Yelled = false; for (std::list<uint64>::const_iterator itr = BrokenList.begin(); itr != BrokenList.end(); ++itr) if (Creature* unit = Unit::GetCreature(*me, *itr)) { if (!Yelled) { unit->AI()->Talk(SAY_BROKEN_FREE_01); Yelled = true; } unit->HandleEmoteCommand(EMOTE_ONESHOT_KNEEL); } } ++EndingTalkCount; SoulRetrieveTimer = 1500; break; case 3: if (!BrokenList.empty()) { for (std::list<uint64>::const_iterator itr = BrokenList.begin(); itr != BrokenList.end(); ++itr) if (Creature* unit = Unit::GetCreature(*me, *itr)) // This is the incorrect spell, but can't seem to find the right one. unit->CastSpell(unit, 39656, true); } ++EndingTalkCount; SoulRetrieveTimer = 5000; break; case 4: if (!BrokenList.empty()) { for (std::list<uint64>::const_iterator itr = BrokenList.begin(); itr != BrokenList.end(); ++itr) if (Creature* unit = Unit::GetCreature((*me), *itr)) unit->AI()->Talk(SAY_BROKEN_FREE_02); } SoulRetrieveTimer = 0; break; } } else SoulRetrieveTimer -= diff; } if (!UpdateVictim()) return; if (DestructivePoisonTimer <= diff) { Creature* Shade = Unit::GetCreature((*me), ShadeGUID); if (Shade && Shade->IsAlive()) DoCast(Shade, SPELL_DESTRUCTIVE_POISON); DestructivePoisonTimer = 15000; } else DestructivePoisonTimer -= diff; if (LightningBoltTimer <= diff) { DoCastVictim(SPELL_LIGHTNING_BOLT); LightningBoltTimer = 10000; } else LightningBoltTimer -= diff; DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (!Phase) return; if (me->getThreatManager().getThreatList().empty()) // Reset if event is begun and we don't have a threatlist { EnterEvadeMode(); return; } Creature* Essence = NULL; if (EssenceGUID) { Essence = Unit::GetCreature(*me, EssenceGUID); if (!Essence) { EnterEvadeMode(); return; } } if (Timer <= diff) { switch (Counter) { case 0: me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY2H); // I R ANNNGRRRY! DoStartNoMovement(me); Timer = 3000; break; case 1: Timer = 2800; me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_SUBMERGE); // Release the cube DoCast(me, SPELL_SUBMERGE); DoStartNoMovement(me); break; case 2: Timer = 5000; if (Creature* Summon = DoSpawnCreature(23417+Phase, 0, 0, 0, 0, TEMPSUMMON_DEAD_DESPAWN, 0)) { me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_SUBMERGED); // Ribs: open Summon->AI()->AttackStart(SelectTarget(SELECT_TARGET_TOPAGGRO, 0)); EssenceGUID = Summon->GetGUID(); DoStartNoMovement(me); } else EnterEvadeMode(); break; case 3: Timer = 1000; if (Phase == 3) { if (!Essence->isAlive()) DoCast(me, 7, true); else return; } else { if (Essence->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE)) { MergeThreatList(Essence); Essence->RemoveAllAuras(); Essence->DeleteThreatList(); Essence->GetMotionMaster()->MoveFollow(me, 0.0f, 0.0f); } else return; } break; case 4: Timer = 1500; if (Essence->IsWithinDistInMap(me, 10)) { Essence->SetUInt32Value(UNIT_NPC_EMOTESTATE, 374); //rotate and disappear Timer = 2000; me->RemoveAurasDueToSpell(SPELL_SUBMERGE); } else { MergeThreatList(Essence); Essence->RemoveAllAuras(); Essence->DeleteThreatList(); Essence->GetMotionMaster()->MoveFollow(me, 0, 0); return; } break; case 5: if (Phase == 1) { DoScriptText(SUFF_SAY_AFTER, Essence); } else { DoScriptText(DESI_SAY_AFTER, Essence); } Essence->DespawnOrUnsummon(); me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0); EssenceGUID = 0; SoulCount = 0; SoulDeathCount = 0; Timer = 3000; break; case 6: if (SoulCount < NUMBER_ENSLAVED_SOUL) { if (SummonSoul()) ++SoulCount; Timer = 500; return; } break; case 7: if (SoulDeathCount >= SoulCount) { Counter = 1; ++Phase; Timer = 5000; } return; default: break; } ++Counter; } else Timer -= diff; }
void HandleDummy(SpellEffIndex /*effIndex*/) { uint32 roll = urand(1, 100); uint8 ev; if (roll <= 50) ev = EVENT_MISS; else if (roll <= 83) ev = EVENT_HIT; else ev = EVENT_MISS_BIRD; Unit* shooter = GetCaster(); Creature* wilhelm = GetHitUnit()->ToCreature(); Creature* apple = shooter->FindNearestCreature(NPC_APPLE, 30); Creature* drostan = shooter->FindNearestCreature(NPC_DROSTAN, 30); if (!wilhelm || !apple || !drostan) return; switch (ev) { case EVENT_MISS_BIRD: { Creature* crunchy = shooter->FindNearestCreature(NPC_CRUNCHY, 30); Creature* bird = shooter->FindNearestCreature(NPC_THICKBIRD, 30); if (!bird || !crunchy) ; // fall to EVENT_MISS else { shooter->CastSpell(bird, SPELL_MISS_BIRD_APPLE); bird->CastSpell(bird, SPELL_BIRD_FALL); wilhelm->AI()->Talk(SAY_WILHELM_MISS); drostan->AI()->Talk(SAY_DROSTAN_REPLY_MISS); bird->KillSelf(); crunchy->GetMotionMaster()->MovePoint(0, bird->GetPositionX(), bird->GetPositionY(), bird->GetMap()->GetWaterOrGroundLevel(bird->GetPhaseShift(), bird->GetPositionX(), bird->GetPositionY(), bird->GetPositionZ())); /// @todo Make crunchy perform emote eat when he reaches the bird break; } } case EVENT_MISS: { shooter->CastSpell(wilhelm, SPELL_MISS_APPLE); wilhelm->AI()->Talk(SAY_WILHELM_MISS); drostan->AI()->Talk(SAY_DROSTAN_REPLY_MISS); break; } case EVENT_HIT: { shooter->CastSpell(apple, SPELL_HIT_APPLE); apple->CastSpell(apple, SPELL_APPLE_FALL); wilhelm->AI()->Talk(SAY_WILHELM_HIT); if (Player* player = shooter->ToPlayer()) player->KilledMonsterCredit(NPC_APPLE); break; } } }
void Update(uint32 diff) { if (!instance->HavePlayers()) return; // portals should spawn if other portal is dead and doors are closed if (bActive && uiMainEventPhase == IN_PROGRESS) { if (uiActivationTimer < diff) { AddWave(); bActive = false; uiActivationTimer = 5000; } else uiActivationTimer -= diff; } // if main event is in progress and players have wiped then reset instance if ( uiMainEventPhase == IN_PROGRESS && CheckWipe()) { SetData(DATA_REMOVE_NPC, 1); StartBossEncounter(uiFirstBoss, false); StartBossEncounter(uiSecondBoss, false); SetData(DATA_MAIN_DOOR,GO_STATE_ACTIVE); SetData(DATA_WAVE_COUNT, 0); uiMainEventPhase = NOT_STARTED; if (Creature* pSinclari = instance->GetCreature(uiSinclari)) { pSinclari->SetVisibility(VISIBILITY_ON); std::list<Creature*> GuardList; pSinclari->GetCreatureListWithEntryInGrid(GuardList, NPC_VIOLET_HOLD_GUARD, 40.0f); if (!GuardList.empty()) { for (std::list<Creature*>::const_iterator itr = GuardList.begin(); itr != GuardList.end(); ++itr) { if (Creature* pGuard = *itr) { pGuard->SetVisibility(VISIBILITY_ON); pGuard->SetReactState(REACT_AGGRESSIVE); pGuard->GetMotionMaster()->MovePoint(1,pGuard->GetHomePosition()); } } } pSinclari->GetMotionMaster()->MovePoint(1,pSinclari->GetHomePosition()); pSinclari->RemoveFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_NOT_SELECTABLE); } } // Cyanigosa is spawned but not tranformed, prefight event Creature *pCyanigosa = instance->GetCreature(uiCyanigosa); if (pCyanigosa && !pCyanigosa->HasAura(CYANIGOSA_SPELL_TRANSFORM)) { if (uiCyanigosaEventTimer <= diff) { switch(uiCyanigosaEventPhase) { case 1: pCyanigosa->CastSpell(pCyanigosa, CYANIGOSA_BLUE_AURA, false); DoScriptText(CYANIGOSA_SAY_SPAWN, pCyanigosa); uiCyanigosaEventTimer = 7*IN_MILISECONDS; ++uiCyanigosaEventPhase; break; case 2: pCyanigosa->GetMotionMaster()->MoveJump(MiddleRoomLocation.GetPositionX(), MiddleRoomLocation.GetPositionY(), MiddleRoomLocation.GetPositionZ(), 10.0f, 20.0f); pCyanigosa->CastSpell(pCyanigosa, CYANIGOSA_BLUE_AURA, false); uiCyanigosaEventTimer = 7*IN_MILISECONDS; ++uiCyanigosaEventPhase; break; case 3: pCyanigosa->RemoveAurasDueToSpell(CYANIGOSA_BLUE_AURA); pCyanigosa->CastSpell(pCyanigosa, CYANIGOSA_SPELL_TRANSFORM, 0); pCyanigosa->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_NON_ATTACKABLE); pCyanigosa->SetReactState(REACT_AGGRESSIVE); uiCyanigosaEventTimer = 2*IN_MILISECONDS; ++uiCyanigosaEventPhase; break; case 4: uiCyanigosaEventPhase = 0; break; } } else uiCyanigosaEventTimer -= diff; } // if there are NPCs in front of the prison door, which are casting the door seal spell and doors are active if (GetData(DATA_NPC_PRESENCE_AT_DOOR) && uiMainEventPhase == IN_PROGRESS) { // if door integrity is > 0 then decrase it's integrity state if(GetData(DATA_DOOR_INTEGRITY)) { if(uiDoorSpellTimer < diff) { SetData(DATA_DOOR_INTEGRITY,GetData(DATA_DOOR_INTEGRITY)-1); uiDoorSpellTimer =2000; } else uiDoorSpellTimer -= diff; } // else set door state to active (means door will open and group have failed to sustain mob invasion on the door) else { SetData(DATA_MAIN_DOOR,GO_STATE_ACTIVE); uiMainEventPhase = FAIL; } } }
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; } }
static bool HandleWpLoadCommand(ChatHandler* handler, const char* args) { if (!*args) return false; // optional char* path_number = NULL; if (*args) path_number = strtok((char*)args, " "); uint32 pathid = 0; uint32 guidLow = 0; Creature* target = handler->getSelectedCreature(); // Did player provide a path_id? if (!path_number) return false; if (!target) { handler->SendSysMessage(LANG_SELECT_CREATURE); handler->SetSentErrorMessage(true); return false; } if (target->GetEntry() == 1) { handler->PSendSysMessage("%s%s|r", "|cffff33ff", "You want to load path to a waypoint? Aren't you?"); handler->SetSentErrorMessage(true); return false; } pathid = atoi(path_number); if (!pathid) { handler->PSendSysMessage("%s%s|r", "|cffff33ff", "No valid path number provided."); return true; } guidLow = target->GetDBTableGUIDLow(); QueryResult result = WorldDatabase.PQuery("SELECT guid FROM creature_addon WHERE guid = '%u'", guidLow); PreparedStatement* stmt; if (result) { stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_CREATURE_ADDON_PATH); stmt->setUInt32(0, pathid); stmt->setUInt32(1, guidLow); } else { stmt = WorldDatabase.GetPreparedStatement(WORLD_INS_CREATURE_ADDON); stmt->setUInt32(0, guidLow); stmt->setUInt32(1, pathid); } WorldDatabase.Execute(stmt); stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_CREATURE_MOVEMENT_TYPE); stmt->setUInt8(0, uint8(WAYPOINT_MOTION_TYPE)); stmt->setUInt32(1, guidLow); WorldDatabase.Execute(stmt); target->LoadPath(pathid); target->SetDefaultMovementType(WAYPOINT_MOTION_TYPE); target->GetMotionMaster()->Initialize(); target->MonsterSay("Path loaded.", 0, 0); return true; }
void UpdateAI(uint32 diff) { if (!phase) return; if (timer <= diff) { Player* player = Player::GetPlayer(*me, playerGUID); Creature* orphan = Creature::GetCreature(*me, orphanGUID); if (!orphan || !player) { Reset(); return; } switch (phase) { case 1: orphan->GetMotionMaster()->MovePoint(0, me->GetPositionX() + cos(me->GetOrientation()) * 5, me->GetPositionY() + sin(me->GetOrientation()) * 5, me->GetPositionZ()); orphan->AI()->Talk(TEXT_ORACLE_ORPHAN_11); timer = 5000; break; case 2: orphan->SetFacingToObject(me); orphan->AI()->Talk(TEXT_ORACLE_ORPHAN_12); timer = 5000; break; case 3: orphan->AI()->Talk(TEXT_ORACLE_ORPHAN_13); timer = 5000; break; case 4: Talk(TEXT_ALEXSTRASZA_2); me->SetStandState(UNIT_STAND_STATE_KNEEL); me->SetFacingToObject(orphan); timer = 5000; break; case 5: orphan->AI()->Talk(TEXT_ORACLE_ORPHAN_14); timer = 5000; break; case 6: me->SetStandState(UNIT_STAND_STATE_STAND); me->SetOrientation(me->GetHomePosition().GetOrientation()); player->GroupEventHappens(QUEST_THE_DRAGON_QUEEN_ORACLE, me); orphan->GetMotionMaster()->MoveFollow(player, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); Reset(); return; case 7: orphan->GetMotionMaster()->MovePoint(0, me->GetPositionX() + cos(me->GetOrientation()) * 5, me->GetPositionY() + sin(me->GetOrientation()) * 5, me->GetPositionZ()); orphan->AI()->Talk(TEXT_WOLVAR_ORPHAN_11); timer = 5000; break; case 8: if (Creature* krasus = me->FindNearestCreature(NPC_KRASUS, 10.0f)) { orphan->SetFacingToObject(krasus); krasus->AI()->Talk(TEXT_KRASUS_8); } timer = 5000; break; case 9: orphan->AI()->Talk(TEXT_WOLVAR_ORPHAN_12); timer = 5000; break; case 10: orphan->SetFacingToObject(me); Talk(TEXT_ALEXSTRASZA_2); timer = 5000; break; case 11: orphan->AI()->Talk(TEXT_WOLVAR_ORPHAN_13); timer = 5000; break; case 12: player->GroupEventHappens(QUEST_THE_DRAGON_QUEEN_WOLVAR, me); orphan->GetMotionMaster()->MoveFollow(player, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); Reset(); return; } ++phase; } else timer -= diff; }