diff options
Diffstat (limited to 'src/server/scripts')
221 files changed, 14802 insertions, 18439 deletions
diff --git a/src/server/scripts/CMakeLists.txt b/src/server/scripts/CMakeLists.txt index 8beb5faacde..3a241fcd95e 100644 --- a/src/server/scripts/CMakeLists.txt +++ b/src/server/scripts/CMakeLists.txt @@ -94,7 +94,7 @@ if (USE_SCRIPTPCH) set(PRIVATE_PCH_SOURCE ScriptPCH.cpp) if (MSVC) list(INSERT PRIVATE_SOURCES 0 ScriptPCH.cpp) - endif (MSVC) + endif (MSVC) endif () GroupSources(${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/src/server/scripts/Commands/cs_ban.cpp b/src/server/scripts/Commands/cs_ban.cpp index 5c390a34e11..137620123a6 100644 --- a/src/server/scripts/Commands/cs_ban.cpp +++ b/src/server/scripts/Commands/cs_ban.cpp @@ -587,8 +587,7 @@ public: static bool HandleBanListIPCommand(ChatHandler* handler, char const* args) { - PreparedStatement* stmt = nullptr; - stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_EXPIRED_IP_BANS); + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_EXPIRED_IP_BANS); LoginDatabase.Execute(stmt); char* filterStr = strtok((char*)args, " "); diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp index 69f7ecb3f9a..a7ac9028bc8 100644 --- a/src/server/scripts/Commands/cs_debug.cpp +++ b/src/server/scripts/Commands/cs_debug.cpp @@ -972,7 +972,7 @@ public: Map* map = handler->GetSession()->GetPlayer()->GetMap(); - if (!v->Create(map->GenerateLowGuid<HighGuid::Vehicle>(), map, handler->GetSession()->GetPlayer()->GetPhaseMask(), entry, x, y, z, o, nullptr, id)) + if (!v->Create(map->GenerateLowGuid<HighGuid::Vehicle>(), map, handler->GetSession()->GetPlayer()->GetPhaseMask(), entry, { x, y, z, o }, nullptr, id)) { delete v; return false; diff --git a/src/server/scripts/Commands/cs_disable.cpp b/src/server/scripts/Commands/cs_disable.cpp index bc80d3d6fd0..b8d1116574d 100644 --- a/src/server/scripts/Commands/cs_disable.cpp +++ b/src/server/scripts/Commands/cs_disable.cpp @@ -187,8 +187,7 @@ public: break; } - PreparedStatement* stmt = nullptr; - stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_DISABLES); + PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_DISABLES); stmt->setUInt32(0, entry); stmt->setUInt8(1, disableType); PreparedQueryResult result = WorldDatabase.Query(stmt); @@ -313,8 +312,7 @@ public: break; } - PreparedStatement* stmt = nullptr; - stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_DISABLES); + PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_DISABLES); stmt->setUInt32(0, entry); stmt->setUInt8(1, disableType); PreparedQueryResult result = WorldDatabase.Query(stmt); diff --git a/src/server/scripts/Commands/cs_go.cpp b/src/server/scripts/Commands/cs_go.cpp index 6a27060c2ed..7d0563b2acc 100644 --- a/src/server/scripts/Commands/cs_go.cpp +++ b/src/server/scripts/Commands/cs_go.cpp @@ -138,8 +138,6 @@ public: float o = fields[3].GetFloat(); uint32 mapId = fields[4].GetUInt16(); - Transport* transport = nullptr; - if (!MapManager::IsValidMapCoord(mapId, x, y, z, o) || sObjectMgr->IsTransportMap(mapId)) { handler->PSendSysMessage(LANG_INVALID_TARGET_COORD, x, y, mapId); @@ -157,11 +155,7 @@ public: else player->SaveRecallPosition(); - if (player->TeleportTo(mapId, x, y, z, o)) - { - if (transport) - transport->AddPassenger(player); - } + player->TeleportTo(mapId, x, y, z, o); return true; } @@ -272,28 +266,18 @@ public: if (!guidLow) return false; - float x, y, z, o; - uint32 mapId; - // by DB guid - if (GameObjectData const* goData = sObjectMgr->GetGOData(guidLow)) - { - x = goData->posX; - y = goData->posY; - z = goData->posZ; - o = goData->orientation; - mapId = goData->mapid; - } - else + GameObjectData const* goData = sObjectMgr->GetGameObjectData(guidLow); + if (!goData) { handler->SendSysMessage(LANG_COMMAND_GOOBJNOTFOUND); handler->SetSentErrorMessage(true); return false; } - if (!MapManager::IsValidMapCoord(mapId, x, y, z, o) || sObjectMgr->IsTransportMap(mapId)) + if (!MapManager::IsValidMapCoord(goData->spawnPoint) || sObjectMgr->IsTransportMap(goData->spawnPoint.GetMapId())) { - handler->PSendSysMessage(LANG_INVALID_TARGET_COORD, x, y, mapId); + handler->PSendSysMessage(LANG_INVALID_TARGET_COORD, goData->spawnPoint.GetPositionX(), goData->spawnPoint.GetPositionY(), goData->spawnPoint.GetMapId()); handler->SetSentErrorMessage(true); return false; } @@ -308,7 +292,7 @@ public: else player->SaveRecallPosition(); - player->TeleportTo(mapId, x, y, z, o); + player->TeleportTo(goData->spawnPoint); return true; } diff --git a/src/server/scripts/Commands/cs_gobject.cpp b/src/server/scripts/Commands/cs_gobject.cpp index a315355ff44..fd4baf69037 100644 --- a/src/server/scripts/Commands/cs_gobject.cpp +++ b/src/server/scripts/Commands/cs_gobject.cpp @@ -38,6 +38,10 @@ EndScriptData */ #include "RBAC.h" #include "WorldSession.h" +// definitions are over in cs_npc.cpp +bool HandleNpcSpawnGroup(ChatHandler* handler, char const* args); +bool HandleNpcDespawnGroup(ChatHandler* handler, char const* args); + class gobject_commandscript : public CommandScript { public: @@ -57,15 +61,17 @@ public: }; static std::vector<ChatCommand> gobjectCommandTable = { - { "activate", rbac::RBAC_PERM_COMMAND_GOBJECT_ACTIVATE, false, &HandleGameObjectActivateCommand, "" }, - { "delete", rbac::RBAC_PERM_COMMAND_GOBJECT_DELETE, false, &HandleGameObjectDeleteCommand, "" }, - { "info", rbac::RBAC_PERM_COMMAND_GOBJECT_INFO, false, &HandleGameObjectInfoCommand, "" }, - { "move", rbac::RBAC_PERM_COMMAND_GOBJECT_MOVE, false, &HandleGameObjectMoveCommand, "" }, - { "near", rbac::RBAC_PERM_COMMAND_GOBJECT_NEAR, false, &HandleGameObjectNearCommand, "" }, - { "target", rbac::RBAC_PERM_COMMAND_GOBJECT_TARGET, false, &HandleGameObjectTargetCommand, "" }, - { "turn", rbac::RBAC_PERM_COMMAND_GOBJECT_TURN, false, &HandleGameObjectTurnCommand, "" }, - { "add", rbac::RBAC_PERM_COMMAND_GOBJECT_ADD, false, nullptr, "", gobjectAddCommandTable }, - { "set", rbac::RBAC_PERM_COMMAND_GOBJECT_SET, false, nullptr, "", gobjectSetCommandTable }, + { "activate", rbac::RBAC_PERM_COMMAND_GOBJECT_ACTIVATE, false, &HandleGameObjectActivateCommand, "" }, + { "delete", rbac::RBAC_PERM_COMMAND_GOBJECT_DELETE, false, &HandleGameObjectDeleteCommand, "" }, + { "info", rbac::RBAC_PERM_COMMAND_GOBJECT_INFO, false, &HandleGameObjectInfoCommand, "" }, + { "move", rbac::RBAC_PERM_COMMAND_GOBJECT_MOVE, false, &HandleGameObjectMoveCommand, "" }, + { "near", rbac::RBAC_PERM_COMMAND_GOBJECT_NEAR, false, &HandleGameObjectNearCommand, "" }, + { "target", rbac::RBAC_PERM_COMMAND_GOBJECT_TARGET, false, &HandleGameObjectTargetCommand, "" }, + { "turn", rbac::RBAC_PERM_COMMAND_GOBJECT_TURN, false, &HandleGameObjectTurnCommand, "" }, + { "spawngroup", rbac::RBAC_PERM_COMMAND_GOBJECT_SPAWNGROUP, false, &HandleNpcSpawnGroup, "" }, + { "despawngroup", rbac::RBAC_PERM_COMMAND_GOBJECT_DESPAWNGROUP, false, &HandleNpcDespawnGroup,""}, + { "add", rbac::RBAC_PERM_COMMAND_GOBJECT_ADD, false, nullptr, "", gobjectAddCommandTable }, + { "set", rbac::RBAC_PERM_COMMAND_GOBJECT_SET, false, nullptr, "", gobjectSetCommandTable }, }; static std::vector<ChatCommand> commandTable = { @@ -169,14 +175,14 @@ public: object = new GameObject(); // this will generate a new guid if the object is in an instance - if (!object->LoadGameObjectFromDB(guidLow, map)) + if (!object->LoadFromDB(guidLow, map, true)) { delete object; return false; } /// @todo is it really necessary to add both the real and DB table guid here ? - sObjectMgr->AddGameobjectToGrid(guidLow, sObjectMgr->GetGOData(guidLow)); + sObjectMgr->AddGameobjectToGrid(guidLow, sObjectMgr->GetGameObjectData(guidLow)); handler->PSendSysMessage(LANG_GAMEOBJECT_ADD, objectId, objectInfo->name.c_str(), guidLow, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ()); return true; @@ -345,6 +351,9 @@ public: if (!guidLow) return false; + Player const* const player = handler->GetSession()->GetPlayer(); + // force respawn to make sure we find something + player->GetMap()->RemoveRespawnTime(SPAWN_TYPE_GAMEOBJECT, guidLow, true); GameObject* object = handler->GetObjectFromPlayerMapByDbGuid(guidLow); if (!object) { @@ -356,7 +365,7 @@ public: ObjectGuid ownerGuid = object->GetOwnerGUID(); if (ownerGuid) { - Unit* owner = ObjectAccessor::GetUnit(*handler->GetSession()->GetPlayer(), ownerGuid); + Unit* owner = ObjectAccessor::GetUnit(*player, ownerGuid); if (!owner || !ownerGuid.IsPlayer()) { handler->PSendSysMessage(LANG_COMMAND_DELOBJREFERCREATURE, ownerGuid.GetCounter(), guidLow); @@ -430,7 +439,7 @@ public: object->Delete(); object = new GameObject(); - if (!object->LoadGameObjectFromDB(guidLow, map)) + if (!object->LoadFromDB(guidLow, map, true)) { delete object; return false; @@ -499,7 +508,7 @@ public: object->Delete(); object = new GameObject(); - if (!object->LoadGameObjectFromDB(guidLow, map)) + if (!object->LoadFromDB(guidLow, map, true)) { delete object; return false; @@ -578,7 +587,7 @@ public: if (!gameObjectInfo) continue; - handler->PSendSysMessage(LANG_GO_LIST_CHAT, guid, entry, guid, gameObjectInfo->name.c_str(), x, y, z, mapId); + handler->PSendSysMessage(LANG_GO_LIST_CHAT, guid, entry, guid, gameObjectInfo->name.c_str(), x, y, z, mapId, "", ""); ++count; } while (result->NextRow()); @@ -611,7 +620,7 @@ public: if (!cValue) return false; ObjectGuid::LowType guidLow = atoul(cValue); - GameObjectData const* data = sObjectMgr->GetGOData(guidLow); + GameObjectData const* data = sObjectMgr->GetGameObjectData(guidLow); if (!data) return false; entry = data->id; @@ -623,9 +632,16 @@ public: GameObjectTemplate const* gameObjectInfo = sObjectMgr->GetGameObjectTemplate(entry); + GameObject* thisGO = nullptr; + if (!gameObjectInfo) return false; + if (*args && handler->GetSession()->GetPlayer()) + thisGO = handler->GetSession()->GetPlayer()->FindNearestGameObject(entry, 30); + else if (handler->getSelectedObject() && handler->getSelectedObject()->GetTypeId() == TYPEID_GAMEOBJECT) + thisGO = handler->getSelectedObject()->ToGameObject(); + type = gameObjectInfo->type; displayId = gameObjectInfo->displayId; name = gameObjectInfo->name; @@ -634,10 +650,32 @@ public: else if (type == GAMEOBJECT_TYPE_FISHINGHOLE) lootId = gameObjectInfo->fishinghole.lootId; + // If we have a real object, send some info about it + if (thisGO) + { + handler->PSendSysMessage(LANG_SPAWNINFO_GUIDINFO, thisGO->GetGUID().ToString().c_str()); + handler->PSendSysMessage(LANG_SPAWNINFO_SPAWNID_LOCATION, thisGO->GetSpawnId(), thisGO->GetPositionX(), thisGO->GetPositionY(), thisGO->GetPositionZ()); + if (Player* player = handler->GetSession()->GetPlayer()) + { + Position playerPos = player->GetPosition(); + float dist = thisGO->GetExactDist(&playerPos); + handler->PSendSysMessage(LANG_SPAWNINFO_DISTANCEFROMPLAYER, dist); + } + } handler->PSendSysMessage(LANG_GOINFO_ENTRY, entry); handler->PSendSysMessage(LANG_GOINFO_TYPE, type); handler->PSendSysMessage(LANG_GOINFO_LOOTID, lootId); handler->PSendSysMessage(LANG_GOINFO_DISPLAYID, displayId); + if (WorldObject* object = handler->getSelectedObject()) + { + if (object->ToGameObject() && object->ToGameObject()->GetGameObjectData() && object->ToGameObject()->GetGameObjectData()->spawnGroupData->groupId) + { + SpawnGroupTemplateData const* groupData = object->ToGameObject()->GetGameObjectData()->spawnGroupData; + handler->PSendSysMessage(LANG_SPAWNINFO_GROUP_ID, groupData->name.c_str(), groupData->groupId, groupData->flags, object->GetMap()->IsSpawnGroupActive(groupData->groupId)); + } + if (object->ToGameObject()) + handler->PSendSysMessage(LANG_SPAWNINFO_COMPATIBILITY_MODE, object->ToGameObject()->GetRespawnCompatibilityMode()); + } handler->PSendSysMessage(LANG_GOINFO_NAME, name.c_str()); handler->PSendSysMessage(LANG_GOINFO_SIZE, gameObjectInfo->size); diff --git a/src/server/scripts/Commands/cs_instance.cpp b/src/server/scripts/Commands/cs_instance.cpp index 682976ba897..6855fe21efc 100644 --- a/src/server/scripts/Commands/cs_instance.cpp +++ b/src/server/scripts/Commands/cs_instance.cpp @@ -256,8 +256,7 @@ public: } map->GetInstanceScript()->SetBossState(encounterId, EncounterState(state)); - std::string stateName = InstanceScript::GetBossStateName(state); - handler->PSendSysMessage(LANG_COMMAND_INST_SET_BOSS_STATE, encounterId, state, stateName); + handler->PSendSysMessage(LANG_COMMAND_INST_SET_BOSS_STATE, encounterId, state, InstanceScript::GetBossStateName(state)); return true; } @@ -321,8 +320,7 @@ public: } uint32 state = map->GetInstanceScript()->GetBossState(encounterId); - std::string stateName = InstanceScript::GetBossStateName(state); - handler->PSendSysMessage(LANG_COMMAND_INST_GET_BOSS_STATE, encounterId, state, stateName); + handler->PSendSysMessage(LANG_COMMAND_INST_GET_BOSS_STATE, encounterId, state, InstanceScript::GetBossStateName(state)); return true; } }; diff --git a/src/server/scripts/Commands/cs_list.cpp b/src/server/scripts/Commands/cs_list.cpp index 8b502f60e11..304b7578177 100644 --- a/src/server/scripts/Commands/cs_list.cpp +++ b/src/server/scripts/Commands/cs_list.cpp @@ -25,9 +25,12 @@ EndScriptData */ #include "ScriptMgr.h" #include "CharacterCache.h" #include "Chat.h" +#include "Creature.h" #include "DatabaseEnv.h" #include "DBCStores.h" +#include "GameObject.h" #include "Language.h" +#include "MapManager.h" #include "ObjectAccessor.h" #include "ObjectMgr.h" #include "Player.h" @@ -45,11 +48,13 @@ public: { static std::vector<ChatCommand> listCommandTable = { - { "creature", rbac::RBAC_PERM_COMMAND_LIST_CREATURE, true, &HandleListCreatureCommand, "" }, - { "item", rbac::RBAC_PERM_COMMAND_LIST_ITEM, true, &HandleListItemCommand, "" }, - { "object", rbac::RBAC_PERM_COMMAND_LIST_OBJECT, true, &HandleListObjectCommand, "" }, - { "auras", rbac::RBAC_PERM_COMMAND_LIST_AURAS, false, &HandleListAurasCommand, "" }, - { "mail", rbac::RBAC_PERM_COMMAND_LIST_MAIL, true, &HandleListMailCommand, "" }, + { "creature", rbac::RBAC_PERM_COMMAND_LIST_CREATURE, true, &HandleListCreatureCommand, "" }, + { "item", rbac::RBAC_PERM_COMMAND_LIST_ITEM, true, &HandleListItemCommand, "" }, + { "object", rbac::RBAC_PERM_COMMAND_LIST_OBJECT, true, &HandleListObjectCommand, "" }, + { "auras", rbac::RBAC_PERM_COMMAND_LIST_AURAS, false, &HandleListAurasCommand, "" }, + { "mail", rbac::RBAC_PERM_COMMAND_LIST_MAIL, true, &HandleListMailCommand, "" }, + { "spawnpoints", rbac::RBAC_PERM_COMMAND_LIST_SPAWNPOINTS, false, &HandleListSpawnPointsCommand, "" }, + { "respawns", rbac::RBAC_PERM_COMMAND_LIST_RESPAWNS, false, &HandleListRespawnsCommand, "" }, }; static std::vector<ChatCommand> commandTable = { @@ -117,11 +122,40 @@ public: float y = fields[2].GetFloat(); float z = fields[3].GetFloat(); uint16 mapId = fields[4].GetUInt16(); + bool liveFound = false; + // Get map (only support base map from console) + Map* thisMap; if (handler->GetSession()) - handler->PSendSysMessage(LANG_CREATURE_LIST_CHAT, guid, guid, cInfo->Name.c_str(), x, y, z, mapId); + thisMap = handler->GetSession()->GetPlayer()->GetMap(); else - handler->PSendSysMessage(LANG_CREATURE_LIST_CONSOLE, guid, cInfo->Name.c_str(), x, y, z, mapId); + thisMap = sMapMgr->FindBaseNonInstanceMap(mapId); + + // If map found, try to find active version of this creature + if (thisMap) + { + auto const creBounds = thisMap->GetCreatureBySpawnIdStore().equal_range(guid); + if (creBounds.first != creBounds.second) + { + for (std::unordered_multimap<uint32, Creature*>::const_iterator itr = creBounds.first; itr != creBounds.second;) + { + if (handler->GetSession()) + handler->PSendSysMessage(LANG_CREATURE_LIST_CHAT, guid, guid, cInfo->Name.c_str(), x, y, z, mapId, itr->second->GetGUID().ToString().c_str(), itr->second->IsAlive() ? "*" : " "); + else + handler->PSendSysMessage(LANG_CREATURE_LIST_CONSOLE, guid, cInfo->Name.c_str(), x, y, z, mapId, itr->second->GetGUID().ToString().c_str(), itr->second->IsAlive() ? "*" : " "); + ++itr; + } + liveFound = true; + } + } + + if (!liveFound) + { + if (handler->GetSession()) + handler->PSendSysMessage(LANG_CREATURE_LIST_CHAT, guid, guid, cInfo->Name.c_str(), x, y, z, mapId, "", ""); + else + handler->PSendSysMessage(LANG_CREATURE_LIST_CONSOLE, guid, cInfo->Name.c_str(), x, y, z, mapId, "", ""); + } } while (result->NextRow()); } @@ -407,11 +441,40 @@ public: float z = fields[3].GetFloat(); uint16 mapId = fields[4].GetUInt16(); uint32 entry = fields[5].GetUInt32(); + bool liveFound = false; + // Get map (only support base map from console) + Map* thisMap; if (handler->GetSession()) - handler->PSendSysMessage(LANG_GO_LIST_CHAT, guid, entry, guid, gInfo->name.c_str(), x, y, z, mapId); + thisMap = handler->GetSession()->GetPlayer()->GetMap(); else - handler->PSendSysMessage(LANG_GO_LIST_CONSOLE, guid, gInfo->name.c_str(), x, y, z, mapId); + thisMap = sMapMgr->FindBaseNonInstanceMap(mapId); + + // If map found, try to find active version of this object + if (thisMap) + { + auto const goBounds = thisMap->GetGameObjectBySpawnIdStore().equal_range(guid); + if (goBounds.first != goBounds.second) + { + for (std::unordered_multimap<uint32, GameObject*>::const_iterator itr = goBounds.first; itr != goBounds.second;) + { + if (handler->GetSession()) + handler->PSendSysMessage(LANG_GO_LIST_CHAT, guid, entry, guid, gInfo->name.c_str(), x, y, z, mapId, itr->second->GetGUID().ToString().c_str(), itr->second->isSpawned() ? "*" : " "); + else + handler->PSendSysMessage(LANG_GO_LIST_CONSOLE, guid, gInfo->name.c_str(), x, y, z, mapId, itr->second->GetGUID().ToString().c_str(), itr->second->isSpawned() ? "*" : " "); + ++itr; + } + liveFound = true; + } + } + + if (!liveFound) + { + if (handler->GetSession()) + handler->PSendSysMessage(LANG_GO_LIST_CHAT, guid, entry, guid, gInfo->name.c_str(), x, y, z, mapId, "", ""); + else + handler->PSendSysMessage(LANG_GO_LIST_CONSOLE, guid, gInfo->name.c_str(), x, y, z, mapId, "", ""); + } } while (result->NextRow()); } @@ -581,8 +644,104 @@ public: handler->PSendSysMessage(LANG_LIST_MAIL_NOT_FOUND); return true; } + + static bool HandleListSpawnPointsCommand(ChatHandler* handler, char const* /*args*/) + { + Player const* player = handler->GetSession()->GetPlayer(); + Map const* map = player->GetMap(); + uint32 const mapId = map->GetId(); + bool const showAll = map->IsBattlegroundOrArena() || map->IsDungeon(); + handler->PSendSysMessage("Listing all spawn points in map %u (%s)%s:", mapId, map->GetMapName(), showAll ? "" : " within 5000yd"); + for (auto const& pair : sObjectMgr->GetAllCreatureData()) + { + SpawnData const& data = pair.second; + if (data.spawnPoint.GetMapId() != mapId) + continue; + CreatureTemplate const* cTemp = sObjectMgr->GetCreatureTemplate(data.id); + if (!cTemp) + continue; + if (showAll || data.spawnPoint.IsInDist2d(player, 5000.0)) + handler->PSendSysMessage("Type: %u | SpawnId: %u | Entry: %u (%s) | X: %.3f | Y: %.3f | Z: %.3f", uint32(data.type), data.spawnId, data.id, cTemp->Name.c_str(), data.spawnPoint.GetPositionX(), data.spawnPoint.GetPositionY(), data.spawnPoint.GetPositionZ()); + } + for (auto const& pair : sObjectMgr->GetAllGameObjectData()) + { + SpawnData const& data = pair.second; + if (data.spawnPoint.GetMapId() != mapId) + continue; + GameObjectTemplate const* goTemp = sObjectMgr->GetGameObjectTemplate(data.id); + if (!goTemp) + continue; + if (showAll || data.spawnPoint.IsInDist2d(player, 5000.0)) + handler->PSendSysMessage("Type: %u | SpawnId: %u | Entry: %u (%s) | X: %.3f | Y: %.3f | Z: %.3f", uint32(data.type), data.spawnId, data.id, goTemp->name.c_str(), data.spawnPoint.GetPositionX(), data.spawnPoint.GetPositionY(), data.spawnPoint.GetPositionZ()); + } + return true; + } + + static char const* GetZoneName(uint32 zoneId, LocaleConstant locale) + { + AreaTableEntry const* zoneEntry = sAreaTableStore.LookupEntry(zoneId); + return zoneEntry ? zoneEntry->area_name[locale] : "<unknown zone>"; + } + static bool HandleListRespawnsCommand(ChatHandler* handler, char const* args) + { + Player const* player = handler->GetSession()->GetPlayer(); + Map const* map = player->GetMap(); + uint32 range = 0; + if (*args) + range = atoi((char*)args); + + RespawnVector respawns; + LocaleConstant locale = handler->GetSession()->GetSessionDbcLocale(); + char const* stringOverdue = sObjectMgr->GetTrinityString(LANG_LIST_RESPAWNS_OVERDUE, locale); + char const* stringCreature = sObjectMgr->GetTrinityString(LANG_LIST_RESPAWNS_CREATURES, locale); + char const* stringGameobject = sObjectMgr->GetTrinityString(LANG_LIST_RESPAWNS_GAMEOBJECTS, locale); + + uint32 zoneId = player->GetZoneId(); + if (range) + handler->PSendSysMessage(LANG_LIST_RESPAWNS_RANGE, stringCreature, range); + else + handler->PSendSysMessage(LANG_LIST_RESPAWNS_ZONE, stringCreature, GetZoneName(zoneId, handler->GetSessionDbcLocale()), zoneId); + handler->PSendSysMessage(LANG_LIST_RESPAWNS_LISTHEADER); + map->GetRespawnInfo(respawns, SPAWN_TYPEMASK_CREATURE, range ? 0 : zoneId); + for (RespawnInfo* ri : respawns) + { + CreatureData const* data = sObjectMgr->GetCreatureData(ri->spawnId); + if (!data) + continue; + if (range && !player->IsInDist(data->spawnPoint, range)) + continue; + uint32 gridY = ri->gridId / MAX_NUMBER_OF_GRIDS; + uint32 gridX = ri->gridId % MAX_NUMBER_OF_GRIDS; + + std::string respawnTime = ri->respawnTime > time(NULL) ? secsToTimeString(uint64(ri->respawnTime - time(NULL)), true) : stringOverdue; + handler->PSendSysMessage("%u | %u | [%02u,%02u] | %s (%u) | %s", ri->spawnId, ri->entry, gridX, gridY, GetZoneName(ri->zoneId, handler->GetSessionDbcLocale()), ri->zoneId, map->IsSpawnGroupActive(data->spawnGroupData->groupId) ? respawnTime.c_str() : "inactive"); + } + + respawns.clear(); + if (range) + handler->PSendSysMessage(LANG_LIST_RESPAWNS_RANGE, stringGameobject, range); + else + handler->PSendSysMessage(LANG_LIST_RESPAWNS_ZONE, stringGameobject, GetZoneName(zoneId, handler->GetSessionDbcLocale()), zoneId); + handler->PSendSysMessage(LANG_LIST_RESPAWNS_LISTHEADER); + map->GetRespawnInfo(respawns, SPAWN_TYPEMASK_GAMEOBJECT, range ? 0 : zoneId); + for (RespawnInfo* ri : respawns) + { + GameObjectData const* data = sObjectMgr->GetGameObjectData(ri->spawnId); + if (!data) + continue; + if (range && !player->IsInDist(data->spawnPoint, range)) + continue; + uint32 gridY = ri->gridId / MAX_NUMBER_OF_GRIDS; + uint32 gridX = ri->gridId % MAX_NUMBER_OF_GRIDS; + + std::string respawnTime = ri->respawnTime > time(NULL) ? secsToTimeString(uint64(ri->respawnTime - time(NULL)), true) : stringOverdue; + handler->PSendSysMessage("%u | %u | [% 02u, % 02u] | %s (%u) | %s", ri->spawnId, ri->entry, gridX, gridY, GetZoneName(ri->zoneId, handler->GetSessionDbcLocale()), ri->zoneId, map->IsSpawnGroupActive(data->spawnGroupData->groupId) ? respawnTime.c_str() : "inactive"); + } + return true; + } }; + void AddSC_list_commandscript() { new list_commandscript(); diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index 29f1a0763fb..0860585dc65 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -544,10 +544,11 @@ public: } else if (map->Instanceable()) { - Group* targetGroup = target->GetGroup(); Map* targetMap = target->GetMap(); - Player* targetGroupLeader = ObjectAccessor::GetPlayer(map, targetGroup->GetLeaderGUID()); - + Player* targetGroupLeader = nullptr; + if (Group* targetGroup = target->GetGroup()) + targetGroupLeader = ObjectAccessor::GetPlayer(map, targetGroup->GetLeaderGUID()); + // check if far teleport is allowed if (!targetGroupLeader || (targetGroupLeader->GetMapId() != map->GetId()) || (targetGroupLeader->GetInstanceId() != map->GetInstanceId())) if ((targetMap->GetId() != map->GetId()) || (targetMap->GetInstanceId() != map->GetInstanceId())) @@ -1910,10 +1911,22 @@ public: return true; } + // First handle any creatures that still have a corpse around Trinity::RespawnDo u_do; Trinity::WorldObjectWorker<Trinity::RespawnDo> worker(player, u_do); Cell::VisitGridObjects(player, worker, player->GetGridActivationRange()); + // Now handle any that had despawned, but had respawn time logged. + RespawnVector data; + player->GetMap()->GetRespawnInfo(data, SPAWN_TYPEMASK_ALL, 0); + if (!data.empty()) + { + uint32 const gridId = Trinity::ComputeGridCoord(player->GetPositionX(), player->GetPositionY()).GetId(); + for (RespawnInfo* info : data) + if (info->gridId == gridId) + player->GetMap()->RemoveRespawnTime(info, true); + } + return true; } @@ -1977,15 +1990,15 @@ public: stmt->setInt64(0, muteTime); } - stmt->setString(1, muteReasonStr.c_str()); - stmt->setString(2, muteBy.c_str()); + stmt->setString(1, muteReasonStr); + stmt->setString(2, muteBy); stmt->setUInt32(3, accountId); LoginDatabase.Execute(stmt); stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_ACCOUNT_MUTE); stmt->setUInt32(0, accountId); stmt->setUInt32(1, notSpeakTime); - stmt->setString(2, muteBy.c_str()); - stmt->setString(3, muteReasonStr.c_str()); + stmt->setString(2, muteBy); + stmt->setString(3, muteReasonStr); LoginDatabase.Execute(stmt); std::string nameLink = handler->playerLink(targetName); @@ -2122,9 +2135,9 @@ public: float x, y, z; motionMaster->GetDestination(x, y, z); - for (uint8 i = 0; i < MAX_MOTION_SLOT; ++i) + for (uint8 itr = 0; itr < MAX_MOTION_SLOT; ++itr) { - MovementGenerator* movementGenerator = motionMaster->GetMotionSlot(i); + MovementGenerator* movementGenerator = motionMaster->GetMotionSlot(MovementSlot(itr)); if (!movementGenerator) { handler->SendSysMessage("Empty"); diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp index dfb9ddb66a6..54c48cd1205 100644 --- a/src/server/scripts/Commands/cs_npc.cpp +++ b/src/server/scripts/Commands/cs_npc.cpp @@ -176,6 +176,86 @@ EnumName<CreatureFlagsExtra> const flagsExtra[FLAGS_EXTRA_COUNT] = CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_IMMUNITY_KNOCKBACK) }; +bool HandleNpcSpawnGroup(ChatHandler* handler, char const* args) +{ + if (!*args) + return false; + + bool ignoreRespawn = false; + bool force = false; + uint32 groupId = 0; + + // Decode arguments + char* arg = strtok((char*)args, " "); + while (arg) + { + std::string thisArg = arg; + std::transform(thisArg.begin(), thisArg.end(), thisArg.begin(), ::tolower); + if (thisArg == "ignorerespawn") + ignoreRespawn = true; + else if (thisArg == "force") + force = true; + else if (thisArg.empty() || !(std::count_if(thisArg.begin(), thisArg.end(), ::isdigit) == (int)thisArg.size())) + return false; + else + groupId = atoi(thisArg.c_str()); + + arg = strtok(NULL, " "); + } + + Player* player = handler->GetSession()->GetPlayer(); + + std::vector <WorldObject*> creatureList; + if (!player->GetMap()->SpawnGroupSpawn(groupId, ignoreRespawn, force, &creatureList)) + { + handler->PSendSysMessage(LANG_SPAWNGROUP_BADGROUP, groupId); + handler->SetSentErrorMessage(true); + return false; + } + + handler->PSendSysMessage(LANG_SPAWNGROUP_SPAWNCOUNT, creatureList.size()); + for (WorldObject* obj : creatureList) + handler->PSendSysMessage("%s (%s)", obj->GetName(), obj->GetGUID().ToString().c_str()); + + return true; +} + +bool HandleNpcDespawnGroup(ChatHandler* handler, char const* args) +{ + if (!*args) + return false; + + bool deleteRespawnTimes = false; + uint32 groupId = 0; + + // Decode arguments + char* arg = strtok((char*)args, " "); + while (arg) + { + std::string thisArg = arg; + std::transform(thisArg.begin(), thisArg.end(), thisArg.begin(), ::tolower); + if (thisArg == "removerespawntime") + deleteRespawnTimes = true; + else if (thisArg.empty() || !(std::count_if(thisArg.begin(), thisArg.end(), ::isdigit) == (int)thisArg.size())) + return false; + else + groupId = atoi(thisArg.c_str()); + + arg = strtok(nullptr, " "); + } + + Player* player = handler->GetSession()->GetPlayer(); + + if (!player->GetMap()->SpawnGroupDespawn(groupId, deleteRespawnTimes)) + { + handler->PSendSysMessage(LANG_SPAWNGROUP_BADGROUP, groupId); + handler->SetSentErrorMessage(true); + return false; + } + + return true; +} + class npc_commandscript : public CommandScript { public: @@ -219,21 +299,23 @@ public: }; static std::vector<ChatCommand> npcCommandTable = { - { "info", rbac::RBAC_PERM_COMMAND_NPC_INFO, false, &HandleNpcInfoCommand, "" }, - { "near", rbac::RBAC_PERM_COMMAND_NPC_NEAR, false, &HandleNpcNearCommand, "" }, - { "move", rbac::RBAC_PERM_COMMAND_NPC_MOVE, false, &HandleNpcMoveCommand, "" }, - { "playemote", rbac::RBAC_PERM_COMMAND_NPC_PLAYEMOTE, false, &HandleNpcPlayEmoteCommand, "" }, - { "say", rbac::RBAC_PERM_COMMAND_NPC_SAY, false, &HandleNpcSayCommand, "" }, - { "textemote", rbac::RBAC_PERM_COMMAND_NPC_TEXTEMOTE, false, &HandleNpcTextEmoteCommand, "" }, - { "whisper", rbac::RBAC_PERM_COMMAND_NPC_WHISPER, false, &HandleNpcWhisperCommand, "" }, - { "yell", rbac::RBAC_PERM_COMMAND_NPC_YELL, false, &HandleNpcYellCommand, "" }, - { "tame", rbac::RBAC_PERM_COMMAND_NPC_TAME, false, &HandleNpcTameCommand, "" }, - { "add", rbac::RBAC_PERM_COMMAND_NPC_ADD, false, nullptr, "", npcAddCommandTable }, - { "delete", rbac::RBAC_PERM_COMMAND_NPC_DELETE, false, nullptr, "", npcDeleteCommandTable }, - { "follow", rbac::RBAC_PERM_COMMAND_NPC_FOLLOW, false, nullptr, "", npcFollowCommandTable }, - { "set", rbac::RBAC_PERM_COMMAND_NPC_SET, false, nullptr, "", npcSetCommandTable }, - { "evade", rbac::RBAC_PERM_COMMAND_NPC_EVADE, false, &HandleNpcEvadeCommand, "" }, - { "showloot", rbac::RBAC_PERM_COMMAND_NPC_SHOWLOOT, false, &HandleNpcShowLootCommand, "" }, + { "info", rbac::RBAC_PERM_COMMAND_NPC_INFO, false, &HandleNpcInfoCommand, "" }, + { "near", rbac::RBAC_PERM_COMMAND_NPC_NEAR, false, &HandleNpcNearCommand, "" }, + { "move", rbac::RBAC_PERM_COMMAND_NPC_MOVE, false, &HandleNpcMoveCommand, "" }, + { "playemote", rbac::RBAC_PERM_COMMAND_NPC_PLAYEMOTE, false, &HandleNpcPlayEmoteCommand, "" }, + { "say", rbac::RBAC_PERM_COMMAND_NPC_SAY, false, &HandleNpcSayCommand, "" }, + { "textemote", rbac::RBAC_PERM_COMMAND_NPC_TEXTEMOTE, false, &HandleNpcTextEmoteCommand, "" }, + { "whisper", rbac::RBAC_PERM_COMMAND_NPC_WHISPER, false, &HandleNpcWhisperCommand, "" }, + { "yell", rbac::RBAC_PERM_COMMAND_NPC_YELL, false, &HandleNpcYellCommand, "" }, + { "tame", rbac::RBAC_PERM_COMMAND_NPC_TAME, false, &HandleNpcTameCommand, "" }, + { "spawngroup", rbac::RBAC_PERM_COMMAND_NPC_SPAWNGROUP, false, &HandleNpcSpawnGroup, "" }, + { "despawngroup", rbac::RBAC_PERM_COMMAND_NPC_DESPAWNGROUP, false, &HandleNpcDespawnGroup, "" }, + { "add", rbac::RBAC_PERM_COMMAND_NPC_ADD, false, nullptr, "", npcAddCommandTable }, + { "delete", rbac::RBAC_PERM_COMMAND_NPC_DELETE, false, nullptr, "", npcDeleteCommandTable }, + { "follow", rbac::RBAC_PERM_COMMAND_NPC_FOLLOW, false, nullptr, "", npcFollowCommandTable }, + { "set", rbac::RBAC_PERM_COMMAND_NPC_SET, false, nullptr, "", npcSetCommandTable }, + { "evade", rbac::RBAC_PERM_COMMAND_NPC_EVADE, false, &HandleNpcEvadeCommand, "" }, + { "showloot", rbac::RBAC_PERM_COMMAND_NPC_SHOWLOOT, false, &HandleNpcShowLootCommand, "" }, }; static std::vector<ChatCommand> commandTable = { @@ -257,22 +339,16 @@ public: return false; Player* chr = handler->GetSession()->GetPlayer(); - float x = chr->GetPositionX(); - float y = chr->GetPositionY(); - float z = chr->GetPositionZ(); - float o = chr->GetOrientation(); Map* map = chr->GetMap(); if (Transport* trans = chr->GetTransport()) { ObjectGuid::LowType guid = map->GenerateLowGuid<HighGuid::Unit>(); CreatureData& data = sObjectMgr->NewOrExistCreatureData(guid); + data.spawnId = guid; data.id = id; data.phaseMask = chr->GetPhaseMaskForSpawn(); - data.posX = chr->GetTransOffsetX(); - data.posY = chr->GetTransOffsetY(); - data.posZ = chr->GetTransOffsetZ(); - data.orientation = chr->GetTransOffsetO(); + data.spawnPoint.Relocate(chr->GetTransOffsetX(), chr->GetTransOffsetY(), chr->GetTransOffsetZ(), chr->GetTransOffsetO()); Creature* creature = trans->CreateNPCPassenger(guid, &data); @@ -283,7 +359,7 @@ public: } Creature* creature = new Creature(); - if (!creature->Create(map->GenerateLowGuid<HighGuid::Unit>(), map, chr->GetPhaseMaskForSpawn(), id, x, y, z, o)) + if (!creature->Create(map->GenerateLowGuid<HighGuid::Unit>(), map, chr->GetPhaseMaskForSpawn(), id, *chr)) { delete creature; return false; @@ -298,7 +374,7 @@ public: creature->CleanupsBeforeDelete(); delete creature; creature = new Creature(); - if (!creature->LoadCreatureFromDB(db_guid, map)) + if (!creature->LoadFromDB(db_guid, map, true, true)) { delete creature; return false; @@ -473,7 +549,7 @@ public: static bool HandleNpcDeleteCommand(ChatHandler* handler, char const* args) { - Creature* unit = nullptr; + Creature* creature = nullptr; if (*args) { @@ -485,22 +561,30 @@ public: ObjectGuid::LowType lowguid = atoul(cId); if (!lowguid) return false; - unit = handler->GetCreatureFromPlayerMapByDbGuid(lowguid); + // force respawn to make sure we find something + handler->GetSession()->GetPlayer()->GetMap()->RemoveRespawnTime(SPAWN_TYPE_CREATURE, lowguid, true); + // then try to find it + creature = handler->GetCreatureFromPlayerMapByDbGuid(lowguid); } else - unit = handler->getSelectedCreature(); + creature = handler->getSelectedCreature(); - if (!unit || unit->IsPet() || unit->IsTotem()) + if (!creature || creature->IsPet() || creature->IsTotem()) { handler->SendSysMessage(LANG_SELECT_CREATURE); handler->SetSentErrorMessage(true); return false; } - // Delete the creature - unit->CombatStop(); - unit->DeleteFromDB(); - unit->AddObjectToRemoveList(); + if (TempSummon* summon = creature->ToTempSummon()) + summon->UnSummon(); + else + { + // Delete the creature + creature->CombatStop(); + creature->DeleteFromDB(); + creature->AddObjectToRemoveList(); + } handler->SendSysMessage(LANG_COMMAND_DELCREATMESSAGE); @@ -690,13 +774,20 @@ public: uint32 nativeid = target->GetNativeDisplayId(); uint32 Entry = target->GetEntry(); - int64 curRespawnDelay = target->GetRespawnTimeEx()-time(nullptr); + int64 curRespawnDelay = target->GetRespawnCompatibilityMode() ? target->GetRespawnTimeEx() - time(nullptr) : target->GetMap()->GetCreatureRespawnTime(target->GetSpawnId()) - time(nullptr); + if (curRespawnDelay < 0) curRespawnDelay = 0; std::string curRespawnDelayStr = secsToTimeString(uint64(curRespawnDelay), true); std::string defRespawnDelayStr = secsToTimeString(target->GetRespawnDelay(), true); handler->PSendSysMessage(LANG_NPCINFO_CHAR, target->GetSpawnId(), target->GetGUID().GetCounter(), faction, npcflags, Entry, displayid, nativeid); + if (target->GetCreatureData() && target->GetCreatureData()->spawnGroupData->groupId) + { + SpawnGroupTemplateData const* const groupData = target->GetCreatureData()->spawnGroupData; + handler->PSendSysMessage(LANG_SPAWNINFO_GROUP_ID, groupData->name.c_str(), groupData->groupId, groupData->flags, target->GetMap()->IsSpawnGroupActive(groupData->groupId)); + } + handler->PSendSysMessage(LANG_SPAWNINFO_COMPATIBILITY_MODE, target->GetRespawnCompatibilityMode()); handler->PSendSysMessage(LANG_NPCINFO_LEVEL, target->getLevel()); handler->PSendSysMessage(LANG_NPCINFO_EQUIPMENT, target->GetCurrentEquipmentId(), target->GetOriginalEquipmentId()); handler->PSendSysMessage(LANG_NPCINFO_HEALTH, target->GetCreateHealth(), target->GetMaxHealth(), target->GetHealth()); @@ -766,7 +857,7 @@ public: if (!creatureTemplate) continue; - handler->PSendSysMessage(LANG_CREATURE_LIST_CHAT, guid, guid, creatureTemplate->Name.c_str(), x, y, z, mapId); + handler->PSendSysMessage(LANG_CREATURE_LIST_CHAT, guid, guid, creatureTemplate->Name.c_str(), x, y, z, mapId, "", ""); ++count; } @@ -784,8 +875,13 @@ public: ObjectGuid::LowType lowguid = 0; Creature* creature = handler->getSelectedCreature(); + Player const* player = handler->GetSession()->GetPlayer(); + if (!player) + return false; - if (!creature) + if (creature) + lowguid = creature->GetSpawnId(); + else { // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r char* cId = handler->extractKeyFromLink((char*)args, "Hcreature"); @@ -793,63 +889,45 @@ public: return false; lowguid = atoul(cId); - - // Attempting creature load from DB data - 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 + // Attempting creature load from DB data + CreatureData const* data = sObjectMgr->GetCreatureData(lowguid); + if (!data) { - lowguid = creature->GetSpawnId(); + handler->PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid); + handler->SetSentErrorMessage(true); + return false; } - 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 (creature) + if (player->GetMapId() != data->spawnPoint.GetMapId()) { - if (CreatureData const* data = sObjectMgr->GetCreatureData(creature->GetSpawnId())) - { - const_cast<CreatureData*>(data)->posX = x; - const_cast<CreatureData*>(data)->posY = y; - const_cast<CreatureData*>(data)->posZ = z; - const_cast<CreatureData*>(data)->orientation = o; - } - creature->UpdatePosition(x, y, z, o); - creature->GetMotionMaster()->Initialize(); - if (creature->IsAlive()) // dead creature will reset movement generator at respawn - { - creature->setDeathState(JUST_DIED); - creature->Respawn(); - } + handler->PSendSysMessage(LANG_COMMAND_CREATUREATSAMEMAP, lowguid); + handler->SetSentErrorMessage(true); + return false; } - PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_CREATURE_POSITION); + // update position in memory + const_cast<CreatureData*>(data)->spawnPoint.Relocate(*player); - stmt->setFloat(0, x); - stmt->setFloat(1, y); - stmt->setFloat(2, z); - stmt->setFloat(3, o); + // update position in DB + PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_CREATURE_POSITION); + stmt->setFloat(0, player->GetPositionX()); + stmt->setFloat(1, player->GetPositionY()); + stmt->setFloat(2, player->GetPositionZ()); + stmt->setFloat(3, player->GetOrientation()); stmt->setUInt32(4, lowguid); - WorldDatabase.Execute(stmt); + // respawn selected creature at the new location + if (creature) + { + if (creature->IsAlive()) + creature->setDeathState(JUST_DIED); + creature->Respawn(true); + if (!creature->GetRespawnCompatibilityMode()) + creature->AddObjectToRemoveList(); + } + handler->PSendSysMessage(LANG_COMMAND_CREATUREMOVED); return true; } @@ -1529,13 +1607,13 @@ public: handler->PSendSysMessage(LANG_COMMAND_NPC_SHOWLOOT_LABEL_2, "Per-player quest items"); _IterateNotNormalLootMap(handler, loot.GetPlayerQuestItems(), loot.quest_items); } - + if (!loot.GetPlayerFFAItems().empty()) { handler->PSendSysMessage(LANG_COMMAND_NPC_SHOWLOOT_LABEL_2, "FFA items per allowed player"); _IterateNotNormalLootMap(handler, loot.GetPlayerFFAItems(), loot.items); } - + if (!loot.GetPlayerNonQuestNonFFAConditionalItems().empty()) { handler->PSendSysMessage(LANG_COMMAND_NPC_SHOWLOOT_LABEL_2, "Per-player conditional items"); diff --git a/src/server/scripts/Commands/cs_reload.cpp b/src/server/scripts/Commands/cs_reload.cpp index faeb77cccec..d40d67fc859 100644 --- a/src/server/scripts/Commands/cs_reload.cpp +++ b/src/server/scripts/Commands/cs_reload.cpp @@ -129,6 +129,8 @@ public: { "pickpocketing_loot_template", rbac::RBAC_PERM_COMMAND_RELOAD_PICKPOCKETING_LOOT_TEMPLATE, true, &HandleReloadLootTemplatesPickpocketingCommand, "" }, { "points_of_interest", rbac::RBAC_PERM_COMMAND_RELOAD_POINTS_OF_INTEREST, true, &HandleReloadPointsOfInterestCommand, "" }, { "prospecting_loot_template", rbac::RBAC_PERM_COMMAND_RELOAD_PROSPECTING_LOOT_TEMPLATE, true, &HandleReloadLootTemplatesProspectingCommand, "" }, + { "quest_greeting", rbac::RBAC_PERM_COMMAND_RELOAD_QUEST_GREETING, true, &HandleReloadQuestGreetingCommand, "" }, + { "quest_greeting_locale", rbac::RBAC_PERM_COMMAND_RELOAD_QUEST_GREETING_LOCALE, true, &HandleReloadLocalesQuestGreetingCommand, "" }, { "quest_poi", rbac::RBAC_PERM_COMMAND_RELOAD_QUEST_POI, true, &HandleReloadQuestPOICommand, "" }, { "quest_template", rbac::RBAC_PERM_COMMAND_RELOAD_QUEST_TEMPLATE, true, &HandleReloadQuestTemplateCommand, "" }, { "rbac", rbac::RBAC_PERM_COMMAND_RELOAD_RBAC, true, &HandleReloadRBACCommand, "" }, @@ -243,6 +245,7 @@ public: static bool HandleReloadAllQuestCommand(ChatHandler* handler, char const* /*args*/) { + HandleReloadQuestGreetingCommand(handler, ""); HandleReloadQuestAreaTriggersCommand(handler, "a"); HandleReloadQuestPOICommand(handler, "a"); HandleReloadQuestTemplateCommand(handler, "a"); @@ -317,6 +320,7 @@ public: HandleReloadLocalesPageTextCommand(handler, "a"); HandleReloadLocalesPointsOfInterestCommand(handler, "a"); HandleReloadLocalesQuestCommand(handler, "a"); + HandleReloadLocalesQuestGreetingCommand(handler, ""); return true; } @@ -523,6 +527,22 @@ public: return true; } + static bool HandleReloadQuestGreetingCommand(ChatHandler* handler, char const* /*args*/) + { + TC_LOG_INFO("misc", "Re-Loading Quest Greeting ..."); + sObjectMgr->LoadQuestGreetings(); + handler->SendGlobalGMSysMessage("DB table `quest_greeting` reloaded."); + return true; + } + + static bool HandleReloadLocalesQuestGreetingCommand(ChatHandler* handler, char const* /*args*/) + { + TC_LOG_INFO("misc", "Re-Loading Quest Greeting locales..."); + sObjectMgr->LoadQuestGreetingsLocales(); + handler->SendGlobalGMSysMessage("DB table `quest_greeting_locale` reloaded."); + return true; + } + static bool HandleReloadQuestTemplateCommand(ChatHandler* handler, char const* /*args*/) { TC_LOG_INFO("misc", "Re-Loading Quest Templates..."); diff --git a/src/server/scripts/Commands/cs_wp.cpp b/src/server/scripts/Commands/cs_wp.cpp index efd02314d0e..582cc7b8c79 100644 --- a/src/server/scripts/Commands/cs_wp.cpp +++ b/src/server/scripts/Commands/cs_wp.cpp @@ -31,6 +31,7 @@ EndScriptData */ #include "MotionMaster.h" #include "Player.h" #include "RBAC.h" +#include "WaypointDefines.h" #include "WaypointManager.h" #include "WorldSession.h" @@ -259,7 +260,7 @@ public: stmt->setUInt32(0, guildLow); WorldDatabase.Execute(stmt); - target->UpdateWaypointID(0); + target->UpdateCurrentWaypointInfo(0, 0); stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_CREATURE_MOVEMENT_TYPE); stmt->setUInt8(0, uint8(IDLE_MOTION_TYPE)); @@ -662,7 +663,7 @@ public: // re-create Creature* wpCreature = new Creature(); - if (!wpCreature->Create(map->GenerateLowGuid<HighGuid::Unit>(), map, chr->GetPhaseMaskForSpawn(), VISUAL_WAYPOINT, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation())) + if (!wpCreature->Create(map->GenerateLowGuid<HighGuid::Unit>(), map, chr->GetPhaseMaskForSpawn(), VISUAL_WAYPOINT, *chr)) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT); delete wpCreature; @@ -671,8 +672,7 @@ public: wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn()); // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells(); - /// @todo Should we first use "Create" then use "LoadFromDB"? - if (!wpCreature->LoadCreatureFromDB(wpCreature->GetSpawnId(), map)) + if (!wpCreature->LoadFromDB(wpCreature->GetSpawnId(), map, true, true)) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT); delete wpCreature; @@ -874,7 +874,7 @@ public: float o = chr->GetOrientation(); Creature* wpCreature = new Creature(); - if (!wpCreature->Create(map->GenerateLowGuid<HighGuid::Unit>(), map, chr->GetPhaseMaskForSpawn(), id, x, y, z, o)) + if (!wpCreature->Create(map->GenerateLowGuid<HighGuid::Unit>(), map, chr->GetPhaseMaskForSpawn(), id, { x, y, z, o })) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id); delete wpCreature; @@ -891,7 +891,7 @@ public: WorldDatabase.Execute(stmt); // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells(); - if (!wpCreature->LoadCreatureFromDB(wpCreature->GetSpawnId(), map)) + if (!wpCreature->LoadFromDB(wpCreature->GetSpawnId(), map, true, true)) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id); delete wpCreature; @@ -937,7 +937,7 @@ public: Map* map = chr->GetMap(); Creature* creature = new Creature(); - if (!creature->Create(map->GenerateLowGuid<HighGuid::Unit>(), map, chr->GetPhaseMaskForSpawn(), id, x, y, z, o)) + if (!creature->Create(map->GenerateLowGuid<HighGuid::Unit>(), map, chr->GetPhaseMaskForSpawn(), id, { x, y, z, o })) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id); delete creature; @@ -945,7 +945,7 @@ public: } creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn()); - if (!creature->LoadCreatureFromDB(creature->GetSpawnId(), map)) + if (!creature->LoadFromDB(creature->GetSpawnId(), map, true, true)) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id); delete creature; @@ -986,7 +986,7 @@ public: Map* map = chr->GetMap(); Creature* creature = new Creature(); - if (!creature->Create(map->GenerateLowGuid<HighGuid::Unit>(), map, chr->GetPhaseMaskForSpawn(), id, x, y, z, o)) + if (!creature->Create(map->GenerateLowGuid<HighGuid::Unit>(), map, chr->GetPhaseMaskForSpawn(), id, { x, y, z, o })) { handler->PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id); delete creature; @@ -994,7 +994,7 @@ public: } creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn()); - if (!creature->LoadCreatureFromDB(creature->GetSpawnId(), map)) + if (!creature->LoadFromDB(creature->GetSpawnId(), map, true, true)) { handler->PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id); delete creature; diff --git a/src/server/scripts/EasternKingdoms/AlteracValley/alterac_valley.cpp b/src/server/scripts/EasternKingdoms/AlteracValley/alterac_valley.cpp index f0edc7af0c7..b58fc0b8d8e 100644 --- a/src/server/scripts/EasternKingdoms/AlteracValley/alterac_valley.cpp +++ b/src/server/scripts/EasternKingdoms/AlteracValley/alterac_valley.cpp @@ -107,7 +107,7 @@ class npc_av_marshal_or_warmaster : public CreatureScript events.ScheduleEvent(EVENT_CHECK_RESET, 5000); } - void JustRespawned() override + void JustAppeared() override { Reset(); } diff --git a/src/server/scripts/EasternKingdoms/AlteracValley/boss_drekthar.cpp b/src/server/scripts/EasternKingdoms/AlteracValley/boss_drekthar.cpp index cf034ed0ece..ed97d7670a1 100644 --- a/src/server/scripts/EasternKingdoms/AlteracValley/boss_drekthar.cpp +++ b/src/server/scripts/EasternKingdoms/AlteracValley/boss_drekthar.cpp @@ -71,7 +71,7 @@ public: events.ScheduleEvent(EVENT_RANDOM_YELL, urand(20 * IN_MILLISECONDS, 30 * IN_MILLISECONDS)); //20 to 30 seconds } - void JustRespawned() override + void JustAppeared() override { Reset(); Talk(SAY_RESPAWN); diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/blackrock_depths.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/blackrock_depths.cpp index bcd4a915595..854f571c18c 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/blackrock_depths.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/blackrock_depths.cpp @@ -135,9 +135,9 @@ public: return GetBlackrockDepthsAI<npc_grimstoneAI>(creature); } - struct npc_grimstoneAI : public npc_escortAI + struct npc_grimstoneAI : public EscortAI { - npc_grimstoneAI(Creature* creature) : npc_escortAI(creature) + npc_grimstoneAI(Creature* creature) : EscortAI(creature) { Initialize(); instance = creature->GetInstanceScript(); @@ -202,7 +202,7 @@ public: MobDeath_Timer = 2500; } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { switch (waypointId) { @@ -349,7 +349,7 @@ public: } if (CanWalk) - npc_escortAI::UpdateAI(diff); + EscortAI::UpdateAI(diff); } }; }; @@ -510,9 +510,9 @@ class npc_rocknot : public CreatureScript public: npc_rocknot() : CreatureScript("npc_rocknot") { } - struct npc_rocknotAI : public npc_escortAI + struct npc_rocknotAI : public EscortAI { - npc_rocknotAI(Creature* creature) : npc_escortAI(creature) + npc_rocknotAI(Creature* creature) : EscortAI(creature) { Initialize(); instance = creature->GetInstanceScript(); @@ -543,7 +543,7 @@ public: go->SetGoState((GOState)state); } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { switch (waypointId) { @@ -597,7 +597,7 @@ public: } else BreakDoor_Timer -= diff; } - npc_escortAI::UpdateAI(diff); + EscortAI::UpdateAI(diff); } void QuestReward(Player* /*player*/, Quest const* quest, uint32 /*item*/) override diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/blackrock_depths.h b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/blackrock_depths.h index 5102c58b9b6..75d4e85e8ed 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/blackrock_depths.h +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/blackrock_depths.h @@ -73,4 +73,6 @@ inline AI* GetBlackrockDepthsAI(T* obj) return GetInstanceAI<AI>(obj, BRDScriptName); } +#define RegisterBlackrockDepthsCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetBlackrockDepthsAI) + #endif diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_coren_direbrew.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_coren_direbrew.cpp index b854239c303..77f3a4cd2e6 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_coren_direbrew.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_coren_direbrew.cpp @@ -114,309 +114,271 @@ Position const AntagonistPos[3] = { 896.2667f, -130.483f, -49.66249f, 2.600541f } }; -class boss_coren_direbrew : public CreatureScript +struct boss_coren_direbrew : public BossAI { -public: - boss_coren_direbrew() : CreatureScript("boss_coren_direbrew") { } + boss_coren_direbrew(Creature* creature) : BossAI(creature, DATA_COREN) { } - struct boss_coren_direbrewAI : public BossAI + bool GossipSelect(Player* player, uint32 menuId, uint32 gossipListId) override { - boss_coren_direbrewAI(Creature* creature) : BossAI(creature, DATA_COREN) { } + if (menuId != GOSSIP_ID) + return false; - bool GossipSelect(Player* player, uint32 menuId, uint32 gossipListId) override + if (gossipListId == GOSSIP_OPTION_FIGHT) { - if (menuId != GOSSIP_ID) - return false; + Talk(SAY_INSULT, player); + DoAction(ACTION_START_FIGHT); + } + else if (gossipListId == GOSSIP_OPTION_APOLOGIZE) + CloseGossipMenuFor(player); - if (gossipListId == GOSSIP_OPTION_FIGHT) - { - Talk(SAY_INSULT, player); - DoAction(ACTION_START_FIGHT); - } - else if (gossipListId == GOSSIP_OPTION_APOLOGIZE) - CloseGossipMenuFor(player); + return false; + } - return false; - } + void Reset() override + { + _Reset(); + me->SetImmuneToPC(true); + me->SetFaction(FACTION_FRIENDLY); + events.SetPhase(PHASE_ALL); - void Reset() override - { - _Reset(); - me->SetImmuneToPC(true); - me->SetFaction(FACTION_FRIENDLY); - events.SetPhase(PHASE_ALL); + for (uint8 i = 0; i < MAX_ANTAGONISTS; ++i) + me->SummonCreature(NPC_ANTAGONIST, AntagonistPos[i], TEMPSUMMON_DEAD_DESPAWN); + } - for (uint8 i = 0; i < MAX_ANTAGONISTS; ++i) - me->SummonCreature(NPC_ANTAGONIST, AntagonistPos[i], TEMPSUMMON_DEAD_DESPAWN); - } + void EnterEvadeMode(EvadeReason /*why*/) override + { + _EnterEvadeMode(); + summons.DespawnAll(); + _DespawnAtEvade(Seconds(10)); + } - void MoveInLineOfSight(Unit* who) override - { - if (!events.IsInPhase(PHASE_ALL) || who->GetTypeId() != TYPEID_PLAYER) - return; + void MoveInLineOfSight(Unit* who) override + { + if (!events.IsInPhase(PHASE_ALL) || who->GetTypeId() != TYPEID_PLAYER) + return; - events.SetPhase(PHASE_INTRO); - events.ScheduleEvent(EVENT_INTRO_1, Seconds(6), 0, PHASE_INTRO); - Talk(SAY_INTRO); - } + events.SetPhase(PHASE_INTRO); + events.ScheduleEvent(EVENT_INTRO_1, Seconds(6), 0, PHASE_INTRO); + Talk(SAY_INTRO); + } - void DoAction(int32 action) override + void DoAction(int32 action) override + { + if (action == ACTION_START_FIGHT) { - if (action == ACTION_START_FIGHT) - { - events.SetPhase(PHASE_ONE); - me->SetImmuneToPC(false); - me->SetFaction(FACTION_GOBLIN_DARK_IRON_BAR_PATRON); - me->SetInCombatWithZone(); + events.SetPhase(PHASE_ONE); + me->SetImmuneToPC(false); + me->SetFaction(FACTION_GOBLIN_DARK_IRON_BAR_PATRON); + me->SetInCombatWithZone(); - EntryCheckPredicate pred(NPC_ANTAGONIST); - summons.DoAction(ACTION_ANTAGONIST_HOSTILE, pred); + EntryCheckPredicate pred(NPC_ANTAGONIST); + summons.DoAction(ACTION_ANTAGONIST_HOSTILE, pred); - events.ScheduleEvent(EVENT_SUMMON_MOLE_MACHINE, Seconds(15)); - events.ScheduleEvent(EVENT_DIREBREW_DISARM, Seconds(20)); - } + events.ScheduleEvent(EVENT_SUMMON_MOLE_MACHINE, Seconds(15)); + events.ScheduleEvent(EVENT_DIREBREW_DISARM, Seconds(20)); } + } - void DamageTaken(Unit* /*attacker*/, uint32& damage) override + void DamageTaken(Unit* /*attacker*/, uint32& damage) override + { + if (me->HealthBelowPctDamaged(66, damage) && events.IsInPhase(PHASE_ONE)) { - if (me->HealthBelowPctDamaged(66, damage) && events.IsInPhase(PHASE_ONE)) - { - events.SetPhase(PHASE_TWO); - SummonSister(NPC_ILSA_DIREBREW); - } - else if (me->HealthBelowPctDamaged(33, damage) && events.IsInPhase(PHASE_TWO)) - { - events.SetPhase(PHASE_THREE); - SummonSister(NPC_URSULA_DIREBREW); - } + events.SetPhase(PHASE_TWO); + SummonSister(NPC_ILSA_DIREBREW); } - - void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) override + else if (me->HealthBelowPctDamaged(33, damage) && events.IsInPhase(PHASE_TWO)) { - if (summon->GetEntry() == NPC_ILSA_DIREBREW) - events.ScheduleEvent(EVENT_RESPAWN_ILSA, Seconds(1)); - else if (summon->GetEntry() == NPC_URSULA_DIREBREW) - events.ScheduleEvent(EVENT_RESPAWN_URSULA, Seconds(1)); + events.SetPhase(PHASE_THREE); + SummonSister(NPC_URSULA_DIREBREW); } + } - void JustDied(Unit* /*killer*/) override - { - _JustDied(); + void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) override + { + if (summon->GetEntry() == NPC_ILSA_DIREBREW) + events.ScheduleEvent(EVENT_RESPAWN_ILSA, Seconds(1)); + else if (summon->GetEntry() == NPC_URSULA_DIREBREW) + events.ScheduleEvent(EVENT_RESPAWN_URSULA, Seconds(1)); + } - Map::PlayerList const& players = me->GetMap()->GetPlayers(); - if (!players.isEmpty()) - { - if (Group* group = players.begin()->GetSource()->GetGroup()) - if (group->isLFGGroup()) - sLFGMgr->FinishDungeon(group->GetGUID(), 287, me->GetMap()); - } - } + void JustDied(Unit* /*killer*/) override + { + _JustDied(); - void SummonSister(uint32 entry) + Map::PlayerList const& players = me->GetMap()->GetPlayers(); + if (!players.isEmpty()) { - if (Creature* sister = me->SummonCreature(entry, me->GetPosition(), TEMPSUMMON_DEAD_DESPAWN)) - sister->SetInCombatWithZone(); + if (Group* group = players.begin()->GetSource()->GetGroup()) + if (group->isLFGGroup()) + sLFGMgr->FinishDungeon(group->GetGUID(), 287, me->GetMap()); } + } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim() && !events.IsInPhase(PHASE_INTRO)) - return; + void SummonSister(uint32 entry) + { + if (Creature* sister = me->SummonCreature(entry, me->GetPosition(), TEMPSUMMON_DEAD_DESPAWN)) + sister->SetInCombatWithZone(); + } - events.Update(diff); + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim() && !events.IsInPhase(PHASE_INTRO)) + return; - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + events.Update(diff); - while (uint32 eventId = events.ExecuteEvent()) + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) { - switch (eventId) + case EVENT_INTRO_1: + Talk(SAY_INTRO1); + events.ScheduleEvent(EVENT_INTRO_2, Seconds(4), 0, PHASE_INTRO); + break; + case EVENT_INTRO_2: { - case EVENT_INTRO_1: - Talk(SAY_INTRO1); - events.ScheduleEvent(EVENT_INTRO_2, Seconds(4), 0, PHASE_INTRO); - break; - case EVENT_INTRO_2: - { - EntryCheckPredicate pred(NPC_ANTAGONIST); - summons.DoAction(ACTION_ANTAGONIST_SAY_1, pred); - events.ScheduleEvent(EVENT_INTRO_3, Seconds(3), 0, PHASE_INTRO); - break; - } - case EVENT_INTRO_3: - { - Talk(SAY_INTRO2); - EntryCheckPredicate pred(NPC_ANTAGONIST); - summons.DoAction(ACTION_ANTAGONIST_SAY_2, pred); - break; - } - case EVENT_RESPAWN_ILSA: - SummonSister(NPC_ILSA_DIREBREW); - break; - case EVENT_RESPAWN_URSULA: - SummonSister(NPC_URSULA_DIREBREW); - break; - case EVENT_SUMMON_MOLE_MACHINE: - DoCastAOE(SPELL_MOLE_MACHINE_TARGET_PICKER); - events.Repeat(Seconds(15)); - break; - case EVENT_DIREBREW_DISARM: - DoCastSelf(SPELL_DIREBREW_DISARM_PRE_CAST, true); - events.Repeat(Seconds(20)); - break; - default: - break; + EntryCheckPredicate pred(NPC_ANTAGONIST); + summons.DoAction(ACTION_ANTAGONIST_SAY_1, pred); + events.ScheduleEvent(EVENT_INTRO_3, Seconds(3), 0, PHASE_INTRO); + break; } - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + case EVENT_INTRO_3: + { + Talk(SAY_INTRO2); + EntryCheckPredicate pred(NPC_ANTAGONIST); + summons.DoAction(ACTION_ANTAGONIST_SAY_2, pred); + break; + } + case EVENT_RESPAWN_ILSA: + SummonSister(NPC_ILSA_DIREBREW); + break; + case EVENT_RESPAWN_URSULA: + SummonSister(NPC_URSULA_DIREBREW); + break; + case EVENT_SUMMON_MOLE_MACHINE: + me->CastCustomSpell(SPELL_MOLE_MACHINE_TARGET_PICKER, SPELLVALUE_MAX_TARGETS, 1, nullptr, true); + events.Repeat(Seconds(15)); + break; + case EVENT_DIREBREW_DISARM: + DoCastSelf(SPELL_DIREBREW_DISARM_PRE_CAST, true); + events.Repeat(Seconds(20)); + break; + default: + break; } - DoMeleeAttackIfReady(); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; } - }; - CreatureAI* GetAI(Creature* creature) const override - { - return GetBlackrockDepthsAI<boss_coren_direbrewAI>(creature); + DoMeleeAttackIfReady(); } }; -class npc_coren_direbrew_sisters : public CreatureScript +struct npc_coren_direbrew_sisters : public ScriptedAI { -public: - npc_coren_direbrew_sisters() : CreatureScript("npc_coren_direbrew_sisters") { } + npc_coren_direbrew_sisters(Creature* creature) : ScriptedAI(creature) { } - struct npc_coren_direbrew_sistersAI : public ScriptedAI + void SetGUID(ObjectGuid guid, int32 data) override { - npc_coren_direbrew_sistersAI(Creature* creature) : ScriptedAI(creature) { } - - void SetGUID(ObjectGuid guid, int32 data) override - { - if (data == DATA_TARGET_GUID) - _targetGUID = guid; - } - - ObjectGuid GetGUID(int32 data) const override - { - if (data == DATA_TARGET_GUID) - return _targetGUID; + if (data == DATA_TARGET_GUID) + _targetGUID = guid; + } - return ObjectGuid::Empty; - } + ObjectGuid GetGUID(int32 data) const override + { + if (data == DATA_TARGET_GUID) + return _targetGUID; - void EnterCombat(Unit* /*who*/) override - { - DoCastSelf(SPELL_PORT_TO_COREN); + return ObjectGuid::Empty; + } - if (me->GetEntry() == NPC_URSULA_DIREBREW) - DoCastSelf(SPELL_BARRELED_CONTROL_AURA); - else - DoCastSelf(SPELL_SEND_MUG_CONTROL_AURA); + void EnterCombat(Unit* /*who*/) override + { + DoCastSelf(SPELL_PORT_TO_COREN); - _scheduler - .SetValidator([this] - { - return !me->HasUnitState(UNIT_STATE_CASTING); - }) - .Schedule(Seconds(2), [this](TaskContext mugChuck) - { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, false, true, -SPELL_HAS_DARK_BREWMAIDENS_BREW)) - DoCast(target, SPELL_CHUCK_MUG); - mugChuck.Repeat(Seconds(4)); - }); - } + if (me->GetEntry() == NPC_URSULA_DIREBREW) + DoCastSelf(SPELL_BARRELED_CONTROL_AURA); + else + DoCastSelf(SPELL_SEND_MUG_CONTROL_AURA); - void UpdateAI(uint32 diff) override + _scheduler + .SetValidator([this] { - _scheduler.Update(diff, [this] - { - DoMeleeAttackIfReady(); - }); - } - - private: - ObjectGuid _targetGUID; - TaskScheduler _scheduler; - }; + return !me->HasUnitState(UNIT_STATE_CASTING); + }) + .Schedule(Seconds(2), [this](TaskContext mugChuck) + { + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, false, true, -SPELL_HAS_DARK_BREWMAIDENS_BREW)) + DoCast(target, SPELL_CHUCK_MUG); + mugChuck.Repeat(Seconds(4)); + }); + } - CreatureAI* GetAI(Creature* creature) const override + void UpdateAI(uint32 diff) override { - return GetBlackrockDepthsAI<npc_coren_direbrew_sistersAI>(creature); + _scheduler.Update(diff, [this] + { + DoMeleeAttackIfReady(); + }); } + +private: + ObjectGuid _targetGUID; + TaskScheduler _scheduler; }; -class npc_direbrew_minion : public CreatureScript +struct npc_direbrew_minion : public ScriptedAI { -public: - npc_direbrew_minion() : CreatureScript("npc_direbrew_minion") { } + npc_direbrew_minion(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { } - struct npc_direbrew_minionAI : public ScriptedAI + void Reset() override { - npc_direbrew_minionAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { } - - void Reset() override - { - me->SetFaction(FACTION_GOBLIN_DARK_IRON_BAR_PATRON); - DoCastAOE(SPELL_MOLE_MACHINE_EMERGE, true); - me->SetInCombatWithZone(); - } - - void IsSummonedBy(Unit* /*summoner*/) override - { - if (Creature* coren = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_COREN))) - coren->AI()->JustSummoned(me); - } - - private: - InstanceScript* _instance; - }; + me->SetFaction(FACTION_GOBLIN_DARK_IRON_BAR_PATRON); + me->SetInCombatWithZone(); + } - CreatureAI* GetAI(Creature* creature) const override + void IsSummonedBy(Unit* /*summoner*/) override { - return GetBlackrockDepthsAI<npc_direbrew_minionAI>(creature); + if (Creature* coren = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_COREN))) + coren->AI()->JustSummoned(me); } + +private: + InstanceScript* _instance; }; -class npc_direbrew_antagonist : public CreatureScript +struct npc_direbrew_antagonist : public ScriptedAI { -public: - npc_direbrew_antagonist() : CreatureScript("npc_direbrew_antagonist") { } + npc_direbrew_antagonist(Creature* creature) : ScriptedAI(creature) { } - struct npc_direbrew_antagonistAI : public ScriptedAI + void DoAction(int32 action) override { - npc_direbrew_antagonistAI(Creature* creature) : ScriptedAI(creature) { } - - void DoAction(int32 action) override - { - switch (action) - { - case ACTION_ANTAGONIST_SAY_1: - Talk(SAY_ANTAGONIST_1); - break; - case ACTION_ANTAGONIST_SAY_2: - Talk(SAY_ANTAGONIST_2); - break; - case ACTION_ANTAGONIST_HOSTILE: - me->SetImmuneToPC(false); - me->SetFaction(FACTION_GOBLIN_DARK_IRON_BAR_PATRON); - me->SetInCombatWithZone(); - break; - default: - break; - } - } - - void EnterCombat(Unit* who) override + switch (action) { - Talk(SAY_ANTAGONIST_COMBAT, who); - ScriptedAI::EnterCombat(who); + case ACTION_ANTAGONIST_SAY_1: + Talk(SAY_ANTAGONIST_1); + break; + case ACTION_ANTAGONIST_SAY_2: + Talk(SAY_ANTAGONIST_2); + break; + case ACTION_ANTAGONIST_HOSTILE: + me->SetImmuneToPC(false); + me->SetFaction(FACTION_GOBLIN_DARK_IRON_BAR_PATRON); + me->SetInCombatWithZone(); + break; + default: + break; } - }; + } - CreatureAI* GetAI(Creature* creature) const override + void EnterCombat(Unit* who) override { - return GetBlackrockDepthsAI<npc_direbrew_antagonistAI>(creature); + Talk(SAY_ANTAGONIST_COMBAT, who); + ScriptedAI::EnterCombat(who); } }; @@ -435,12 +397,12 @@ public: _scheduler .Schedule(Seconds(1), [this](TaskContext /*context*/) { - me->UseDoorOrButton(8); - me->CastSpell((Unit*)nullptr, SPELL_MOLE_MACHINE_EMERGE, true); + me->UseDoorOrButton(10000); + me->CastSpell(nullptr, SPELL_MOLE_MACHINE_EMERGE, true); }) .Schedule(Seconds(4), [this](TaskContext /*context*/) { - if (GameObject* trap = me->FindNearestGameObject(GO_MOLE_MACHINE_TRAP, 3.0f)) + if (GameObject* trap = me->GetLinkedTrap()) { trap->SetLootState(GO_ACTIVATED); trap->UseDoorOrButton(); @@ -463,236 +425,170 @@ public: } }; -// 47407 - Direbrew's Disarm (precast) -class spell_direbrew_disarm : public SpellScriptLoader -{ - public: - spell_direbrew_disarm() : SpellScriptLoader("spell_direbrew_disarm") { } - - class spell_direbrew_disarm_AuraScript : public AuraScript - { - PrepareAuraScript(spell_direbrew_disarm_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DIREBREW_DISARM, SPELL_DIREBREW_DISARM_GROW }); - } - - void PeriodicTick(AuraEffect const* /*aurEff*/) - { - if (Aura* aura = GetTarget()->GetAura(SPELL_DIREBREW_DISARM_GROW)) - { - aura->SetStackAmount(aura->GetStackAmount() + 1); - aura->SetDuration(aura->GetDuration() - 1500); - } - } - - void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - GetTarget()->CastSpell(GetTarget(), SPELL_DIREBREW_DISARM_GROW, true); - GetTarget()->CastSpell(GetTarget(), SPELL_DIREBREW_DISARM); - } - - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_direbrew_disarm_AuraScript::PeriodicTick, EFFECT_1, SPELL_AURA_PERIODIC_DUMMY); - OnEffectApply += AuraEffectRemoveFn(spell_direbrew_disarm_AuraScript::OnApply, EFFECT_1, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL); - } - }; - - AuraScript* GetAuraScript() const override - { - return new spell_direbrew_disarm_AuraScript(); - } -}; - // 47691 - Summon Mole Machine Target Picker -class spell_direbrew_summon_mole_machine_target_picker : public SpellScriptLoader +class spell_direbrew_summon_mole_machine_target_picker : public SpellScript { - public: - spell_direbrew_summon_mole_machine_target_picker() : SpellScriptLoader("spell_direbrew_summon_mole_machine_target_picker") { } - - class spell_direbrew_summon_mole_machine_target_picker_SpellScript : public SpellScript - { - PrepareSpellScript(spell_direbrew_summon_mole_machine_target_picker_SpellScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_MOLE_MACHINE_MINION_SUMMONER }); - } + PrepareSpellScript(spell_direbrew_summon_mole_machine_target_picker); - void HandleScriptEffect(SpellEffIndex /*effIndex*/) - { - GetCaster()->CastSpell(GetHitUnit(), SPELL_MOLE_MACHINE_MINION_SUMMONER, true); - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_MOLE_MACHINE_MINION_SUMMONER }); + } - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_direbrew_summon_mole_machine_target_picker_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - } - }; + void HandleScriptEffect(SpellEffIndex /*effIndex*/) + { + GetCaster()->CastSpell(GetHitUnit(), SPELL_MOLE_MACHINE_MINION_SUMMONER, true); + } - SpellScript* GetSpellScript() const override - { - return new spell_direbrew_summon_mole_machine_target_picker_SpellScript(); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_direbrew_summon_mole_machine_target_picker::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } }; // 47370 - Send Mug Target Picker -class spell_send_mug_target_picker : public SpellScriptLoader +class spell_send_mug_target_picker : public SpellScript { - public: - spell_send_mug_target_picker() : SpellScriptLoader("spell_send_mug_target_picker") { } - - class spell_send_mug_target_picker_SpellScript : public SpellScript - { - PrepareSpellScript(spell_send_mug_target_picker_SpellScript); + PrepareSpellScript(spell_send_mug_target_picker); - void FilterTargets(std::list<WorldObject*>& targets) - { - Unit* caster = GetCaster(); - - targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_HAS_DARK_BREWMAIDENS_BREW)); + void FilterTargets(std::list<WorldObject*>& targets) + { + Unit* caster = GetCaster(); - if (targets.size() > 1) - targets.remove_if([caster](WorldObject* obj) - { - if (obj->GetGUID() == caster->GetAI()->GetGUID(DATA_TARGET_GUID)) - return true; - return false; - }); + targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_HAS_DARK_BREWMAIDENS_BREW)); - if (targets.empty()) - return; + if (targets.size() > 1) + targets.remove_if([caster](WorldObject* obj) + { + if (obj->GetGUID() == caster->GetAI()->GetGUID(DATA_TARGET_GUID)) + return true; + return false; + }); - WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets); - targets.clear(); - targets.push_back(target); - } + if (targets.empty()) + return; - void HandleDummy(SpellEffIndex /*effIndex*/) - { - Unit* caster = GetCaster(); - caster->GetAI()->SetGUID(GetHitUnit()->GetGUID(), DATA_TARGET_GUID); - caster->CastSpell(GetHitUnit(), SPELL_SEND_FIRST_MUG, true); - } + WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets); + targets.clear(); + targets.push_back(target); + } - void Register() override - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_send_mug_target_picker_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); - OnEffectHitTarget += SpellEffectFn(spell_send_mug_target_picker_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + void HandleDummy(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + caster->GetAI()->SetGUID(GetHitUnit()->GetGUID(), DATA_TARGET_GUID); + caster->CastSpell(GetHitUnit(), SPELL_SEND_FIRST_MUG, true); + } - SpellScript* GetSpellScript() const override - { - return new spell_send_mug_target_picker_SpellScript(); - } + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_send_mug_target_picker::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); + OnEffectHitTarget += SpellEffectFn(spell_send_mug_target_picker::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; // 47344 - Request Second Mug -class spell_request_second_mug : public SpellScriptLoader +class spell_request_second_mug : public SpellScript { - public: - spell_request_second_mug() : SpellScriptLoader("spell_request_second_mug") { } - - class spell_request_second_mug_SpellScript : public SpellScript - { - PrepareSpellScript(spell_request_second_mug_SpellScript); + PrepareSpellScript(spell_request_second_mug); - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_SEND_SECOND_MUG }); - } - - void HandleScriptEffect(SpellEffIndex /*effIndex*/) - { - GetHitUnit()->CastSpell(GetCaster(), SPELL_SEND_SECOND_MUG, true); - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SEND_SECOND_MUG }); + } - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_request_second_mug_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - } - }; + void HandleScriptEffect(SpellEffIndex /*effIndex*/) + { + GetHitUnit()->CastSpell(GetCaster(), SPELL_SEND_SECOND_MUG, true); + } - SpellScript* GetSpellScript() const override - { - return new spell_request_second_mug_SpellScript(); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_request_second_mug::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } }; // 47369 - Send Mug Control Aura -class spell_send_mug_control_aura : public SpellScriptLoader +class spell_send_mug_control_aura : public AuraScript { - public: - spell_send_mug_control_aura() : SpellScriptLoader("spell_send_mug_control_aura") { } - - class spell_send_mug_control_aura_AuraScript : public AuraScript - { - PrepareAuraScript(spell_send_mug_control_aura_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_SEND_MUG_TARGET_PICKER }); - } + PrepareAuraScript(spell_send_mug_control_aura); - void PeriodicTick(AuraEffect const* /*aurEff*/) - { - GetTarget()->CastSpell(GetTarget(), SPELL_SEND_MUG_TARGET_PICKER, true); - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SEND_MUG_TARGET_PICKER }); + } - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_send_mug_control_aura_AuraScript::PeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); - } - }; + void PeriodicTick(AuraEffect const* /*aurEff*/) + { + GetTarget()->CastSpell(GetTarget(), SPELL_SEND_MUG_TARGET_PICKER, true); + } - AuraScript* GetAuraScript() const override - { - return new spell_send_mug_control_aura_AuraScript(); - } + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_send_mug_control_aura::PeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + } }; // 50278 - Barreled Control Aura -class spell_barreled_control_aura : public SpellScriptLoader +class spell_barreled_control_aura : public AuraScript { - public: - spell_barreled_control_aura() : SpellScriptLoader("spell_barreled_control_aura") { } + PrepareAuraScript(spell_barreled_control_aura); - class spell_barreled_control_aura_AuraScript : public AuraScript - { - PrepareAuraScript(spell_barreled_control_aura_AuraScript); + void PeriodicTick(AuraEffect const* /*aurEff*/) + { + PreventDefaultAction(); + GetTarget()->CastSpell(nullptr, SPELL_BARRELED, true); + } - void PeriodicTick(AuraEffect const* /*aurEff*/) - { - PreventDefaultAction(); - GetTarget()->CastSpell((Unit*)nullptr, SPELL_BARRELED, true); - } + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_barreled_control_aura::PeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } +}; - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_barreled_control_aura_AuraScript::PeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); - } - }; +// 47407 - Direbrew's Disarm (precast) +class spell_direbrew_disarm : public AuraScript +{ + PrepareAuraScript(spell_direbrew_disarm); - AuraScript* GetAuraScript() const override + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_DIREBREW_DISARM, SPELL_DIREBREW_DISARM_GROW }); + } + + void PeriodicTick(AuraEffect const* /*aurEff*/) + { + if (Aura* aura = GetTarget()->GetAura(SPELL_DIREBREW_DISARM_GROW)) { - return new spell_barreled_control_aura_AuraScript(); + aura->SetStackAmount(aura->GetStackAmount() + 1); + aura->SetDuration(aura->GetDuration() - 1500); } + } + + void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->CastSpell(GetTarget(), SPELL_DIREBREW_DISARM_GROW, true); + GetTarget()->CastSpell(GetTarget(), SPELL_DIREBREW_DISARM); + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_direbrew_disarm::PeriodicTick, EFFECT_1, SPELL_AURA_PERIODIC_DUMMY); + OnEffectApply += AuraEffectRemoveFn(spell_direbrew_disarm::OnApply, EFFECT_1, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL); + } }; void AddSC_boss_coren_direbrew() { - new boss_coren_direbrew(); - new npc_coren_direbrew_sisters(); - new npc_direbrew_minion(); - new npc_direbrew_antagonist(); + RegisterBlackrockDepthsCreatureAI(boss_coren_direbrew); + RegisterBlackrockDepthsCreatureAI(npc_coren_direbrew_sisters); + RegisterBlackrockDepthsCreatureAI(npc_direbrew_minion); + RegisterBlackrockDepthsCreatureAI(npc_direbrew_antagonist); new go_direbrew_mole_machine(); - new spell_direbrew_disarm(); - new spell_direbrew_summon_mole_machine_target_picker(); - new spell_send_mug_target_picker(); - new spell_request_second_mug(); - new spell_send_mug_control_aura(); - new spell_barreled_control_aura(); + RegisterSpellScript(spell_direbrew_summon_mole_machine_target_picker); + RegisterSpellScript(spell_send_mug_target_picker); + RegisterSpellScript(spell_request_second_mug); + RegisterAuraScript(spell_send_mug_control_aura); + RegisterAuraScript(spell_barreled_control_aura); + RegisterAuraScript(spell_direbrew_disarm); } diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp index 076966a2acb..105b27e711e 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp @@ -355,7 +355,7 @@ public: nefarian->setActive(true); nefarian->SetCanFly(true); nefarian->SetDisableGravity(true); - nefarian->CastSpell((Unit*)nullptr, SPELL_SHADOWFLAME_INITIAL); + nefarian->CastSpell(nullptr, SPELL_SHADOWFLAME_INITIAL); nefarian->GetMotionMaster()->MovePoint(1, NefarianLoc[1]); } events.CancelEvent(EVENT_MIND_CONTROL); diff --git a/src/server/scripts/EasternKingdoms/Gnomeregan/gnomeregan.cpp b/src/server/scripts/EasternKingdoms/Gnomeregan/gnomeregan.cpp index 83d0fdcc943..b965e3063e9 100644 --- a/src/server/scripts/EasternKingdoms/Gnomeregan/gnomeregan.cpp +++ b/src/server/scripts/EasternKingdoms/Gnomeregan/gnomeregan.cpp @@ -94,9 +94,9 @@ public: return GetGnomereganAI<npc_blastmaster_emi_shortfuseAI>(creature); } - struct npc_blastmaster_emi_shortfuseAI : public npc_escortAI + struct npc_blastmaster_emi_shortfuseAI : public EscortAI { - npc_blastmaster_emi_shortfuseAI(Creature* creature) : npc_escortAI(creature) + npc_blastmaster_emi_shortfuseAI(Creature* creature) : EscortAI(creature) { instance = creature->GetInstanceScript(); creature->RestoreFaction(); @@ -219,7 +219,7 @@ public: } } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { //just in case if (GetPlayerForEscort()) diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_prince_malchezaar.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_prince_malchezaar.cpp index fcd307ada07..2cb87b96262 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/boss_prince_malchezaar.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_prince_malchezaar.cpp @@ -491,8 +491,7 @@ public: { if (axe->GetVictim()) ResetThreat(axe->GetVictim(), axe); - if (target) - AddThreat(target, 1000000.0f, axe); + AddThreat(target, 1000000.0f, axe); } } } diff --git a/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp b/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp index 8c5f57e9a8e..994dc2a989a 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp @@ -131,9 +131,9 @@ class npc_barnes : public CreatureScript public: npc_barnes() : CreatureScript("npc_barnes") { } - struct npc_barnesAI : public npc_escortAI + struct npc_barnesAI : public EscortAI { - npc_barnesAI(Creature* creature) : npc_escortAI(creature) + npc_barnesAI(Creature* creature) : EscortAI(creature) { Initialize(); RaidWiped = false; @@ -184,7 +184,7 @@ public: void EnterCombat(Unit* /*who*/) override { } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { switch (waypointId) { @@ -288,7 +288,7 @@ public: void UpdateAI(uint32 diff) override { - npc_escortAI::UpdateAI(diff); + EscortAI::UpdateAI(diff); if (HasEscortState(STATE_ESCORT_PAUSED)) { diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp index 5cf03b678f6..3a10b0f5619 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp @@ -392,8 +392,7 @@ public: for (uint8 i = 0; i < 3; ++i) { - Unit* target = nullptr; - target = SelectTarget(SELECT_TARGET_RANDOM, 0); + Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0); Creature* Orb = DoSpawnCreature(CREATURE_ARCANE_SPHERE, 5, 5, 0, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000); if (Orb && target) @@ -564,15 +563,12 @@ public: Rebirth = true; } - if (Rebirth) + if (Death_Timer <= diff) { - if (Death_Timer <= diff) - { - me->SummonCreature(CREATURE_PHOENIX_EGG, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 45000); - me->DisappearAndDie(); - Rebirth = false; - } else Death_Timer -= diff; - } + me->SummonCreature(CREATURE_PHOENIX_EGG, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 45000); + me->DisappearAndDie(); + Rebirth = false; + } else Death_Timer -= diff; } if (!UpdateVictim()) diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_selin_fireheart.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_selin_fireheart.cpp index 86592f5677c..93f10b1a81e 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_selin_fireheart.cpp +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_selin_fireheart.cpp @@ -65,6 +65,7 @@ enum Misc ACTION_SWITCH_PHASE = 1 }; +// @todo crystals should really be a DB creature summon group, having them in `creature` like this will cause tons of despawn/respawn bugs class boss_selin_fireheart : public CreatureScript { public: @@ -72,23 +73,15 @@ class boss_selin_fireheart : public CreatureScript struct boss_selin_fireheartAI : public BossAI { - boss_selin_fireheartAI(Creature* creature) : BossAI(creature, DATA_SELIN) - { - _scheduledEvents = false; - } + boss_selin_fireheartAI(Creature* creature) : BossAI(creature, DATA_SELIN), _scheduledEvents(false) { } void Reset() override { - Crystals.clear(); - me->GetCreatureListWithEntryInGrid(Crystals, NPC_FEL_CRYSTAL, 250.0f); + std::list<Creature*> crystals; + me->GetCreatureListWithEntryInGrid(crystals, NPC_FEL_CRYSTAL, 250.0f); - for (Creature* creature : Crystals) - { - if (!creature->IsAlive()) - creature->Respawn(); - - creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - } + for (Creature* creature : crystals) + creature->Respawn(true); _Reset(); CrystalGUID.Clear(); @@ -112,21 +105,16 @@ class boss_selin_fireheart : public CreatureScript void SelectNearestCrystal() { - if (Crystals.empty()) - return; - - Crystals.sort(Trinity::ObjectDistanceOrderPred(me)); - if (Creature* CrystalChosen = Crystals.front()) + if (Creature* crystal = me->FindNearestCreature(NPC_FEL_CRYSTAL, 250.0f)) { Talk(SAY_ENERGY); Talk(EMOTE_CRYSTAL); - DoCast(CrystalChosen, SPELL_FEL_CRYSTAL_DUMMY); - CrystalGUID = CrystalChosen->GetGUID(); - Crystals.remove(CrystalChosen); - + DoCast(crystal, SPELL_FEL_CRYSTAL_DUMMY); + CrystalGUID = crystal->GetGUID(); + float x, y, z; - CrystalChosen->GetClosePoint(x, y, z, me->GetCombatReach(), CONTACT_DISTANCE); + crystal->GetClosePoint(x, y, z, me->GetCombatReach(), CONTACT_DISTANCE); events.SetPhase(PHASE_DRAIN); me->SetWalk(false); @@ -136,14 +124,11 @@ class boss_selin_fireheart : public CreatureScript void ShatterRemainingCrystals() { - if (Crystals.empty()) - return; + std::list<Creature*> crystals; + me->GetCreatureListWithEntryInGrid(crystals, NPC_FEL_CRYSTAL, 250.0f); - for (Creature* crystal : Crystals) - { - if (crystal && crystal->IsAlive()) - crystal->KillSelf(); - } + for (Creature* crystal : crystals) + crystal->KillSelf(); } void EnterCombat(Unit* /*who*/) override @@ -259,7 +244,6 @@ class boss_selin_fireheart : public CreatureScript } private: - std::list<Creature*> Crystals; ObjectGuid CrystalGUID; bool _scheduledEvents; }; diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp index aa3b894bbe3..d11f352f6c0 100644 --- a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp @@ -1071,7 +1071,7 @@ class npc_scarlet_miner_cart : public CreatureScript if (apply) { _playerGUID = who->GetGUID(); - me->CastSpell((Unit*)nullptr, SPELL_SUMMON_MINER, true); + me->CastSpell(nullptr, SPELL_SUMMON_MINER, true); } else { @@ -1107,9 +1107,9 @@ class npc_scarlet_miner : public CreatureScript public: npc_scarlet_miner() : CreatureScript("npc_scarlet_miner") { } - struct npc_scarlet_minerAI : public npc_escortAI + struct npc_scarlet_minerAI : public EscortAI { - npc_scarlet_minerAI(Creature* creature) : npc_escortAI(creature) + npc_scarlet_minerAI(Creature* creature) : EscortAI(creature) { Initialize(); me->SetReactState(REACT_PASSIVE); @@ -1138,7 +1138,7 @@ class npc_scarlet_miner : public CreatureScript void InitWaypoint() { - AddWaypoint(1, 2389.03f, -5902.74f, 109.014f, 5000); + AddWaypoint(1, 2389.03f, -5902.74f, 109.014f, 0.f, 5000); AddWaypoint(2, 2341.812012f, -5900.484863f, 102.619743f); AddWaypoint(3, 2306.561279f, -5901.738281f, 91.792419f); AddWaypoint(4, 2300.098389f, -5912.618652f, 86.014885f); @@ -1157,7 +1157,7 @@ class npc_scarlet_miner : public CreatureScript AddWaypoint(14, 2172.516602f, -6146.752441f, 1.074235f); AddWaypoint(15, 2138.918457f, -6158.920898f, 1.342926f); AddWaypoint(16, 2129.866699f, -6174.107910f, 4.380779f); - AddWaypoint(17, 2117.709473f, -6193.830078f, 13.3542f, 10000); + AddWaypoint(17, 2117.709473f, -6193.830078f, 13.3542f, 0.f, 10000); } else { @@ -1165,7 +1165,7 @@ class npc_scarlet_miner : public CreatureScript AddWaypoint(14, 2234.265625f, -6163.741211f, 0.916021f); AddWaypoint(15, 2268.071777f, -6158.750977f, 1.822252f); AddWaypoint(16, 2270.028320f, -6176.505859f, 6.340538f); - AddWaypoint(17, 2271.739014f, -6195.401855f, 13.3542f, 10000); + AddWaypoint(17, 2271.739014f, -6195.401855f, 13.3542f, 0.f, 10000); } } @@ -1176,7 +1176,7 @@ class npc_scarlet_miner : public CreatureScript SetDespawnAtFar(false); } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { switch (waypointId) { @@ -1224,7 +1224,7 @@ class npc_scarlet_miner : public CreatureScript else IntroTimer -= diff; } - npc_escortAI::UpdateAI(diff); + EscortAI::UpdateAI(diff); } }; diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter2.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter2.cpp index 5e02a18caa6..968b0cd0f61 100644 --- a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter2.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter2.cpp @@ -201,9 +201,9 @@ class npc_koltira_deathweaver : public CreatureScript public: npc_koltira_deathweaver() : CreatureScript("npc_koltira_deathweaver") { } - struct npc_koltira_deathweaverAI : public npc_escortAI + struct npc_koltira_deathweaverAI : public EscortAI { - npc_koltira_deathweaverAI(Creature* creature) : npc_escortAI(creature) + npc_koltira_deathweaverAI(Creature* creature) : EscortAI(creature) { Initialize(); me->SetReactState(REACT_DEFENSIVE); @@ -228,7 +228,7 @@ public: } } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { switch (waypointId) { @@ -281,7 +281,7 @@ public: void UpdateAI(uint32 uiDiff) override { - npc_escortAI::UpdateAI(uiDiff); + EscortAI::UpdateAI(uiDiff); if (HasEscortState(STATE_ESCORT_PAUSED)) { @@ -687,7 +687,7 @@ public: switch (ExecuteSpeech_Counter) { - case 0: + case 0: Talk(SAY_EXEC_START, player); break; case 1: diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp index 5484bb78c2f..61806772fcd 100644 --- a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp @@ -274,9 +274,9 @@ class npc_highlord_darion_mograine : public CreatureScript public: npc_highlord_darion_mograine() : CreatureScript("npc_highlord_darion_mograine") { } - struct npc_highlord_darion_mograineAI : public npc_escortAI + struct npc_highlord_darion_mograineAI : public EscortAI { - npc_highlord_darion_mograineAI(Creature* creature) : npc_escortAI(creature) + npc_highlord_darion_mograineAI(Creature* creature) : EscortAI(creature) { Reset(); } @@ -453,7 +453,7 @@ public: SetEscortPaused(bOnHold); } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { switch (waypointId) { @@ -571,12 +571,12 @@ public: void EnterEvadeMode(EvadeReason why) override { if (!bIsBattle)//do not reset self if we are in battle - npc_escortAI::EnterEvadeMode(why); + EscortAI::EnterEvadeMode(why); } void UpdateAI(uint32 diff) override { - npc_escortAI::UpdateAI(diff); + EscortAI::UpdateAI(diff); if (!bIsBattle) { diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_herod.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_herod.cpp index 509faae7957..35d551afa71 100644 --- a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_herod.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_herod.cpp @@ -149,9 +149,9 @@ public: return GetScarletMonasteryAI<npc_scarlet_traineeAI>(creature); } - struct npc_scarlet_traineeAI : public npc_escortAI + struct npc_scarlet_traineeAI : public EscortAI { - npc_scarlet_traineeAI(Creature* creature) : npc_escortAI(creature) + npc_scarlet_traineeAI(Creature* creature) : EscortAI(creature) { Start_Timer = urand(1000, 6000); } @@ -159,7 +159,6 @@ public: uint32 Start_Timer; void Reset() override { } - void WaypointReached(uint32 /*waypointId*/) override { } void EnterCombat(Unit* /*who*/) override { } void UpdateAI(uint32 diff) override @@ -173,7 +172,7 @@ public: } else Start_Timer -= diff; } - npc_escortAI::UpdateAI(diff); + EscortAI::UpdateAI(diff); } }; }; diff --git a/src/server/scripts/EasternKingdoms/Scholomance/boss_illucia_barov.cpp b/src/server/scripts/EasternKingdoms/Scholomance/boss_illucia_barov.cpp index 8db6ade664d..ae50fee187a 100644 --- a/src/server/scripts/EasternKingdoms/Scholomance/boss_illucia_barov.cpp +++ b/src/server/scripts/EasternKingdoms/Scholomance/boss_illucia_barov.cpp @@ -28,10 +28,11 @@ Category: Scholomance enum Spells { - SPELL_CURSEOFAGONY = 34794, - SPELL_SHADOWSHOCK = 34799, - SPELL_SILENCE = 34803, - SPELL_FEAR = 34803 + SPELL_CURSEOFAGONY = 18671, + SPELL_DOMINATE = 7645, // UNUSED YET added for documentation + SPELL_FEAR = 12542, + SPELL_SHADOWSHOCK = 17234, + SPELL_SILENCE = 12528 }; enum Events diff --git a/src/server/scripts/EasternKingdoms/ShadowfangKeep/shadowfang_keep.cpp b/src/server/scripts/EasternKingdoms/ShadowfangKeep/shadowfang_keep.cpp index 86ef68e8c4a..21585333cbf 100644 --- a/src/server/scripts/EasternKingdoms/ShadowfangKeep/shadowfang_keep.cpp +++ b/src/server/scripts/EasternKingdoms/ShadowfangKeep/shadowfang_keep.cpp @@ -67,16 +67,16 @@ class npc_shadowfang_prisoner : public CreatureScript public: npc_shadowfang_prisoner() : CreatureScript("npc_shadowfang_prisoner") { } - struct npc_shadowfang_prisonerAI : public npc_escortAI + struct npc_shadowfang_prisonerAI : public EscortAI { - npc_shadowfang_prisonerAI(Creature* creature) : npc_escortAI(creature) + npc_shadowfang_prisonerAI(Creature* creature) : EscortAI(creature) { instance = creature->GetInstanceScript(); } InstanceScript* instance; - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { switch (waypointId) { @@ -333,7 +333,7 @@ class spell_shadowfang_keep_haunting_spirits : public SpellScriptLoader void HandleDummyTick(AuraEffect const* aurEff) { - GetTarget()->CastSpell((Unit*)nullptr, aurEff->GetAmount(), true); + GetTarget()->CastSpell(nullptr, aurEff->GetAmount(), true); } void HandleUpdatePeriodic(AuraEffect* aurEff) diff --git a/src/server/scripts/EasternKingdoms/Stratholme/instance_stratholme.cpp b/src/server/scripts/EasternKingdoms/Stratholme/instance_stratholme.cpp index f55ed325148..42780658f2b 100644 --- a/src/server/scripts/EasternKingdoms/Stratholme/instance_stratholme.cpp +++ b/src/server/scripts/EasternKingdoms/Stratholme/instance_stratholme.cpp @@ -24,6 +24,7 @@ SDCategory: Stratholme EndScriptData */ #include "ScriptMgr.h" +#include "AreaBoundary.h" #include "Creature.h" #include "EventMap.h" #include "GameObject.h" @@ -33,17 +34,15 @@ EndScriptData */ #include "Player.h" #include "stratholme.h" -enum Misc -{ - MAX_ENCOUNTER = 6 -}; - enum InstanceEvents { EVENT_BARON_RUN = 1, EVENT_SLAUGHTER_SQUARE = 2 }; +Position const timmyTheCruelSpawnPosition = { 3625.358f, -3188.108f, 130.3985f, 4.834562f }; +EllipseBoundary const beforeScarletGate(Position(3671.158f, -3181.79f), 60.0f, 40.0f); + class instance_stratholme : public InstanceMapScript { public: @@ -54,16 +53,22 @@ class instance_stratholme : public InstanceMapScript instance_stratholme_InstanceMapScript(Map* map) : InstanceScript(map) { SetHeaders(DataHeader); + for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) EncounterState[i] = NOT_STARTED; for (uint8 i = 0; i < 5; ++i) IsSilverHandDead[i] = false; + + timmySpawned = false; + scarletsKilled = 0; } uint32 EncounterState[MAX_ENCOUNTER]; + uint8 scarletsKilled; bool IsSilverHandDead[5]; + bool timmySpawned; ObjectGuid serviceEntranceGUID; ObjectGuid gauntletGate1GUID; @@ -82,6 +87,33 @@ class instance_stratholme : public InstanceMapScript GuidSet abomnationGUID; EventMap events; + void OnUnitDeath(Unit* who) override + { + switch (who->GetEntry()) + { + case NPC_CRIMSON_GUARDSMAN: + case NPC_CRIMSON_CONJUROR: + case NPC_CRIMSON_INITATE: + case NPC_CRIMSON_GALLANT: + { + if (!timmySpawned) + { + Position pos = who->ToCreature()->GetHomePosition(); + // check if they're in front of the entrance + if (beforeScarletGate.IsWithinBoundary(pos)) + { + if (++scarletsKilled >= TIMMY_THE_CRUEL_CRUSADERS_REQUIRED) + { + instance->SummonCreature(NPC_TIMMY_THE_CRUEL, timmyTheCruelSpawnPosition); + timmySpawned = true; + } + } + } + break; + } + } + } + bool StartSlaugtherSquare() { //change to DONE when crystals implemented diff --git a/src/server/scripts/EasternKingdoms/Stratholme/stratholme.h b/src/server/scripts/EasternKingdoms/Stratholme/stratholme.h index e30d6feecdc..d82d0849863 100644 --- a/src/server/scripts/EasternKingdoms/Stratholme/stratholme.h +++ b/src/server/scripts/EasternKingdoms/Stratholme/stratholme.h @@ -57,6 +57,14 @@ enum STRCreatureIds NPC_ABOM_VENOM = 10417, NPC_BLACK_GUARD = 10394, NPC_YSIDA = 16031, + + // Scarlet side creatures + NPC_CRIMSON_GUARDSMAN = 10418, + NPC_CRIMSON_CONJUROR = 10419, + NPC_CRIMSON_INITATE = 10420, + NPC_CRIMSON_GALLANT = 10424, + + NPC_TIMMY_THE_CRUEL = 10808 }; enum STRGameobjectIds @@ -84,6 +92,13 @@ enum STRSpellIds SPELL_BARON_ULTIMATUM = 27861 }; +enum STRMisc +{ + //! amount of crusade monsters required to be killed in order for timmy the cruel to spawn + TIMMY_THE_CRUEL_CRUSADERS_REQUIRED = 15, + MAX_ENCOUNTER = 6 +}; + template <class AI, class T> inline AI* GetStratholmeAI(T* obj) { diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp index 88254211099..c58b8afac7a 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp @@ -186,7 +186,7 @@ public: Talk(YELL_KILL); } - void JustRespawned() override + void JustAppeared() override { Talk(YELL_BIRTH); } diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp index 5dd4a3248ac..c671878d465 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/> * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -16,808 +15,782 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Boss_Kalecgos -SD%Complete: 95 -SDComment: -SDCategory: Sunwell_Plateau -EndScriptData */ - #include "ScriptMgr.h" #include "GameObject.h" #include "GameObjectAI.h" #include "InstanceScript.h" -#include "Log.h" -#include "Map.h" #include "MotionMaster.h" -#include "ObjectAccessor.h" #include "Player.h" #include "ScriptedCreature.h" +#include "SpellAuraEffects.h" +#include "SpellScript.h" #include "sunwell_plateau.h" #include "TemporarySummon.h" #include "WorldSession.h" enum Yells { - SAY_SATH_AGGRO = 0, - SAY_SATH_SLAY = 1, - SAY_SATH_DEATH = 2, - SAY_SATH_SPELL1 = 3, - SAY_SATH_SPELL2 = 4, - - SAY_EVIL_AGGRO = 0, - SAY_EVIL_SLAY = 1, - SAY_GOOD_PLRWIN = 2, - SAY_EVIL_ENRAGE = 3, - - SAY_GOOD_AGGRO = 0, - SAY_GOOD_NEAR_DEATH = 1, - SAY_GOOD_NEAR_DEATH2 = 2 + SAY_SATH_AGGRO = 0, + SAY_SATH_SLAY = 1, + SAY_SATH_DEATH = 2, + SAY_SATH_SPELL1 = 3, + SAY_SATH_SPELL2 = 4, + + SAY_EVIL_AGGRO = 0, + SAY_EVIL_SLAY = 1, + SAY_OUTRO_1 = 2, + SAY_OUTRO_2 = 3, + EMOTE_ENRAGE = 4, + SAY_ARCANE_BUFFET = 6, + + SAY_GOOD_NEAR_DEATH_0 = 0, + SAY_GOOD_NEAR_DEATH_1 = 1, + SAY_GOOD_NEAR_DEATH_2 = 2, + SAY_GOOD_DEATH = 3 }; enum Spells { - AURA_SUNWELL_RADIANCE = 45769, - AURA_SPECTRAL_EXHAUSTION = 44867, - AURA_SPECTRAL_REALM = 46021, - AURA_SPECTRAL_INVISIBILITY = 44801, - AURA_DEMONIC_VISUAL = 44800, - - SPELL_SPECTRAL_BLAST = 44869, - SPELL_TELEPORT_SPECTRAL = 46019, - SPELL_ARCANE_BUFFET = 45018, - SPELL_FROST_BREATH = 44799, - SPELL_TAIL_LASH = 45122, - - SPELL_BANISH = 44836, - SPELL_TRANSFORM_KALEC = 44670, - SPELL_ENRAGE = 44807, - - SPELL_CORRUPTION_STRIKE = 45029, - SPELL_AGONY_CURSE = 45032, - SPELL_SHADOW_BOLT = 45031, - - SPELL_HEROIC_STRIKE = 45026, - SPELL_REVITALIZE = 45027 + SPELL_SPECTRAL_BLAST = 44869, + SPELL_ARCANE_BUFFET = 45018, + SPELL_FROST_BREATH = 44799, + SPELL_TAIL_LASH = 45122, + SPELL_WILD_MAGIC_1 = 45001, + SPELL_WILD_MAGIC_2 = 45002, + SPELL_WILD_MAGIC_3 = 45004, + SPELL_WILD_MAGIC_4 = 45006, + SPELL_WILD_MAGIC_5 = 45010, + SPELL_WILD_MAGIC_6 = 44978, + SPELL_BANISH = 44836, + SPELL_ENRAGE = 44807, + SPELL_DEMONIC_VISUAL = 44800, + SPELL_CORRUPTION_STRIKE = 45029, + SPELL_AGONY_CURSE = 45032, + SPELL_SHADOW_BOLT = 45031, + SPELL_TAP_CHECK = 46732, + SPELL_TAP_CHECK_DAMAGE = 46733, + SPELL_AGONY_CURSE_VISUAL_1 = 45083, + SPELL_AGONY_CURSE_VISUAL_2 = 45084, + SPELL_AGONY_CURSE_VISUAL_3 = 45085, + SPELL_AGONY_CURSE_ALLY = 45034, + SPELL_HEROIC_STRIKE = 45026, + SPELL_REVITALIZE = 45027, + SPELL_SPECTRAL_BLAST_EFFECT = 44866, + SPELL_SPECTRAL_BLAST_VISUAL = 46648, + SPELL_SPECTRAL_REALM_TRIGGER = 44811, + SPELL_SPECTRAL_REALM_TELEPORT = 46019, + SPELL_SPECTRAL_REALM_AURA = 46021, + SPELL_SPECTRAL_REALM_2 = 44845, + SPELL_SPECTRAL_REALM_REACTION = 44852, + SPELL_SPECTRAL_EXHAUSTION = 44867, + SPELL_TELEPORT_BACK = 46020 +}; + +enum KalecgosEvents +{ + EVENT_ARCANE_BUFFET = 1, + EVENT_FROST_BREATH, + EVENT_WILD_MAGIC, + EVENT_TAIL_LASH, + EVENT_SPECTRAL_BLAST, + EVENT_CHECK_TIMER, + EVENT_OUTRO_START, + EVENT_OUTRO_1, + EVENT_OUTRO_2, + EVENT_OUTRO_3, + EVENT_REVITALIZE, + EVENT_HEROIC_STRIKE, + EVENT_SHADOWBOLT, + EVENT_AGONY_CURSE, + EVENT_CORRUPTION_STRIKE }; enum SWPActions { - DO_ENRAGE = 1, - DO_BANISH = 2 + ACTION_START_OUTRO = 1, + ACTION_ENRAGE }; -enum Misc +enum KalecSayPhases { - FLY_X = 1679, - FLY_Y = 900, - FLY_Z = 82, - CENTER_X = 1705, - CENTER_Y = 930, - RADIUS = 30, - MAX_PLAYERS_IN_SPECTRAL_REALM = 0 // over this, teleport object won't work, 0 disables check + PHASE_SAY_ONE = 1, + PHASE_SAY_TWO, + PHASE_SAY_THREE, + PHASE_SAY_FOUR, + PHASE_OUTRO }; -#define DRAGON_REALM_Z 53.079f -#define DEMON_REALM_Z -74.558f +enum KalecgosPoints +{ + POINT_OUTRO_1 = 0, + POINT_OUTRO_2 +}; -uint32 WildMagic[] = { 44978, 45001, 45002, 45004, 45006, 45010 }; +Position const KalecgosSummonPos = { 1709.094f, 927.5035f, -74.28364f, 2.932153f }; +Position const FlyPos[2] = +{ + { 1704.18f, 927.999f, 57.888f }, + { 1614.355f, 846.9694f, 119.0971f } +}; -class boss_kalecgos : public CreatureScript +uint32 const WildMagicSpells[6] = { -public: - boss_kalecgos() : CreatureScript("boss_kalecgos") { } + SPELL_WILD_MAGIC_1, + SPELL_WILD_MAGIC_2, + SPELL_WILD_MAGIC_3, + SPELL_WILD_MAGIC_4, + SPELL_WILD_MAGIC_5, + SPELL_WILD_MAGIC_6 +}; - struct boss_kalecgosAI : public ScriptedAI +struct boss_kalecgos : public BossAI +{ + boss_kalecgos(Creature* creature) : BossAI(creature, DATA_KALECGOS), _isEnraged(false), _isBanished(false) { } + + void Reset() override { - boss_kalecgosAI(Creature* creature) : ScriptedAI(creature) - { - Initialize(); - instance = creature->GetInstanceScript(); - bJustReset = false; - me->setActive(true); - } + _isEnraged = false; + _isBanished = false; + _Reset(); + events.ScheduleEvent(EVENT_ARCANE_BUFFET, Seconds(8)); + events.ScheduleEvent(EVENT_FROST_BREATH, Seconds(15)); + events.ScheduleEvent(EVENT_WILD_MAGIC, Seconds(10)); + events.ScheduleEvent(EVENT_TAIL_LASH, Seconds(25)); + events.ScheduleEvent(EVENT_SPECTRAL_BLAST, Seconds(20), Seconds(25)); + events.ScheduleEvent(EVENT_CHECK_TIMER, Seconds(1)); + } - void Initialize() - { - SathGUID.Clear(); - ArcaneBuffetTimer = 8000; - FrostBreathTimer = 15000; - WildMagicTimer = 10000; - TailLashTimer = 25000; - SpectralBlastTimer = urand(20000, 25000); - CheckTimer = 1000; - ResetTimer = 30000; - - TalkTimer = 0; - TalkSequence = 0; - isFriendly = false; - isEnraged = false; - isBanished = false; - } + void EnterEvadeMode(EvadeReason /*why*/) override + { + if (events.IsInPhase(PHASE_OUTRO)) + return; - InstanceScript* instance; + _EnterEvadeMode(); + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); + instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_SPECTRAL_REALM_AURA); + summons.DespawnAll(); + DespawnPortals(); - uint32 ArcaneBuffetTimer; - uint32 FrostBreathTimer; - uint32 WildMagicTimer; - uint32 SpectralBlastTimer; - uint32 TailLashTimer; - uint32 CheckTimer; - uint32 TalkTimer; - uint32 TalkSequence; - uint32 ResetTimer; + if (Creature* sathrovar = instance->GetCreature(DATA_SATHROVARR)) + _DespawnAtEvade(Seconds(10), sathrovar); - bool isFriendly; - bool isEnraged; - bool isBanished; - bool bJustReset; + _DespawnAtEvade(Seconds(10)); + } - ObjectGuid SathGUID; + void DespawnPortals() + { + std::vector<GameObject*> portals; + me->GetGameObjectListWithEntryInGrid(portals, GO_SPECTRAL_RIFT); + for (GameObject* portal : portals) + portal->Delete(); + } - void Reset() override + void DoAction(int32 action) override + { + switch (action) { - if (Creature* sath = instance->GetCreature(DATA_SATHROVARR)) - SathGUID = sath->GetGUID(); + case ACTION_START_OUTRO: + events.ScheduleEvent(EVENT_OUTRO_START, Seconds(1)); + break; + case ACTION_ENRAGE: + _isEnraged = true; + Talk(EMOTE_ENRAGE); + DoCastSelf(SPELL_ENRAGE, true); + break; + default: + break; + } + } - instance->SetBossState(DATA_KALECGOS, NOT_STARTED); + void DamageTaken(Unit* who, uint32 &damage) override + { + if (damage >= me->GetHealth() && who->GetGUID() != me->GetGUID()) + damage = 0; + } - if (Creature* Sath = ObjectAccessor::GetCreature(*me, SathGUID)) - Sath->AI()->EnterEvadeMode(); + void EnterCombat(Unit* /*who*/) override + { + instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me); + Talk(SAY_EVIL_AGGRO); + _EnterCombat(); - me->SetFaction(FACTION_MONSTER); - if (!bJustReset) //first reset at create + if (Creature* kalecgosHuman = me->SummonCreature(NPC_KALECGOS_HUMAN, KalecgosSummonPos, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 1000)) + if (Creature* sathrovar = instance->GetCreature(DATA_SATHROVARR)) { - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE + UNIT_FLAG_NOT_SELECTABLE); - me->SetDisableGravity(false); - me->SetVisible(true); - me->SetStandState(UNIT_STAND_STATE_SLEEP); + sathrovar->SetInCombatWith(kalecgosHuman); + kalecgosHuman->SetInCombatWith(sathrovar); } - me->SetFullHealth(); //dunno why it does not resets health at evade.. - } + } + + void KilledUnit(Unit* who) override + { + if (who->GetTypeId() == TYPEID_PLAYER && roll_chance_i(50)) + Talk(SAY_EVIL_SLAY); + } + + void MovementInform(uint32 type, uint32 id) override + { + if (type != POINT_MOTION_TYPE) + return; - void EnterEvadeMode(EvadeReason why) override + switch (id) { - bJustReset = true; - me->SetVisible(false); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE + UNIT_FLAG_NOT_SELECTABLE); - ScriptedAI::EnterEvadeMode(why); + case POINT_OUTRO_1: + Talk(SAY_OUTRO_1); + events.ScheduleEvent(EVENT_OUTRO_3, Seconds(9)); + break; + case POINT_OUTRO_2: + me->SetVisible(false); + DespawnPortals(); + me->KillSelf(); + break; + default: + break; } + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim() && !events.IsInPhase(PHASE_OUTRO)) + return; + + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - void DoAction(int32 param) override + while (uint32 eventId = events.ExecuteEvent()) { - switch (param) + switch (eventId) { - case DO_ENRAGE: - isEnraged = true; - me->CastSpell(me, SPELL_ENRAGE, true); + case EVENT_ARCANE_BUFFET: + if (roll_chance_i(20)) + Talk(SAY_ARCANE_BUFFET); + DoCastAOE(SPELL_ARCANE_BUFFET); + events.Repeat(Seconds(8)); break; - case DO_BANISH: - isBanished = true; - me->CastSpell(me, SPELL_BANISH, true); + case EVENT_FROST_BREATH: + DoCastAOE(SPELL_FROST_BREATH); + events.Repeat(Seconds(15)); break; - } - } - - void UpdateAI(uint32 diff) override - { - if (TalkTimer) - { - if (!TalkSequence) - { - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE + UNIT_FLAG_NOT_SELECTABLE); - me->InterruptNonMeleeSpells(true); - me->RemoveAllAuras(); - me->GetThreatManager().ClearAllThreat(); - me->CombatStop(); - ++TalkSequence; - } - if (TalkTimer <= diff) - { - if (isFriendly) - GoodEnding(); - else - BadEnding(); - ++TalkSequence; - } else TalkTimer -= diff; - } - else - { - if (bJustReset) - { - if (ResetTimer <= diff) - { - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE); - me->SetDisableGravity(false); - me->SetVisible(true); - me->SetStandState(UNIT_STAND_STATE_SLEEP); - ResetTimer = 10000; - bJustReset = false; - } else ResetTimer -= diff; - return; - } - - if (!UpdateVictim()) - return; + case EVENT_TAIL_LASH: + DoCastAOE(SPELL_TAIL_LASH); + events.Repeat(Seconds(15)); + break; + case EVENT_WILD_MAGIC: + DoCastAOE(WildMagicSpells[urand(0, 5)], true); + events.Repeat(Seconds(20)); + break; + case EVENT_SPECTRAL_BLAST: + DoCastAOE(SPELL_SPECTRAL_BLAST, true); + events.Repeat(Seconds(20), Seconds(25)); + break; + case EVENT_CHECK_TIMER: + if (!_isEnraged && HealthBelowPct(10)) + DoAction(ACTION_ENRAGE); - if (CheckTimer <= diff) - { - if (me->GetDistance(CENTER_X, CENTER_Y, DRAGON_REALM_Z) >= 75) - { - EnterEvadeMode(EVADE_REASON_BOUNDARY); - return; - } - if (HealthBelowPct(10) && !isEnraged) + if (HealthBelowPct(1)) { - if (Creature* Sath = ObjectAccessor::GetCreature(*me, SathGUID)) - Sath->AI()->DoAction(DO_ENRAGE); - DoAction(DO_ENRAGE); - } - if (!isBanished && HealthBelowPct(1)) - { - if (Creature* Sath = ObjectAccessor::GetCreature(*me, SathGUID)) + if (Creature* sathrovarr = instance->GetCreature(DATA_SATHROVARR)) { - if (Sath->HasAura(SPELL_BANISH)) + if (sathrovarr->HasAura(SPELL_BANISH)) { - Sath->DealDamage(Sath, Sath->GetHealth()); - return; + sathrovarr->CastSpell(sathrovarr, SPELL_TAP_CHECK, true); + break; } - else - DoAction(DO_BANISH); - } - else - { - TC_LOG_ERROR("scripts", "Didn't find Shathrowar. Kalecgos event reseted."); - EnterEvadeMode(EVADE_REASON_OTHER); - return; } + if (_isBanished) + break; + + _isBanished = true; + DoCastSelf(SPELL_BANISH, true); + events.Reset(); } - CheckTimer = 1000; - } else CheckTimer -= diff; + events.Repeat(Seconds(1)); + break; + case EVENT_OUTRO_START: + events.Reset(); + events.SetPhase(PHASE_OUTRO); + me->SetRegenerateHealth(false); + me->SetReactState(REACT_PASSIVE); + me->InterruptNonMeleeSpells(true); + me->RemoveAllAttackers(); + me->AttackStop(); + me->SetFaction(FACTION_FRIENDLY); + me->RemoveAllAuras(); + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); + events.ScheduleEvent(EVENT_OUTRO_1, Seconds(3)); + break; + case EVENT_OUTRO_1: + me->SetDisableGravity(true); + me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); + events.ScheduleEvent(EVENT_OUTRO_2, Seconds(3)); + break; + case EVENT_OUTRO_2: + me->GetMotionMaster()->MovePoint(POINT_OUTRO_1, FlyPos[0]); + break; + case EVENT_OUTRO_3: + Talk(SAY_OUTRO_2); + me->GetMotionMaster()->MovePoint(POINT_OUTRO_2, FlyPos[1], false); + break; + default: + break; + } - if (ArcaneBuffetTimer <= diff) - { - DoCastAOE(SPELL_ARCANE_BUFFET); - ArcaneBuffetTimer = 8000; - } else ArcaneBuffetTimer -= diff; + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + } - if (FrostBreathTimer <= diff) - { - DoCastAOE(SPELL_FROST_BREATH); - FrostBreathTimer = 15000; - } else FrostBreathTimer -= diff; + DoMeleeAttackIfReady(); + } - if (TailLashTimer <= diff) - { - DoCastAOE(SPELL_TAIL_LASH); - TailLashTimer = 15000; - } else TailLashTimer -= diff; +private: + bool _isEnraged; + bool _isBanished; +}; - if (WildMagicTimer <= diff) - { - DoCastAOE(WildMagic[rand32() % 6]); - WildMagicTimer = 20000; - } else WildMagicTimer -= diff; +struct boss_kalecgos_human : public ScriptedAI +{ + boss_kalecgos_human(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { } - if (SpectralBlastTimer <= diff) - { - ThreatContainer::StorageType const& m_threatlist = me->GetThreatManager().getThreatList(); - std::list<Unit*> targetList; - for (ThreatContainer::StorageType::const_iterator itr = m_threatlist.begin(); itr!= m_threatlist.end(); ++itr) - { - Unit* target = (*itr)->getTarget(); - if (target - && target->GetTypeId() == TYPEID_PLAYER - && (!target->GetVictim() || target->GetGUID() != me->EnsureVictim()->GetGUID()) - && target->GetPositionZ() > me->GetPositionZ() - 5 - && !target->HasAura(AURA_SPECTRAL_EXHAUSTION)) - { - targetList.push_back(target); - } - } - if (targetList.empty()) - { - SpectralBlastTimer = 1000; - return; - } + void Reset() override + { + _events.Reset(); + _events.SetPhase(PHASE_SAY_ONE); - std::list<Unit*>::const_iterator i = targetList.begin(); - advance(i, rand32() % targetList.size()); - if ((*i)) - { - (*i)->CastSpell((*i), SPELL_SPECTRAL_BLAST, true); - SpectralBlastTimer = 20000 + rand32() % 5000; - } else SpectralBlastTimer = 1000; - } else SpectralBlastTimer -= diff; + if (Creature* sath = _instance->GetCreature(DATA_SATHROVARR)) + _sathGUID = sath->GetGUID(); - DoMeleeAttackIfReady(); - } - } + _events.ScheduleEvent(EVENT_REVITALIZE, Seconds(5)); + _events.ScheduleEvent(EVENT_HEROIC_STRIKE, Seconds(3)); + } - void MoveInLineOfSight(Unit* who) override - { - if (bJustReset)//boss is invisible, don't attack - return; + void JustDied(Unit* /*killer*/) override + { + Talk(SAY_GOOD_DEATH); + } - if (!me->GetVictim() && me->IsValidAttackTarget(who)) - { - float attackRadius = me->GetAttackDistance(who); - if (me->IsWithinDistInMap(who, attackRadius)) - AttackStart(who); - } - } + void DamageTaken(Unit* who, uint32 &damage) override + { + if (who->GetGUID() != _sathGUID) + damage = 0; - void DamageTaken(Unit* done_by, uint32 &damage) override + if (HealthBelowPct(75) && _events.IsInPhase(PHASE_SAY_ONE)) { - if (damage >= me->GetHealth() && done_by != me) - damage = 0; + Talk(SAY_GOOD_NEAR_DEATH_0); + _events.SetPhase(PHASE_SAY_TWO); } - - void EnterCombat(Unit* /*who*/) override + else if (HealthBelowPct(50) && _events.IsInPhase(PHASE_SAY_TWO)) { - me->SetStandState(UNIT_STAND_STATE_STAND); - Talk(SAY_EVIL_AGGRO); - DoZoneInCombat(); - - instance->SetBossState(DATA_KALECGOS, IN_PROGRESS); + _events.SetPhase(PHASE_SAY_THREE); + Talk(SAY_GOOD_NEAR_DEATH_1); } - - void KilledUnit(Unit* /*victim*/) override + else if (HealthBelowPct(10) && _events.IsInPhase(PHASE_SAY_THREE)) { - Talk(SAY_EVIL_SLAY); + _events.SetPhase(PHASE_SAY_FOUR); + Talk(SAY_GOOD_NEAR_DEATH_2); } + } - void MovementInform(uint32 type, uint32 /*id*/) override - { - if (type != POINT_MOTION_TYPE) - return; - me->SetVisible(false); - if (isFriendly) - { - me->setDeathState(JUST_DIED); - me->GetMap()->ToInstanceMap()->PermBindAllPlayers(); - } - else - { - me->GetMotionMaster()->MoveTargetedHome(); - TalkTimer = 1000; - } - } + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - void GoodEnding() - { - switch (TalkSequence) - { - case 1: - me->SetFaction(FACTION_FRIENDLY); - TalkTimer = 1000; - break; - case 2: - Talk(SAY_GOOD_PLRWIN); - TalkTimer = 10000; - break; - case 3: - me->SetDisableGravity(true); - me->GetMotionMaster()->MovePoint(0, FLY_X, FLY_Y, FLY_Z); - TalkTimer = 600000; - break; - default: - break; - } - } + _events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - void BadEnding() + while (uint32 eventId = _events.ExecuteEvent()) { - switch (TalkSequence) + switch (eventId) { - case 1: - Talk(SAY_EVIL_ENRAGE); - TalkTimer = 3000; + case EVENT_REVITALIZE: + DoCastSelf(SPELL_REVITALIZE); + _events.Repeat(Seconds(5)); break; - case 2: - me->SetDisableGravity(true); - me->GetMotionMaster()->MovePoint(0, FLY_X, FLY_Y, FLY_Z); - TalkTimer = 15000; - break; - case 3: - EnterEvadeMode(EVADE_REASON_OTHER); + case EVENT_HEROIC_STRIKE: + DoCastVictim(SPELL_HEROIC_STRIKE); + _events.Repeat(Seconds(2)); break; default: break; } + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; } - }; - CreatureAI* GetAI(Creature* creature) const override - { - return GetSunwellPlateauAI<boss_kalecgosAI>(creature); + DoMeleeAttackIfReady(); } + +private: + InstanceScript* _instance; + EventMap _events; + ObjectGuid _sathGUID; }; -class boss_kalec : public CreatureScript +class CurseAgonySelector : NonTankTargetSelector { public: - boss_kalec() : CreatureScript("boss_kalec") { } + CurseAgonySelector(Unit* source) : NonTankTargetSelector(source, true) { } - CreatureAI* GetAI(Creature* creature) const override + bool operator()(WorldObject* target) const { - return GetSunwellPlateauAI<boss_kalecAI>(creature); + if (Unit* unitTarget = target->ToUnit()) + return !NonTankTargetSelector::operator()(unitTarget) + || unitTarget->HasAura(SPELL_AGONY_CURSE) || unitTarget->HasAura(SPELL_AGONY_CURSE_ALLY) + || !unitTarget->HasAura(SPELL_SPECTRAL_REALM_AURA); + return false; } +}; - struct boss_kalecAI : public ScriptedAI - { - InstanceScript* instance; +struct boss_sathrovarr : public BossAI +{ + boss_sathrovarr(Creature* creature) : BossAI(creature, DATA_KALECGOS), _isEnraged(false), _isBanished(false) { } - uint32 RevitalizeTimer; - uint32 HeroicStrikeTimer; - uint32 YellTimer; - uint32 YellSequence; + void Reset() override + { + _isEnraged = false; + _isBanished = false; + _Reset(); + events.ScheduleEvent(EVENT_SHADOWBOLT, Seconds(7), Seconds(10)); + events.ScheduleEvent(EVENT_AGONY_CURSE, Seconds(20)); + events.ScheduleEvent(EVENT_CORRUPTION_STRIKE, Seconds(13)); + events.ScheduleEvent(EVENT_CHECK_TIMER, Seconds(1)); + } - ObjectGuid SathGUID; + void EnterCombat(Unit* /*who*/) override + { + _EnterCombat(); + Talk(SAY_SATH_AGGRO); + } - bool isEnraged; // if demon is enraged + void EnterEvadeMode(EvadeReason why) override + { + if (Creature* kalecgos = instance->GetCreature(DATA_KALECGOS_DRAGON)) + kalecgos->AI()->EnterEvadeMode(why); + } - boss_kalecAI(Creature* creature) : ScriptedAI(creature) + void SpellHit(Unit* caster, SpellInfo const* spell) override + { + if (spell->Id == SPELL_TAP_CHECK_DAMAGE) { - Initialize(); - instance = creature->GetInstanceScript(); + DoCastSelf(SPELL_TELEPORT_BACK, true); + caster->Kill(me); } + } - void Initialize() - { - RevitalizeTimer = 5000; - HeroicStrikeTimer = 3000; - YellTimer = 5000; - YellSequence = 0; - - isEnraged = false; - } + void DamageTaken(Unit* who, uint32 &damage) override + { + if (damage >= me->GetHealth() && who->GetGUID() != me->GetGUID()) + damage = 0; + } - void Reset() override + void KilledUnit(Unit* target) override + { + if (target->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_SATH_SLAY); + else if (Creature* kalecgosHuman = instance->GetCreature(DATA_KALECGOS_HUMAN)) { - if (Creature* sath = instance->GetCreature(DATA_SATHROVARR)) - SathGUID = sath->GetGUID(); - - Initialize(); + if (kalecgosHuman->GetGUID() == target->GetGUID()) + EnterEvadeMode(EVADE_REASON_OTHER); } + } - void DamageTaken(Unit* done_by, uint32 &damage) override - { - if (done_by->GetGUID() != SathGUID) - damage = 0; - else if (isEnraged) - damage *= 3; - } + void JustDied(Unit* /*killer*/) override + { + _JustDied(); + Talk(SAY_SATH_DEATH); + instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_SPECTRAL_REALM_AURA); + if (Creature* kalecgos = instance->GetCreature(DATA_KALECGOS_DRAGON)) + kalecgos->AI()->DoAction(ACTION_START_OUTRO); + } - void UpdateAI(uint32 diff) override + void ExecuteEvent(uint32 eventId) override + { + switch (eventId) { - if (!me->HasAura(AURA_SPECTRAL_INVISIBILITY)) - me->CastSpell(me, AURA_SPECTRAL_INVISIBILITY, true); - - if (!UpdateVictim()) - return; - - if (YellTimer <= diff) + case EVENT_SHADOWBOLT: + if (roll_chance_i(20)) + Talk(SAY_SATH_SPELL1); + DoCastAOE(SPELL_SHADOW_BOLT); + events.Repeat(Seconds(7), Seconds(10)); + break; + case EVENT_AGONY_CURSE: { - switch (YellSequence) + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, CurseAgonySelector(me))) + DoCast(target, SPELL_AGONY_CURSE); + else + DoCastVictim(SPELL_AGONY_CURSE); + events.Repeat(Seconds(20)); + break; + } + case EVENT_CORRUPTION_STRIKE: + if (roll_chance_i(20)) + Talk(SAY_SATH_SPELL2); + DoCastVictim(SPELL_CORRUPTION_STRIKE); + events.Repeat(Seconds(13)); + break; + case EVENT_CHECK_TIMER: + { + if (HealthBelowPct(10) && !_isEnraged) { - case 0: - Talk(SAY_GOOD_AGGRO); - ++YellSequence; - break; - case 1: - if (HealthBelowPct(50)) - { - Talk(SAY_GOOD_NEAR_DEATH); - ++YellSequence; - } - break; - case 2: - if (HealthBelowPct(10)) + _isEnraged = true; + if (Creature* kalecgos = instance->GetCreature(DATA_KALECGOS_DRAGON)) + kalecgos->AI()->DoAction(ACTION_ENRAGE); + } + + if (HealthBelowPct(1)) + { + if (Creature* kalecgos = instance->GetCreature(DATA_KALECGOS_DRAGON)) + { + if (kalecgos->HasAura(SPELL_BANISH)) { - Talk(SAY_GOOD_NEAR_DEATH2); - ++YellSequence; + DoCastSelf(SPELL_TAP_CHECK, true); + break; } + } + if (_isBanished) break; - default: - break; + + _isBanished = true; + DoCastSelf(SPELL_BANISH, true); } - YellTimer = 5000; + events.Repeat(Seconds(1)); + break; } - - if (RevitalizeTimer <= diff) - { - DoCast(me, SPELL_REVITALIZE); - RevitalizeTimer = 5000; - } else RevitalizeTimer -= diff; - - if (HeroicStrikeTimer <= diff) - { - DoCastVictim(SPELL_HEROIC_STRIKE); - HeroicStrikeTimer = 2000; - } else HeroicStrikeTimer -= diff; - - DoMeleeAttackIfReady(); + default: + break; } - }; + } + +private: + bool _isEnraged; + bool _isBanished; }; -class kalecgos_teleporter : public GameObjectScript +class go_kalecgos_spectral_rift : public GameObjectScript { -public: - kalecgos_teleporter() : GameObjectScript("kalecgos_teleporter") { } - - struct kalecgos_teleporterAI : public GameObjectAI - { - kalecgos_teleporterAI(GameObject* go) : GameObjectAI(go) { } + public: + go_kalecgos_spectral_rift() : GameObjectScript("go_kalecgos_spectral_rift") { } - bool GossipHello(Player* player) override + struct go_kalecgos_spectral_riftAI : public GameObjectAI { -#if MAX_PLAYERS_IN_SPECTRAL_REALM > 0 - uint8 SpectralPlayers = 0; - Map::PlayerList const& PlayerList = go->GetMap()->GetPlayers(); - for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) - { - if (i->GetSource() && i->GetSource()->GetPositionZ() < DEMON_REALM_Z + 5) - ++SpectralPlayers; - } + go_kalecgos_spectral_riftAI(GameObject* go) : GameObjectAI(go) { } - if (player->HasAura(AURA_SPECTRAL_EXHAUSTION) || SpectralPlayers >= MAX_PLAYERS_IN_SPECTRAL_REALM) + bool GossipHello(Player* player) override { + if (!player->HasAura(SPELL_SPECTRAL_EXHAUSTION)) + player->CastSpell(player, SPELL_SPECTRAL_REALM_TRIGGER, true); return true; } -#endif + }; - player->CastSpell(player, SPELL_TELEPORT_SPECTRAL, true); - return true; + GameObjectAI* GetAI(GameObject* go) const override + { + return GetSunwellPlateauAI<go_kalecgos_spectral_riftAI>(go); } - }; - - GameObjectAI* GetAI(GameObject* go) const override - { - return GetSunwellPlateauAI<kalecgos_teleporterAI>(go); - } }; -class boss_sathrovarr : public CreatureScript +// 46732 - Tap Check +class spell_kalecgos_tap_check : public SpellScript { -public: - boss_sathrovarr() : CreatureScript("boss_sathrovarr") { } + PrepareSpellScript(spell_kalecgos_tap_check); - CreatureAI* GetAI(Creature* creature) const override + bool Validate(SpellInfo const* spellInfo) override { - return GetSunwellPlateauAI<boss_sathrovarrAI>(creature); + return ValidateSpellInfo({ uint32(spellInfo->Effects[EFFECT_0].CalcValue()) }); } - struct boss_sathrovarrAI : public ScriptedAI + void HandleDummy(SpellEffIndex /*effIndex*/) { - boss_sathrovarrAI(Creature* creature) : ScriptedAI(creature) - { - Initialize(); - instance = creature->GetInstanceScript(); - } + GetHitUnit()->CastSpell(GetCaster(), (uint32)GetSpellInfo()->Effects[EFFECT_0].CalcValue(), true); + } - void Initialize() + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_kalecgos_tap_check::HandleDummy, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } +}; + +class SpectralBlastSelector : NonTankTargetSelector +{ + public: + SpectralBlastSelector(Unit* source) : NonTankTargetSelector(source, true) { } + + bool operator()(WorldObject* target) const { - ShadowBoltTimer = urand(7, 10) * 1000; - AgonyCurseTimer = 20000; - CorruptionStrikeTimer = 13000; - CheckTimer = 1000; - ResetThreat = 1000; - isEnraged = false; - isBanished = false; + if (Unit* unitTarget = target->ToUnit()) + return !NonTankTargetSelector::operator()(unitTarget) || + unitTarget->HasAura(SPELL_SPECTRAL_EXHAUSTION) || unitTarget->HasAura(SPELL_SPECTRAL_REALM_AURA); + return false; } +}; - InstanceScript* instance; +// 44869 - Spectral Blast +class spell_kalecgos_spectral_blast : public SpellScript +{ + PrepareSpellScript(spell_kalecgos_spectral_blast); - uint32 CorruptionStrikeTimer; - uint32 AgonyCurseTimer; - uint32 ShadowBoltTimer; - uint32 CheckTimer; - uint32 ResetThreat; + bool Validate(SpellInfo const* /*spell*/) override + { + return ValidateSpellInfo( + { + SPELL_SPECTRAL_BLAST_EFFECT, + SPELL_SPECTRAL_BLAST_VISUAL, + SPELL_SPECTRAL_REALM_TRIGGER + }); + } - ObjectGuid KalecGUID; - ObjectGuid KalecgosGUID; + void FilterTargets(std::list<WorldObject*>& targets) + { + targets.remove_if(SpectralBlastSelector(GetCaster())); + } - bool isEnraged; - bool isBanished; + void HandleDummy(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + Unit* target = GetHitUnit(); - void Reset() override - { - me->SetFullHealth();//dunno why it does not resets health at evade.. - me->setActive(true); - if (Creature* kalecgos = instance->GetCreature(DATA_KALECGOS_DRAGON)) - KalecgosGUID = kalecgos->GetGUID(); - instance->SetBossState(DATA_KALECGOS, NOT_STARTED); - if (KalecGUID) - { - if (Creature* Kalec = ObjectAccessor::GetCreature(*me, KalecGUID)) - Kalec->setDeathState(JUST_DIED); - KalecGUID.Clear(); - } + target->CastSpell(target, SPELL_SPECTRAL_BLAST_EFFECT, true); + caster->CastSpell(target, SPELL_SPECTRAL_BLAST_VISUAL, true); + caster->CastSpell(target, SPELL_SPECTRAL_REALM_TRIGGER, true); + } - Initialize(); + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_kalecgos_spectral_blast::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + OnEffectHitTarget += SpellEffectFn(spell_kalecgos_spectral_blast::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } +}; - me->CastSpell(me, AURA_DEMONIC_VISUAL, true); - TeleportAllPlayersBack(); - } +// 44811 - Spectral Realm +class spell_kalecgos_spectral_realm_trigger : public SpellScript +{ + PrepareSpellScript(spell_kalecgos_spectral_realm_trigger); - void EnterCombat(Unit* /*who*/) override + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( { - if (Creature* Kalec = me->SummonCreature(NPC_KALECGOS_HUMAN, me->GetPositionX() + 10, me->GetPositionY() + 5, me->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0)) - { - KalecGUID = Kalec->GetGUID(); - me->CombatStart(Kalec); - AddThreat(Kalec, 100.0f); - Kalec->setActive(true); - } - Talk(SAY_SATH_AGGRO); - } + SPELL_SPECTRAL_REALM_TELEPORT, + SPELL_SPECTRAL_REALM_AURA, + SPELL_SPECTRAL_REALM_2, + SPELL_SPECTRAL_REALM_REACTION + }); + } - void DamageTaken(Unit* done_by, uint32 &damage) override - { - if (damage >= me->GetHealth() && done_by != me) - damage = 0; - } + void HandleDummy(SpellEffIndex /*effIndex*/) + { + Unit* target = GetHitUnit(); + target->CastSpell(target, SPELL_SPECTRAL_REALM_TELEPORT, true); + target->CastSpell(target, SPELL_SPECTRAL_REALM_AURA, true); + target->CastSpell(target, SPELL_SPECTRAL_REALM_2, true); + target->CastSpell(target, SPELL_SPECTRAL_REALM_REACTION, true); + } - void KilledUnit(Unit* target) override - { - if (target->GetGUID() == KalecGUID) - { - TeleportAllPlayersBack(); - if (Creature* Kalecgos = ObjectAccessor::GetCreature(*me, KalecgosGUID)) - { - ENSURE_AI(boss_kalecgos::boss_kalecgosAI, Kalecgos->AI())->TalkTimer = 1; - ENSURE_AI(boss_kalecgos::boss_kalecgosAI, Kalecgos->AI())->isFriendly = false; - } - EnterEvadeMode(); - return; - } - Talk(SAY_SATH_SLAY); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_kalecgos_spectral_realm_trigger::HandleDummy, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } +}; + +// 46021 - Spectral Realm +class spell_kalecgos_spectral_realm_aura : public AuraScript +{ + PrepareAuraScript(spell_kalecgos_spectral_realm_aura); - void JustDied(Unit* /*killer*/) override + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( { - Talk(SAY_SATH_DEATH); - me->UpdatePosition(me->GetPositionX(), me->GetPositionY(), DRAGON_REALM_Z, me->GetOrientation()); - TeleportAllPlayersBack(); - if (Creature* Kalecgos = ObjectAccessor::GetCreature(*me, KalecgosGUID)) - { - ENSURE_AI(boss_kalecgos::boss_kalecgosAI, Kalecgos->AI())->TalkTimer = 1; - ENSURE_AI(boss_kalecgos::boss_kalecgosAI, Kalecgos->AI())->isFriendly = true; - } + SPELL_SPECTRAL_REALM_REACTION, + SPELL_TELEPORT_BACK, + SPELL_SPECTRAL_EXHAUSTION + }); + } - instance->SetBossState(DATA_KALECGOS, DONE); - } + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + target->RemoveAurasDueToSpell(SPELL_SPECTRAL_REALM_REACTION); + target->CastSpell(target, SPELL_TELEPORT_BACK, true); + target->CastSpell(target, SPELL_SPECTRAL_EXHAUSTION, true); + } - void TeleportAllPlayersBack() - { - Map::PlayerList const& playerList = me->GetMap()->GetPlayers(); - Position const& homePos = me->GetHomePosition(); - for (Map::PlayerList::const_iterator itr = playerList.begin(); itr != playerList.end(); ++itr) - { - Player* player = itr->GetSource(); - if (player->IsInDist(&homePos, 50.0f) && player->GetPositionZ() <= DEMON_REALM_Z + 10.f) - { - player->RemoveAura(AURA_SPECTRAL_REALM); - player->TeleportTo(me->GetMap()->GetId(), player->GetPositionX(), - player->GetPositionY(), DRAGON_REALM_Z + 5, player->GetOrientation()); - } - } - } + void Register() override + { + AfterEffectRemove += AuraEffectRemoveFn(spell_kalecgos_spectral_realm_aura::OnRemove, EFFECT_0, SPELL_AURA_MOD_INVISIBILITY_DETECT, AURA_EFFECT_HANDLE_REAL); + } +}; - void DoAction(int32 param) override - { - switch (param) - { - case DO_ENRAGE: - isEnraged = true; - me->CastSpell(me, SPELL_ENRAGE, true); - break; - case DO_BANISH: - isBanished = true; - me->CastSpell(me, SPELL_BANISH, true); - break; - } - } +// 45032, 45034 - Curse of Boundless Agony +class spell_kalecgos_curse_of_boundless_agony : public AuraScript +{ + PrepareAuraScript(spell_kalecgos_curse_of_boundless_agony); - void UpdateAI(uint32 diff) override + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( { - if (!me->HasAura(AURA_SPECTRAL_INVISIBILITY)) - me->CastSpell(me, AURA_SPECTRAL_INVISIBILITY, true); + SPELL_AGONY_CURSE_VISUAL_1, + SPELL_AGONY_CURSE_VISUAL_2, + SPELL_AGONY_CURSE_VISUAL_3, + SPELL_AGONY_CURSE_ALLY + }); + } - if (!UpdateVictim()) + void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (InstanceScript* instance = GetTarget()->GetInstanceScript()) + if (instance->GetBossState(DATA_KALECGOS) == IN_PROGRESS) return; - if (CheckTimer <= diff) - { - Creature* Kalec = ObjectAccessor::GetCreature(*me, KalecGUID); - if (!Kalec || !Kalec->IsAlive()) - { - if (Creature* Kalecgos = ObjectAccessor::GetCreature(*me, KalecgosGUID)) - Kalecgos->AI()->EnterEvadeMode(); - return; - } - - if (HealthBelowPct(10) && !isEnraged) - { - if (Creature* Kalecgos = ObjectAccessor::GetCreature(*me, KalecgosGUID)) - Kalecgos->AI()->DoAction(DO_ENRAGE); - DoAction(DO_ENRAGE); - } - - Creature* Kalecgos = ObjectAccessor::GetCreature(*me, KalecgosGUID); - if (Kalecgos && !Kalecgos->IsInCombat()) - { - EnterEvadeMode(); - return; - } - - if (!isBanished && HealthBelowPct(1)) - { - if (Kalecgos) - { - if (Kalecgos->HasAura(SPELL_BANISH)) - { - me->DealDamage(me, me->GetHealth()); - return; - } - DoAction(DO_BANISH); - } - else - { - EnterEvadeMode(); - return; - } - } - CheckTimer = 1000; - } else CheckTimer -= diff; + Remove(AURA_REMOVE_BY_CANCEL); + } - if (ResetThreat <= diff) - { - ThreatContainer::StorageType threatlist = me->GetThreatManager().getThreatList(); - for (ThreatContainer::StorageType::const_iterator itr = threatlist.begin(); itr != threatlist.end(); ++itr) - { - if (Unit* unit = ObjectAccessor::GetUnit(*me, (*itr)->getUnitGuid())) - if (unit->GetPositionZ() > me->GetPositionZ() + 5) - me->GetThreatManager().ModifyThreatByPercent(unit, -100); - } - ResetThreat = 1000; - } else ResetThreat -= diff; + void OnPeriodic(AuraEffect const* aurEff) + { + if (aurEff->GetTickNumber() <= 5) + GetTarget()->CastSpell(GetTarget(), SPELL_AGONY_CURSE_VISUAL_1, true); + else if (aurEff->GetTickNumber() <= 10) + GetTarget()->CastSpell(GetTarget(), SPELL_AGONY_CURSE_VISUAL_2, true); + else + GetTarget()->CastSpell(GetTarget(), SPELL_AGONY_CURSE_VISUAL_3, true); + } - if (ShadowBoltTimer <= diff) - { - if (!(rand32() % 5)) - Talk(SAY_SATH_SPELL1); - DoCast(me, SPELL_SHADOW_BOLT); - ShadowBoltTimer = 7000 + (rand32() % 3000); - } else ShadowBoltTimer -= diff; + void HandleEffectPeriodicUpdate(AuraEffect* aurEff) + { + if (aurEff->GetTickNumber() > 1 && aurEff->GetTickNumber() % 5 == 1) + aurEff->SetAmount(aurEff->GetAmount() * 2); + } - if (AgonyCurseTimer <= diff) - { - Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1); - if (!target) - target = me->GetVictim(); - DoCast(target, SPELL_AGONY_CURSE); - AgonyCurseTimer = 20000; - } else AgonyCurseTimer -= diff; - - if (CorruptionStrikeTimer <= diff) - { - if (!(rand32() % 5))Talk(SAY_SATH_SPELL2); - DoCastVictim(SPELL_CORRUPTION_STRIKE); - CorruptionStrikeTimer = 13000; - } else CorruptionStrikeTimer -= diff; + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_CANCEL) + GetTarget()->CastSpell(GetTarget(), SPELL_AGONY_CURSE_ALLY, true); + } - DoMeleeAttackIfReady(); - } - }; + void Register() override + { + AfterEffectApply += AuraEffectApplyFn(spell_kalecgos_curse_of_boundless_agony::OnApply, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL); + OnEffectPeriodic += AuraEffectPeriodicFn(spell_kalecgos_curse_of_boundless_agony::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE); + OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_kalecgos_curse_of_boundless_agony::HandleEffectPeriodicUpdate, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE); + AfterEffectRemove += AuraEffectRemoveFn(spell_kalecgos_curse_of_boundless_agony::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL); + } }; void AddSC_boss_kalecgos() { - new boss_kalecgos(); - new boss_sathrovarr(); - new boss_kalec(); - new kalecgos_teleporter(); + RegisterSunwellPlateauCreatureAI(boss_kalecgos); + RegisterSunwellPlateauCreatureAI(boss_sathrovarr); + RegisterSunwellPlateauCreatureAI(boss_kalecgos_human); + new go_kalecgos_spectral_rift(); + RegisterSpellScript(spell_kalecgos_tap_check); + RegisterSpellScript(spell_kalecgos_spectral_blast); + RegisterSpellScript(spell_kalecgos_spectral_realm_trigger); + RegisterAuraScript(spell_kalecgos_spectral_realm_aura); + RegisterAuraScript(spell_kalecgos_curse_of_boundless_agony); } diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp index f0bcb9dd3de..ae9725525a1 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp @@ -124,7 +124,7 @@ class VoidSpawnSummon : public BasicEvent bool Execute(uint64 /*time*/, uint32 /*diff*/) { - _owner->CastSpell((Unit*)nullptr, SPELL_SUMMON_VOID_SENTINEL, true); + _owner->CastSpell(nullptr, SPELL_SUMMON_VOID_SENTINEL, true); return true; } @@ -589,7 +589,7 @@ class spell_summon_blood_elves_script : SpellScriptLoader void HandleScript(SpellEffIndex /*effIndex*/) { for (uint8 i = 0; i < MAX_SUMMON_BLOOD_ELVES; ++i) - GetCaster()->CastSpell((Unit*)nullptr, SummonBloodElvesSpells[urand(0,3)], true); + GetCaster()->CastSpell(nullptr, SummonBloodElvesSpells[urand(0,3)], true); } void Register() override @@ -621,7 +621,7 @@ class spell_muru_darkness : SpellScriptLoader void HandleAfterCast() { for (uint8 i = 0; i < MAX_SUMMON_DARK_FIEND; ++i) - GetCaster()->CastSpell((Unit*)nullptr, SummonDarkFiendSpells[i], true); + GetCaster()->CastSpell(nullptr, SummonDarkFiendSpells[i], true); } void Register() override @@ -683,7 +683,7 @@ class spell_transform_visual_missile_periodic : public SpellScriptLoader void OnPeriodic(AuraEffect const* /*aurEff*/) { - GetTarget()->CastSpell((Unit*)nullptr, RAND(TRANSFORM_VISUAL_MISSILE_1, TRANSFORM_VISUAL_MISSILE_2), true); + GetTarget()->CastSpell(nullptr, RAND(TRANSFORM_VISUAL_MISSILE_1, TRANSFORM_VISUAL_MISSILE_2), true); } void Register() override @@ -709,7 +709,7 @@ class spell_summon_blood_elves_periodic : public SpellScriptLoader void OnPeriodic(AuraEffect const* /*aurEff*/) { - GetTarget()->CastSpell((Unit*)nullptr, SPELL_SUMMON_BLOOD_ELVES_SCRIPT, true); + GetTarget()->CastSpell(nullptr, SPELL_SUMMON_BLOOD_ELVES_SCRIPT, true); } void Register() override diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/instance_sunwell_plateau.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/instance_sunwell_plateau.cpp index 6b3c2b1bcaf..e5df84f8ba1 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/instance_sunwell_plateau.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/instance_sunwell_plateau.cpp @@ -16,6 +16,7 @@ */ #include "ScriptMgr.h" +#include "AreaBoundary.h" #include "InstanceScript.h" #include "Log.h" #include "Map.h" @@ -60,6 +61,11 @@ ObjectData const creatureData[] = { 0, 0 } // END }; +BossBoundaryData const boundaries = +{ + { DATA_KALECGOS, new BoundaryUnionBoundary(new CircleBoundary(Position(1704.9f, 928.4f), 34.0), new RectangleBoundary(1689.2f, 1713.3f, 762.2f, 1074.8f)) } +}; + class instance_sunwell_plateau : public InstanceMapScript { public: @@ -73,6 +79,7 @@ class instance_sunwell_plateau : public InstanceMapScript SetBossNumber(EncounterCount); LoadDoorData(doorData); LoadObjectData(creatureData, nullptr); + LoadBossBoundaries(boundaries); } Player const* GetPlayerInMap() const diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/sunwell_plateau.h b/src/server/scripts/EasternKingdoms/SunwellPlateau/sunwell_plateau.h index cec43582958..85fbde015fb 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/sunwell_plateau.h +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/sunwell_plateau.h @@ -111,7 +111,8 @@ enum SWPGameObjectIds GO_BOSS_COLLISION_2 = 188524, GO_FIRE_BARRIER = 188075, GO_MURUS_GATE_1 = 187990, - GO_MURUS_GATE_2 = 188118 + GO_MURUS_GATE_2 = 188118, + GO_SPECTRAL_RIFT = 187055 }; template <class AI, class T> @@ -120,4 +121,6 @@ AI* GetSunwellPlateauAI(T* obj) return GetInstanceAI<AI>(obj, SunwellPlateauScriptName); } +#define RegisterSunwellPlateauCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetSunwellPlateauAI) + #endif // SUNWELL_PLATEAU_H diff --git a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h index ae1323af6aa..57d738698c7 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h +++ b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h @@ -33,7 +33,7 @@ enum ZADataTypes BOSS_HEXLORD = 4, BOSS_ZULJIN = 5, MAX_ENCOUNTER, - + DATA_GONGEVENT, DATA_CHESTLOOTED, TYPE_RAND_VENDOR_1, diff --git a/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp b/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp index 371be75b9f6..047467d0338 100644 --- a/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp +++ b/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp @@ -175,16 +175,13 @@ void AddSC_instance_zulgurub(); //void AddSC_alterac_mountains(); void AddSC_arathi_highlands(); void AddSC_blasted_lands(); -void AddSC_burning_steppes(); void AddSC_duskwood(); //void AddSC_eastern_plaguelands(); void AddSC_ghostlands(); void AddSC_hinterlands(); -void AddSC_isle_of_queldanas(); void AddSC_redridge_mountains(); void AddSC_silverpine_forest(); void AddSC_stormwind_city(); -void AddSC_stranglethorn_vale(); void AddSC_swamp_of_sorrows(); void AddSC_tirisfal_glades(); void AddSC_undercity(); @@ -354,16 +351,13 @@ void AddEasternKingdomsScripts() //AddSC_alterac_mountains(); AddSC_arathi_highlands(); AddSC_blasted_lands(); - AddSC_burning_steppes(); AddSC_duskwood(); //AddSC_eastern_plaguelands(); AddSC_ghostlands(); AddSC_hinterlands(); - AddSC_isle_of_queldanas(); AddSC_redridge_mountains(); AddSC_silverpine_forest(); AddSC_stormwind_city(); - AddSC_stranglethorn_vale(); AddSC_swamp_of_sorrows(); AddSC_tirisfal_glades(); AddSC_undercity(); diff --git a/src/server/scripts/EasternKingdoms/zone_arathi_highlands.cpp b/src/server/scripts/EasternKingdoms/zone_arathi_highlands.cpp index 501838888ef..2d3d36d425a 100644 --- a/src/server/scripts/EasternKingdoms/zone_arathi_highlands.cpp +++ b/src/server/scripts/EasternKingdoms/zone_arathi_highlands.cpp @@ -60,11 +60,11 @@ class npc_professor_phizzlethorpe : public CreatureScript public: npc_professor_phizzlethorpe() : CreatureScript("npc_professor_phizzlethorpe") { } - struct npc_professor_phizzlethorpeAI : public npc_escortAI + struct npc_professor_phizzlethorpeAI : public EscortAI { - npc_professor_phizzlethorpeAI(Creature* creature) : npc_escortAI(creature) { } + npc_professor_phizzlethorpeAI(Creature* creature) : EscortAI(creature) { } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { Player* player = GetPlayerForEscort(); if (!player) @@ -118,14 +118,14 @@ class npc_professor_phizzlethorpe : public CreatureScript if (quest->GetQuestId() == QUEST_SUNKEN_TREASURE) { Talk(SAY_PROGRESS_1, player); - npc_escortAI::Start(false, false, player->GetGUID(), quest); + EscortAI::Start(false, false, player->GetGUID(), quest); me->SetFaction(FACTION_ESCORTEE_N_NEUTRAL_PASSIVE); } } void UpdateAI(uint32 diff) override { - npc_escortAI::UpdateAI(diff); + EscortAI::UpdateAI(diff); } }; diff --git a/src/server/scripts/EasternKingdoms/zone_burning_steppes.cpp b/src/server/scripts/EasternKingdoms/zone_burning_steppes.cpp deleted file mode 100644 index e6170d0e65e..00000000000 --- a/src/server/scripts/EasternKingdoms/zone_burning_steppes.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/* ScriptData -SDName: Burning_Steppes -SD%Complete: 100 -SDComment: Quest support: 4866 -SDCategory: Burning Steppes -EndScriptData */ - -/* ContentData -npc_ragged_john -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "Player.h" - -/*###### -## npc_ragged_john -######*/ - -enum RaggedJohn -{ - QUEST_MOTHERS_MILK = 4866, - SPELL_MOTHERS_MILK = 16468, - SPELL_WICKED_MILKING = 16472 -}; - -class npc_ragged_john : public CreatureScript -{ - public: - npc_ragged_john() : CreatureScript("npc_ragged_john") { } - - struct npc_ragged_johnAI : public ScriptedAI - { - npc_ragged_johnAI(Creature* creature) : ScriptedAI(creature) { } - - void Reset() override { } - - void MoveInLineOfSight(Unit* who) override - { - if (who->HasAura(SPELL_MOTHERS_MILK)) - { - if (who->GetTypeId() == TYPEID_PLAYER && me->IsWithinDistInMap(who, 15) && who->isInAccessiblePlaceFor(me)) - { - DoCast(who, SPELL_WICKED_MILKING); - if (Player* player = who->ToPlayer()) - player->AreaExploredOrEventHappens(QUEST_MOTHERS_MILK); - } - } - - ScriptedAI::MoveInLineOfSight(who); - } - - void EnterCombat(Unit* /*who*/) override { } - - bool GossipHello(Player* player) override - { - if (me->IsQuestGiver()) - { - player->PrepareQuestMenu(me->GetGUID()); - SendGossipMenuFor(player, player->GetGossipTextId(me), me->GetGUID()); - } - return true; - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_ragged_johnAI(creature); - } -}; - -void AddSC_burning_steppes() -{ - new npc_ragged_john(); -} diff --git a/src/server/scripts/EasternKingdoms/zone_ghostlands.cpp b/src/server/scripts/EasternKingdoms/zone_ghostlands.cpp index 5a8197d8f5f..28d942c0716 100644 --- a/src/server/scripts/EasternKingdoms/zone_ghostlands.cpp +++ b/src/server/scripts/EasternKingdoms/zone_ghostlands.cpp @@ -60,11 +60,11 @@ class npc_ranger_lilatha : public CreatureScript public: npc_ranger_lilatha() : CreatureScript("npc_ranger_lilatha") { } - struct npc_ranger_lilathaAI : public npc_escortAI + struct npc_ranger_lilathaAI : public EscortAI { - npc_ranger_lilathaAI(Creature* creature) : npc_escortAI(creature) { } + npc_ranger_lilathaAI(Creature* creature) : EscortAI(creature) { } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { Player* player = GetPlayerForEscort(); if (!player) diff --git a/src/server/scripts/EasternKingdoms/zone_hinterlands.cpp b/src/server/scripts/EasternKingdoms/zone_hinterlands.cpp index af79fd66ea5..519bfe5f619 100644 --- a/src/server/scripts/EasternKingdoms/zone_hinterlands.cpp +++ b/src/server/scripts/EasternKingdoms/zone_hinterlands.cpp @@ -55,9 +55,9 @@ class npc_oox09hl : public CreatureScript public: npc_oox09hl() : CreatureScript("npc_oox09hl") { } - struct npc_oox09hlAI : public npc_escortAI + struct npc_oox09hlAI : public EscortAI { - npc_oox09hlAI(Creature* creature) : npc_escortAI(creature) { } + npc_oox09hlAI(Creature* creature) : EscortAI(creature) { } void Reset() override { } @@ -81,11 +81,11 @@ public: me->SetStandState(UNIT_STAND_STATE_STAND); me->SetFaction(player->GetTeam() == ALLIANCE ? FACTION_ESCORTEE_A_PASSIVE : FACTION_ESCORTEE_H_PASSIVE); Talk(SAY_OOX_START, player); - npc_escortAI::Start(false, false, player->GetGUID(), quest); + EscortAI::Start(false, false, player->GetGUID(), quest); } } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { switch (waypointId) { @@ -103,7 +103,7 @@ public: } } - void WaypointStart(uint32 pointId) override + void WaypointStarted(uint32 pointId, uint32 /*pathId*/) override { switch (pointId) { @@ -168,9 +168,9 @@ class npc_rinji : public CreatureScript public: npc_rinji() : CreatureScript("npc_rinji") { } - struct npc_rinjiAI : public npc_escortAI + struct npc_rinjiAI : public EscortAI { - npc_rinjiAI(Creature* creature) : npc_escortAI(creature) + npc_rinjiAI(Creature* creature) : EscortAI(creature) { Initialize(); _IsByOutrunner = false; @@ -188,12 +188,12 @@ public: Initialize(); } - void JustRespawned() override + void JustAppeared() override { _IsByOutrunner = false; spawnId = 0; - npc_escortAI::JustRespawned(); + EscortAI::JustAppeared(); } void EnterCombat(Unit* who) override @@ -241,11 +241,11 @@ public: if (GameObject* go = me->FindNearestGameObject(GO_RINJI_CAGE, INTERACTION_DISTANCE)) go->UseDoorOrButton(); - npc_escortAI::Start(false, false, player->GetGUID(), quest); + EscortAI::Start(false, false, player->GetGUID(), quest); } } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { Player* player = GetPlayerForEscort(); if (!player) diff --git a/src/server/scripts/EasternKingdoms/zone_isle_of_queldanas.cpp b/src/server/scripts/EasternKingdoms/zone_isle_of_queldanas.cpp deleted file mode 100644 index db23c49f437..00000000000 --- a/src/server/scripts/EasternKingdoms/zone_isle_of_queldanas.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/* ScriptData -SDName: Isle_of_Queldanas -SD%Complete: 100 -SDComment: Quest support: 11541 -SDCategory: Isle Of Quel'Danas -EndScriptData */ - -/* ContentData -npc_greengill_slave -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "Player.h" -#include "SpellInfo.h" - -/*###### -## npc_greengill_slave -######*/ - -enum GreengillSlave -{ - NPC_DARKSPINE_MYRIDON = 25060, - QUEST_GREENGILL_COAST = 11541, - SPELL_ENRAGE = 45111, - SPELL_ORB_MURLOC_CONTROL = 45109, - SPELL_GREENGILL_SLAVE_FREED = 45110 -}; - -class npc_greengill_slave : public CreatureScript -{ -public: - npc_greengill_slave() : CreatureScript("npc_greengill_slave") { } - - struct npc_greengill_slaveAI : public ScriptedAI - { - npc_greengill_slaveAI(Creature* creature) : ScriptedAI(creature) { } - - void SpellHit(Unit* caster, SpellInfo const* spellInfo) override - { - Player* player = caster->ToPlayer(); - - if (!player) - return; - - if (spellInfo->Id == SPELL_ORB_MURLOC_CONTROL && !me->HasAura(SPELL_ENRAGE)) - { - if (player->GetQuestStatus(QUEST_GREENGILL_COAST) == QUEST_STATUS_INCOMPLETE) - DoCast(player, SPELL_GREENGILL_SLAVE_FREED, true); - - DoCast(me, SPELL_ENRAGE); - - if (Creature* Myrmidon = me->FindNearestCreature(NPC_DARKSPINE_MYRIDON, 70)) - { - AddThreat(Myrmidon, 100000.0f); - AttackStart(Myrmidon); - } - } - } - - void UpdateAI(uint32 /*diff*/) override - { - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_greengill_slaveAI(creature); - } -}; - -void AddSC_isle_of_queldanas() -{ - new npc_greengill_slave(); -} diff --git a/src/server/scripts/EasternKingdoms/zone_redridge_mountains.cpp b/src/server/scripts/EasternKingdoms/zone_redridge_mountains.cpp index bcd4f9bcb37..4e4f767d989 100644 --- a/src/server/scripts/EasternKingdoms/zone_redridge_mountains.cpp +++ b/src/server/scripts/EasternKingdoms/zone_redridge_mountains.cpp @@ -43,9 +43,9 @@ class npc_corporal_keeshan : public CreatureScript public: npc_corporal_keeshan() : CreatureScript("npc_corporal_keeshan") { } - struct npc_corporal_keeshanAI : public npc_escortAI + struct npc_corporal_keeshanAI : public EscortAI { - npc_corporal_keeshanAI(Creature* creature) : npc_escortAI(creature) + npc_corporal_keeshanAI(Creature* creature) : EscortAI(creature) { Initialize(); } @@ -69,11 +69,11 @@ public: { Talk(SAY_CORPORAL_1, player); me->SetFaction(FACTION_ESCORTEE_N_NEUTRAL_ACTIVE); - npc_escortAI::Start(true, false, player->GetGUID(), quest); + EscortAI::Start(true, false, player->GetGUID(), quest); } } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { Player* player = GetPlayerForEscort(); if (!player) @@ -105,7 +105,7 @@ public: if (HasEscortState(STATE_ESCORT_NONE)) return; - npc_escortAI::UpdateAI(diff); + EscortAI::UpdateAI(diff); if (phase) { diff --git a/src/server/scripts/EasternKingdoms/zone_silverpine_forest.cpp b/src/server/scripts/EasternKingdoms/zone_silverpine_forest.cpp index 4a4e19d0225..bad77139853 100644 --- a/src/server/scripts/EasternKingdoms/zone_silverpine_forest.cpp +++ b/src/server/scripts/EasternKingdoms/zone_silverpine_forest.cpp @@ -65,11 +65,11 @@ class npc_deathstalker_erland : public CreatureScript public: npc_deathstalker_erland() : CreatureScript("npc_deathstalker_erland") { } - struct npc_deathstalker_erlandAI : public npc_escortAI + struct npc_deathstalker_erlandAI : public EscortAI { - npc_deathstalker_erlandAI(Creature* creature) : npc_escortAI(creature) { } + npc_deathstalker_erlandAI(Creature* creature) : EscortAI(creature) { } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { Player* player = GetPlayerForEscort(); if (!player) diff --git a/src/server/scripts/EasternKingdoms/zone_stormwind_city.cpp b/src/server/scripts/EasternKingdoms/zone_stormwind_city.cpp index d883f282549..e7f5ed8866f 100644 --- a/src/server/scripts/EasternKingdoms/zone_stormwind_city.cpp +++ b/src/server/scripts/EasternKingdoms/zone_stormwind_city.cpp @@ -128,9 +128,9 @@ public: return new npc_lord_gregor_lescovarAI(creature); } - struct npc_lord_gregor_lescovarAI : public npc_escortAI + struct npc_lord_gregor_lescovarAI : public EscortAI { - npc_lord_gregor_lescovarAI(Creature* creature) : npc_escortAI(creature) + npc_lord_gregor_lescovarAI(Creature* creature) : EscortAI(creature) { Initialize(); } @@ -173,7 +173,7 @@ public: } } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { switch (waypointId) { @@ -264,7 +264,7 @@ public: } } else uiTimer -= uiDiff; } - npc_escortAI::UpdateAI(uiDiff); + EscortAI::UpdateAI(uiDiff); if (!UpdateVictim()) return; @@ -389,9 +389,9 @@ public: return new npc_tyrion_spybotAI(creature); } - struct npc_tyrion_spybotAI : public npc_escortAI + struct npc_tyrion_spybotAI : public EscortAI { - npc_tyrion_spybotAI(Creature* creature) : npc_escortAI(creature) + npc_tyrion_spybotAI(Creature* creature) : EscortAI(creature) { Initialize(); } @@ -410,7 +410,7 @@ public: Initialize(); } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { switch (waypointId) { @@ -506,7 +506,7 @@ public: } } else uiTimer -= uiDiff; } - npc_escortAI::UpdateAI(uiDiff); + EscortAI::UpdateAI(uiDiff); if (!UpdateVictim()) return; diff --git a/src/server/scripts/EasternKingdoms/zone_stranglethorn_vale.cpp b/src/server/scripts/EasternKingdoms/zone_stranglethorn_vale.cpp deleted file mode 100644 index 0d399cb907e..00000000000 --- a/src/server/scripts/EasternKingdoms/zone_stranglethorn_vale.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/* ScriptData -SDName: Stranglethorn_Vale -SD%Complete: 100 -SDComment: Quest support: 592 -SDCategory: Stranglethorn Vale -EndScriptData */ - -/* ContentData -npc_yenniku -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "Player.h" -#include "SpellInfo.h" - -/*###### -## npc_yenniku -######*/ - -class npc_yenniku : public CreatureScript -{ -public: - npc_yenniku() : CreatureScript("npc_yenniku") { } - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_yennikuAI(creature); - } - - struct npc_yennikuAI : public ScriptedAI - { - npc_yennikuAI(Creature* creature) : ScriptedAI(creature) - { - Initialize(); - bReset = false; - } - - void Initialize() - { - Reset_Timer = 0; - } - - uint32 Reset_Timer; - bool bReset; - - void Reset() override - { - Initialize(); - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE); - } - - void SpellHit(Unit* caster, SpellInfo const* spell) override - { - if (bReset || spell->Id != 3607) - return; - - if (Player* player = caster->ToPlayer()) - { - if (player->GetQuestStatus(592) == QUEST_STATUS_INCOMPLETE) //Yenniku's Release - { - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_STUN); - me->CombatStop(); //stop combat - me->GetThreatManager().ClearAllThreat(); //unsure of this - me->SetFaction(FACTION_HORDE_GENERIC); - - bReset = true; - Reset_Timer = 60000; - } - } - } - - void EnterCombat(Unit* /*who*/) override { } - - void UpdateAI(uint32 diff) override - { - if (bReset) - { - if (Reset_Timer <= diff) - { - EnterEvadeMode(); - bReset = false; - me->SetFaction(FACTION_TROLL_BLOODSCALP); - return; - } - - Reset_Timer -= diff; - - if (me->IsInCombat() && me->GetVictim()) - { - if (Player* player = me->EnsureVictim()->ToPlayer()) - { - if (player->GetTeam() == HORDE) - { - me->CombatStop(); - me->GetThreatManager().ClearAllThreat(); - } - } - } - } - - //Return since we have no target - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - } - }; -}; - -/*###### -## -######*/ - -void AddSC_stranglethorn_vale() -{ - new npc_yenniku(); -} diff --git a/src/server/scripts/EasternKingdoms/zone_swamp_of_sorrows.cpp b/src/server/scripts/EasternKingdoms/zone_swamp_of_sorrows.cpp index e0396397889..fcc2ea370ec 100644 --- a/src/server/scripts/EasternKingdoms/zone_swamp_of_sorrows.cpp +++ b/src/server/scripts/EasternKingdoms/zone_swamp_of_sorrows.cpp @@ -43,9 +43,9 @@ class npc_galen_goodward : public CreatureScript public: npc_galen_goodward() : CreatureScript("npc_galen_goodward") { } - struct npc_galen_goodwardAI : public npc_escortAI + struct npc_galen_goodwardAI : public EscortAI { - npc_galen_goodwardAI(Creature* creature) : npc_escortAI(creature) + npc_galen_goodwardAI(Creature* creature) : EscortAI(creature) { galensCageGUID.Clear(); Reset(); @@ -67,11 +67,11 @@ public: if (quest->GetQuestId() == QUEST_GALENS_ESCAPE) { Talk(SAY_QUEST_ACCEPTED, player); - npc_escortAI::Start(false, false, player->GetGUID(), quest); + EscortAI::Start(false, false, player->GetGUID(), quest); } } - void WaypointStart(uint32 uiPointId) override + void WaypointStarted(uint32 uiPointId, uint32 /*pathId*/) override { switch (uiPointId) { @@ -95,7 +95,7 @@ public: } } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { switch (waypointId) { @@ -118,7 +118,7 @@ public: void UpdateAI(uint32 diff) override { - npc_escortAI::UpdateAI(diff); + EscortAI::UpdateAI(diff); if (HasEscortState(STATE_ESCORT_NONE)) return; diff --git a/src/server/scripts/EasternKingdoms/zone_tirisfal_glades.cpp b/src/server/scripts/EasternKingdoms/zone_tirisfal_glades.cpp index 374dd3ef5c4..2a7178d6fcb 100644 --- a/src/server/scripts/EasternKingdoms/zone_tirisfal_glades.cpp +++ b/src/server/scripts/EasternKingdoms/zone_tirisfal_glades.cpp @@ -42,9 +42,15 @@ EndContentData */ enum Calvin { - SAY_COMPLETE = 0, - SPELL_DRINK = 2639, // possibly not correct spell (but iconId is correct) - QUEST_590 = 590 + SAY_COMPLETE = 0, + SPELL_DRINK = 7737, // Possibly incorrect spell, but both duration and icon are correct + QUEST_590 = 590, + + EVENT_EMOTE_RUDE = 1, + EVENT_TALK = 2, + EVENT_DRINK = 3, + EVENT_SET_QUESTGIVER_FLAG = 4, + EVENT_STAND = 5 }; class npc_calvin_montague : public CreatureScript @@ -54,82 +60,59 @@ public: struct npc_calvin_montagueAI : public ScriptedAI { - npc_calvin_montagueAI(Creature* creature) : ScriptedAI(creature) - { - Initialize(); - } - - void Initialize() - { - m_uiPhase = 0; - m_uiPhaseTimer = 5000; - m_uiPlayerGUID.Clear(); - } - - uint32 m_uiPhase; - uint32 m_uiPhaseTimer; - ObjectGuid m_uiPlayerGUID; + npc_calvin_montagueAI(Creature* creature) : ScriptedAI(creature) { } void Reset() override { - Initialize(); - me->RestoreFaction(); - if (!me->IsImmuneToPC()) me->SetImmuneToPC(true); } void EnterCombat(Unit* /*who*/) override { } - void DamageTaken(Unit* pDoneBy, uint32 &uiDamage) override + void DamageTaken(Unit* /*attacker*/, uint32 &damage) override { - if (uiDamage > me->GetHealth() || me->HealthBelowPctDamaged(15, uiDamage)) + if (damage > me->GetHealth() || me->HealthBelowPctDamaged(15, damage)) { - uiDamage = 0; - - me->RestoreFaction(); - me->SetImmuneToPC(true); + damage = 0; me->CombatStop(true); - - m_uiPhase = 1; - - if (pDoneBy->GetTypeId() == TYPEID_PLAYER) - m_uiPlayerGUID = pDoneBy->GetGUID(); + EnterEvadeMode(); + _events.ScheduleEvent(EVENT_EMOTE_RUDE, Seconds(3)); } } void UpdateAI(uint32 diff) override { - if (m_uiPhase) - { - if (m_uiPhaseTimer <= diff) - m_uiPhaseTimer = 7500; - else - { - m_uiPhaseTimer -= diff; - return; - } + _events.Update(diff); - switch (m_uiPhase) + if (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) { - case 1: + case EVENT_EMOTE_RUDE: + me->HandleEmoteCommand(EMOTE_ONESHOT_RUDE); + _events.ScheduleEvent(EVENT_TALK, Seconds(2)); + break; + case EVENT_TALK: Talk(SAY_COMPLETE); - ++m_uiPhase; + _events.ScheduleEvent(EVENT_DRINK, Seconds(5)); break; - case 2: - if (Player* player = ObjectAccessor::GetPlayer(*me, m_uiPlayerGUID)) + case EVENT_DRINK: + if (Player* player = ObjectAccessor::GetPlayer(*me, _playerGUID)) player->AreaExploredOrEventHappens(QUEST_590); - - DoCast(me, SPELL_DRINK, true); - ++m_uiPhase; + _playerGUID.Clear(); + DoCastSelf(SPELL_DRINK); + _events.ScheduleEvent(EVENT_SET_QUESTGIVER_FLAG, Seconds(12)); + break; + case EVENT_SET_QUESTGIVER_FLAG: + me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); + _events.ScheduleEvent(EVENT_STAND, Seconds(3)); break; - case 3: - EnterEvadeMode(); + case EVENT_STAND: + me->SetStandState(UNIT_STAND_STATE_STAND); break; } - - return; } if (!UpdateVictim()) @@ -142,11 +125,17 @@ public: { if (quest->GetQuestId() == QUEST_590) { + _playerGUID = player->GetGUID(); me->SetFaction(FACTION_ENEMY); me->SetImmuneToPC(false); AttackStart(player); + me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); } } + + private: + EventMap _events; + ObjectGuid _playerGUID; }; CreatureAI* GetAI(Creature* creature) const override diff --git a/src/server/scripts/EasternKingdoms/zone_undercity.cpp b/src/server/scripts/EasternKingdoms/zone_undercity.cpp index 37fe5cec1f9..4eaf6ce0002 100644 --- a/src/server/scripts/EasternKingdoms/zone_undercity.cpp +++ b/src/server/scripts/EasternKingdoms/zone_undercity.cpp @@ -82,6 +82,11 @@ enum Sylvanas GUID_EVENT_INVOKER = 1, }; +enum Sounds +{ + SOUND_AGGRO = 5886 +}; + float HighborneLoc[4][3]= { {1285.41f, 312.47f, 0.51f}, @@ -120,6 +125,7 @@ public: void EnterCombat(Unit* /*who*/) override { + DoPlaySoundToSet(me, SOUND_AGGRO); _events.ScheduleEvent(EVENT_FADE, 30000); _events.ScheduleEvent(EVENT_SUMMON_SKELETON, 20000); _events.ScheduleEvent(EVENT_BLACK_ARROW, 15000); diff --git a/src/server/scripts/EasternKingdoms/zone_western_plaguelands.cpp b/src/server/scripts/EasternKingdoms/zone_western_plaguelands.cpp index 7ba95268562..159a37812a9 100644 --- a/src/server/scripts/EasternKingdoms/zone_western_plaguelands.cpp +++ b/src/server/scripts/EasternKingdoms/zone_western_plaguelands.cpp @@ -19,12 +19,11 @@ /* ScriptData SDName: Western_Plaguelands SD%Complete: 90 -SDComment: Quest support: 5097, 5098, 5216, 5219, 5222, 5225, 5229, 5231, 5233, 5235. To obtain Vitreous Focuser (could use more spesifics about gossip items) +SDComment: Quest support: 5097, 5098, 5216, 5219, 5222, 5225, 5229, 5231, 5233, 5235. SDCategory: Western Plaguelands EndScriptData */ /* ContentData -npcs_dithers_and_arbington npc_the_scourge_cauldron npc_andorhal_tower EndContentData */ @@ -36,99 +35,6 @@ EndContentData */ #include "WorldSession.h" /*###### -## npcs_dithers_and_arbington -######*/ - -enum DithersAndArbington -{ - GOSSIP_ITEM_ID_FELSTONE_FIELD = 0, - GOSSIP_ITEM_ID_DALSON_S_TEARS = 1, - GOSSIP_ITEM_ID_WRITHING_HAUNT = 2, - GOSSIP_ITEM_ID_GAHRRON_S_WITH = 3, - GOSSIP_MENU_ID_LETS_GET_TO_WORK = 3223, - GOSSIP_MENU_ID_VITREOUS_FOCUSER = 3229, - NPC_TEXT_OSSEOUS_AGITATORS = 3980, - NPC_TEXT_SOMATIC_INTENSIFIERS_1 = 3981, - NPC_TEXT_SOMATIC_INTENSIFIERS_2 = 3982, - NPC_TEXT_ECTOPLASMIC_RESONATORS = 3983, - NPC_TEXT_LET_S_GET_TO_WORK = 3985, - QUEST_MISSION_ACCOMPLISHED_H = 5237, - QUEST_MISSION_ACCOMPLISHED_A = 5238, - CREATE_ITEM_VITREOUS_FOCUSER = 17529 -}; - -class npcs_dithers_and_arbington : public CreatureScript -{ - public: - npcs_dithers_and_arbington() : CreatureScript("npcs_dithers_and_arbington") { } - - struct npcs_dithers_and_arbingtonAI : public ScriptedAI - { - npcs_dithers_and_arbingtonAI(Creature* creature) : ScriptedAI(creature) { } - - bool GossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override - { - uint32 const action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId); - ClearGossipMenuFor(player); - switch (action) - { - case GOSSIP_ACTION_TRADE: - player->GetSession()->SendListInventory(me->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 1: - AddGossipItemFor(player, GOSSIP_MENU_ID_VITREOUS_FOCUSER, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5); - SendGossipMenuFor(player, NPC_TEXT_OSSEOUS_AGITATORS, me->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 2: - AddGossipItemFor(player, GOSSIP_MENU_ID_VITREOUS_FOCUSER, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5); - SendGossipMenuFor(player, NPC_TEXT_SOMATIC_INTENSIFIERS_1, me->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 3: - AddGossipItemFor(player, GOSSIP_MENU_ID_VITREOUS_FOCUSER, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5); - SendGossipMenuFor(player, NPC_TEXT_SOMATIC_INTENSIFIERS_2, me->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 4: - AddGossipItemFor(player, GOSSIP_MENU_ID_VITREOUS_FOCUSER, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5); - SendGossipMenuFor(player, NPC_TEXT_ECTOPLASMIC_RESONATORS, me->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 5: - CloseGossipMenuFor(player); - DoCast(player, CREATE_ITEM_VITREOUS_FOCUSER, false); - break; - } - return true; - } - - bool GossipHello(Player* player) override - { - if (me->IsQuestGiver()) - player->PrepareQuestMenu(me->GetGUID()); - - if (me->IsVendor()) - AddGossipItemFor(player, GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); - - if (player->GetQuestRewardStatus(QUEST_MISSION_ACCOMPLISHED_H) || player->GetQuestRewardStatus(QUEST_MISSION_ACCOMPLISHED_A)) - { - AddGossipItemFor(player, GOSSIP_MENU_ID_LETS_GET_TO_WORK, GOSSIP_ITEM_ID_FELSTONE_FIELD, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - AddGossipItemFor(player, GOSSIP_MENU_ID_LETS_GET_TO_WORK, GOSSIP_ITEM_ID_DALSON_S_TEARS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - AddGossipItemFor(player, GOSSIP_MENU_ID_LETS_GET_TO_WORK, GOSSIP_ITEM_ID_WRITHING_HAUNT, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); - AddGossipItemFor(player, GOSSIP_MENU_ID_LETS_GET_TO_WORK, GOSSIP_ITEM_ID_GAHRRON_S_WITH, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4); - SendGossipMenuFor(player, NPC_TEXT_LET_S_GET_TO_WORK, me->GetGUID()); - } - else - SendGossipMenuFor(player, player->GetGossipTextId(me), me->GetGUID()); - - return true; - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npcs_dithers_and_arbingtonAI(creature); - } -}; - -/*###### ## npc_the_scourge_cauldron ######*/ @@ -248,7 +154,6 @@ public: void AddSC_western_plaguelands() { - new npcs_dithers_and_arbington(); new npc_the_scourge_cauldron(); new npc_andorhal_tower(); } diff --git a/src/server/scripts/EasternKingdoms/zone_wetlands.cpp b/src/server/scripts/EasternKingdoms/zone_wetlands.cpp index 51dbdf19a03..6120b89ee2b 100644 --- a/src/server/scripts/EasternKingdoms/zone_wetlands.cpp +++ b/src/server/scripts/EasternKingdoms/zone_wetlands.cpp @@ -56,9 +56,9 @@ public: return new npc_tapoke_slim_jahnAI(creature); } - struct npc_tapoke_slim_jahnAI : public npc_escortAI + struct npc_tapoke_slim_jahnAI : public EscortAI { - npc_tapoke_slim_jahnAI(Creature* creature) : npc_escortAI(creature) + npc_tapoke_slim_jahnAI(Creature* creature) : EscortAI(creature) { Initialize(); } @@ -76,7 +76,7 @@ public: Initialize(); } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { switch (waypointId) { diff --git a/src/server/scripts/Kalimdor/BlackfathomDeeps/blackfathom_deeps.cpp b/src/server/scripts/Kalimdor/BlackfathomDeeps/blackfathom_deeps.cpp index 921af01bfb4..a026506bb9d 100644 --- a/src/server/scripts/Kalimdor/BlackfathomDeeps/blackfathom_deeps.cpp +++ b/src/server/scripts/Kalimdor/BlackfathomDeeps/blackfathom_deeps.cpp @@ -223,16 +223,16 @@ class npc_morridune : public CreatureScript public: npc_morridune() : CreatureScript("npc_morridune") { } - struct npc_morriduneAI : public npc_escortAI + struct npc_morriduneAI : public EscortAI { - npc_morriduneAI(Creature* creature) : npc_escortAI(creature) + npc_morriduneAI(Creature* creature) : EscortAI(creature) { Talk(SAY_MORRIDUNE_1); me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); Start(false); } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { switch (waypointId) { diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp index b41eb13c46c..885d611e3bc 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp @@ -99,7 +99,7 @@ public: Talk(SAY_ONSLAY); } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { if (waypointId == 7) { @@ -121,8 +121,8 @@ public: { if (IsEvent) { - //Must update npc_escortAI - npc_escortAI::UpdateAI(diff); + //Must update EscortAI + EscortAI::UpdateAI(diff); if (!go) { go = true; diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp index 985f4e214a8..5e3ba51b1ca 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp @@ -102,7 +102,7 @@ public: Talk(SAY_ONSLAY); } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { if (waypointId == 7 && instance) { @@ -124,8 +124,8 @@ public: { if (IsEvent) { - //Must update npc_escortAI - npc_escortAI::UpdateAI(diff); + //Must update EscortAI + EscortAI::UpdateAI(diff); if (!go) { go = true; @@ -225,10 +225,6 @@ public: { } - void WaypointReached(uint32 /*waypointId*/) override - { - } - void MoveInLineOfSight(Unit* who) override { diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp index 25c174cb26a..fc26c35a314 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp @@ -97,7 +97,7 @@ public: Talk(SAY_ONSLAY); } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { if (waypointId == 7 && instance) { @@ -119,8 +119,8 @@ public: { if (IsEvent) { - //Must update npc_escortAI - npc_escortAI::UpdateAI(diff); + //Must update EscortAI + EscortAI::UpdateAI(diff); if (!go) { go = true; diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_rage_winterchill.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_rage_winterchill.cpp index d1677b2c8ef..746350853b9 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_rage_winterchill.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_rage_winterchill.cpp @@ -92,7 +92,7 @@ public: Talk(SAY_ONSLAY); } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { if (waypointId == 7 && instance) { @@ -114,8 +114,8 @@ public: { if (IsEvent) { - //Must update npc_escortAI - npc_escortAI::UpdateAI(diff); + //Must update EscortAI + EscortAI::UpdateAI(diff); if (!go) { go = true; diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp index 48b8e59a5a7..ec918cbb3a4 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp @@ -316,7 +316,7 @@ float HordeFirePos[65][8]=//spawn points for the fire visuals (GO) in the horde {5545.43f, -2647.82f, 1483.05f, 5.38848f, 0, 0, 0.432578f, -0.901596f} }; -hyjalAI::hyjalAI(Creature* creature) : npc_escortAI(creature), Summons(me) +hyjalAI::hyjalAI(Creature* creature) : EscortAI(creature), Summons(me) { Initialize(); instance = creature->GetInstanceScript(); @@ -447,7 +447,7 @@ void hyjalAI::MoveInLineOfSight(Unit* who) if (IsDummy) return; - npc_escortAI::MoveInLineOfSight(who); + EscortAI::MoveInLineOfSight(who); } void hyjalAI::SummonCreature(uint32 entry, float Base[4][3]) @@ -930,7 +930,7 @@ void hyjalAI::RespawnNearPos(float x, float y) Cell::VisitGridObjects(x, y, me->GetMap(), worker, me->GetGridActivationRange()); } -void hyjalAI::WaypointReached(uint32 waypointId) +void hyjalAI::WaypointReached(uint32 waypointId, uint32 /*pathId*/) { if (waypointId == 1 || (waypointId == 0 && me->GetEntry() == THRALL)) { @@ -979,7 +979,7 @@ void hyjalAI::WaypointReached(uint32 waypointId) } void hyjalAI::DoOverrun(uint32 faction, const uint32 diff) { - npc_escortAI::UpdateAI(diff); + EscortAI::UpdateAI(diff); if (WaitForTeleport) { if (TeleportTimer <= diff) diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.h b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.h index a61a568f61b..9a0c1f78b92 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.h +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.h @@ -115,7 +115,7 @@ enum YellId DEATH = 6, // Used on death }; -struct hyjalAI : public npc_escortAI +struct hyjalAI : public EscortAI { hyjalAI(Creature* creature); @@ -144,7 +144,7 @@ struct hyjalAI : public npc_escortAI void SummonedCreatureDespawn(Creature* summoned) override; void HideNearPos(float x, float y); void RespawnNearPos(float x, float y); - void WaypointReached(uint32 waypointId) override; + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override; void DoOverrun(uint32 faction, const uint32 diff); void MoveInLineOfSight(Unit* who) override; diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp index f9cd454c67e..6d05e6094b1 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp @@ -176,7 +176,7 @@ float HordeOverrunWP[21][3]=//waypoints in the horde base used in the end in the {5429.91f, -2718.44f, 1493.42f}//20 end 2 }; -hyjal_trashAI::hyjal_trashAI(Creature* creature) : npc_escortAI(creature) +hyjal_trashAI::hyjal_trashAI(Creature* creature) : EscortAI(creature) { instance = creature->GetInstanceScript(); IsEvent = false; @@ -443,7 +443,7 @@ public: void EnterCombat(Unit* /*who*/) override { } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { if (waypointId == 0 && !IsOverrun) { @@ -498,7 +498,7 @@ public: if (!CanMove)return; hyjal_trashAI::UpdateAI(diff); if (IsEvent || IsOverrun) - npc_escortAI::UpdateAI(diff); + EscortAI::UpdateAI(diff); if (IsEvent) { if (!go) @@ -558,7 +558,7 @@ public: KnockDownTimer = 10000; } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { if (waypointId == 7 && !IsOverrun) { @@ -590,7 +590,7 @@ public: { hyjal_trashAI::UpdateAI(diff); if (IsEvent || IsOverrun) - npc_escortAI::UpdateAI(diff); + EscortAI::UpdateAI(diff); if (IsEvent) { if (!go) @@ -656,7 +656,7 @@ public: RandomMove = false; } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { if (waypointId == 7 && !IsOverrun) { @@ -689,7 +689,7 @@ public: { hyjal_trashAI::UpdateAI(diff); if (IsEvent || IsOverrun) - npc_escortAI::UpdateAI(diff); + EscortAI::UpdateAI(diff); if (IsEvent) { if (!go) @@ -766,7 +766,7 @@ public: summons.Despawn(summon); } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { if (waypointId == 7 && !IsOverrun) { @@ -810,7 +810,7 @@ public: hyjal_trashAI::UpdateAI(diff); if (IsEvent || IsOverrun) - npc_escortAI::UpdateAI(diff); + EscortAI::UpdateAI(diff); if (IsEvent) { @@ -879,7 +879,7 @@ public: ShellTimer = 50000 + rand32() % 10000; } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { if (waypointId == 7 && !IsOverrun) { @@ -904,7 +904,7 @@ public: { hyjal_trashAI::UpdateAI(diff); if (IsEvent || IsOverrun) - npc_escortAI::UpdateAI(diff); + EscortAI::UpdateAI(diff); if (IsEvent) { if (!go) @@ -975,7 +975,7 @@ public: WebTimer = 20000 + rand32() % 5000; } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { if (waypointId == 7 && !IsOverrun) { @@ -1000,7 +1000,7 @@ public: { hyjal_trashAI::UpdateAI(diff); if (IsEvent || IsOverrun) - npc_escortAI::UpdateAI(diff); + EscortAI::UpdateAI(diff); if (IsEvent) { if (!go) @@ -1061,7 +1061,7 @@ public: ManaBurnTimer = 9000 + rand32() % 5000; } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { if (waypointId == 7 && !IsOverrun) { @@ -1086,7 +1086,7 @@ public: { hyjal_trashAI::UpdateAI(diff); if (IsEvent || IsOverrun) - npc_escortAI::UpdateAI(diff); + EscortAI::UpdateAI(diff); if (IsEvent) { if (!go) @@ -1155,7 +1155,7 @@ public: me->SetDisableGravity(true); } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { if (waypointId == 2 && !IsOverrun) { @@ -1189,7 +1189,7 @@ public: if (IsEvent || IsOverrun) { ENSURE_AI(hyjal_trashAI, me->AI())->SetCanAttack(false); - npc_escortAI::UpdateAI(diff); + EscortAI::UpdateAI(diff); } if (IsEvent) @@ -1280,7 +1280,7 @@ public: me->SetDisableGravity(true); } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { if (waypointId == 2 && !IsOverrun) { @@ -1310,7 +1310,7 @@ public: if (IsEvent || IsOverrun) { ENSURE_AI(hyjal_trashAI, me->AI())->SetCanAttack(false); - npc_escortAI::UpdateAI(diff); + EscortAI::UpdateAI(diff); } if (IsEvent) diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.h b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.h index 66189f9c71d..d3ccbecf7ea 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.h +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.h @@ -21,7 +21,7 @@ #include "hyjal.h" #include "ScriptedEscortAI.h" -struct hyjal_trashAI : public npc_escortAI +struct hyjal_trashAI : public EscortAI { hyjal_trashAI(Creature* creature); diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp index 26c718c3930..860b4a38968 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp @@ -258,9 +258,9 @@ class npc_arthas : public CreatureScript public: npc_arthas() : CreatureScript("npc_arthas") { } - struct npc_arthasAI : public npc_escortAI + struct npc_arthasAI : public EscortAI { - npc_arthasAI(Creature* creature) : npc_escortAI(creature) + npc_arthasAI(Creature* creature) : EscortAI(creature) { Initialize(); instance = creature->GetInstanceScript(); @@ -336,7 +336,7 @@ public: void AttackStart(Unit* who) override { if (who && !who->IsImmuneToPC()) - npc_escortAI::AttackStart(who); + EscortAI::AttackStart(who); } void EnterCombat(Unit* /*who*/) override @@ -391,7 +391,7 @@ public: ++step; } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { switch (waypointId) { @@ -511,7 +511,7 @@ public: void UpdateAI(uint32 diff) override { - npc_escortAI::UpdateAI(diff); + EscortAI::UpdateAI(diff); if (bStepping) { @@ -901,7 +901,7 @@ public: } } else if (instance->GetBossState(bossEvent) == FAIL) - npc_escortAI::EnterEvadeMode(); + EscortAI::EnterEvadeMode(); else phaseTimer = 10000; break; @@ -1061,7 +1061,7 @@ public: JumpToNextStep(15000); } else if (instance->GetBossState(DATA_EPOCH) == FAIL) - npc_escortAI::EnterEvadeMode(); + EscortAI::EnterEvadeMode(); else phaseTimer = 10000; break; @@ -1106,7 +1106,7 @@ public: JumpToNextStep(1000); } else if (instance->GetBossState(DATA_MAL_GANIS) == FAIL) - npc_escortAI::EnterEvadeMode(); + EscortAI::EnterEvadeMode(); else phaseTimer = 10000; break; @@ -1196,7 +1196,7 @@ public: return false; AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_ITEM_ARTHAS_0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); SendGossipMenuFor(player, 907, me->GetGUID()); - break; + break; } case 1: AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_ITEM_ARTHAS_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp index 29e94b2bd9f..c4ba72f2563 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp @@ -197,9 +197,9 @@ class npc_thrall_old_hillsbrad : public CreatureScript public: npc_thrall_old_hillsbrad() : CreatureScript("npc_thrall_old_hillsbrad") { } - struct npc_thrall_old_hillsbradAI : public npc_escortAI + struct npc_thrall_old_hillsbradAI : public EscortAI { - npc_thrall_old_hillsbradAI(Creature* creature) : npc_escortAI(creature) + npc_thrall_old_hillsbradAI(Creature* creature) : EscortAI(creature) { Initialize(); instance = creature->GetInstanceScript(); @@ -217,7 +217,7 @@ public: bool LowHp; bool HadMount; - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { switch (waypointId) { @@ -354,7 +354,7 @@ public: if (Creature* Taretha = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_TARETHA))) { if (Player* player = GetPlayerForEscort()) - ENSURE_AI(npc_escortAI, (Taretha->AI()))->Start(false, true, player->GetGUID()); + ENSURE_AI(EscortAI, (Taretha->AI()))->Start(false, true, player->GetGUID()); } //kill credit Creature for quest @@ -455,7 +455,7 @@ public: void UpdateAI(uint32 diff) override { - npc_escortAI::UpdateAI(diff); + EscortAI::UpdateAI(diff); if (!UpdateVictim()) return; @@ -564,16 +564,16 @@ class npc_taretha : public CreatureScript public: npc_taretha() : CreatureScript("npc_taretha") { } - struct npc_tarethaAI : public npc_escortAI + struct npc_tarethaAI : public EscortAI { - npc_tarethaAI(Creature* creature) : npc_escortAI(creature) + npc_tarethaAI(Creature* creature) : EscortAI(creature) { instance = creature->GetInstanceScript(); } InstanceScript* instance; - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { switch (waypointId) { @@ -591,7 +591,7 @@ public: void UpdateAI(uint32 diff) override { - npc_escortAI::UpdateAI(diff); + EscortAI::UpdateAI(diff); } bool GossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override diff --git a/src/server/scripts/Kalimdor/RazorfenKraul/razorfen_kraul.cpp b/src/server/scripts/Kalimdor/RazorfenKraul/razorfen_kraul.cpp index b2ee684d0f5..131087fb683 100644 --- a/src/server/scripts/Kalimdor/RazorfenKraul/razorfen_kraul.cpp +++ b/src/server/scripts/Kalimdor/RazorfenKraul/razorfen_kraul.cpp @@ -46,9 +46,9 @@ class npc_willix : public CreatureScript public: npc_willix() : CreatureScript("npc_willix") { } - struct npc_willixAI : public npc_escortAI + struct npc_willixAI : public EscortAI { - npc_willixAI(Creature* creature) : npc_escortAI(creature) { } + npc_willixAI(Creature* creature) : EscortAI(creature) { } void QuestAccept(Player* player, Quest const* quest) override { @@ -60,7 +60,7 @@ public: } } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { Player* player = GetPlayerForEscort(); if (!player) diff --git a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_bug_trio.cpp b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_bug_trio.cpp index 2a775ecf9fd..77e1ef0e77e 100644 --- a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_bug_trio.cpp +++ b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_bug_trio.cpp @@ -204,9 +204,7 @@ public: //Charge_Timer if (Charge_Timer <= diff) { - Unit* target = nullptr; - target = SelectTarget(SELECT_TARGET_RANDOM, 0); - if (target) + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) { DoCast(target, SPELL_CHARGE); //me->SendMonsterMove(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, true, 1); diff --git a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_ouro.cpp b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_ouro.cpp index 3a154f40eed..0e6a24b3ee3 100644 --- a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_ouro.cpp +++ b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_ouro.cpp @@ -122,10 +122,7 @@ public: //ChangeTarget_Timer if (Submerged && ChangeTarget_Timer <= diff) { - Unit* target = nullptr; - target = SelectTarget(SELECT_TARGET_RANDOM, 0); - - if (target) + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) DoTeleportTo(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()); ChangeTarget_Timer = urand(10000, 20000); diff --git a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_twinemperors.cpp b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_twinemperors.cpp index bbcf18d5b84..602f5652e4a 100644 --- a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_twinemperors.cpp +++ b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_twinemperors.cpp @@ -558,9 +558,7 @@ public: //Blizzard_Timer if (Blizzard_Timer <= diff) { - Unit* target = nullptr; - target = SelectTarget(SELECT_TARGET_RANDOM, 0, 45, true); - if (target) + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 45, true)) DoCast(target, SPELL_BLIZZARD); Blizzard_Timer = 15000 + rand32() % 15000; } else Blizzard_Timer -= diff; diff --git a/src/server/scripts/Kalimdor/WailingCaverns/wailing_caverns.cpp b/src/server/scripts/Kalimdor/WailingCaverns/wailing_caverns.cpp index 0286de05581..48308c9bc16 100644 --- a/src/server/scripts/Kalimdor/WailingCaverns/wailing_caverns.cpp +++ b/src/server/scripts/Kalimdor/WailingCaverns/wailing_caverns.cpp @@ -81,9 +81,9 @@ class npc_disciple_of_naralex : public CreatureScript public: npc_disciple_of_naralex() : CreatureScript("npc_disciple_of_naralex") { } - struct npc_disciple_of_naralexAI : public npc_escortAI + struct npc_disciple_of_naralexAI : public EscortAI { - npc_disciple_of_naralexAI(Creature* creature) : npc_escortAI(creature) + npc_disciple_of_naralexAI(Creature* creature) : EscortAI(creature) { instance = creature->GetInstanceScript(); eventTimer = 0; @@ -98,7 +98,7 @@ public: uint32 eventProgress; InstanceScript* instance; - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { switch (waypointId) { @@ -153,7 +153,7 @@ public: void UpdateAI(uint32 diff) override { if (currentEvent != TYPE_NARALEX_PART3) - npc_escortAI::UpdateAI(diff); + EscortAI::UpdateAI(diff); if (eventTimer <= diff) { @@ -177,7 +177,7 @@ public: ++eventProgress; Talk(SAY_BANISH_THE_SPIRITS); DoCast(me, SPELL_SERPENTINE_CLEANSING); - //CAST_AI(npc_escort::npc_escortAI, me->AI())->SetCanDefend(false); + //CAST_AI(EscortAI, me->AI())->SetCanDefend(false); eventTimer = 30000; me->SummonCreature(NPC_DEVIATE_VIPER, -61.5261f, 273.676f, -92.8442f, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000); me->SummonCreature(NPC_DEVIATE_VIPER, -58.4658f, 280.799f, -92.8393f, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000); @@ -186,7 +186,7 @@ public: else if (eventProgress == 2) { - //CAST_AI(npc_escort::npc_escortAI, me->AI())->SetCanDefend(true); + //CAST_AI(EscortAI, me->AI())->SetCanDefend(true); Talk(SAY_CAVERNS_PURIFIED); instance->SetData(TYPE_NARALEX_PART2, DONE); if (me->HasAura(SPELL_SERPENTINE_CLEANSING)) @@ -206,7 +206,7 @@ public: { ++eventProgress; eventTimer = 15000; - //CAST_AI(npc_escort::npc_escortAI, me->AI())->SetCanDefend(false); + //CAST_AI(EscortAI, me->AI())->SetCanDefend(false); if (Creature* naralex = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_NARALEX))) DoCast(naralex, SPELL_NARALEXS_AWAKENING, true); Talk(EMOTE_AWAKENING_RITUAL); diff --git a/src/server/scripts/Kalimdor/zone_ashenvale.cpp b/src/server/scripts/Kalimdor/zone_ashenvale.cpp index f5680664e27..964c8506113 100644 --- a/src/server/scripts/Kalimdor/zone_ashenvale.cpp +++ b/src/server/scripts/Kalimdor/zone_ashenvale.cpp @@ -64,9 +64,9 @@ class npc_ruul_snowhoof : public CreatureScript public: npc_ruul_snowhoof() : CreatureScript("npc_ruul_snowhoof") { } - struct npc_ruul_snowhoofAI : public npc_escortAI + struct npc_ruul_snowhoofAI : public EscortAI { - npc_ruul_snowhoofAI(Creature* creature) : npc_escortAI(creature) { } + npc_ruul_snowhoofAI(Creature* creature) : EscortAI(creature) { } void Reset() override { @@ -86,11 +86,11 @@ public: if (quest->GetQuestId() == QUEST_FREEDOM_TO_RUUL) { me->SetFaction(FACTION_ESCORTEE_N_NEUTRAL_PASSIVE); - npc_escortAI::Start(true, false, player->GetGUID()); + EscortAI::Start(true, false, player->GetGUID()); } } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { Player* player = GetPlayerForEscort(); if (!player) @@ -121,7 +121,7 @@ public: void UpdateAI(uint32 diff) override { - npc_escortAI::UpdateAI(diff); + EscortAI::UpdateAI(diff); } }; @@ -181,9 +181,9 @@ class npc_muglash : public CreatureScript public: npc_muglash() : CreatureScript("npc_muglash") { } - struct npc_muglashAI : public npc_escortAI + struct npc_muglashAI : public EscortAI { - npc_muglashAI(Creature* creature) : npc_escortAI(creature) + npc_muglashAI(Creature* creature) : EscortAI(creature) { Initialize(); } @@ -229,11 +229,11 @@ public: { Talk(SAY_MUG_START1); me->SetFaction(FACTION_ESCORTEE_N_NEUTRAL_PASSIVE); - npc_escortAI::Start(true, false, player->GetGUID()); + EscortAI::Start(true, false, player->GetGUID()); } } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { if (Player* player = GetPlayerForEscort()) { @@ -291,7 +291,7 @@ public: void UpdateAI(uint32 diff) override { - npc_escortAI::UpdateAI(diff); + EscortAI::UpdateAI(diff); if (!me->GetVictim()) { diff --git a/src/server/scripts/Kalimdor/zone_azshara.cpp b/src/server/scripts/Kalimdor/zone_azshara.cpp index 0813b05705f..bea3ac7dd73 100644 --- a/src/server/scripts/Kalimdor/zone_azshara.cpp +++ b/src/server/scripts/Kalimdor/zone_azshara.cpp @@ -24,104 +24,6 @@ #include "ScriptedGossip.h" #include "SpellInfo.h" -/*###### -## npc_spitelashes -######*/ - -enum Spitelashes -{ - SPELL_POLYMORPH_RANK1 = 118, - SPELL_POLYMORPH_RANK2 = 12824, - SPELL_POLYMORPH_RANK3 = 12825, - SPELL_POLYMORPH_RANK4 = 12826, - SPELL_POLYMORPH = 29124, - SPELL_POLYMORPH_BACKFIRE = 28406, - SPELL_REMOVE_POLYMORPH = 6924 -}; - -class npc_spitelashes : public CreatureScript -{ -public: - npc_spitelashes() : CreatureScript("npc_spitelashes") { } - - struct npc_spitelashesAI : public ScriptedAI - { - npc_spitelashesAI(Creature* creature) : ScriptedAI(creature) - { - Initialize(); - } - - void Initialize() - { - morphtimer = 0; - spellhit = false; - } - - uint32 morphtimer; - bool spellhit; - - void Reset() override - { - Initialize(); - } - - void EnterCombat(Unit* /*who*/) override { } - - void SpellHit(Unit* unit, SpellInfo const* spell) override - { - if (spellhit) - return; - - switch (spell->Id) - { - case SPELL_POLYMORPH_RANK1: - case SPELL_POLYMORPH_RANK2: - case SPELL_POLYMORPH_RANK3: - case SPELL_POLYMORPH_RANK4: - if (Player* player = unit->ToPlayer()) - if (player->GetQuestStatus(9364) == QUEST_STATUS_INCOMPLETE) - { - spellhit = true; - DoCast(me, SPELL_POLYMORPH); - } - break; - default: - break; - } - } - - void UpdateAI(uint32 diff) override - { - // we mustn't remove the Creature in the same round in which we cast the summon spell, otherwise there will be no summons - if (spellhit && morphtimer >= 5000) - { - me->DespawnOrUnsummon(); - return; - } - // walk 5 seconds before summoning - if (spellhit && morphtimer < 5000) - { - morphtimer += diff; - if (morphtimer >= 5000) - { - DoCast(me, SPELL_POLYMORPH_BACKFIRE); // summon copies - DoCast(me, SPELL_REMOVE_POLYMORPH); // visual explosion - } - } - if (!UpdateVictim()) - return; - - /// @todo add abilities for the different creatures - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_spitelashesAI(creature); - } -}; - /*#### # npc_rizzle_sprysprocket ####*/ @@ -468,7 +370,6 @@ public: void AddSC_azshara() { - new npc_spitelashes(); new npc_rizzle_sprysprocket(); new npc_depth_charge(); } diff --git a/src/server/scripts/Kalimdor/zone_azuremyst_isle.cpp b/src/server/scripts/Kalimdor/zone_azuremyst_isle.cpp index c4036fbe836..3ce50e2f2f4 100644 --- a/src/server/scripts/Kalimdor/zone_azuremyst_isle.cpp +++ b/src/server/scripts/Kalimdor/zone_azuremyst_isle.cpp @@ -348,9 +348,9 @@ class npc_magwin : public CreatureScript public: npc_magwin() : CreatureScript("npc_magwin") { } - struct npc_magwinAI : public npc_escortAI + struct npc_magwinAI : public EscortAI { - npc_magwinAI(Creature* creature) : npc_escortAI(creature) { } + npc_magwinAI(Creature* creature) : EscortAI(creature) { } void Reset() override { @@ -371,7 +371,7 @@ public: } } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { if (Player* player = GetPlayerForEscort()) { @@ -410,7 +410,7 @@ public: break; case EVENT_START_ESCORT: if (Player* player = ObjectAccessor::GetPlayer(*me, _player)) - npc_escortAI::Start(true, false, player->GetGUID()); + EscortAI::Start(true, false, player->GetGUID()); _events.ScheduleEvent(EVENT_STAND, Seconds(2)); break; case EVENT_STAND: // Remove kneel standstate. Using a separate delayed event because it causes unwanted delay before starting waypoint movement. @@ -428,7 +428,7 @@ public: } } - npc_escortAI::UpdateEscortAI(diff); + EscortAI::UpdateEscortAI(diff); } private: @@ -718,128 +718,6 @@ public: } }; -/*######## -## Quest: The Prophecy of Akida -########*/ - -enum BristlelimbCage -{ - QUEST_THE_PROPHECY_OF_AKIDA = 9544, - NPC_STILLPINE_CAPITIVE = 17375, - GO_BRISTELIMB_CAGE = 181714, - - CAPITIVE_SAY = 0, - - POINT_INIT = 1, - EVENT_DESPAWN = 1, -}; - -class npc_stillpine_capitive : public CreatureScript -{ - public: - npc_stillpine_capitive() : CreatureScript("npc_stillpine_capitive") { } - - struct npc_stillpine_capitiveAI : public ScriptedAI - { - npc_stillpine_capitiveAI(Creature* creature) : ScriptedAI(creature) - { - Initialize(); - } - - void Initialize() - { - _playerGUID.Clear(); - _movementComplete = false; - } - - void Reset() override - { - if (GameObject* cage = me->FindNearestGameObject(GO_BRISTELIMB_CAGE, 5.0f)) - { - cage->SetLootState(GO_JUST_DEACTIVATED); - cage->SetGoState(GO_STATE_READY); - } - _events.Reset(); - Initialize(); - } - - void StartMoving(Player* owner) - { - if (owner) - { - Talk(CAPITIVE_SAY, owner); - _playerGUID = owner->GetGUID(); - } - Position pos = me->GetNearPosition(3.0f, 0.0f); - me->GetMotionMaster()->MovePoint(POINT_INIT, pos); - } - - void MovementInform(uint32 type, uint32 id) override - { - if (type != POINT_MOTION_TYPE || id != POINT_INIT) - return; - - if (Player* _player = ObjectAccessor::GetPlayer(*me, _playerGUID)) - _player->KilledMonsterCredit(me->GetEntry(), me->GetGUID()); - - _movementComplete = true; - _events.ScheduleEvent(EVENT_DESPAWN, 3500); - } - - void UpdateAI(uint32 diff) override - { - if (!_movementComplete) - return; - - _events.Update(diff); - - if (_events.ExecuteEvent() == EVENT_DESPAWN) - me->DespawnOrUnsummon(); - } - - private: - ObjectGuid _playerGUID; - EventMap _events; - bool _movementComplete; - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_stillpine_capitiveAI(creature); - } -}; - -class go_bristlelimb_cage : public GameObjectScript -{ - public: - go_bristlelimb_cage() : GameObjectScript("go_bristlelimb_cage") { } - - struct go_bristlelimb_cageAI : public GameObjectAI - { - go_bristlelimb_cageAI(GameObject* go) : GameObjectAI(go) { } - - bool GossipHello(Player* player) override - { - me->SetGoState(GO_STATE_READY); - if (player->GetQuestStatus(QUEST_THE_PROPHECY_OF_AKIDA) == QUEST_STATUS_INCOMPLETE) - { - if (Creature* capitive = me->FindNearestCreature(NPC_STILLPINE_CAPITIVE, 5.0f, true)) - { - me->ResetDoorOrButton(); - ENSURE_AI(npc_stillpine_capitive::npc_stillpine_capitiveAI, capitive->AI())->StartMoving(player); - return false; - } - } - return true; - } - }; - - GameObjectAI* GetAI(GameObject* go) const override - { - return new go_bristlelimb_cageAI(go); - } -}; - void AddSC_azuremyst_isle() { new npc_draenei_survivor(); @@ -849,6 +727,4 @@ void AddSC_azuremyst_isle() new npc_geezle(); new npc_death_ravager(); new go_ravager_cage(); - new npc_stillpine_capitive(); - new go_bristlelimb_cage(); } diff --git a/src/server/scripts/Kalimdor/zone_bloodmyst_isle.cpp b/src/server/scripts/Kalimdor/zone_bloodmyst_isle.cpp index 86eae7f4b40..3a92623ce15 100644 --- a/src/server/scripts/Kalimdor/zone_bloodmyst_isle.cpp +++ b/src/server/scripts/Kalimdor/zone_bloodmyst_isle.cpp @@ -355,9 +355,9 @@ class npc_demolitionist_legoso : public CreatureScript public: npc_demolitionist_legoso() : CreatureScript("npc_demolitionist_legoso") { } - struct npc_demolitionist_legosoAI : public npc_escortAI + struct npc_demolitionist_legosoAI : public EscortAI { - npc_demolitionist_legosoAI(Creature* creature) : npc_escortAI(creature) + npc_demolitionist_legosoAI(Creature* creature) : EscortAI(creature) { Initialize(); } @@ -466,7 +466,7 @@ public: if (HasEscortState(STATE_ESCORT_NONE)) return; - npc_escortAI::UpdateAI(diff); + EscortAI::UpdateAI(diff); if (_phase) { @@ -710,7 +710,7 @@ public: } } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { Player* player = GetPlayerForEscort(); if (!player) diff --git a/src/server/scripts/Kalimdor/zone_darkshore.cpp b/src/server/scripts/Kalimdor/zone_darkshore.cpp index b2bdd76c137..8d07fd1e506 100644 --- a/src/server/scripts/Kalimdor/zone_darkshore.cpp +++ b/src/server/scripts/Kalimdor/zone_darkshore.cpp @@ -204,9 +204,9 @@ class npc_prospector_remtravel : public CreatureScript public: npc_prospector_remtravel() : CreatureScript("npc_prospector_remtravel") { } - struct npc_prospector_remtravelAI : public npc_escortAI + struct npc_prospector_remtravelAI : public EscortAI { - npc_prospector_remtravelAI(Creature* creature) : npc_escortAI(creature) { } + npc_prospector_remtravelAI(Creature* creature) : EscortAI(creature) { } void Reset() override { } @@ -222,7 +222,7 @@ public: //pSummoned->AI()->AttackStart(me); } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { if (Player* player = GetPlayerForEscort()) { diff --git a/src/server/scripts/Kalimdor/zone_desolace.cpp b/src/server/scripts/Kalimdor/zone_desolace.cpp index 4360574a65f..74786200a43 100644 --- a/src/server/scripts/Kalimdor/zone_desolace.cpp +++ b/src/server/scripts/Kalimdor/zone_desolace.cpp @@ -176,9 +176,9 @@ class npc_dalinda : public CreatureScript public: npc_dalinda() : CreatureScript("npc_dalinda") { } - struct npc_dalindaAI : public npc_escortAI + struct npc_dalindaAI : public EscortAI { - npc_dalindaAI(Creature* creature) : npc_escortAI(creature) { } + npc_dalindaAI(Creature* creature) : EscortAI(creature) { } void Reset() override { } @@ -191,7 +191,7 @@ public: return; } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { Player* player = GetPlayerForEscort(); @@ -209,7 +209,7 @@ public: void UpdateAI(uint32 diff) override { - npc_escortAI::UpdateAI(diff); + EscortAI::UpdateAI(diff); if (!UpdateVictim()) return; diff --git a/src/server/scripts/Kalimdor/zone_feralas.cpp b/src/server/scripts/Kalimdor/zone_feralas.cpp index 16c30f6fadd..0d0f75d4d4d 100644 --- a/src/server/scripts/Kalimdor/zone_feralas.cpp +++ b/src/server/scripts/Kalimdor/zone_feralas.cpp @@ -63,11 +63,11 @@ class npc_oox22fe : public CreatureScript public: npc_oox22fe() : CreatureScript("npc_oox22fe") { } - struct npc_oox22feAI : public npc_escortAI + struct npc_oox22feAI : public EscortAI { - npc_oox22feAI(Creature* creature) : npc_escortAI(creature) { } + npc_oox22feAI(Creature* creature) : EscortAI(creature) { } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { switch (waypointId) { diff --git a/src/server/scripts/Kalimdor/zone_moonglade.cpp b/src/server/scripts/Kalimdor/zone_moonglade.cpp index e19d8797bc9..792fe737c8b 100644 --- a/src/server/scripts/Kalimdor/zone_moonglade.cpp +++ b/src/server/scripts/Kalimdor/zone_moonglade.cpp @@ -111,10 +111,10 @@ public: return new npc_clintar_spiritAI(creature); } - struct npc_clintar_spiritAI : public npc_escortAI + struct npc_clintar_spiritAI : public EscortAI { public: - npc_clintar_spiritAI(Creature* creature) : npc_escortAI(creature) + npc_clintar_spiritAI(Creature* creature) : EscortAI(creature) { Initialize(); PlayerGUID.Clear(); @@ -189,7 +189,7 @@ public: AttackStart(player->getAttackerForHelper()); return; } - npc_escortAI::EnterEvadeMode(why); + EscortAI::EnterEvadeMode(why); } void StartEvent(Player* player) @@ -198,7 +198,7 @@ public: { for (uint8 i = 0; i < 41; ++i) { - AddWaypoint(i, Clintar_spirit_WP[i][0], Clintar_spirit_WP[i][1], Clintar_spirit_WP[i][2], (uint32)Clintar_spirit_WP[i][4]); + AddWaypoint(i, Clintar_spirit_WP[i][0], Clintar_spirit_WP[i][1], Clintar_spirit_WP[i][2], Clintar_spirit_WP[i][3], (uint32)Clintar_spirit_WP[i][4]); } PlayerGUID = player->GetGUID(); Start(true, false, PlayerGUID); @@ -210,7 +210,7 @@ public: void UpdateAI(uint32 diff) override { - npc_escortAI::UpdateAI(diff); + EscortAI::UpdateAI(diff); if (!PlayerGUID) { @@ -370,7 +370,7 @@ public: } else if (EventOnWait) EventTimer -= diff; } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { CurrWP = waypointId; EventTimer = 0; diff --git a/src/server/scripts/Kalimdor/zone_orgrimmar.cpp b/src/server/scripts/Kalimdor/zone_orgrimmar.cpp index 2603173e992..fc0d5120015 100644 --- a/src/server/scripts/Kalimdor/zone_orgrimmar.cpp +++ b/src/server/scripts/Kalimdor/zone_orgrimmar.cpp @@ -170,6 +170,11 @@ enum ThrallWarchief SPELL_SHOCK = 16034 }; +enum Sounds +{ + SOUND_AGGRO = 5880 +}; + /// @todo verify abilities/timers class npc_thrall_warchief : public CreatureScript { @@ -197,7 +202,10 @@ public: Initialize(); } - void EnterCombat(Unit* /*who*/) override { } + void EnterCombat(Unit* /*who*/) override + { + DoPlaySoundToSet(me, SOUND_AGGRO); + } void UpdateAI(uint32 diff) override { diff --git a/src/server/scripts/Kalimdor/zone_silithus.cpp b/src/server/scripts/Kalimdor/zone_silithus.cpp index f5b6ebba946..2ac6d96b883 100644 --- a/src/server/scripts/Kalimdor/zone_silithus.cpp +++ b/src/server/scripts/Kalimdor/zone_silithus.cpp @@ -1226,13 +1226,13 @@ class go_wind_stone : public GameObjectScript case NPC_DUKE_WATER: case NPC_DUKE_EARTH: case NPC_DUKE_AIR: - summons->AI()->Talk(SAY_DUKE_AGGRO); + summons->AI()->Talk(SAY_DUKE_AGGRO, player); break; case NPC_ROYAL_FIRE: case NPC_ROYAL_AIR: case NPC_ROYAL_EARTH: case NPC_ROYAL_WATER: - summons->AI()->Talk(YELL_ROYAL_AGGRO); + summons->AI()->Talk(YELL_ROYAL_AGGRO, player); break; } summons->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); diff --git a/src/server/scripts/Kalimdor/zone_stonetalon_mountains.cpp b/src/server/scripts/Kalimdor/zone_stonetalon_mountains.cpp index fa9164fced8..9095ac29830 100644 --- a/src/server/scripts/Kalimdor/zone_stonetalon_mountains.cpp +++ b/src/server/scripts/Kalimdor/zone_stonetalon_mountains.cpp @@ -46,11 +46,11 @@ class npc_kaya_flathoof : public CreatureScript public: npc_kaya_flathoof() : CreatureScript("npc_kaya_flathoof") { } - struct npc_kaya_flathoofAI : public npc_escortAI + struct npc_kaya_flathoofAI : public EscortAI { - npc_kaya_flathoofAI(Creature* creature) : npc_escortAI(creature) { } + npc_kaya_flathoofAI(Creature* creature) : EscortAI(creature) { } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { Player* player = GetPlayerForEscort(); if (!player) diff --git a/src/server/scripts/Kalimdor/zone_tanaris.cpp b/src/server/scripts/Kalimdor/zone_tanaris.cpp index b1e44a4ac55..1898b9406b0 100644 --- a/src/server/scripts/Kalimdor/zone_tanaris.cpp +++ b/src/server/scripts/Kalimdor/zone_tanaris.cpp @@ -24,7 +24,6 @@ SDCategory: Tanaris EndScriptData */ /* ContentData -npc_aquementas npc_custodian_of_time npc_OOX17 npc_tooga @@ -40,127 +39,6 @@ EndContentData */ #include "WorldSession.h" /*###### -## npc_aquementas -######*/ - -enum Aquementas -{ - AGGRO_YELL_AQUE = 0, - - SPELL_AQUA_JET = 13586, - SPELL_FROST_SHOCK = 15089, - - ITEM_BOOK_OF_AQUOR = 11169, - ITEM_SILVERY_CLAWS = 11172, - ITEM_IRONTREE_HEART = 11173, - ITEM_SILVER_TOTEM = 11522 -}; - -class npc_aquementas : public CreatureScript -{ -public: - npc_aquementas() : CreatureScript("npc_aquementas") { } - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_aquementasAI(creature); - } - - struct npc_aquementasAI : public ScriptedAI - { - npc_aquementasAI(Creature* creature) : ScriptedAI(creature) - { - Initialize(); - } - - void Initialize() - { - SendItemTimer = 0; - SwitchFactionTimer = 10000; - - isFriendly = true; - - AquaJetTimer = 5000; - FrostShockTimer = 1000; - } - - uint32 SendItemTimer; - uint32 SwitchFactionTimer; - bool isFriendly; - - uint32 FrostShockTimer; - uint32 AquaJetTimer; - - void Reset() override - { - Initialize(); - me->SetFaction(FACTION_FRIENDLY); - } - - void SendItem(Unit* receiver) - { - Player* player = receiver->ToPlayer(); - - if (player && player->HasItemCount(ITEM_BOOK_OF_AQUOR, 1, false) && - player->HasItemCount(ITEM_SILVERY_CLAWS, 11, false) && - player->HasItemCount(ITEM_IRONTREE_HEART, 1, false) && - !player->HasItemCount(ITEM_SILVER_TOTEM, 1, true)) - { - ItemPosCountVec dest; - uint8 msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, 11522, 1, nullptr); - if (msg == EQUIP_ERR_OK) - player->StoreNewItem(dest, ITEM_SILVER_TOTEM, true); - } - } - - void EnterCombat(Unit* who) override - { - Talk(AGGRO_YELL_AQUE, who); - } - - void UpdateAI(uint32 diff) override - { - if (isFriendly) - { - if (SwitchFactionTimer <= diff) - { - me->SetFaction(FACTION_ELEMENTAL); - isFriendly = false; - } else SwitchFactionTimer -= diff; - } - - if (!UpdateVictim()) - return; - - if (!isFriendly) - { - if (SendItemTimer <= diff) - { - if (me->GetVictim() && me->EnsureVictim()->GetTypeId() == TYPEID_PLAYER) - SendItem(me->GetVictim()); - SendItemTimer = 5000; - } else SendItemTimer -= diff; - } - - if (FrostShockTimer <= diff) - { - DoCastVictim(SPELL_FROST_SHOCK); - FrostShockTimer = 15000; - } else FrostShockTimer -= diff; - - if (AquaJetTimer <= diff) - { - DoCast(me, SPELL_AQUA_JET); - AquaJetTimer = 15000; - } else AquaJetTimer -= diff; - - DoMeleeAttackIfReady(); - } - }; - -}; - -/*###### ## npc_custodian_of_time ######*/ @@ -195,11 +73,11 @@ public: return new npc_custodian_of_timeAI(creature); } - struct npc_custodian_of_timeAI : public npc_escortAI + struct npc_custodian_of_timeAI : public EscortAI { - npc_custodian_of_timeAI(Creature* creature) : npc_escortAI(creature) { } + npc_custodian_of_timeAI(Creature* creature) : EscortAI(creature) { } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { if (Player* player = GetPlayerForEscort()) { @@ -290,7 +168,7 @@ public: void UpdateAI(uint32 diff) override { - npc_escortAI::UpdateAI(diff); + EscortAI::UpdateAI(diff); } }; @@ -319,11 +197,11 @@ class npc_OOX17 : public CreatureScript public: npc_OOX17() : CreatureScript("npc_OOX17") { } - struct npc_OOX17AI : public npc_escortAI + struct npc_OOX17AI : public EscortAI { - npc_OOX17AI(Creature* creature) : npc_escortAI(creature) { } + npc_OOX17AI(Creature* creature) : EscortAI(creature) { } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { if (Player* player = GetPlayerForEscort()) { @@ -551,7 +429,6 @@ public: void AddSC_tanaris() { - new npc_aquementas(); new npc_custodian_of_time(); new npc_OOX17(); new npc_tooga(); diff --git a/src/server/scripts/Kalimdor/zone_the_barrens.cpp b/src/server/scripts/Kalimdor/zone_the_barrens.cpp index 4e1c211ddde..2029ee3fbba 100644 --- a/src/server/scripts/Kalimdor/zone_the_barrens.cpp +++ b/src/server/scripts/Kalimdor/zone_the_barrens.cpp @@ -101,13 +101,13 @@ class npc_gilthares : public CreatureScript public: npc_gilthares() : CreatureScript("npc_gilthares") { } - struct npc_giltharesAI : public npc_escortAI + struct npc_giltharesAI : public EscortAI { - npc_giltharesAI(Creature* creature) : npc_escortAI(creature) { } + npc_giltharesAI(Creature* creature) : EscortAI(creature) { } void Reset() override { } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { Player* player = GetPlayerForEscort(); if (!player) @@ -530,9 +530,9 @@ class npc_wizzlecrank_shredder : public CreatureScript public: npc_wizzlecrank_shredder() : CreatureScript("npc_wizzlecrank_shredder") { } - struct npc_wizzlecrank_shredderAI : public npc_escortAI + struct npc_wizzlecrank_shredderAI : public EscortAI { - npc_wizzlecrank_shredderAI(Creature* creature) : npc_escortAI(creature) + npc_wizzlecrank_shredderAI(Creature* creature) : EscortAI(creature) { IsPostEvent = false; PostEventTimer = 1000; @@ -556,7 +556,7 @@ public: } } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { switch (waypointId) { @@ -579,7 +579,7 @@ public: } } - void WaypointStart(uint32 PointId) override + void WaypointStarted(uint32 PointId, uint32 /*pathId*/) override { Player* player = GetPlayerForEscort(); diff --git a/src/server/scripts/Kalimdor/zone_thousand_needles.cpp b/src/server/scripts/Kalimdor/zone_thousand_needles.cpp index a1439f4cc00..7823e535bb2 100644 --- a/src/server/scripts/Kalimdor/zone_thousand_needles.cpp +++ b/src/server/scripts/Kalimdor/zone_thousand_needles.cpp @@ -56,13 +56,13 @@ class npc_kanati : public CreatureScript public: npc_kanati() : CreatureScript("npc_kanati") { } - struct npc_kanatiAI : public npc_escortAI + struct npc_kanatiAI : public EscortAI { - npc_kanatiAI(Creature* creature) : npc_escortAI(creature) { } + npc_kanatiAI(Creature* creature) : EscortAI(creature) { } void Reset() override { } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { switch (waypointId) { @@ -136,13 +136,13 @@ class npc_lakota_windsong : public CreatureScript public: npc_lakota_windsong() : CreatureScript("npc_lakota_windsong") { } - struct npc_lakota_windsongAI : public npc_escortAI + struct npc_lakota_windsongAI : public EscortAI { - npc_lakota_windsongAI(Creature* creature) : npc_escortAI(creature) { } + npc_lakota_windsongAI(Creature* creature) : EscortAI(creature) { } void Reset() override { } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { switch (waypointId) { @@ -216,13 +216,13 @@ class npc_paoka_swiftmountain : public CreatureScript public: npc_paoka_swiftmountain() : CreatureScript("npc_paoka_swiftmountain") { } - struct npc_paoka_swiftmountainAI : public npc_escortAI + struct npc_paoka_swiftmountainAI : public EscortAI { - npc_paoka_swiftmountainAI(Creature* creature) : npc_escortAI(creature) { } + npc_paoka_swiftmountainAI(Creature* creature) : EscortAI(creature) { } void Reset() override { } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { switch (waypointId) { diff --git a/src/server/scripts/Kalimdor/zone_thunder_bluff.cpp b/src/server/scripts/Kalimdor/zone_thunder_bluff.cpp index 0f894631345..cca5311c8b8 100644 --- a/src/server/scripts/Kalimdor/zone_thunder_bluff.cpp +++ b/src/server/scripts/Kalimdor/zone_thunder_bluff.cpp @@ -41,6 +41,11 @@ enum CairneBloodhoof SPELL_UPPERCUT = 22916 }; +enum Sounds +{ + SOUND_AGGRO = 5884 +}; + #define GOSSIP_HCB "I know this is rather silly but a young ward who is a bit shy would like your hoofprint." /// @todo verify abilities/timers class npc_cairne_bloodhoof : public CreatureScript @@ -75,7 +80,10 @@ public: Initialize(); } - void EnterCombat(Unit* /*who*/) override { } + void EnterCombat(Unit* /*who*/) override + { + DoPlaySoundToSet(me, SOUND_AGGRO); + } void UpdateAI(uint32 diff) override { diff --git a/src/server/scripts/Kalimdor/zone_ungoro_crater.cpp b/src/server/scripts/Kalimdor/zone_ungoro_crater.cpp index 4a1456a18c0..f7f7c5cd1dd 100644 --- a/src/server/scripts/Kalimdor/zone_ungoro_crater.cpp +++ b/src/server/scripts/Kalimdor/zone_ungoro_crater.cpp @@ -57,9 +57,9 @@ class npc_ame : public CreatureScript public: npc_ame() : CreatureScript("npc_ame") { } - struct npc_ameAI : public npc_escortAI + struct npc_ameAI : public EscortAI { - npc_ameAI(Creature* creature) : npc_escortAI(creature) + npc_ameAI(Creature* creature) : EscortAI(creature) { Initialize(); } @@ -71,7 +71,7 @@ public: uint32 DemoralizingShoutTimer; - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { if (Player* player = GetPlayerForEscort()) { @@ -118,7 +118,7 @@ public: void UpdateAI(uint32 diff) override { - npc_escortAI::UpdateAI(diff); + EscortAI::UpdateAI(diff); if (!UpdateVictim()) return; diff --git a/src/server/scripts/Kalimdor/zone_winterspring.cpp b/src/server/scripts/Kalimdor/zone_winterspring.cpp index 9bc3711e830..5e7080ae621 100644 --- a/src/server/scripts/Kalimdor/zone_winterspring.cpp +++ b/src/server/scripts/Kalimdor/zone_winterspring.cpp @@ -19,12 +19,11 @@ /* ScriptData SDName: Winterspring SD%Complete: Almost Completely Emptied -SDComment: Vendor Rivern Frostwind. Quest Support 4901 +SDComment: Quest Support 4901 SDCategory: Winterspring EndScriptData */ /* ContentData -npc_rivern_frostwind npc_ranshalla go_elune_fire EndContentData */ @@ -36,52 +35,9 @@ EndContentData */ #include "ObjectAccessor.h" #include "Player.h" #include "ScriptedEscortAI.h" -#include "ScriptedGossip.h" #include "TemporarySummon.h" #include "WorldSession.h" -/*###### -## npc_rivern_frostwind -######*/ - -class npc_rivern_frostwind : public CreatureScript -{ -public: - npc_rivern_frostwind() : CreatureScript("npc_rivern_frostwind") { } - - struct npc_rivern_frostwindAI : public ScriptedAI - { - npc_rivern_frostwindAI(Creature* creature) : ScriptedAI(creature) { } - - bool GossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override - { - uint32 const action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId); - ClearGossipMenuFor(player); - if (action == GOSSIP_ACTION_TRADE) - player->GetSession()->SendListInventory(me->GetGUID()); - - return true; - } - - bool GossipHello(Player* player) override - { - if (me->IsQuestGiver()) - player->PrepareQuestMenu(me->GetGUID()); - - if (me->IsVendor() && player->GetReputationRank(589) == REP_EXALTED) - AddGossipItemFor(player, GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); - - SendGossipMenuFor(player, player->GetGossipTextId(me), me->GetGUID()); - return true; - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_rivern_frostwindAI(creature); - } -}; - enum Says { // Escort texts @@ -307,9 +263,9 @@ class npc_ranshalla : public CreatureScript public: npc_ranshalla() : CreatureScript("npc_ranshalla") { } - struct npc_ranshallaAI : public npc_escortAI, private DialogueHelper + struct npc_ranshallaAI : public EscortAI, private DialogueHelper { - npc_ranshallaAI(Creature* creature) : npc_escortAI(creature), DialogueHelper(introDialogue) + npc_ranshallaAI(Creature* creature) : EscortAI(creature), DialogueHelper(introDialogue) { Initialize(); } @@ -393,7 +349,7 @@ public: StartNextDialogueText(SAY_PRIESTESS_ALTAR_3); } - void WaypointReached(uint32 pointId) override + void WaypointReached(uint32 pointId, uint32 /*pathId*/) override { switch (pointId) { @@ -580,7 +536,7 @@ public: if (events.ExecuteEvent() == EVENT_RESUME) StartNextDialogueText(SAY_PRIESTESS_ALTAR_3); - npc_escortAI::UpdateEscortAI(diff); + EscortAI::UpdateEscortAI(diff); } void QuestAccept(Player* player, Quest const* quest) override @@ -643,7 +599,6 @@ public: void AddSC_winterspring() { - new npc_rivern_frostwind(); new npc_ranshalla(); new go_elune_fire(); } diff --git a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/ahnkahet.h b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/ahnkahet.h index 00bd46ce2d5..ba70be7f02d 100644 --- a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/ahnkahet.h +++ b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/ahnkahet.h @@ -37,13 +37,7 @@ enum AKDataTypes // Additional Data DATA_SPHERE_1 = 5, DATA_SPHERE_2 = 6, - DATA_PRINCE_TALDARAM_PLATFORM = 7, - DATA_PL_JEDOGA_TARGET = 8, - DATA_ADD_JEDOGA_OPFER = 9, - DATA_ADD_JEDOGA_INITIAND = 10, - DATA_JEDOGA_TRIGGER_SWITCH = 11, - DATA_JEDOGA_RESET_INITIANDS = 12, - DATA_ALL_INITIAND_DEAD = 13 + DATA_PRINCE_TALDARAM_PLATFORM = 7 }; enum AKCreatureIds @@ -59,7 +53,9 @@ enum AKCreatureIds NPC_AHNKAHAR_SWARMER = 30178, // Jedoga Shadowseeker - NPC_INITIAND = 30114, + NPC_TWILIGHT_INITIATE = 30114, + NPC_TWILIGHT_VOLUNTEER = 30385, + NPC_TWILIGHT_WORSHIPPER = 30111, NPC_JEDOGA_CONTROLLER = 30181, // Amanitar @@ -88,4 +84,6 @@ inline AI* GetAhnKahetAI(T* obj) return GetInstanceAI<AI>(obj, AhnKahetScriptName); } +#define RegisterAhnKahetCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetAhnKahetAI) + #endif // AHNKAHET_H_ diff --git a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_amanitar.cpp b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_amanitar.cpp index f4881aaa9ed..514e8a44742 100644 --- a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_amanitar.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_amanitar.cpp @@ -19,218 +19,266 @@ #include "ahnkahet.h" #include "InstanceScript.h" #include "ScriptedCreature.h" -#include "TemporarySummon.h" +#include "SpellScript.h" -enum Spells +enum AmanitarSpells { - SPELL_BASH = 57094, // Victim - SPELL_ENTANGLING_ROOTS = 57095, // Random Victim 100Y - SPELL_MINI = 57055, // Self - SPELL_VENOM_BOLT_VOLLEY = 57088, // Random Victim 100Y - SPELL_HEALTHY_MUSHROOM_POTENT_FUNGUS = 56648, // Killer 3Y - SPELL_POISONOUS_MUSHROOM_POISON_CLOUD = 57061, // Self - Duration 8 Sec - SPELL_POISONOUS_MUSHROOM_VISUAL_AREA = 61566, // Self - SPELL_POISONOUS_MUSHROOM_VISUAL_AURA = 56741, // Self - SPELL_PUTRID_MUSHROOM = 31690, // To make the mushrooms visible - SPELL_POWER_MUSHROOM_VISUAL_AURA = 56740, + //Amanitar + SPELL_BASH = 57094, + SPELL_ENTANGLING_ROOTS = 57095, + SPELL_MINI = 57055, + SPELL_VENOM_BOLT_VOLLEY = 57088, + SPELL_REMOVE_MUSHROOM_POWER = 57283, + //Mushrooms + SPELL_POTENT_FUNGUS = 56648, + SPELL_POISONOUS_MUSHROOM_POISON_CLOUD = 57061, + SPELL_POISONOUS_MUSHROOM_VISUAL_AURA = 56741, + SPELL_POWER_MUSHROOM_VISUAL_AURA = 56740, + SPELL_PUTRID_MUSHROOM = 31690, + SPELL_GROW = 57059, + SPELL_SHRINK = 31691 }; -enum Creatures -{ - NPC_TRIGGER = 19656 -}; - -enum Events +enum AmanitarEvents { EVENT_SPAWN = 1, EVENT_MINI, EVENT_ROOT, EVENT_BASH, EVENT_BOLT, - EVENT_AURA + EVENT_RESPAWN }; -class boss_amanitar : public CreatureScript +Position const MushroomPositions[32] = { - public: - boss_amanitar() : CreatureScript("boss_amanitar") { } + { 373.4807f, -856.5301f, -74.30518f, 0.2094395f }, + { 358.4792f, -879.3193f, -75.9463f, 5.166174f }, + { 356.5531f, -846.3022f, -72.1796f, 3.193953f }, + { 332.369f, -846.081f, -74.30516f, 4.834562f }, + { 360.2234f, -862.055f, -75.22755f, 1.658063f }, + { 351.7189f, -890.9619f, -76.54617f, 1.064651f }, + { 345.8126f, -869.1772f, -77.17728f, 1.361357f }, + { 367.5179f, -884.0129f, -77.32881f, 4.276057f }, + { 370.6044f, -868.4305f, -74.19881f, 0.8901179f }, + { 381.3156f, -873.2377f, -74.82656f, 1.099557f }, + { 371.5869f, -873.8141f, -74.72424f, 1.082104f }, + { 340.4079f, -891.6375f, -74.99128f, 1.134464f }, + { 368.21f, -851.5953f, -73.99741f, 4.694936f }, + { 328.7047f, -853.9812f, -75.51253f, 0.5759587f }, + { 366.4145f, -876.39f, -75.52739f, 5.253441f }, + { 380.1362f, -861.4344f, -73.45917f, 3.787364f }, + { 373.3007f, -888.8057f, -79.03593f, 5.602507f }, + { 348.3599f, -848.0839f, -73.54117f, 1.745329f }, + { 352.5586f, -882.6624f, -75.68202f, 3.822271f }, + { 357.8967f, -871.179f, -75.77553f, 2.443461f }, + { 360.1034f, -842.3351f, -71.08852f, 4.34587f }, + { 348.1334f, -861.5244f, -74.61307f, 2.565634f }, + { 401.4896f, -866.7059f, -73.22395f, 0.8901179f }, + { 360.1683f, -889.1515f, -76.74798f, 3.612832f }, + { 350.1828f, -907.7313f, -74.94678f, 5.044002f }, + { 340.6278f, -856.5973f, -74.23862f, 4.415683f }, + { 366.4849f, -859.7621f, -74.82679f, 1.500983f }, + { 359.1482f, -853.3346f, -74.47543f, 5.654867f }, + { 374.9992f, -879.0921f, -75.56115f, 1.867502f }, + { 339.5252f, -850.4612f, -74.45442f, 4.764749f }, + { 337.0534f, -864.002f, -75.72749f, 4.642576f }, + { 398.2797f, -851.8694f, -68.84419f, 0.5759587f } +}; - struct boss_amanitarAI : public BossAI - { - boss_amanitarAI(Creature* creature) : BossAI(creature, DATA_AMANITAR) { } +struct boss_amanitar : public BossAI +{ + boss_amanitar(Creature* creature) : BossAI(creature, DATA_AMANITAR) { } - void Reset() override - { - _Reset(); - me->SetMeleeDamageSchool(SPELL_SCHOOL_NATURE); - me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_NATURE, true); - } + void EnterCombat(Unit* /*who*/) override + { + _EnterCombat(); + events.ScheduleEvent(EVENT_ROOT, Seconds(5), Seconds(9)); + events.ScheduleEvent(EVENT_BASH, Seconds(10), Seconds(14)); + events.ScheduleEvent(EVENT_BOLT, Seconds(15), Seconds(20)); + events.ScheduleEvent(EVENT_MINI, Seconds(12), Seconds(18)); + events.ScheduleEvent(EVENT_SPAWN, Seconds(1)); + events.ScheduleEvent(EVENT_RESPAWN, Seconds(40), Seconds(60)); + } - void EnterCombat(Unit* /*who*/) override - { - _EnterCombat(); + void EnterEvadeMode(EvadeReason /*why*/) override + { + _EnterEvadeMode(); + summons.DespawnAll(); + instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_MINI); + _DespawnAtEvade(); + } - events.ScheduleEvent(EVENT_ROOT, urand(5, 9) * IN_MILLISECONDS); - events.ScheduleEvent(EVENT_BASH, urand(10, 14) * IN_MILLISECONDS); - events.ScheduleEvent(EVENT_BOLT, urand(15, 20) * IN_MILLISECONDS); - events.ScheduleEvent(EVENT_MINI, urand(12, 18) * IN_MILLISECONDS); - events.ScheduleEvent(EVENT_SPAWN, 5 * IN_MILLISECONDS); - } + void JustDied(Unit* /*killer*/) override + { + _JustDied(); + DoCastAOE(SPELL_REMOVE_MUSHROOM_POWER); + instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_MINI); + } - void JustDied(Unit* /*killer*/) override - { - _JustDied(); - instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_MINI); - } + void JustSummoned(Creature* summon) override + { + summons.Summon(summon); + } - void SpawnAdds() - { - uint8 u = 0; + void SummonedCreatureDies(Creature* summon, Unit* killer) override + { + _mushroomsDeque.push_back(summon->GetPosition()); - for (uint8 i = 0; i < 30; ++i) - { - Position pos = me->GetRandomNearPosition(30.0f); - me->UpdateGroundPositionZ(pos.GetPositionX(), pos.GetPositionY(), pos.m_positionZ); + BossAI::SummonedCreatureDies(summon, killer); + } - if (Creature* trigger = me->SummonCreature(NPC_TRIGGER, pos)) - { - Creature* temp1 = trigger->FindNearestCreature(NPC_HEALTHY_MUSHROOM, 4.0f, true); - Creature* temp2 = trigger->FindNearestCreature(NPC_POISONOUS_MUSHROOM, 4.0f, true); - if (!temp1 && !temp2) - { - u = 1 - u; - me->SummonCreature(u > 0 ? NPC_POISONOUS_MUSHROOM : NPC_HEALTHY_MUSHROOM, pos, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 60 * IN_MILLISECONDS); - } - trigger->DespawnOrUnsummon(); - } - } - } + void SpawnMushroom(Position const pos) + { + me->SummonCreature(roll_chance_i(40) ? NPC_HEALTHY_MUSHROOM : NPC_POISONOUS_MUSHROOM, pos, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 4000); + } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - events.Update(diff); + events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_SPAWN: + for (Position const pos : MushroomPositions) + SpawnMushroom(pos); + break; + case EVENT_MINI: + if (SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true, true, -SPELL_MINI)) { - case EVENT_SPAWN: - SpawnAdds(); - events.ScheduleEvent(EVENT_SPAWN, 20 * IN_MILLISECONDS); - break; - case EVENT_MINI: - DoCast(SPELL_MINI); - events.ScheduleEvent(EVENT_MINI, urand(25, 30) * IN_MILLISECONDS); - break; - case EVENT_ROOT: - DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true), SPELL_ENTANGLING_ROOTS, true); - events.ScheduleEvent(EVENT_ROOT, urand(10, 15) * IN_MILLISECONDS); - break; - case EVENT_BASH: - DoCastVictim(SPELL_BASH); - events.ScheduleEvent(EVENT_BASH, urand(7, 12) * IN_MILLISECONDS); - break; - case EVENT_BOLT: - DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true), SPELL_VENOM_BOLT_VOLLEY, true); - events.ScheduleEvent(EVENT_BOLT, urand(18, 22) * IN_MILLISECONDS); - break; - default: - break; + DoCastAOE(SPELL_MINI); + events.Repeat(Seconds(30)); } - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - } - DoMeleeAttackIfReady(); + else + events.Repeat(Seconds(1)); + break; + case EVENT_ROOT: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100.0f, true)) + DoCast(target, SPELL_ENTANGLING_ROOTS, true); + events.Repeat(Seconds(10), Seconds(15)); + break; + case EVENT_BASH: + DoCastVictim(SPELL_BASH); + events.Repeat(Seconds(7), Seconds(12)); + break; + case EVENT_BOLT: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true)) + DoCast(target, SPELL_VENOM_BOLT_VOLLEY, true); + events.Repeat(Seconds(18), Seconds(22)); + break; + case EVENT_RESPAWN: + while (!_mushroomsDeque.empty()) + { + SpawnMushroom(_mushroomsDeque.front()); + _mushroomsDeque.pop_front(); + } + events.Repeat(Seconds(40), Seconds(60)); + break; + default: + break; } - }; - CreatureAI* GetAI(Creature* creature) const override - { - return GetAhnKahetAI<boss_amanitarAI>(creature); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; } + + DoMeleeAttackIfReady(); + } + + private: + std::deque<Position> _mushroomsDeque; }; -class npc_amanitar_mushrooms : public CreatureScript +struct npc_amanitar_mushrooms : public ScriptedAI { -public: - npc_amanitar_mushrooms() : CreatureScript("npc_amanitar_mushrooms") { } + npc_amanitar_mushrooms(Creature* creature) : ScriptedAI(creature), _active(false) { } - struct npc_amanitar_mushroomsAI : public ScriptedAI + void Reset() override { - npc_amanitar_mushroomsAI(Creature* creature) : ScriptedAI(creature) { } + me->SetReactState(REACT_PASSIVE); + me->SetDisplayId(me->GetCreatureTemplate()->Modelid2); + DoCastSelf(SPELL_PUTRID_MUSHROOM); + DoCastSelf(SPELL_SHRINK, true); + DoCastSelf(SPELL_GROW, true); - EventMap events; + if (me->GetEntry() == NPC_HEALTHY_MUSHROOM) + { + DoCastSelf(SPELL_POWER_MUSHROOM_VISUAL_AURA); + _active = true; + } + else + DoCastSelf(SPELL_POISONOUS_MUSHROOM_VISUAL_AURA); - void Reset() override + _scheduler.Schedule(Milliseconds(800), [this](TaskContext /*context*/) { - events.Reset(); - events.ScheduleEvent(EVENT_AURA, 1 * IN_MILLISECONDS); + DoCastSelf(SPELL_GROW, true); + }); + } + + void MoveInLineOfSight(Unit* target) override + { + if (_active || target->GetTypeId() != TYPEID_PLAYER || me->GetDistance2d(target) > 2.0f) + return; - me->SetDisplayId(me->GetCreatureTemplate()->Modelid2); - DoCast(SPELL_PUTRID_MUSHROOM); + _active = true; - if (me->GetEntry() == NPC_POISONOUS_MUSHROOM) - DoCast(SPELL_POISONOUS_MUSHROOM_VISUAL_AURA); - else - DoCast(SPELL_POWER_MUSHROOM_VISUAL_AURA); - } + target->RemoveAurasDueToSpell(SPELL_POTENT_FUNGUS); + DoCastAOE(SPELL_POISONOUS_MUSHROOM_POISON_CLOUD); - void DamageTaken(Unit* /*attacker*/, uint32 &damage) override + _scheduler.Schedule(Seconds(1), [this](TaskContext /*context*/) { - if (damage >= me->GetHealth() && me->GetEntry() == NPC_HEALTHY_MUSHROOM) - DoCast(me, SPELL_HEALTHY_MUSHROOM_POTENT_FUNGUS, true); - } + me->SetObjectScale(0.1f); + me->DespawnOrUnsummon(Seconds(4)); + }); + } - void EnterCombat(Unit* /*who*/) override { } - void AttackStart(Unit* /*victim*/) override { } + void JustDied(Unit* /*killer*/) override + { + if (me->GetEntry() == NPC_HEALTHY_MUSHROOM) + DoCastAOE(SPELL_POTENT_FUNGUS, true); + } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; + void UpdateAI(uint32 diff) override + { + _scheduler.Update(diff); + } - events.Update(diff); +private: + TaskScheduler _scheduler; + bool _active; +}; - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; +// 56648 - Potent Fungus +class spell_amanitar_potent_fungus : public AuraScript +{ + PrepareAuraScript(spell_amanitar_potent_fungus); - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_AURA: - if (me->GetEntry() == NPC_POISONOUS_MUSHROOM) - { - DoCast(me, SPELL_POISONOUS_MUSHROOM_VISUAL_AREA, true); - DoCast(me, SPELL_POISONOUS_MUSHROOM_POISON_CLOUD); - } - events.ScheduleEvent(EVENT_AURA, 7 * IN_MILLISECONDS); - break; - default: - break; - } - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - } - } - }; + void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + if (!target->HasAura(SPELL_MINI)) + return; + + target->RemoveAurasDueToSpell(SPELL_MINI); + Remove(); + } - CreatureAI* GetAI(Creature* creature) const override + void Register() override { - return GetAhnKahetAI<npc_amanitar_mushroomsAI>(creature); + AfterEffectApply += AuraEffectApplyFn(spell_amanitar_potent_fungus::OnApply, EFFECT_0, SPELL_AURA_MOD_SCALE, AURA_EFFECT_HANDLE_REAL); } }; void AddSC_boss_amanitar() { - new boss_amanitar(); - new npc_amanitar_mushrooms(); + RegisterAhnKahetCreatureAI(boss_amanitar); + RegisterAhnKahetCreatureAI(npc_amanitar_mushrooms); + RegisterAuraScript(spell_amanitar_potent_fungus); } diff --git a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_jedoga_shadowseeker.cpp b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_jedoga_shadowseeker.cpp index 882b3c22410..7ab94f69186 100644 --- a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_jedoga_shadowseeker.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_jedoga_shadowseeker.cpp @@ -15,589 +15,484 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* - * Comment: Visuals missing, de-germanize code, wow 3.3.5a-ize - * Patch 3.3.2 (2010-01-02): Jedoga Shadowseeker now only ascends once during the encounter. - */ - #include "ScriptMgr.h" #include "ahnkahet.h" #include "InstanceScript.h" #include "MotionMaster.h" #include "ObjectAccessor.h" #include "ScriptedCreature.h" +#include "Spell.h" +#include "SpellScript.h" +#include "TemporarySummon.h" enum Yells { - TEXT_AGGRO = 0, - TEXT_SACRIFICE_1 = 1, - TEXT_SACRIFICE_2 = 2, - TEXT_SLAY = 3, - TEXT_DEATH = 4, - TEXT_PREACHING = 5 + SAY_AGGRO = 0, + SAY_CHOOSE = 1, + SAY_SACRIFICE = 2, + SAY_SLAY = 3, + SAY_DEATH = 4, + SAY_PREACHING = 5, + + SAY_CHOSEN = 0, + SAY_SACRIFICED = 1 }; -enum Spells +enum JedogaSpells { - SPELL_SPHERE_VISUAL = 56075, - SPELL_GIFT_OF_THE_HERALD = 56219, - SPELL_CYCLONE_STRIKE = 56855, // Self - SPELL_LIGHTNING_BOLT = 56891, // 40Y - SPELL_THUNDERSHOCK = 56926 // 30Y + SPELL_RANDOM_LIGHTNING_VISUAL = 56327, + SPELL_HOVER_FALL_1 = 56100, + SPELL_HOVER_FALL_2 = 56157, + SPELL_SPHERE_VISUAL = 56075, + SPELL_LIGHTNING_BOLT = 56891, + SPELL_THUNDERSHOCK = 56926, + SPELL_CYCLONE_STRIKE = 56855, + SPELL_SACRIFICE_BEAM = 56150, + + //Jedoga Controller + SPELL_BEAM_VISUAL_JEDOGA = 56312, + SPELL_SACRIFICE_VISUAL = 56133, + + //Twilight Volunteer + SPELL_SPHERE_VISUAL_VOLUNTEER = 56102, + SPELL_PILLAR_OF_LIGHTNING = 56868 }; -const Position JedogaPosition[2] = +enum JedogaEvents { - {372.330994f, -705.278015f, -0.624178f, 5.427970f}, - {372.330994f, -705.278015f, -16.179716f, 5.427970f} + EVENT_INTRO_SAY = 1, + EVENT_START_FIGHT_1, + EVENT_START_FIGHT_2, + EVENT_CYCLONE_STRIKE, + EVENT_LIGHTNING_BOLT, + EVENT_THUNDERSHOCK, + EVENT_START_PHASE_TWO, + EVENT_FLY_DELAY, + EVENT_END_PHASE_TWO, + EVENT_CHOOSE_VOLUNTEER, + EVENT_SUMMON_VOLUNTEER }; -enum Misc +enum JedogaPhases { - ACTION_INITIAND_KILLED = 1, - DATA_VOLUNTEER_WORK = 2 + PHASE_INTRO = 0, + PHASE_ONE, + PHASE_TWO, + PHASE_THREE }; -class boss_jedoga_shadowseeker : public CreatureScript +enum JedogaPoints { -public: - boss_jedoga_shadowseeker() : CreatureScript("boss_jedoga_shadowseeker") { } - - struct boss_jedoga_shadowseekerAI : public ScriptedAI - { - boss_jedoga_shadowseekerAI(Creature* creature) : ScriptedAI(creature) - { - Initialize(); - instance = creature->GetInstanceScript(); - bFirstTime = true; - bPreDone = false; - } - - void Initialize() - { - uiOpFerTimer = urand(15 * IN_MILLISECONDS, 20 * IN_MILLISECONDS); + POINT_INITIAL_POSITION = 0, + POINT_SACRIFICE, + POINT_GROUND, + POINT_PHASE_TWO, + POINT_PHASE_TWO_FLY +}; - uiCycloneTimer = 3 * IN_MILLISECONDS; - uiBoltTimer = 7 * IN_MILLISECONDS; - uiThunderTimer = 12 * IN_MILLISECONDS; +Position const SacrificePosition = { 376.5385f, -707.3567f, -16.14124f }; +Position const JedogaGroundPosition = { 371.6281f, -704.4836f, -16.17967f }; +Position const JedogaFlyPosition = { 371.627f, -704.4217f, -6.707521f }; +Position const JedogaControllerPositions[3] = +{ + { 402.7893f, -748.5251f, 29.39399f, 2.024582f }, + { 420.1999f, -727.0132f, 28.88036f, 2.042035f }, + { 375.4977f, -707.3635f, -16.0964f, 2.426008f } +}; - bOpFerok = false; - bOpFerokFail = false; - bOnGround = false; - bCanDown = false; - volunteerWork = true; - } +typedef std::pair<Position, Position> VolunteerPositionPair; +std::vector<VolunteerPositionPair> const VolunteerSpotPositions = +{ + { { 400.7701f, -784.8928f, -31.60143f }, { 365.9514f, -719.1235f, -16.17974f } }, + { { 397.3595f, -788.5157f, -31.59679f }, { 359.7433f, -715.017f, -16.17974f } }, + { { 399.3177f, -787.2599f, -31.59631f }, { 362.0263f, -719.1036f, -16.17974f } }, + { { 460.4623f, -719.2227f, -31.58718f }, { 389.266f, -679.3693f, -16.17973f } }, + { { 456.0909f, -724.3412f, -31.58718f }, { 400.5992f, -691.7954f, -16.17973f } }, + { { 452.6613f, -726.9518f, -31.58718f }, { 400.3423f, -701.5115f, -16.17974f } }, + { { 447.8852f, -732.3298f, -31.58718f }, { 389.861f, -710.6993f, -16.17974f } }, + { { 457.562f, -721.1855f, -31.58718f }, { 395.4494f, -684.5345f, -16.17973f } }, + { { 451.7243f, -730.2181f, -31.58718f }, { 397.0945f, -708.4188f, -15.99747f } }, + { { 413.9582f, -777.132f, -31.58716f }, { 388.1394f, -723.124f, -15.9938f } }, + { { 411.5661f, -781.2356f, -31.58716f }, { 381.7102f, -730.0745f, -15.99554f } }, + { { 407.395f, -786.793f, -31.58716f }, { 366.9791f, -737.3303f, -16.17974f } }, + { { 404.9166f, -788.3472f, -31.58716f }, { 358.6124f, -735.9944f, -15.9855f } }, + { { 401.5697f, -791.2033f, -31.58717f }, { 351.9383f, -729.6436f, -16.17974f } }, + { { 410.1105f, -785.4691f, -31.58716f }, { 373.1659f, -736.2893f, -16.17974f } }, + { { 442.5644f, -730.2499f, -31.59826f }, { 390.5955f, -714.6851f, -16.17974f } }, + { { 445.5233f, -725.9542f, -31.60173f }, { 393.9694f, -708.1727f, -16.17974f } }, + { { 448.5531f, -722.5888f, -31.60066f }, { 395.2702f, -702.556f, -16.17974f } }, + { { 449.8521f, -719.7265f, -31.58849f }, { 394.5757f, -695.1004f, -16.17974f } }, + { { 453.5134f, -717.7018f, -31.59883f }, { 387.6152f, -690.1782f, -16.17974f } }, + { { 457.8564f, -711.7424f, -31.59773f }, { 378.6874f, -687.1343f, -16.17973f } }, + { { 410.0583f, -774.4119f, -31.60115f }, { 383.8151f, -723.4276f, -16.17974f } }, + { { 408.7458f, -777.955f, -31.59873f }, { 376.9857f, -725.0735f, -16.17974f } }, + { { 405.2404f, -779.6614f, -31.60512f }, { 373.3736f, -722.7498f, -16.17974f } }, + { { 404.0797f, -783.829f, -31.59497f }, { 367.8631f, -722.5212f, -16.17974f } } +}; - InstanceScript* instance; +enum JedogaMisc +{ + SUMMON_GROUP_INITIATES = 1, + SUMMON_GROUP_WORSHIPPERS = 2, + DATA_VOLUNTEER_WORK = 1, + ACTION_CHOSEN = 1, + ACTION_SACRIFICE = 2, + TWILIGHT_INITIATES_SIZE = 15 +}; - uint32 uiOpFerTimer; - uint32 uiCycloneTimer; - uint32 uiBoltTimer; - uint32 uiThunderTimer; +struct boss_jedoga_shadowseeker : public BossAI +{ + boss_jedoga_shadowseeker(Creature* creature) : BossAI(creature, DATA_JEDOGA_SHADOWSEEKER), _initiatesKilled(0), _volunteerWork(true) { } - bool bPreDone; - bool bOpFerok; - bool bOnGround; - bool bOpFerokFail; - bool bCanDown; - bool volunteerWork; - bool bFirstTime; + void Reset() override + { + _Reset(); + events.SetPhase(PHASE_INTRO); + me->SetReactState(REACT_PASSIVE); + me->SummonCreatureGroup(SUMMON_GROUP_INITIATES); - void Reset() override - { - Initialize(); + if (TempSummon* controller = me->SummonCreature(NPC_JEDOGA_CONTROLLER, JedogaControllerPositions[0], TEMPSUMMON_MANUAL_DESPAWN)) + controller->CastSpell(me, SPELL_BEAM_VISUAL_JEDOGA); + if (TempSummon* controller = me->SummonCreature(NPC_JEDOGA_CONTROLLER, JedogaControllerPositions[1], TEMPSUMMON_MANUAL_DESPAWN)) + controller->CastSpell(me, SPELL_BEAM_VISUAL_JEDOGA); - if (!bFirstTime) - instance->SetBossState(DATA_JEDOGA_SHADOWSEEKER, FAIL); + events.ScheduleEvent(EVENT_INTRO_SAY, Minutes(2), 0, PHASE_INTRO); + } - instance->SetGuidData(DATA_PL_JEDOGA_TARGET, ObjectGuid::Empty); - instance->SetGuidData(DATA_ADD_JEDOGA_OPFER, ObjectGuid::Empty); - instance->SetData(DATA_JEDOGA_RESET_INITIANDS, 0); - MoveUp(); + void EnterCombat(Unit* /*who*/) override + { + me->RemoveAurasDueToSpell(SPELL_SPHERE_VISUAL); + me->RemoveAurasDueToSpell(SPELL_RANDOM_LIGHTNING_VISUAL); + me->SummonCreatureGroup(SUMMON_GROUP_WORSHIPPERS); - bFirstTime = false; - } + _EnterCombat(); + Talk(SAY_AGGRO); + events.SetPhase(PHASE_ONE); - void EnterCombat(Unit* who) override + for (VolunteerPositionPair posPair : VolunteerSpotPositions) { - if (!instance || (who->GetTypeId() == TYPEID_UNIT && who->GetEntry() == NPC_JEDOGA_CONTROLLER)) - return; - - Talk(TEXT_AGGRO); - me->SetInCombatWithZone(); - instance->SetBossState(DATA_JEDOGA_SHADOWSEEKER, IN_PROGRESS); + if (TempSummon* volunteer = me->SummonCreature(NPC_TWILIGHT_VOLUNTEER, posPair.first, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 3000)) + { + volunteer->GetMotionMaster()->MovePoint(POINT_INITIAL_POSITION, posPair.second); + _volunteerGUIDS.push_back(volunteer->GetGUID()); + } } + } - void AttackStart(Unit* who) override - { - if (!who || (who->GetTypeId() == TYPEID_UNIT && who->GetEntry() == NPC_JEDOGA_CONTROLLER)) - return; - - ScriptedAI::AttackStart(who); - } + void EnterEvadeMode(EvadeReason /*why*/) override + { + summons.DespawnAll(); + _EnterEvadeMode(); + _DespawnAtEvade(Seconds(15)); + } - void KilledUnit(Unit* Victim) override - { - if (!Victim || Victim->GetTypeId() != TYPEID_PLAYER) - return; + void KilledUnit(Unit* Victim) override + { + if (Victim->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_SLAY); + } - Talk(TEXT_SLAY); - } + void JustDied(Unit* /*killer*/) override + { + _JustDied(); + Talk(SAY_DEATH); + } - void JustDied(Unit* /*killer*/) override - { - Talk(TEXT_DEATH); - instance->SetBossState(DATA_JEDOGA_SHADOWSEEKER, DONE); - } + uint32 GetData(uint32 type) const override + { + if (type == DATA_VOLUNTEER_WORK) + return _volunteerWork ? 1 : 0; - void DoAction(int32 action) override - { - if (action == ACTION_INITIAND_KILLED) - volunteerWork = false; - } + return 0; + } - uint32 GetData(uint32 type) const override + void DamageTaken(Unit* /*done_by*/, uint32& /*damage*/) override + { + if (HealthBelowPct(55) && events.IsInPhase(PHASE_ONE)) { - if (type == DATA_VOLUNTEER_WORK) - return volunteerWork ? 1 : 0; - - return 0; + events.Reset(); + events.SetPhase(PHASE_TWO); + events.ScheduleEvent(EVENT_START_PHASE_TWO, Seconds(1)); } + } - void MoveInLineOfSight(Unit* who) override + void DoAction(int32 action) override + { + if (action == ACTION_SACRIFICE) { - if (!instance || !who || (who->GetTypeId() == TYPEID_UNIT && who->GetEntry() == NPC_JEDOGA_CONTROLLER)) - return; - - if (!bPreDone && who->GetTypeId() == TYPEID_PLAYER && me->GetDistance(who) < 100.0f) - { - Talk(TEXT_PREACHING); - bPreDone = true; - } - - if (instance->GetBossState(DATA_JEDOGA_SHADOWSEEKER) != IN_PROGRESS || !bOnGround) - return; - - if (!me->GetVictim() && me->CanCreatureAttack(who)) - { - float attackRadius = me->GetAttackDistance(who); - if (me->IsWithinDistInMap(who, attackRadius) && me->IsWithinLOSInMap(who)) - { - if (!me->GetVictim()) - { - who->RemoveAurasByType(SPELL_AURA_MOD_STEALTH); - AttackStart(who); - } - else - { - who->SetInCombatWith(me); - AddThreat(who, 0.0f); - } - } - } + Talk(SAY_SACRIFICE); + DoCastAOE(SPELL_SACRIFICE_BEAM); + events.ScheduleEvent(EVENT_END_PHASE_TWO, Seconds(3)); + events.RescheduleEvent(EVENT_SUMMON_VOLUNTEER, Seconds(15)); } + } - void MoveDown() + void JustSummoned(Creature* summon) override + { + if (summon->GetEntry() == NPC_TWILIGHT_WORSHIPPER) { - bOpFerokFail = false; - - instance->SetData(DATA_JEDOGA_TRIGGER_SWITCH, 0); - me->GetMotionMaster()->MovePoint(1, JedogaPosition[1]); - me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, false); - me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_MAGIC, false); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE + UNIT_FLAG_NON_ATTACKABLE); - - me->RemoveAurasDueToSpell(SPELL_SPHERE_VISUAL); - - bOnGround = true; - - if (UpdateVictim()) - { - AttackStart(me->GetVictim()); - me->GetMotionMaster()->MoveChase(me->GetVictim()); - } - else - { - if (Unit* target = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_PL_JEDOGA_TARGET))) - { - AttackStart(target); - instance->SetData(DATA_JEDOGA_RESET_INITIANDS, 0); - if (instance->GetBossState(DATA_JEDOGA_SHADOWSEEKER) != IN_PROGRESS) - EnterCombat(target); - } - else if (!me->IsInCombat()) - EnterEvadeMode(); - } + summon->SetStandState(UNIT_STAND_STATE_KNEEL); + summons.Summon(summon); + return; } - void MoveUp() - { - me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, true); - me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_MAGIC, true); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE + UNIT_FLAG_NON_ATTACKABLE); - - me->AttackStop(); - me->RemoveAllAuras(); - me->LoadCreaturesAddon(); - me->GetMotionMaster()->MovePoint(0, JedogaPosition[0]); - - instance->SetData(DATA_JEDOGA_TRIGGER_SWITCH, 1); - if (instance->GetBossState(DATA_JEDOGA_SHADOWSEEKER) == IN_PROGRESS) - OpferRufen(); - - bOnGround = false; - uiOpFerTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS); - } + BossAI::JustSummoned(summon); + } - void OpferRufen() + void SummonedCreatureDies(Creature* summon, Unit* killer) override + { + if (summon->GetEntry() == NPC_TWILIGHT_INITIATE) { - ObjectGuid opfer = instance->GetGuidData(DATA_ADD_JEDOGA_INITIAND); - - if (opfer) + if (++_initiatesKilled == TWILIGHT_INITIATES_SIZE) { - Talk(TEXT_SACRIFICE_1); - instance->SetGuidData(DATA_ADD_JEDOGA_OPFER, opfer); + DoCastSelf(SPELL_HOVER_FALL_1); + me->RemoveByteFlag(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_ANIM_TIER, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER); + events.ScheduleEvent(EVENT_START_FIGHT_1, Seconds(1)); } - else - bCanDown = true; } - - void Opfern() + else if (summon->GetEntry() == NPC_TWILIGHT_VOLUNTEER) { - Talk(TEXT_SACRIFICE_2); - - me->InterruptNonMeleeSpells(false); - DoCast(me, SPELL_GIFT_OF_THE_HERALD, false); - - bOpFerok = false; - bCanDown = true; - } - - void UpdateAI(uint32 diff) override - { - if (instance->GetBossState(DATA_JEDOGA_SHADOWSEEKER) != IN_PROGRESS && instance->GetData(DATA_ALL_INITIAND_DEAD)) - MoveDown(); - - if (bOpFerok && !bOnGround && !bCanDown) Opfern(); + _volunteerWork = false; - if (bOpFerokFail && !bOnGround && !bCanDown) - bCanDown = true; - - if (bCanDown) + if (events.IsInPhase(PHASE_TWO)) { - MoveDown(); - bCanDown = false; + events.SetPhase(PHASE_THREE); + events.RescheduleEvent(EVENT_END_PHASE_TWO, Seconds(1)); } - if (bOnGround) - { - if (!UpdateVictim()) - return; - - if (uiCycloneTimer <= diff) - { - DoCast(me, SPELL_CYCLONE_STRIKE, false); - uiCycloneTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS); - } else uiCycloneTimer -= diff; - - if (uiBoltTimer <= diff) - { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) - me->CastSpell(target, SPELL_LIGHTNING_BOLT, false); - - uiBoltTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS); - } else uiBoltTimer -= diff; - - if (uiThunderTimer <= diff) - { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) - me->CastSpell(target, SPELL_THUNDERSHOCK, false); - - uiThunderTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS); - } else uiThunderTimer -= diff; - - if (uiOpFerTimer <= diff) - MoveUp(); - else - uiOpFerTimer -= diff; - - DoMeleeAttackIfReady(); - } + events.RescheduleEvent(EVENT_SUMMON_VOLUNTEER, Seconds(10)); } - }; - CreatureAI* GetAI(Creature* creature) const override - { - return GetAhnKahetAI<boss_jedoga_shadowseekerAI>(creature); + BossAI::SummonedCreatureDies(summon, killer); } -}; - -class npc_jedoga_initiand : public CreatureScript -{ -public: - npc_jedoga_initiand() : CreatureScript("npc_jedoga_initiand") { } - struct npc_jedoga_initiandAI : public ScriptedAI + void MovementInform(uint32 type, uint32 pointId) override { - npc_jedoga_initiandAI(Creature* creature) : ScriptedAI(creature) - { - Initialize(); - instance = creature->GetInstanceScript(); - } + if (type != POINT_MOTION_TYPE && type != EFFECT_MOTION_TYPE) + return; - void Initialize() + switch (pointId) { - bWalking = false; - bCheckTimer = 2 * IN_MILLISECONDS; + case POINT_GROUND: + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + me->SetReactState(REACT_AGGRESSIVE); + DoZoneInCombat(); + events.ScheduleEvent(EVENT_CYCLONE_STRIKE, Seconds(3)); + events.ScheduleEvent(EVENT_LIGHTNING_BOLT, Seconds(7)); + events.ScheduleEvent(EVENT_THUNDERSHOCK, Seconds(12)); + break; + case POINT_PHASE_TWO: + events.ScheduleEvent(EVENT_FLY_DELAY, Seconds(2)); + break; + case POINT_PHASE_TWO_FLY: + events.ScheduleEvent(EVENT_CHOOSE_VOLUNTEER, Seconds(2)); + break; + default: + break; } + } - InstanceScript* instance; + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim() && !events.IsInPhase(PHASE_INTRO)) + return; - uint32 bCheckTimer; + events.Update(diff); - bool bWalking; + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - void Reset() override + while (uint32 eventId = events.ExecuteEvent()) { - Initialize(); - - if (instance->GetBossState(DATA_JEDOGA_SHADOWSEEKER) != IN_PROGRESS) - { - me->RemoveAurasDueToSpell(SPELL_SPHERE_VISUAL); - me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, false); - me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_MAGIC, false); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE + UNIT_FLAG_NON_ATTACKABLE); - } - else + switch (eventId) { - DoCast(me, SPELL_SPHERE_VISUAL, false); - me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, true); - me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_MAGIC, true); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE + UNIT_FLAG_NON_ATTACKABLE); - } - } + case EVENT_INTRO_SAY: + if (instance->GetBossState(DATA_PRINCE_TALDARAM) == DONE) + Talk(SAY_PREACHING); + events.Repeat(Minutes(2)); + break; + case EVENT_START_FIGHT_1: + me->RemoveAurasDueToSpell(SPELL_BEAM_VISUAL_JEDOGA); + events.ScheduleEvent(EVENT_START_FIGHT_2, Seconds(1)); + break; + case EVENT_START_FIGHT_2: + summons.DespawnEntry(NPC_JEDOGA_CONTROLLER); + me->SetDisableGravity(false); + me->RemoveByteFlag(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_ANIM_TIER, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER); + me->GetMotionMaster()->MoveLand(POINT_GROUND, JedogaGroundPosition); + break; + case EVENT_START_PHASE_TWO: + me->SetReactState(REACT_PASSIVE); + me->AttackStop(); + me->InterruptNonMeleeSpells(true); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + me->GetMotionMaster()->MovePoint(POINT_PHASE_TWO, JedogaGroundPosition); + break; + case EVENT_FLY_DELAY: + me->SetDisableGravity(true); + me->SetByteFlag(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_ANIM_TIER, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER); + me->GetMotionMaster()->MoveTakeoff(POINT_PHASE_TWO_FLY, JedogaFlyPosition); + break; + case EVENT_CHOOSE_VOLUNTEER: + if (TempSummon* controller = me->SummonCreature(NPC_JEDOGA_CONTROLLER, JedogaControllerPositions[2], TEMPSUMMON_MANUAL_DESPAWN)) + { + me->SetFacingToObject(controller); + controller->CastSpell(controller, SPELL_SACRIFICE_VISUAL); + } - void JustDied(Unit* killer) override - { - if (!killer || !instance) - return; + Talk(SAY_CHOOSE); - if (bWalking) - { - if (Creature* boss = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_JEDOGA_SHADOWSEEKER))) - { - if (!ENSURE_AI(boss_jedoga_shadowseeker::boss_jedoga_shadowseekerAI, boss->AI())->bOpFerok) - ENSURE_AI(boss_jedoga_shadowseeker::boss_jedoga_shadowseekerAI, boss->AI())->bOpFerokFail = true; + if (_volunteerGUIDS.empty()) + break; - if (killer->GetTypeId() == TYPEID_PLAYER) - boss->AI()->DoAction(ACTION_INITIAND_KILLED); + _selectedVolunteerGUID = Trinity::Containers::SelectRandomContainerElement(_volunteerGUIDS); + if (Creature* volunteer = ObjectAccessor::GetCreature(*me, _selectedVolunteerGUID)) + volunteer->AI()->DoAction(ACTION_CHOSEN); + break; + case EVENT_SUMMON_VOLUNTEER: + { + uint32 pos = std::distance(_volunteerGUIDS.begin(), std::find(_volunteerGUIDS.begin(), _volunteerGUIDS.end(), _selectedVolunteerGUID)); + if (pos < VolunteerSpotPositions.size()) + { + VolunteerPositionPair posPair = VolunteerSpotPositions.at(pos); + if (TempSummon* volunteer = me->SummonCreature(NPC_TWILIGHT_VOLUNTEER, posPair.first, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 3000)) + volunteer->GetMotionMaster()->MovePoint(POINT_INITIAL_POSITION, posPair.second); + } + break; } - - instance->SetGuidData(DATA_ADD_JEDOGA_OPFER, ObjectGuid::Empty); - - bWalking = false; + case EVENT_END_PHASE_TWO: + summons.DespawnEntry(NPC_JEDOGA_CONTROLLER); + DoCastSelf(SPELL_HOVER_FALL_2); + me->SetDisableGravity(false); + me->RemoveByteFlag(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_ANIM_TIER, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER); + me->GetMotionMaster()->MoveLand(POINT_GROUND, JedogaGroundPosition); + break; + case EVENT_CYCLONE_STRIKE: + DoCastSelf(SPELL_CYCLONE_STRIKE); + events.Repeat(Seconds(15), Seconds(30)); + break; + case EVENT_LIGHTNING_BOLT: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true)) + DoCast(target, SPELL_LIGHTNING_BOLT); + events.Repeat(Seconds(15), Seconds(30)); + break; + case EVENT_THUNDERSHOCK: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true)) + DoCast(target, SPELL_THUNDERSHOCK); + events.Repeat(Seconds(15), Seconds(30)); + break; + default: + break; } - if (killer->GetTypeId() == TYPEID_PLAYER) - instance->SetGuidData(DATA_PL_JEDOGA_TARGET, killer->GetGUID()); - } - - void EnterCombat(Unit* /*who*/) override - { - } - void AttackStart(Unit* victim) override - { - if ((instance->GetBossState(DATA_JEDOGA_SHADOWSEEKER) == IN_PROGRESS) || !victim) + if (me->HasUnitState(UNIT_STATE_CASTING)) return; - - ScriptedAI::AttackStart(victim); } - void MoveInLineOfSight(Unit* who) override + DoMeleeAttackIfReady(); + } - { - if ((instance->GetBossState(DATA_JEDOGA_SHADOWSEEKER) == IN_PROGRESS) || !who) - return; +private: + uint8 _initiatesKilled; + bool _volunteerWork; + GuidVector _volunteerGUIDS; + ObjectGuid _selectedVolunteerGUID; +}; - ScriptedAI::MoveInLineOfSight(who); - } +struct npc_twilight_volunteer : public ScriptedAI +{ + npc_twilight_volunteer(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) + { + me->SetReactState(REACT_PASSIVE); + } - void MovementInform(uint32 uiType, uint32 uiPointId) override + void DoAction(int32 action) override + { + if (action == ACTION_CHOSEN) { - if (uiType != POINT_MOTION_TYPE || !instance) - return; - - switch (uiPointId) - { - case 1: - { - Creature* boss = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_JEDOGA_SHADOWSEEKER)); - if (boss) - { - ENSURE_AI(boss_jedoga_shadowseeker::boss_jedoga_shadowseekerAI, boss->AI())->bOpFerok = true; - ENSURE_AI(boss_jedoga_shadowseeker::boss_jedoga_shadowseekerAI, boss->AI())->bOpFerokFail = false; - me->KillSelf(); - } - } - break; - } + DoCastSelf(SPELL_PILLAR_OF_LIGHTNING); + me->RemoveAurasDueToSpell(SPELL_SPHERE_VISUAL_VOLUNTEER); + Talk(SAY_CHOSEN); + me->SetStandState(UNIT_STAND_STATE_STAND); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + me->SetWalk(true); + me->GetMotionMaster()->MovePoint(POINT_SACRIFICE, SacrificePosition); } + } - void UpdateAI(uint32 diff) override + void MovementInform(uint32 type, uint32 pointId) override + { + if (type != POINT_MOTION_TYPE) + return; + + switch (pointId) { - if (bCheckTimer <= diff) - { - if (me->GetGUID() == instance->GetGuidData(DATA_ADD_JEDOGA_OPFER) && !bWalking) + case POINT_INITIAL_POSITION: + if (Creature* jedoga = _instance->GetCreature(DATA_JEDOGA_SHADOWSEEKER)) + me->SetFacingToObject(jedoga); + + DoCastSelf(SPELL_SPHERE_VISUAL_VOLUNTEER); + me->SetStandState(UNIT_STAND_STATE_KNEEL); + break; + case POINT_SACRIFICE: + if (Creature* jedoga = _instance->GetCreature(DATA_JEDOGA_SHADOWSEEKER)) { - me->RemoveAurasDueToSpell(SPELL_SPHERE_VISUAL); - me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, false); - me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_MAGIC, false); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE + UNIT_FLAG_NON_ATTACKABLE); - - float distance = me->GetDistance(JedogaPosition[1]); - - if (distance < 9.0f) - me->SetSpeedRate(MOVE_WALK, 0.5f); - else if (distance < 15.0f) - me->SetSpeedRate(MOVE_WALK, 0.75f); - else if (distance < 20.0f) - me->SetSpeedRate(MOVE_WALK, 1.0f); - - me->GetMotionMaster()->Clear(false); - me->GetMotionMaster()->MovePoint(1, JedogaPosition[1]); - bWalking = true; - } - if (!bWalking) - { - if (instance->GetBossState(DATA_JEDOGA_SHADOWSEEKER) != IN_PROGRESS && me->HasAura(SPELL_SPHERE_VISUAL)) - { - me->RemoveAurasDueToSpell(SPELL_SPHERE_VISUAL); - me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, false); - me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_MAGIC, false); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE + UNIT_FLAG_NON_ATTACKABLE); - } - if (instance->GetBossState(DATA_JEDOGA_SHADOWSEEKER) == IN_PROGRESS && !me->HasAura(SPELL_SPHERE_VISUAL)) + me->SetStandState(UNIT_STAND_STATE_KNEEL); + jedoga->AI()->DoAction(ACTION_SACRIFICE); + Talk(SAY_SACRIFICED); + + _scheduler.Schedule(Seconds(3), [this](TaskContext /*context*/) { - DoCast(me, SPELL_SPHERE_VISUAL, false); - me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, true); - me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_MAGIC, true); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE + UNIT_FLAG_NON_ATTACKABLE); - } + me->SetStandState(UNIT_STAND_STATE_DEAD); + me->DespawnOrUnsummon(Seconds(5)); + }); } - bCheckTimer = 2*IN_MILLISECONDS; - } else bCheckTimer -= diff; - - //Return since we have no target - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); + break; + default: + break; } - }; + } - CreatureAI* GetAI(Creature* creature) const override + void UpdateAI(uint32 diff) override { - return GetAhnKahetAI<npc_jedoga_initiandAI>(creature); + _scheduler.Update(diff); } -}; -// ------------------------------------------------------------------------------------------------------------ -// Jedogas Aufseher - Entry: 30181 -// ------------------------------------------------------------------------------------------------------------ -enum AufseherSpell -{ - SPELL_BEAM_VISUAL_JEDOGAS_AUFSEHER_1 = 60342, - SPELL_BEAM_VISUAL_JEDOGAS_AUFSEHER_2 = 56312 +private: + InstanceScript* _instance; + TaskScheduler _scheduler; }; -class npc_jedogas_aufseher_trigger : public CreatureScript +// 56328 - Random Lightning Visual Effect +class spell_random_lightning_visual_effect : public SpellScript { -public: - npc_jedogas_aufseher_trigger() : CreatureScript("npc_jedogas_aufseher_trigger") { } + PrepareSpellScript(spell_random_lightning_visual_effect); - struct npc_jedogas_aufseher_triggerAI : public ScriptedAI + void ModDestHeight(SpellDestination& dest) { - npc_jedogas_aufseher_triggerAI(Creature* creature) : ScriptedAI(creature) - { - instance = creature->GetInstanceScript(); - bRemoved = false; - bRemoved2 = false; - bCast = false; - bCast2 = false; - - SetCombatMovement(false); - } - - InstanceScript* instance; - - bool bRemoved; - bool bRemoved2; - bool bCast; - bool bCast2; - - void Reset() override { } - void EnterCombat(Unit* /*who*/) override { } - void AttackStart(Unit* /*victim*/) override { } - void MoveInLineOfSight(Unit* /*who*/) override { } - - - void UpdateAI(uint32 /*diff*/) override - { - if (!bRemoved && me->GetPositionX() > 440.0f) - { - if (instance->GetBossState(DATA_PRINCE_TALDARAM) == DONE) - { - me->InterruptNonMeleeSpells(true); - bRemoved = true; - return; - } - if (!bCast) - { - DoCast(me, SPELL_BEAM_VISUAL_JEDOGAS_AUFSEHER_1, false); - bCast = true; - } - } - if (!bRemoved2 && me->GetPositionX() < 440.0f) - { - if (!bCast2 && instance->GetData(DATA_JEDOGA_TRIGGER_SWITCH)) - { - DoCast(me, SPELL_BEAM_VISUAL_JEDOGAS_AUFSEHER_2, false); - bCast2 = true; - } - if (bCast2 && !instance->GetData(DATA_JEDOGA_TRIGGER_SWITCH)) - { - me->InterruptNonMeleeSpells(true); - bCast2 = false; - } - if (!bRemoved2 && instance->GetBossState(DATA_JEDOGA_SHADOWSEEKER) == DONE) - { - me->InterruptNonMeleeSpells(true); - bRemoved2 = true; - } - } - } - }; + Position const offset = { 0.0f, 0.0f, -19.0f, 0.0f }; + dest.RelocateOffset(offset); + } - CreatureAI* GetAI(Creature* creature) const override + void Register() override { - return GetAhnKahetAI<npc_jedogas_aufseher_triggerAI>(creature); + OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_random_lightning_visual_effect::ModDestHeight, EFFECT_0, TARGET_DEST_CASTER_RANDOM); } + }; class achievement_volunteer_work : public AchievementCriteriaScript { public: - achievement_volunteer_work() : AchievementCriteriaScript("achievement_volunteer_work") - { - } + achievement_volunteer_work() : AchievementCriteriaScript("achievement_volunteer_work") { } bool OnCheck(Player* /*player*/, Unit* target) override { if (!target) return false; - if (Creature* Jedoga = target->ToCreature()) - if (Jedoga->AI()->GetData(DATA_VOLUNTEER_WORK)) + if (Creature* jedoga = target->ToCreature()) + if (jedoga->AI()->GetData(DATA_VOLUNTEER_WORK) == 1) return true; return false; @@ -606,8 +501,8 @@ class achievement_volunteer_work : public AchievementCriteriaScript void AddSC_boss_jedoga_shadowseeker() { - new boss_jedoga_shadowseeker(); - new npc_jedoga_initiand(); - new npc_jedogas_aufseher_trigger(); + RegisterAhnKahetCreatureAI(boss_jedoga_shadowseeker); + RegisterAhnKahetCreatureAI(npc_twilight_volunteer); + RegisterSpellScript(spell_random_lightning_visual_effect); new achievement_volunteer_work(); } diff --git a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp index fcb37f56a87..8c7f36c3231 100644 --- a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp @@ -53,7 +53,8 @@ enum Spells enum Misc { DATA_EMBRACE_DMG = 20000, - H_DATA_EMBRACE_DMG = 40000 + H_DATA_EMBRACE_DMG = 40000, + SUMMON_GROUP_CONTROLLERS = 1 }; #define DATA_SPHERE_DISTANCE 25.0f @@ -104,6 +105,9 @@ class boss_prince_taldaram : public CreatureScript _flameSphereTargetGUID.Clear(); _embraceTargetGUID.Clear(); _embraceTakenDamage = 0; + + if (!CheckSpheres()) + me->SummonCreatureGroup(SUMMON_GROUP_CONTROLLERS); } void EnterCombat(Unit* /*who*/) override @@ -125,6 +129,10 @@ class boss_prince_taldaram : public CreatureScript case NPC_FLAME_SPHERE_2: case NPC_FLAME_SPHERE_3: summon->AI()->SetGUID(_flameSphereTargetGUID); + break; + case NPC_JEDOGA_CONTROLLER: + summon->CastSpell(me, SPELL_BEAM_VISUAL); + break; default: return; } @@ -266,13 +274,15 @@ class boss_prince_taldaram : public CreatureScript void RemovePrison() { me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + summons.DespawnEntry(NPC_JEDOGA_CONTROLLER); me->RemoveAurasDueToSpell(SPELL_BEAM_VISUAL); me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), DATA_GROUND_POSITION_Z, me->GetOrientation()); DoCast(SPELL_HOVER_FALL); me->SetDisableGravity(false); me->GetMotionMaster()->MoveLand(0, me->GetHomePosition()); Talk(SAY_WARNING); - instance->HandleGameObject(instance->GetGuidData(DATA_PRINCE_TALDARAM_PLATFORM), true); + if (GameObject* platform = instance->GetGameObject(DATA_PRINCE_TALDARAM_PLATFORM)) + instance->HandleGameObject(platform->GetGUID(), true); } private: @@ -395,7 +405,7 @@ class go_prince_taldaram_sphere : public GameObjectScript bool GossipHello(Player* /*player*/) override { - Creature* princeTaldaram = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_PRINCE_TALDARAM)); + Creature* princeTaldaram = instance->GetCreature(DATA_PRINCE_TALDARAM); if (princeTaldaram && princeTaldaram->IsAlive()) { me->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); diff --git a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/instance_ahnkahet.cpp b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/instance_ahnkahet.cpp index c629a5e66e7..9315cf3fddd 100644 --- a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/instance_ahnkahet.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/instance_ahnkahet.cpp @@ -16,9 +16,9 @@ */ #include "ScriptMgr.h" +#include "AreaBoundary.h" #include "ahnkahet.h" #include "Creature.h" -#include "CreatureAI.h" #include "GameObject.h" #include "InstanceScript.h" #include "Map.h" @@ -29,6 +29,27 @@ DoorData const doorData[] = { 0, 0, DOOR_TYPE_ROOM } // END }; +ObjectData const creatureData[] = +{ + { NPC_ELDER_NADOX, DATA_ELDER_NADOX }, + { NPC_PRINCE_TALDARAM, DATA_PRINCE_TALDARAM }, + { NPC_JEDOGA_SHADOWSEEKER, DATA_JEDOGA_SHADOWSEEKER }, + { NPC_AMANITAR, DATA_AMANITAR }, + { NPC_HERALD_VOLAZJ, DATA_HERALD_VOLAZJ }, + { 0, 0 } +}; + +ObjectData const gameObjectData[] = +{ + { GO_PRINCE_TALDARAM_PLATFORM, DATA_PRINCE_TALDARAM_PLATFORM }, + { 0, 0 } //END +}; + +BossBoundaryData const boundaries = +{ + { DATA_JEDOGA_SHADOWSEEKER, new ParallelogramBoundary(Position(460.365f, -661.997f, -20.985f), Position(364.958f,-790.211f, -14.207f), Position(347.436f,-657.978f,14.478f)) } +}; + class instance_ahnkahet : public InstanceMapScript { public: @@ -41,46 +62,20 @@ class instance_ahnkahet : public InstanceMapScript SetHeaders(DataHeader); SetBossNumber(EncounterCount); LoadDoorData(doorData); - - SwitchTrigger = 0; + LoadObjectData(creatureData, gameObjectData); + LoadBossBoundaries(boundaries); SpheresState[0] = 0; SpheresState[1] = 0; } - void OnCreatureCreate(Creature* creature) override - { - switch (creature->GetEntry()) - { - case NPC_ELDER_NADOX: - ElderNadoxGUID = creature->GetGUID(); - break; - case NPC_PRINCE_TALDARAM: - PrinceTaldaramGUID = creature->GetGUID(); - break; - case NPC_JEDOGA_SHADOWSEEKER: - JedogaShadowseekerGUID = creature->GetGUID(); - break; - case NPC_AMANITAR: - AmanitarGUID = creature->GetGUID(); - break; - case NPC_HERALD_VOLAZJ: - HeraldVolazjGUID = creature->GetGUID(); - break; - case NPC_INITIAND: - InitiandGUIDs.insert(creature->GetGUID()); - break; - default: - break; - } - } - void OnGameObjectCreate(GameObject* go) override { + InstanceScript::OnGameObjectCreate(go); + switch (go->GetEntry()) { case GO_PRINCE_TALDARAM_PLATFORM: - PrinceTaldaramPlatformGUID = go->GetGUID(); if (GetBossState(DATA_PRINCE_TALDARAM) == DONE) HandleGameObject(ObjectGuid::Empty, true, go); break; @@ -102,21 +97,6 @@ class instance_ahnkahet : public InstanceMapScript else go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); break; - case GO_PRINCE_TALDARAM_GATE: - AddDoor(go, true); - break; - default: - break; - } - } - - void OnGameObjectRemove(GameObject* go) override - { - switch (go->GetEntry()) - { - case GO_PRINCE_TALDARAM_GATE: - AddDoor(go, false); - break; default: break; } @@ -130,20 +110,6 @@ class instance_ahnkahet : public InstanceMapScript case DATA_SPHERE_2: SpheresState[type - DATA_SPHERE_1] = data; break; - case DATA_JEDOGA_TRIGGER_SWITCH: - SwitchTrigger = data; - break; - case DATA_JEDOGA_RESET_INITIANDS: - for (ObjectGuid guid : InitiandGUIDs) - { - if (Creature* creature = instance->GetCreature(guid)) - { - creature->Respawn(); - if (!creature->IsInEvadeMode()) - creature->AI()->EnterEvadeMode(); - } - } - break; default: break; } @@ -156,99 +122,12 @@ class instance_ahnkahet : public InstanceMapScript case DATA_SPHERE_1: case DATA_SPHERE_2: return SpheresState[type - DATA_SPHERE_1]; - case DATA_ALL_INITIAND_DEAD: - for (ObjectGuid guid : InitiandGUIDs) - { - Creature* cr = instance->GetCreature(guid); - if (!cr || cr->IsAlive()) - return 0; - } - return 1; - case DATA_JEDOGA_TRIGGER_SWITCH: - return SwitchTrigger; default: break; } return 0; } - void SetGuidData(uint32 type, ObjectGuid data) override - { - switch (type) - { - case DATA_ADD_JEDOGA_OPFER: - JedogaSacrifices = data; - break; - case DATA_PL_JEDOGA_TARGET: - JedogaTarget = data; - break; - default: - break; - } - } - - ObjectGuid GetGuidData(uint32 type) const override - { - switch (type) - { - case DATA_ELDER_NADOX: - return ElderNadoxGUID; - case DATA_PRINCE_TALDARAM: - return PrinceTaldaramGUID; - case DATA_JEDOGA_SHADOWSEEKER: - return JedogaShadowseekerGUID; - case DATA_AMANITAR: - return AmanitarGUID; - case DATA_HERALD_VOLAZJ: - return HeraldVolazjGUID; - case DATA_PRINCE_TALDARAM_PLATFORM: - return PrinceTaldaramPlatformGUID; - case DATA_ADD_JEDOGA_INITIAND: - { - GuidVector vInitiands; - vInitiands.reserve(InitiandGUIDs.size()); - for (ObjectGuid guid : InitiandGUIDs) - { - Creature* cr = instance->GetCreature(guid); - if (cr && cr->IsAlive()) - vInitiands.push_back(guid); - } - if (vInitiands.empty()) - return ObjectGuid::Empty; - - return Trinity::Containers::SelectRandomContainerElement(vInitiands); - } - case DATA_ADD_JEDOGA_OPFER: - return JedogaSacrifices; - case DATA_PL_JEDOGA_TARGET: - return JedogaTarget; - default: - break; - } - return ObjectGuid::Empty; - } - - bool SetBossState(uint32 type, EncounterState state) override - { - if (!InstanceScript::SetBossState(type, state)) - return false; - - switch (type) - { - case DATA_JEDOGA_SHADOWSEEKER: - if (state == DONE) - { - for (ObjectGuid guid : InitiandGUIDs) - if (Creature* cr = instance->GetCreature(guid)) - cr->DespawnOrUnsummon(); - } - break; - default: - break; - } - return true; - } - void WriteSaveDataMore(std::ostringstream& data) override { data << SpheresState[0] << ' ' << SpheresState[1]; @@ -261,20 +140,7 @@ class instance_ahnkahet : public InstanceMapScript } protected: - ObjectGuid ElderNadoxGUID; - ObjectGuid PrinceTaldaramGUID; - ObjectGuid JedogaShadowseekerGUID; - ObjectGuid AmanitarGUID; - ObjectGuid HeraldVolazjGUID; - - ObjectGuid PrinceTaldaramPlatformGUID; - ObjectGuid JedogaSacrifices; - ObjectGuid JedogaTarget; - - GuidSet InitiandGUIDs; - uint32 SpheresState[2]; - uint8 SwitchTrigger; }; InstanceScript* GetInstanceScript(InstanceMap* map) const override diff --git a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/azjol_nerub.h b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/azjol_nerub.h index 7e42df81f21..f4e8e99b820 100644 --- a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/azjol_nerub.h +++ b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/azjol_nerub.h @@ -37,7 +37,8 @@ enum ANDataTypes DATA_WATCHER_GASHRA, DATA_WATCHER_SILTHIK, DATA_ANUBARAK_WALL, - DATA_ANUBARAK_WALL_2 + DATA_ANUBARAK_WALL_2, + DATA_GATEWATCHER_GREET }; enum ANCreatureIds diff --git a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_hadronox.cpp b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_hadronox.cpp index 89b5268684d..b10add03865 100644 --- a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_hadronox.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_hadronox.cpp @@ -18,6 +18,7 @@ #include "ScriptMgr.h" #include "azjol_nerub.h" #include "InstanceScript.h" +#include "Map.h" #include "MotionMaster.h" #include "ObjectAccessor.h" #include "ScriptedCreature.h" @@ -278,29 +279,22 @@ public: _anubar.push_back(guid); } - void Initialize() + void InitializeAI() override { + BossAI::InitializeAI(); me->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 9.0f); me->SetFloatValue(UNIT_FIELD_COMBATREACH, 9.0f); _enteredCombat = false; _doorsWebbed = false; _lastPlayerCombatState = false; SetStep(0); - SetCombatMovement(true); - SummonCrusherPack(SUMMON_GROUP_CRUSHER_1); - } - - void InitializeAI() override - { - BossAI::InitializeAI(); - if (me->IsAlive()) - Initialize(); } - void JustRespawned() override + void JustAppeared() override { - BossAI::JustRespawned(); - Initialize(); + BossAI::JustAppeared(); + SetCombatMovement(true); + SummonCrusherPack(SUMMON_GROUP_CRUSHER_1); } void UpdateAI(uint32 diff) override @@ -975,6 +969,8 @@ class spell_hadronox_periodic_summon_template_AuraScript : public AuraScript InstanceScript* instance = caster->GetInstanceScript(); if (!instance) return; + if (!instance->instance->HavePlayers()) + return; if (instance->GetBossState(DATA_HADRONOX) == DONE) GetAura()->Remove(); else diff --git a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_krikthir_the_gatewatcher.cpp b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_krikthir_the_gatewatcher.cpp index 506ddd8cad2..1df855f2ab0 100644 --- a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_krikthir_the_gatewatcher.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_krikthir_the_gatewatcher.cpp @@ -132,7 +132,7 @@ class boss_krik_thir : public CreatureScript struct boss_krik_thirAI : public BossAI { - boss_krik_thirAI(Creature* creature) : BossAI(creature, DATA_KRIKTHIR), _hadGreet(false), _hadFrenzy(false), _petsInCombat(false), _watchersActive(0) { } + boss_krik_thirAI(Creature* creature) : BossAI(creature, DATA_KRIKTHIR), _hadFrenzy(false), _petsInCombat(false), _watchersActive(0) { } void SummonAdds() { @@ -157,15 +157,9 @@ class boss_krik_thir : public CreatureScript me->SetReactState(REACT_PASSIVE); } - void InitializeAI() override - { - BossAI::InitializeAI(); - SummonAdds(); - } - - void JustRespawned() override + void JustAppeared() override { - BossAI::JustRespawned(); + BossAI::JustAppeared(); SummonAdds(); } @@ -218,9 +212,9 @@ class boss_krik_thir : public CreatureScript switch (action) { case -ACTION_GATEWATCHER_GREET: - if (!_hadGreet && me->IsAlive() && !me->IsInCombat() && !_petsInCombat) + if (!instance->GetData(DATA_GATEWATCHER_GREET) && me->IsAlive() && !me->IsInCombat() && !_petsInCombat) { - _hadGreet = true; + instance->SetData(DATA_GATEWATCHER_GREET, 1); Talk(SAY_PREFIGHT); } break; @@ -313,7 +307,6 @@ class boss_krik_thir : public CreatureScript } private: - bool _hadGreet; bool _hadFrenzy; bool _petsInCombat; uint8 _watchersActive; diff --git a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/instance_azjol_nerub.cpp b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/instance_azjol_nerub.cpp index eb6692f0251..49da45c2586 100644 --- a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/instance_azjol_nerub.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/instance_azjol_nerub.cpp @@ -71,14 +71,20 @@ class instance_azjol_nerub : public InstanceMapScript LoadBossBoundaries(boundaries); LoadDoorData(doorData); LoadObjectData(creatureData, gameobjectData); + GateWatcherGreet = 0; } void OnUnitDeath(Unit* who) override { InstanceScript::OnUnitDeath(who); + + if (who->GetTypeId() != TYPEID_UNIT || GetBossState(DATA_KRIKTHIR) == DONE) + return; + Creature* creature = who->ToCreature(); - if (!creature || creature->IsCritter() || creature->IsControlledByPlayer()) + if (creature->IsCritter() || creature->IsCharmedOwnedByPlayerOrPlayer()) return; + if (Creature* gatewatcher = GetCreature(DATA_KRIKTHIR)) gatewatcher->AI()->DoAction(-ACTION_GATEWATCHER_GREET); } @@ -93,6 +99,32 @@ class instance_azjol_nerub : public InstanceMapScript return true; } + + uint32 GetData(uint32 type) const override + { + switch (type) + { + case DATA_GATEWATCHER_GREET: + return GateWatcherGreet; + default: + return 0; + } + } + + void SetData(uint32 type, uint32 data) override + { + switch (type) + { + case DATA_GATEWATCHER_GREET: + GateWatcherGreet = data; + break; + default: + break; + } + } + + protected: + uint8 GateWatcherGreet; }; InstanceScript* GetInstanceScript(InstanceMap* map) const override diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_baltharus_the_warborn.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_baltharus_the_warborn.cpp index 16955384cb8..24f35115e04 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_baltharus_the_warborn.cpp +++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_baltharus_the_warborn.cpp @@ -73,8 +73,7 @@ class boss_baltharus_the_warborn : public CreatureScript struct boss_baltharus_the_warbornAI : public BossAI { - boss_baltharus_the_warbornAI(Creature* creature) : BossAI(creature, DATA_BALTHARUS_THE_WARBORN), - _cloneCount(0), _introDone(false) { } + boss_baltharus_the_warbornAI(Creature* creature) : BossAI(creature, DATA_BALTHARUS_THE_WARBORN), _cloneCount(0) { } void Reset() override { @@ -91,9 +90,6 @@ class boss_baltharus_the_warborn : public CreatureScript switch (action) { case ACTION_INTRO_BALTHARUS: - if (_introDone) - return; - _introDone = true; me->setActive(true); events.ScheduleEvent(EVENT_INTRO_TALK, Seconds(7), 0, PHASE_INTRO); break; @@ -232,7 +228,6 @@ class boss_baltharus_the_warborn : public CreatureScript private: uint8 _cloneCount; - bool _introDone; }; CreatureAI* GetAI(Creature* creature) const override diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp index 472dc16191f..3957ad4793c 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp +++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp @@ -566,7 +566,7 @@ class npc_halion_controller : public CreatureScript _twilightDamageTaken = 0; } - void JustRespawned() override + void JustAppeared() override { if (_instance->GetGuidData(DATA_HALION) || _instance->GetBossState(DATA_GENERAL_ZARITHRIAN) != DONE) return; @@ -733,7 +733,7 @@ class npc_halion_controller : public CreatureScript case EVENT_TWILIGHT_MENDING: if (_instance->GetCreature(DATA_HALION)) // Just check if physical Halion is spawned if (Creature* twilightHalion = _instance->GetCreature(DATA_TWILIGHT_HALION)) - twilightHalion->CastSpell((Unit*)nullptr, SPELL_TWILIGHT_MENDING, true); + twilightHalion->CastSpell(nullptr, SPELL_TWILIGHT_MENDING, true); break; case EVENT_TRIGGER_BERSERK: for (uint8 i = DATA_HALION; i <= DATA_TWILIGHT_HALION; i++) @@ -921,7 +921,7 @@ class npc_orb_carrier : public CreatureScript /// However, refreshing it looks bad, so just cast the spell if /// we are not channeling it. if (!me->HasUnitState(UNIT_STATE_CASTING)) - me->CastSpell((Unit*)nullptr, SPELL_TRACK_ROTATION, false); + me->CastSpell(nullptr, SPELL_TRACK_ROTATION, false); scheduler.Update(diff); diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/ruby_sanctum.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/ruby_sanctum.cpp index e43b93e484d..20d8333bbab 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/ruby_sanctum.cpp +++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/ruby_sanctum.cpp @@ -152,12 +152,12 @@ class npc_xerestrasza : public CreatureScript } }; -class at_baltharus_plateau : public AreaTriggerScript +class at_baltharus_plateau : public OnlyOnceAreaTriggerScript { public: - at_baltharus_plateau() : AreaTriggerScript("at_baltharus_plateau") { } + at_baltharus_plateau() : OnlyOnceAreaTriggerScript("at_baltharus_plateau") { } - bool OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/) override + bool _OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/) override { // Only trigger once if (InstanceScript* instance = player->GetInstanceScript()) diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_argent_challenge.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_argent_challenge.cpp index 1061dc37aff..3b997fe9516 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_argent_challenge.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_argent_challenge.cpp @@ -505,9 +505,9 @@ public: npc_argent_soldier() : CreatureScript("npc_argent_soldier") { } // THIS AI NEEDS MORE IMPROVEMENTS - struct npc_argent_soldierAI : public npc_escortAI + struct npc_argent_soldierAI : public EscortAI { - npc_argent_soldierAI(Creature* creature) : npc_escortAI(creature) + npc_argent_soldierAI(Creature* creature) : EscortAI(creature) { instance = creature->GetInstanceScript(); me->SetReactState(REACT_DEFENSIVE); @@ -519,7 +519,7 @@ public: uint8 uiWaypoint; - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { if (waypointId == 0) { @@ -592,7 +592,7 @@ public: void UpdateAI(uint32 uiDiff) override { - npc_escortAI::UpdateAI(uiDiff); + EscortAI::UpdateAI(uiDiff); if (!UpdateVictim()) return; diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_black_knight.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_black_knight.cpp index be1c5b69bd8..c64222cc61c 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_black_knight.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_black_knight.cpp @@ -354,18 +354,16 @@ class npc_black_knight_skeletal_gryphon : public CreatureScript public: npc_black_knight_skeletal_gryphon() : CreatureScript("npc_black_knight_skeletal_gryphon") { } - struct npc_black_knight_skeletal_gryphonAI : public npc_escortAI + struct npc_black_knight_skeletal_gryphonAI : public EscortAI { - npc_black_knight_skeletal_gryphonAI(Creature* creature) : npc_escortAI(creature) + npc_black_knight_skeletal_gryphonAI(Creature* creature) : EscortAI(creature) { Start(false, true); } - void WaypointReached(uint32 /*waypointId*/) override { } - void UpdateAI(uint32 uiDiff) override { - npc_escortAI::UpdateAI(uiDiff); + EscortAI::UpdateAI(uiDiff); UpdateVictim(); } diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp index e0d59e6b4d5..fb2e461da0e 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp @@ -114,7 +114,7 @@ void AggroAllPlayers(Creature* temp) temp->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); temp->SetImmuneToPC(true); temp->SetReactState(REACT_AGGRESSIVE); - temp->EngageWithTarget(player); + temp->EngageWithTarget(player); } } } @@ -152,9 +152,9 @@ class generic_vehicleAI_toc5 : public CreatureScript public: generic_vehicleAI_toc5() : CreatureScript("generic_vehicleAI_toc5") { } - struct generic_vehicleAI_toc5AI : public npc_escortAI + struct generic_vehicleAI_toc5AI : public EscortAI { - generic_vehicleAI_toc5AI(Creature* creature) : npc_escortAI(creature) + generic_vehicleAI_toc5AI(Creature* creature) : EscortAI(creature) { Initialize(); SetDespawnAtEnd(false); @@ -212,7 +212,7 @@ public: Start(false, true); } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { switch (waypointId) { @@ -239,7 +239,7 @@ public: void UpdateAI(uint32 uiDiff) override { - npc_escortAI::UpdateAI(uiDiff); + EscortAI::UpdateAI(uiDiff); if (!UpdateVictim()) return; diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/trial_of_the_champion.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/trial_of_the_champion.cpp index efedf67069f..955e7ff313c 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/trial_of_the_champion.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/trial_of_the_champion.cpp @@ -463,7 +463,7 @@ public: instance->GetData(BOSS_ARGENT_CHALLENGE_P) == NOT_STARTED && instance->GetData(BOSS_BLACK_KNIGHT) == NOT_STARTED) AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_START_EVENT1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - else if (instance) + else AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_START_EVENT2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); SendGossipMenuFor(player, player->GetGossipTextId(me), me->GetGUID()); diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp index 72ac4f0e499..4d3f243a4a7 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp @@ -168,7 +168,7 @@ class boss_anubarak_trial : public CreatureScript struct boss_anubarak_trialAI : public BossAI { - boss_anubarak_trialAI(Creature* creature) : BossAI(creature, BOSS_ANUBARAK) + boss_anubarak_trialAI(Creature* creature) : BossAI(creature, DATA_ANUBARAK) { Initialize(); } @@ -223,7 +223,7 @@ class boss_anubarak_trial : public CreatureScript void JustReachedHome() override { - instance->SetBossState(BOSS_ANUBARAK, FAIL); + instance->SetBossState(DATA_ANUBARAK, FAIL); //Summon Scarab Swarms neutral at random places for (int i = 0; i < 10; i++) if (Creature* scarab = me->SummonCreature(NPC_SCARAB, AnubarakLoc[1].GetPositionX()+urand(0, 50)-25, AnubarakLoc[1].GetPositionY()+urand(0, 50)-25, AnubarakLoc[1].GetPositionZ())) @@ -461,8 +461,8 @@ class npc_swarm_scarab : public CreatureScript DoCast(me, SPELL_ACID_MANDIBLE); me->SetInCombatWithZone(); if (me->IsInCombat()) - if (Creature* Anubarak = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(NPC_ANUBARAK))) - Anubarak->AI()->JustSummoned(me); + if (Creature* anubarak = _instance->GetCreature(DATA_ANUBARAK)) + anubarak->AI()->JustSummoned(me); } void DoAction(int32 actionId) override @@ -485,7 +485,7 @@ class npc_swarm_scarab : public CreatureScript void UpdateAI(uint32 diff) override { - if (_instance->GetBossState(BOSS_ANUBARAK) != IN_PROGRESS) + if (_instance->GetBossState(DATA_ANUBARAK) != IN_PROGRESS) me->DisappearAndDie(); if (!UpdateVictim()) @@ -541,8 +541,8 @@ class npc_nerubian_burrower : public CreatureScript DoCast(me, SPELL_AWAKENED); me->SetInCombatWithZone(); if (me->IsInCombat()) - if (Creature* Anubarak = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(NPC_ANUBARAK))) - Anubarak->AI()->JustSummoned(me); + if (Creature* anubarak = _instance->GetCreature(DATA_ANUBARAK)) + anubarak->AI()->JustSummoned(me); } void DoAction(int32 actionId) override @@ -561,7 +561,7 @@ class npc_nerubian_burrower : public CreatureScript void UpdateAI(uint32 diff) override { - if (_instance->GetBossState(BOSS_ANUBARAK) != IN_PROGRESS) + if (_instance->GetBossState(DATA_ANUBARAK) != IN_PROGRESS) me->DisappearAndDie(); if (!UpdateVictim() && !me->HasAura(SPELL_SUBMERGE_EFFECT)) diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp index fc2d5c466cc..be5772f191f 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp @@ -375,12 +375,11 @@ class boss_toc_champion_controller : public CreatureScript public: boss_toc_champion_controller() : CreatureScript("boss_toc_champion_controller") { } - struct boss_toc_champion_controllerAI : public ScriptedAI + struct boss_toc_champion_controllerAI : public BossAI { - boss_toc_champion_controllerAI(Creature* creature) : ScriptedAI(creature), _summons(me) + boss_toc_champion_controllerAI(Creature* creature) : BossAI(creature, DATA_FACTION_CRUSADERS) { Initialize(); - _instance = creature->GetInstanceScript(); } void Initialize() @@ -396,6 +395,8 @@ class boss_toc_champion_controller : public CreatureScript Initialize(); } + void JustSummoned(Creature* /*summon*/) override { } + std::vector<uint32> SelectChampions(Team playerTeam) { std::vector<uint32> vHealersEntries; @@ -415,7 +416,7 @@ class boss_toc_champion_controller : public CreatureScript vOtherEntries.push_back(playerTeam == ALLIANCE ? NPC_HORDE_WARRIOR : NPC_ALLIANCE_WARRIOR); uint8 healersSubtracted = 2; - if (_instance->instance->GetSpawnMode() == RAID_DIFFICULTY_25MAN_NORMAL || _instance->instance->GetSpawnMode() == RAID_DIFFICULTY_25MAN_HEROIC) + if (instance->instance->GetSpawnMode() == RAID_DIFFICULTY_25MAN_NORMAL || instance->instance->GetSpawnMode() == RAID_DIFFICULTY_25MAN_HEROIC) healersSubtracted = 1; for (uint8 i = 0; i < healersSubtracted; ++i) { @@ -452,7 +453,7 @@ class boss_toc_champion_controller : public CreatureScript vHealersEntries.erase(vHealersEntries.begin() + pos); } - if (_instance->instance->GetSpawnMode() == RAID_DIFFICULTY_10MAN_NORMAL || _instance->instance->GetSpawnMode() == RAID_DIFFICULTY_10MAN_HEROIC) + if (instance->instance->GetSpawnMode() == RAID_DIFFICULTY_10MAN_NORMAL || instance->instance->GetSpawnMode() == RAID_DIFFICULTY_10MAN_HEROIC) for (uint8 i = 0; i < 4; ++i) vOtherEntries.erase(vOtherEntries.begin() + urand(0, vOtherEntries.size() - 1)); @@ -486,7 +487,7 @@ class boss_toc_champion_controller : public CreatureScript uint8 pos = urand(0, vChampionJumpTarget.size()-1); if (Creature* champion = me->SummonCreature(vChampionEntries[i], vChampionJumpOrigin[urand(0, vChampionJumpOrigin.size()-1)], TEMPSUMMON_MANUAL_DESPAWN)) { - _summons.Summon(champion); + summons.Summon(champion); champion->SetReactState(REACT_PASSIVE); champion->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); champion->SetImmuneToPC(false); @@ -515,7 +516,7 @@ class boss_toc_champion_controller : public CreatureScript SummonChampions((Team)uiData); break; case 1: - for (SummonList::iterator i = _summons.begin(); i != _summons.end(); ++i) + for (SummonList::iterator i = summons.begin(); i != summons.end(); ++i) { if (Creature* summon = ObjectAccessor::GetCreature(*me, *i)) { @@ -530,10 +531,10 @@ class boss_toc_champion_controller : public CreatureScript { case FAIL: _championsFailed++; - if (_championsFailed + _championsKilled >= _summons.size()) + if (_championsFailed + _championsKilled >= summons.size()) { - _instance->SetBossState(BOSS_CRUSADERS, FAIL); - _summons.DespawnAll(); + instance->SetBossState(DATA_FACTION_CRUSADERS, FAIL); + summons.DespawnAll(); me->DespawnOrUnsummon(); } break; @@ -544,21 +545,23 @@ class boss_toc_champion_controller : public CreatureScript _championsFailed = 0; _championsKilled = 0; _inProgress = true; - _summons.DoZoneInCombat(); - _instance->SetBossState(BOSS_CRUSADERS, IN_PROGRESS); + summons.DoZoneInCombat(); + instance->SetBossState(DATA_FACTION_CRUSADERS, IN_PROGRESS); } break; case DONE: + { _championsKilled++; if (_championsKilled == 1) - _instance->SetBossState(BOSS_CRUSADERS, SPECIAL); - else if (_championsKilled >= _summons.size()) + instance->SetBossState(DATA_FACTION_CRUSADERS, SPECIAL); + else if (_championsKilled >= summons.size()) { - _instance->SetBossState(BOSS_CRUSADERS, DONE); - _summons.DespawnAll(); + instance->SetBossState(DATA_FACTION_CRUSADERS, DONE); + summons.DespawnAll(); me->DespawnOrUnsummon(); } break; + } default: break; } @@ -568,8 +571,6 @@ class boss_toc_champion_controller : public CreatureScript } } private: - InstanceScript* _instance; - SummonList _summons; uint32 _championsNotStarted; uint32 _championsFailed; uint32 _championsKilled; @@ -584,9 +585,10 @@ class boss_toc_champion_controller : public CreatureScript struct boss_faction_championsAI : public BossAI { - boss_faction_championsAI(Creature* creature, uint32 aitype) : BossAI(creature, BOSS_CRUSADERS) + boss_faction_championsAI(Creature* creature, uint32 aitype) : BossAI(creature, DATA_FACTION_CHAMPIONS) { _aiType = aitype; + SetBoundary(instance->GetBossBoundary(DATA_FACTION_CRUSADERS)); } void Reset() override @@ -598,7 +600,7 @@ struct boss_faction_championsAI : public BossAI void JustReachedHome() override { - if (Creature* pChampionController = ObjectAccessor::GetCreature((*me), instance->GetGuidData(NPC_CHAMPIONS_CONTROLLER))) + if (Creature* pChampionController = instance->GetCreature(DATA_FACTION_CRUSADERS)) pChampionController->AI()->SetData(2, FAIL); me->DespawnOrUnsummon(); } @@ -637,15 +639,17 @@ struct boss_faction_championsAI : public BossAI void JustDied(Unit* /*killer*/) override { if (_aiType != AI_PET) - if (Creature* pChampionController = ObjectAccessor::GetCreature((*me), instance->GetGuidData(NPC_CHAMPIONS_CONTROLLER))) + if (Creature* pChampionController = instance->GetCreature(DATA_FACTION_CRUSADERS)) pChampionController->AI()->SetData(2, DONE); } void EnterCombat(Unit* /*who*/) override { DoCast(me, SPELL_ANTI_AOE, true); - _EnterCombat(); - if (Creature* pChampionController = ObjectAccessor::GetCreature((*me), instance->GetGuidData(NPC_CHAMPIONS_CONTROLLER))) + me->SetCombatPulseDelay(5); + me->setActive(true); + DoZoneInCombat(); + if (Creature* pChampionController = instance->GetCreature(DATA_FACTION_CRUSADERS)) pChampionController->AI()->SetData(2, IN_PROGRESS); } @@ -662,11 +666,11 @@ struct boss_faction_championsAI : public BossAI if (TeamInInstance == ALLIANCE) { - if (Creature* varian = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_VARIAN))) + if (Creature* varian = instance->GetCreature(DATA_VARIAN)) varian->AI()->Talk(SAY_KILL_PLAYER); } else - if (Creature* garrosh = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_GARROSH))) + if (Creature* garrosh = instance->GetCreature(DATA_GARROSH)) garrosh->AI()->Talk(SAY_KILL_PLAYER); } diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp index 8f50ed0e365..8b32acdadb5 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp @@ -102,7 +102,7 @@ class boss_jaraxxus : public CreatureScript struct boss_jaraxxusAI : public BossAI { - boss_jaraxxusAI(Creature* creature) : BossAI(creature, BOSS_JARAXXUS) { } + boss_jaraxxusAI(Creature* creature) : BossAI(creature, DATA_JARAXXUS) { } void Reset() override { @@ -119,7 +119,7 @@ class boss_jaraxxus : public CreatureScript void JustReachedHome() override { _JustReachedHome(); - instance->SetBossState(BOSS_JARAXXUS, FAIL); + instance->SetBossState(DATA_JARAXXUS, FAIL); DoCast(me, SPELL_JARAXXUS_CHAINS); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); me->SetImmuneToPC(true); @@ -238,7 +238,7 @@ class npc_legion_flame : public CreatureScript void UpdateAI(uint32 /*diff*/) override { UpdateVictim(); - if (_instance->GetBossState(BOSS_JARAXXUS) != IN_PROGRESS) + if (_instance->GetBossState(DATA_JARAXXUS) != IN_PROGRESS) me->DespawnOrUnsummon(); } private: @@ -330,7 +330,7 @@ class npc_fel_infernal : public CreatureScript void UpdateAI(uint32 diff) override { - if (_instance->GetBossState(BOSS_JARAXXUS) != IN_PROGRESS) + if (_instance->GetBossState(DATA_JARAXXUS) != IN_PROGRESS) { me->DespawnOrUnsummon(); return; @@ -438,7 +438,7 @@ class npc_mistress_of_pain : public CreatureScript void UpdateAI(uint32 diff) override { - if (_instance->GetBossState(BOSS_JARAXXUS) != IN_PROGRESS) + if (_instance->GetBossState(DATA_JARAXXUS) != IN_PROGRESS) { me->DespawnOrUnsummon(); return; diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp index 17ce9458905..772edda63c6 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp @@ -179,7 +179,10 @@ class boss_gormok : public CreatureScript struct boss_gormokAI : public BossAI { - boss_gormokAI(Creature* creature) : BossAI(creature, BOSS_BEASTS) { } + boss_gormokAI(Creature* creature) : BossAI(creature, DATA_GORMOK_THE_IMPALER) + { + SetBoundary(instance->GetBossBoundary(DATA_NORTHREND_BEASTS)); + } void Reset() override { @@ -192,7 +195,7 @@ class boss_gormok : public CreatureScript void EnterEvadeMode(EvadeReason why) override { - instance->DoUseDoorOrButton(instance->GetGuidData(GO_MAIN_GATE_DOOR)); + instance->DoUseDoorOrButton(instance->GetGuidData(DATA_MAIN_GATE)); ScriptedAI::EnterEvadeMode(why); } @@ -204,7 +207,7 @@ class boss_gormok : public CreatureScript switch (pointId) { case 0: - instance->DoUseDoorOrButton(instance->GetGuidData(GO_MAIN_GATE_DOOR)); + instance->DoUseDoorOrButton(instance->GetGuidData(DATA_MAIN_GATE)); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); me->SetImmuneToPC(false); me->SetReactState(REACT_AGGRESSIVE); @@ -222,7 +225,7 @@ class boss_gormok : public CreatureScript void JustReachedHome() override { - instance->DoUseDoorOrButton(instance->GetGuidData(GO_MAIN_GATE_DOOR)); + instance->DoUseDoorOrButton(instance->GetGuidData(DATA_MAIN_GATE)); instance->SetData(TYPE_NORTHREND_BEASTS, FAIL); me->DespawnOrUnsummon(); @@ -230,8 +233,11 @@ class boss_gormok : public CreatureScript void EnterCombat(Unit* /*who*/) override { - _EnterCombat(); + me->SetCombatPulseDelay(5); + me->setActive(true); + //DoZoneInCombat(); instance->SetData(TYPE_NORTHREND_BEASTS, GORMOK_IN_PROGRESS); + instance->SetBossState(DATA_NORTHREND_BEASTS, IN_PROGRESS); } void DamageTaken(Unit* /*who*/, uint32& damage) override @@ -387,7 +393,7 @@ class npc_snobold_vassal : public CreatureScript void MountOnBoss() { - Unit* gormok = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(NPC_GORMOK)); + Unit* gormok = _instance->GetCreature(DATA_GORMOK_THE_IMPALER); if (gormok && gormok->IsAlive()) { me->AttackStop(); @@ -511,7 +517,7 @@ class npc_firebomb : public CreatureScript struct boss_jormungarAI : public BossAI { - boss_jormungarAI(Creature* creature) : BossAI(creature, BOSS_BEASTS) + boss_jormungarAI(Creature* creature, uint32 bossId) : BossAI(creature, bossId) { OtherWormEntry = 0; ModelStationary = 0; @@ -525,6 +531,7 @@ struct boss_jormungarAI : public BossAI Phase = PHASE_MOBILE; Enraged = false; WasMobile = false; + SetBoundary(instance->GetBossBoundary(DATA_NORTHREND_BEASTS)); } void Reset() override @@ -539,9 +546,14 @@ struct boss_jormungarAI : public BossAI events.ScheduleEvent(EVENT_SLIME_POOL, 15*IN_MILLISECONDS, 0, PHASE_MOBILE); } + uint32 GetOtherWormData(uint32 wormEntry) + { + return wormEntry == NPC_ACIDMAW ? DATA_ACIDMAW : DATA_DREADSCALE; + } + void JustDied(Unit* /*killer*/) override { - if (Creature* otherWorm = ObjectAccessor::GetCreature(*me, instance->GetGuidData(OtherWormEntry))) + if (Creature* otherWorm = instance->GetCreature(GetOtherWormData(OtherWormEntry))) { if (!otherWorm->IsAlive()) { @@ -714,7 +726,7 @@ class boss_acidmaw : public CreatureScript struct boss_acidmawAI : public boss_jormungarAI { - boss_acidmawAI(Creature* creature) : boss_jormungarAI(creature) { } + boss_acidmawAI(Creature* creature) : boss_jormungarAI(creature, DATA_ACIDMAW) { } void Reset() override { @@ -745,7 +757,7 @@ class boss_dreadscale : public CreatureScript struct boss_dreadscaleAI : public boss_jormungarAI { - boss_dreadscaleAI(Creature* creature) : boss_jormungarAI(creature) { } + boss_dreadscaleAI(Creature* creature) : boss_jormungarAI(creature, DATA_DREADSCALE) { } void Reset() override { @@ -772,7 +784,7 @@ class boss_dreadscale : public CreatureScript switch (pointId) { case 0: - instance->DoCloseDoorOrButton(instance->GetGuidData(GO_MAIN_GATE_DOOR)); + instance->DoCloseDoorOrButton(instance->GetGuidData(DATA_MAIN_GATE)); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); me->SetImmuneToPC(false); me->SetReactState(REACT_AGGRESSIVE); @@ -785,13 +797,13 @@ class boss_dreadscale : public CreatureScript void EnterEvadeMode(EvadeReason why) override { - instance->DoUseDoorOrButton(instance->GetGuidData(GO_MAIN_GATE_DOOR)); + instance->DoUseDoorOrButton(instance->GetGuidData(DATA_MAIN_GATE)); boss_jormungarAI::EnterEvadeMode(why); } void JustReachedHome() override { - instance->DoUseDoorOrButton(instance->GetGuidData(GO_MAIN_GATE_DOOR)); + instance->DoUseDoorOrButton(instance->GetGuidData(DATA_MAIN_GATE)); boss_jormungarAI::JustReachedHome(); } @@ -887,9 +899,10 @@ class boss_icehowl : public CreatureScript struct boss_icehowlAI : public BossAI { - boss_icehowlAI(Creature* creature) : BossAI(creature, BOSS_BEASTS) + boss_icehowlAI(Creature* creature) : BossAI(creature, DATA_ICEHOWL) { Initialize(); + SetBoundary(instance->GetBossBoundary(DATA_NORTHREND_BEASTS)); } void Initialize() @@ -946,7 +959,7 @@ class boss_icehowl : public CreatureScript _movementFinish = true; break; case 2: - instance->DoUseDoorOrButton(instance->GetGuidData(GO_MAIN_GATE_DOOR)); + instance->DoUseDoorOrButton(instance->GetGuidData(DATA_MAIN_GATE)); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); me->SetImmuneToPC(false); me->SetReactState(REACT_AGGRESSIVE); @@ -959,13 +972,13 @@ class boss_icehowl : public CreatureScript void EnterEvadeMode(EvadeReason why) override { - instance->DoUseDoorOrButton(instance->GetGuidData(GO_MAIN_GATE_DOOR)); + instance->DoUseDoorOrButton(instance->GetGuidData(DATA_MAIN_GATE)); ScriptedAI::EnterEvadeMode(why); } void JustReachedHome() override { - instance->DoUseDoorOrButton(instance->GetGuidData(GO_MAIN_GATE_DOOR)); + instance->DoUseDoorOrButton(instance->GetGuidData(DATA_MAIN_GATE)); instance->SetData(TYPE_NORTHREND_BEASTS, FAIL); me->DespawnOrUnsummon(); } diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp index 49bd28f7e56..7050f20c1c9 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp @@ -158,9 +158,14 @@ class OrbsDespawner : public BasicEvent Creature* _creature; }; +static uint32 GetSisterData(uint32 sisterEntry) +{ + return sisterEntry == NPC_FJOLA_LIGHTBANE ? DATA_FJOLA_LIGHTBANE : DATA_EYDIS_DARKBANE; +} + struct boss_twin_baseAI : public BossAI { - boss_twin_baseAI(Creature* creature) : BossAI(creature, BOSS_VALKIRIES) + boss_twin_baseAI(Creature* creature, uint32 bossId) : BossAI(creature, bossId) { AuraState = AURA_STATE_NONE; Weapon = 0; @@ -173,6 +178,7 @@ struct boss_twin_baseAI : public BossAI TwinPactSpellId = 0; SpikeSpellId = 0; TouchSpellId = 0; + SetBoundary(instance->GetBossBoundary(DATA_TWIN_VALKIRIES)); } void Reset() override @@ -189,7 +195,7 @@ struct boss_twin_baseAI : public BossAI void JustReachedHome() override { - instance->SetBossState(BOSS_VALKIRIES, FAIL); + instance->SetBossState(DATA_TWIN_VALKIRIES, FAIL); summons.DespawnAll(); me->DespawnOrUnsummon(); @@ -248,12 +254,14 @@ struct boss_twin_baseAI : public BossAI { me->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); pSister->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); - _JustDied(); + events.Reset(); + summons.DespawnAll(); + instance->SetBossState(DATA_TWIN_VALKIRIES, DONE); } else { me->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); - instance->SetBossState(BOSS_VALKIRIES, SPECIAL); + instance->SetBossState(DATA_TWIN_VALKIRIES, SPECIAL); } } summons.DespawnAll(); @@ -262,7 +270,7 @@ struct boss_twin_baseAI : public BossAI // Called when sister pointer needed Creature* GetSister() { - return ObjectAccessor::GetCreature((*me), instance->GetGuidData(SisterNpcId)); + return instance->GetCreature(GetSisterData(SisterNpcId)); } void EnterCombat(Unit* /*who*/) override @@ -273,10 +281,12 @@ struct boss_twin_baseAI : public BossAI me->AddAura(MyEmphatySpellId, pSister); pSister->SetInCombatWithZone(); } - instance->SetBossState(BOSS_VALKIRIES, IN_PROGRESS); + instance->SetBossState(DATA_TWIN_VALKIRIES, IN_PROGRESS); Talk(SAY_AGGRO); DoCast(me, SurgeSpellId); + me->SetCombatPulseDelay(5); + me->setActive(true); events.ScheduleEvent(EVENT_TWIN_SPIKE, 20 * IN_MILLISECONDS); events.ScheduleEvent(EVENT_BERSERK, IsHeroic() ? 6 * MINUTE*IN_MILLISECONDS : 10 * MINUTE*IN_MILLISECONDS); @@ -354,7 +364,7 @@ class boss_fjola : public CreatureScript struct boss_fjolaAI : public boss_twin_baseAI { - boss_fjolaAI(Creature* creature) : boss_twin_baseAI(creature) + boss_fjolaAI(Creature* creature) : boss_twin_baseAI(creature, DATA_FJOLA_LIGHTBANE) { GenerateStageSequence(); } @@ -364,7 +374,7 @@ class boss_fjola : public CreatureScript SetEquipmentSlots(false, EQUIP_MAIN_1, EQUIP_UNEQUIP, EQUIP_NO_CHANGE); Weapon = EQUIP_MAIN_1; AuraState = AURA_STATE_UNKNOWN22; - SisterNpcId = NPC_DARKBANE; + SisterNpcId = NPC_EYDIS_DARKBANE; MyEmphatySpellId = SPELL_TWIN_EMPATHY_DARK; OtherEssenceSpellId = SPELL_DARK_ESSENCE_HELPER; SurgeSpellId = SPELL_LIGHT_SURGE; @@ -421,13 +431,13 @@ class boss_fjola : public CreatureScript void EnterEvadeMode(EvadeReason why) override { - instance->DoUseDoorOrButton(instance->GetGuidData(GO_MAIN_GATE_DOOR)); + instance->DoUseDoorOrButton(instance->GetGuidData(DATA_MAIN_GATE)); boss_twin_baseAI::EnterEvadeMode(why); } void JustReachedHome() override { - instance->DoUseDoorOrButton(instance->GetGuidData(GO_MAIN_GATE_DOOR)); + instance->DoUseDoorOrButton(instance->GetGuidData(DATA_MAIN_GATE)); boss_twin_baseAI::JustReachedHome(); } @@ -465,14 +475,14 @@ class boss_eydis : public CreatureScript struct boss_eydisAI : public boss_twin_baseAI { - boss_eydisAI(Creature* creature) : boss_twin_baseAI(creature) { } + boss_eydisAI(Creature* creature) : boss_twin_baseAI(creature, DATA_EYDIS_DARKBANE) { } void Reset() override { SetEquipmentSlots(false, EQUIP_MAIN_2, EQUIP_UNEQUIP, EQUIP_NO_CHANGE); Weapon = EQUIP_MAIN_2; AuraState = AURA_STATE_UNKNOWN19; - SisterNpcId = NPC_LIGHTBANE; + SisterNpcId = NPC_FJOLA_LIGHTBANE; MyEmphatySpellId = SPELL_TWIN_EMPATHY_LIGHT; OtherEssenceSpellId = SPELL_LIGHT_ESSENCE_HELPER; SurgeSpellId = SPELL_DARK_SURGE; @@ -860,8 +870,8 @@ class spell_power_of_the_twins : public SpellScriptLoader { if (InstanceScript* instance = GetCaster()->GetInstanceScript()) { - if (Creature* Valk = ObjectAccessor::GetCreature(*GetCaster(), instance->GetGuidData(GetCaster()->GetEntry()))) - ENSURE_AI(boss_twin_baseAI, Valk->AI())->EnableDualWield(true); + if (Creature* valk = instance->GetCreature(GetSisterData(GetCaster()->GetEntry()))) + ENSURE_AI(boss_twin_baseAI, valk->AI())->EnableDualWield(true); } } @@ -869,8 +879,8 @@ class spell_power_of_the_twins : public SpellScriptLoader { if (InstanceScript* instance = GetCaster()->GetInstanceScript()) { - if (Creature* Valk = ObjectAccessor::GetCreature(*GetCaster(), instance->GetGuidData(GetCaster()->GetEntry()))) - ENSURE_AI(boss_twin_baseAI, Valk->AI())->EnableDualWield(false); + if (Creature* valk = instance->GetCreature(GetSisterData(GetCaster()->GetEntry()))) + ENSURE_AI(boss_twin_baseAI, valk->AI())->EnableDualWield(false); } } diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp index 506f076be33..28891678aef 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp @@ -29,11 +29,53 @@ BossBoundaryData const boundaries = { - { BOSS_BEASTS, new CircleBoundary(Position(563.26f, 139.6f), 75.0) }, - { BOSS_JARAXXUS, new CircleBoundary(Position(563.26f, 139.6f), 75.0) }, - { BOSS_CRUSADERS, new CircleBoundary(Position(563.26f, 139.6f), 75.0) }, - { BOSS_VALKIRIES, new CircleBoundary(Position(563.26f, 139.6f), 75.0) }, - { BOSS_ANUBARAK, new EllipseBoundary(Position(746.0f, 135.0f), 100.0, 75.0) } + { DATA_NORTHREND_BEASTS, new CircleBoundary(Position(563.26f, 139.6f), 75.0) }, + { DATA_JARAXXUS, new CircleBoundary(Position(563.26f, 139.6f), 75.0) }, + { DATA_FACTION_CRUSADERS, new CircleBoundary(Position(563.26f, 139.6f), 75.0) }, + { DATA_TWIN_VALKIRIES, new CircleBoundary(Position(563.26f, 139.6f), 75.0) }, + { DATA_ANUBARAK, new EllipseBoundary(Position(746.0f, 135.0f), 100.0, 75.0) } +}; + +ObjectData const creatureData[] = +{ + { NPC_GORMOK, DATA_GORMOK_THE_IMPALER }, + { NPC_ACIDMAW, DATA_ACIDMAW }, + { NPC_DREADSCALE, DATA_DREADSCALE }, + { NPC_ICEHOWL, DATA_ICEHOWL }, + { NPC_JARAXXUS, DATA_JARAXXUS }, + { NPC_CHAMPIONS_CONTROLLER, DATA_FACTION_CRUSADERS }, + { NPC_FJOLA_LIGHTBANE, DATA_FJOLA_LIGHTBANE }, + { NPC_EYDIS_DARKBANE, DATA_EYDIS_DARKBANE }, + { NPC_LICH_KING, DATA_LICH_KING }, + { NPC_ANUBARAK, DATA_ANUBARAK }, + { NPC_BARRET_RAMSEY, DATA_BARRET_RAMSEY }, + { NPC_TIRION_FORDRING, DATA_FORDRING }, + { NPC_TIRION_FORDRING_ANUBARAK, DATA_FORDRING_ANUBARAK }, + { NPC_VARIAN, DATA_VARIAN }, + { NPC_GARROSH, DATA_GARROSH }, + { NPC_FIZZLEBANG, DATA_FIZZLEBANG }, + { 0, 0 } // END +}; + +ObjectData const gameObjectData[] = +{ + { GO_CRUSADERS_CACHE_10, DATA_CRUSADERS_CHEST }, + { GO_CRUSADERS_CACHE_25, DATA_CRUSADERS_CHEST }, + { GO_CRUSADERS_CACHE_10_H, DATA_CRUSADERS_CHEST }, + { GO_CRUSADERS_CACHE_25_H, DATA_CRUSADERS_CHEST }, + { GO_ARGENT_COLISEUM_FLOOR, DATA_COLISEUM_FLOOR }, + { GO_MAIN_GATE_DOOR, DATA_MAIN_GATE }, + { GO_EAST_PORTCULLIS, DATA_EAST_PORTCULLIS }, + { GO_WEB_DOOR, DATA_WEB_DOOR }, + { GO_TRIBUTE_CHEST_10H_25, DATA_TRIBUTE_CHEST }, + { GO_TRIBUTE_CHEST_10H_45, DATA_TRIBUTE_CHEST }, + { GO_TRIBUTE_CHEST_10H_50, DATA_TRIBUTE_CHEST }, + { GO_TRIBUTE_CHEST_10H_99, DATA_TRIBUTE_CHEST }, + { GO_TRIBUTE_CHEST_25H_25, DATA_TRIBUTE_CHEST }, + { GO_TRIBUTE_CHEST_25H_45, DATA_TRIBUTE_CHEST }, + { GO_TRIBUTE_CHEST_25H_50, DATA_TRIBUTE_CHEST }, + { GO_TRIBUTE_CHEST_25H_99, DATA_TRIBUTE_CHEST }, + { 0, 0 } // END }; class instance_trial_of_the_crusader : public InstanceMapScript @@ -46,8 +88,9 @@ class instance_trial_of_the_crusader : public InstanceMapScript instance_trial_of_the_crusader_InstanceMapScript(Map* map) : InstanceScript(map) { SetHeaders(DataHeader); - SetBossNumber(MAX_ENCOUNTERS); + SetBossNumber(EncounterCount); LoadBossBoundaries(boundaries); + LoadObjectData(creatureData, gameObjectData); TrialCounter = 50; EventStage = 0; NorthrendBeasts = NOT_STARTED; @@ -62,12 +105,12 @@ class instance_trial_of_the_crusader : public InstanceMapScript bool IsEncounterInProgress() const override { - for (uint8 i = 0; i < MAX_ENCOUNTERS; ++i) + for (uint8 i = 0; i < EncounterCount; ++i) if (GetBossState(i) == IN_PROGRESS) return true; // Special state is set at Faction Champions after first champ dead, encounter is still in combat - if (GetBossState(BOSS_CRUSADERS) == SPECIAL) + if (GetBossState(DATA_FACTION_CRUSADERS) == SPECIAL) return true; return false; @@ -84,8 +127,8 @@ class instance_trial_of_the_crusader : public InstanceMapScript player->SendUpdateWorldState(UPDATE_STATE_UI_SHOW, 0); // make sure Anub'arak isnt missing - if (GetBossState(BOSS_LICH_KING) == DONE && TrialCounter && GetBossState(BOSS_ANUBARAK) != DONE) - if (!ObjectAccessor::GetCreature(*player, GetGuidData(NPC_ANUBARAK))) + if (GetBossState(DATA_LICH_KING) == DONE && TrialCounter && GetBossState(DATA_ANUBARAK) != DONE) + if (!GetCreature(DATA_ANUBARAK)) player->SummonCreature(NPC_ANUBARAK, AnubarakLoc[0], TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME); } @@ -109,100 +152,18 @@ class instance_trial_of_the_crusader : public InstanceMapScript void OnCreatureCreate(Creature* creature) override { - switch (creature->GetEntry()) - { - case NPC_BARRENT: - BarrentGUID = creature->GetGUID(); - if (!TrialCounter) - creature->DespawnOrUnsummon(); - break; - case NPC_TIRION: - TirionGUID = creature->GetGUID(); - break; - case NPC_TIRION_FORDRING: - TirionFordringGUID = creature->GetGUID(); - break; - case NPC_FIZZLEBANG: - FizzlebangGUID = creature->GetGUID(); - break; - case NPC_GARROSH: - GarroshGUID = creature->GetGUID(); - break; - case NPC_VARIAN: - VarianGUID = creature->GetGUID(); - break; - - case NPC_GORMOK: - GormokGUID = creature->GetGUID(); - break; - case NPC_ACIDMAW: - AcidmawGUID = creature->GetGUID(); - break; - case NPC_DREADSCALE: - DreadscaleGUID = creature->GetGUID(); - break; - case NPC_ICEHOWL: - IcehowlGUID = creature->GetGUID(); - break; - case NPC_JARAXXUS: - JaraxxusGUID = creature->GetGUID(); - break; - case NPC_CHAMPIONS_CONTROLLER: - ChampionsControllerGUID = creature->GetGUID(); - break; - case NPC_DARKBANE: - DarkbaneGUID = creature->GetGUID(); - break; - case NPC_LIGHTBANE: - LightbaneGUID = creature->GetGUID(); - break; - case NPC_ANUBARAK: - AnubarakGUID = creature->GetGUID(); - creature->SetRespawnDelay(7 * DAY); - break; - default: - break; - } + InstanceScript::OnCreatureCreate(creature); + if (creature->GetEntry() == NPC_BARRET_RAMSEY) + if (!TrialCounter) + creature->DespawnOrUnsummon(); } void OnGameObjectCreate(GameObject* go) override { - switch (go->GetEntry()) - { - case GO_CRUSADERS_CACHE_10: - case GO_CRUSADERS_CACHE_25: - case GO_CRUSADERS_CACHE_10_H: - case GO_CRUSADERS_CACHE_25_H: - CrusadersCacheGUID = go->GetGUID(); - break; - case GO_ARGENT_COLISEUM_FLOOR: - FloorGUID = go->GetGUID(); - if (GetBossState(BOSS_LICH_KING) == DONE) - go->SetDestructibleState(GO_DESTRUCTIBLE_DAMAGED); - break; - case GO_MAIN_GATE_DOOR: - MainGateDoorGUID = go->GetGUID(); - break; - case GO_EAST_PORTCULLIS: - EastPortcullisGUID = go->GetGUID(); - break; - case GO_WEB_DOOR: - WebDoorGUID = go->GetGUID(); - break; - - case GO_TRIBUTE_CHEST_10H_25: - case GO_TRIBUTE_CHEST_10H_45: - case GO_TRIBUTE_CHEST_10H_50: - case GO_TRIBUTE_CHEST_10H_99: - case GO_TRIBUTE_CHEST_25H_25: - case GO_TRIBUTE_CHEST_25H_45: - case GO_TRIBUTE_CHEST_25H_50: - case GO_TRIBUTE_CHEST_25H_99: - TributeChestGUID = go->GetGUID(); - break; - default: - break; - } + InstanceScript::OnGameObjectCreate(go); + if (go->GetEntry() == GO_ARGENT_COLISEUM_FLOOR) + if (GetBossState(DATA_LICH_KING) == DONE) + go->SetDestructibleState(GO_DESTRUCTIBLE_DAMAGED); } void OnUnitDeath(Unit* unit) override @@ -219,20 +180,20 @@ class instance_trial_of_the_crusader : public InstanceMapScript switch (type) { - case BOSS_BEASTS: + case DATA_NORTHREND_BEASTS: break; - case BOSS_JARAXXUS: + case DATA_JARAXXUS: // Cleanup Icehowl - if (Creature* icehowl = instance->GetCreature(IcehowlGUID)) + if (Creature* icehowl = GetCreature(DATA_ICEHOWL)) icehowl->DespawnOrUnsummon(); if (state == DONE) EventStage = 2000; break; - case BOSS_CRUSADERS: + case DATA_FACTION_CRUSADERS: // Cleanup Jaraxxus - if (Creature* jaraxxus = instance->GetCreature(JaraxxusGUID)) + if (Creature* jaraxxus = GetCreature(DATA_JARAXXUS)) jaraxxus->DespawnOrUnsummon(); - if (Creature* fizzlebang = instance->GetCreature(FizzlebangGUID)) + if (Creature* fizzlebang = GetCreature(DATA_FIZZLEBANG)) fizzlebang->DespawnOrUnsummon(); switch (state) { @@ -247,8 +208,8 @@ class instance_trial_of_the_crusader : public InstanceMapScript DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, SPELL_DEFEAT_FACTION_CHAMPIONS); if (ResilienceWillFixItTimer > 0) DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, SPELL_CHAMPIONS_KILLED_IN_MINUTE); - DoRespawnGameObject(CrusadersCacheGUID, 7*DAY); - if (GameObject* cache = instance->GetGameObject(CrusadersCacheGUID)) + DoRespawnGameObject(GetGuidData(DATA_CRUSADERS_CHEST), 7*DAY); + if (GameObject* cache = GetGameObject(DATA_CRUSADERS_CHEST)) cache->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); EventStage = 3100; break; @@ -256,27 +217,27 @@ class instance_trial_of_the_crusader : public InstanceMapScript break; } break; - case BOSS_VALKIRIES: + case DATA_TWIN_VALKIRIES: // Cleanup chest - if (GameObject* cache = instance->GetGameObject(CrusadersCacheGUID)) + if (GameObject* cache = GetGameObject(DATA_CRUSADERS_CHEST)) cache->Delete(); switch (state) { case FAIL: - if (GetBossState(BOSS_VALKIRIES) == NOT_STARTED) + if (GetBossState(DATA_TWIN_VALKIRIES) == NOT_STARTED) state = NOT_STARTED; break; case SPECIAL: - if (GetBossState(BOSS_VALKIRIES) == SPECIAL) + if (GetBossState(DATA_TWIN_VALKIRIES) == SPECIAL) state = DONE; break; default: break; } break; - case BOSS_LICH_KING: + case DATA_LICH_KING: break; - case BOSS_ANUBARAK: + case DATA_ANUBARAK: switch (state) { case DONE: @@ -319,7 +280,7 @@ class instance_trial_of_the_crusader : public InstanceMapScript } if (tributeChest) - if (Creature* tirion = instance->GetCreature(TirionGUID)) + if (Creature* tirion = GetCreature(DATA_FORDRING)) if (GameObject* chest = tirion->SummonGameObject(tributeChest, 805.62f, 134.87f, 142.16f, 3.27f, QuaternionData(), WEEK)) chest->SetRespawnTime(chest->GetRespawnDelay()); break; @@ -334,16 +295,16 @@ class instance_trial_of_the_crusader : public InstanceMapScript if (IsEncounterInProgress()) { - CloseDoor(GetGuidData(GO_EAST_PORTCULLIS)); - CloseDoor(GetGuidData(GO_WEB_DOOR)); + CloseDoor(GetGuidData(DATA_EAST_PORTCULLIS)); + CloseDoor(GetGuidData(DATA_WEB_DOOR)); } else { - OpenDoor(GetGuidData(GO_EAST_PORTCULLIS)); - OpenDoor(GetGuidData(GO_WEB_DOOR)); + OpenDoor(GetGuidData(DATA_EAST_PORTCULLIS)); + OpenDoor(GetGuidData(DATA_WEB_DOOR)); } - if (type < MAX_ENCOUNTERS) + if (type < EncounterCount) { TC_LOG_DEBUG("scripts", "[ToCr] BossState(type %u) %u = state %u;", type, GetBossState(type), state); if (state == FAIL) @@ -360,21 +321,21 @@ class instance_trial_of_the_crusader : public InstanceMapScript // if theres no more attemps allowed if (!TrialCounter) { - if (Unit* announcer = instance->GetCreature(GetGuidData(NPC_BARRENT))) + if (Unit* announcer = GetCreature(DATA_BARRET_RAMSEY)) announcer->ToCreature()->DespawnOrUnsummon(); - if (Creature* anubArak = instance->GetCreature(GetGuidData(NPC_ANUBARAK))) - anubArak->DespawnOrUnsummon(); + if (Creature* anubarak = GetCreature(DATA_ANUBARAK)) + anubarak->DespawnOrUnsummon(); } } NeedSave = true; - EventStage = (type == BOSS_BEASTS ? 666 : 0); + EventStage = (type == DATA_NORTHREND_BEASTS ? 666 : 0); state = NOT_STARTED; } if (state == DONE || NeedSave) { - if (Unit* announcer = instance->GetCreature(GetGuidData(NPC_BARRENT))) + if (Unit* announcer = GetCreature(DATA_BARRET_RAMSEY)) announcer->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); Save(); } @@ -421,10 +382,10 @@ class instance_trial_of_the_crusader : public InstanceMapScript case ICEHOWL_DONE: EventStage = 400; SetData(TYPE_NORTHREND_BEASTS, DONE); - SetBossState(BOSS_BEASTS, DONE); + SetBossState(DATA_NORTHREND_BEASTS, DONE); break; case FAIL: - SetBossState(BOSS_BEASTS, FAIL); + SetBossState(DATA_NORTHREND_BEASTS, FAIL); break; default: break; @@ -448,57 +409,6 @@ class instance_trial_of_the_crusader : public InstanceMapScript } } - ObjectGuid GetGuidData(uint32 type) const override - { - switch (type) - { - case NPC_BARRENT: - return BarrentGUID; - case NPC_TIRION: - return TirionGUID; - case NPC_TIRION_FORDRING: - return TirionFordringGUID; - case NPC_FIZZLEBANG: - return FizzlebangGUID; - case NPC_GARROSH: - return GarroshGUID; - case NPC_VARIAN: - return VarianGUID; - - case NPC_GORMOK: - return GormokGUID; - case NPC_ACIDMAW: - return AcidmawGUID; - case NPC_DREADSCALE: - return DreadscaleGUID; - case NPC_ICEHOWL: - return IcehowlGUID; - case NPC_JARAXXUS: - return JaraxxusGUID; - case NPC_CHAMPIONS_CONTROLLER: - return ChampionsControllerGUID; - case NPC_DARKBANE: - return DarkbaneGUID; - case NPC_LIGHTBANE: - return LightbaneGUID; - case NPC_ANUBARAK: - return AnubarakGUID; - - case GO_ARGENT_COLISEUM_FLOOR: - return FloorGUID; - case GO_MAIN_GATE_DOOR: - return MainGateDoorGUID; - case GO_EAST_PORTCULLIS: - return EastPortcullisGUID; - case GO_WEB_DOOR: - return WebDoorGUID; - default: - break; - } - - return ObjectGuid::Empty; - } - uint32 GetData(uint32 type) const override { switch (type) @@ -553,7 +463,7 @@ class instance_trial_of_the_crusader : public InstanceMapScript case 6000: case 6005: case 6010: - return NPC_TIRION; + return NPC_TIRION_FORDRING; break; case 5010: case 5030: @@ -595,7 +505,7 @@ class instance_trial_of_the_crusader : public InstanceMapScript return NPC_FIZZLEBANG; break; default: - return NPC_TIRION; + return NPC_TIRION_FORDRING; break; }; default: @@ -615,7 +525,7 @@ class instance_trial_of_the_crusader : public InstanceMapScript NotOneButTwoJormungarsTimer -= diff; } - if (GetBossState(BOSS_CRUSADERS) == SPECIAL && ResilienceWillFixItTimer) + if (GetBossState(DATA_FACTION_CRUSADERS) == SPECIAL && ResilienceWillFixItTimer) { if (ResilienceWillFixItTimer <= diff) ResilienceWillFixItTimer = 0; @@ -630,7 +540,7 @@ class instance_trial_of_the_crusader : public InstanceMapScript std::ostringstream saveStream; - for (uint8 i = 0; i < MAX_ENCOUNTERS; ++i) + for (uint8 i = 0; i < EncounterCount; ++i) saveStream << GetBossState(i) << ' '; saveStream << TrialCounter; @@ -658,7 +568,7 @@ class instance_trial_of_the_crusader : public InstanceMapScript std::istringstream loadStream(strIn); - for (uint8 i = 0; i < MAX_ENCOUNTERS; ++i) + for (uint8 i = 0; i < EncounterCount; ++i) { uint32 tmpState; loadStream >> tmpState; @@ -718,30 +628,6 @@ class instance_trial_of_the_crusader : public InstanceMapScript bool NeedSave; std::string SaveDataBuffer; - ObjectGuid BarrentGUID; - ObjectGuid TirionGUID; - ObjectGuid TirionFordringGUID; - ObjectGuid FizzlebangGUID; - ObjectGuid GarroshGUID; - ObjectGuid VarianGUID; - - ObjectGuid GormokGUID; - ObjectGuid AcidmawGUID; - ObjectGuid DreadscaleGUID; - ObjectGuid IcehowlGUID; - ObjectGuid JaraxxusGUID; - ObjectGuid ChampionsControllerGUID; - ObjectGuid DarkbaneGUID; - ObjectGuid LightbaneGUID; - ObjectGuid AnubarakGUID; - - ObjectGuid CrusadersCacheGUID; - ObjectGuid FloorGUID; - ObjectGuid TributeChestGUID; - ObjectGuid MainGateDoorGUID; - ObjectGuid EastPortcullisGUID; - ObjectGuid WebDoorGUID; - // Achievement stuff uint32 NotOneButTwoJormungarsTimer; uint32 ResilienceWillFixItTimer; diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp index fdc93f56c39..de24ab4a352 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp @@ -164,12 +164,12 @@ struct _Messages static _Messages _GossipMessage[]= { - {MSG_BEASTS, GOSSIP_ACTION_INFO_DEF + 1, false, BOSS_BEASTS}, - {MSG_JARAXXUS, GOSSIP_ACTION_INFO_DEF + 2, false, BOSS_JARAXXUS}, - {MSG_CRUSADERS, GOSSIP_ACTION_INFO_DEF + 3, false, BOSS_CRUSADERS}, - {MSG_VALKIRIES, GOSSIP_ACTION_INFO_DEF + 4, false, BOSS_VALKIRIES}, - {MSG_LICH_KING, GOSSIP_ACTION_INFO_DEF + 5, false, BOSS_ANUBARAK}, - {MSG_ANUBARAK, GOSSIP_ACTION_INFO_DEF + 6, true, BOSS_ANUBARAK} + {MSG_BEASTS, GOSSIP_ACTION_INFO_DEF + 1, false, DATA_NORTHREND_BEASTS}, + {MSG_JARAXXUS, GOSSIP_ACTION_INFO_DEF + 2, false, DATA_JARAXXUS}, + {MSG_CRUSADERS, GOSSIP_ACTION_INFO_DEF + 3, false, DATA_FACTION_CRUSADERS}, + {MSG_VALKIRIES, GOSSIP_ACTION_INFO_DEF + 4, false, DATA_TWIN_VALKIRIES}, + {MSG_LICH_KING, GOSSIP_ACTION_INFO_DEF + 5, false, DATA_ANUBARAK}, + {MSG_ANUBARAK, GOSSIP_ACTION_INFO_DEF + 6, true, DATA_ANUBARAK} }; enum Messages @@ -229,16 +229,16 @@ class npc_announcer_toc10 : public CreatureScript ClearGossipMenuFor(player); CloseGossipMenuFor(player); - if (instance->GetBossState(BOSS_BEASTS) != DONE) + if (instance->GetBossState(DATA_NORTHREND_BEASTS) != DONE) { instance->SetData(TYPE_EVENT, 110); instance->SetData(TYPE_NORTHREND_BEASTS, NOT_STARTED); - instance->SetBossState(BOSS_BEASTS, NOT_STARTED); + instance->SetBossState(DATA_NORTHREND_BEASTS, NOT_STARTED); } - else if (instance->GetBossState(BOSS_JARAXXUS) != DONE) + else if (instance->GetBossState(DATA_JARAXXUS) != DONE) { // if Jaraxxus is spawned, but the raid wiped - if (Creature* jaraxxus = ObjectAccessor::GetCreature(*player, instance->GetGuidData(NPC_JARAXXUS))) + if (Creature* jaraxxus = instance->GetCreature(DATA_JARAXXUS)) { jaraxxus->RemoveAurasDueToSpell(SPELL_JARAXXUS_CHAINS); jaraxxus->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); @@ -249,29 +249,29 @@ class npc_announcer_toc10 : public CreatureScript else { instance->SetData(TYPE_EVENT, 1010); - instance->SetBossState(BOSS_JARAXXUS, NOT_STARTED); + instance->SetBossState(DATA_JARAXXUS, NOT_STARTED); } } - else if (instance->GetBossState(BOSS_CRUSADERS) != DONE) + else if (instance->GetBossState(DATA_FACTION_CRUSADERS) != DONE) { if (player->GetTeam() == ALLIANCE) instance->SetData(TYPE_EVENT, 3000); else instance->SetData(TYPE_EVENT, 3001); - instance->SetBossState(BOSS_CRUSADERS, NOT_STARTED); + instance->SetBossState(DATA_FACTION_CRUSADERS, NOT_STARTED); } - else if (instance->GetBossState(BOSS_VALKIRIES) != DONE) + else if (instance->GetBossState(DATA_TWIN_VALKIRIES) != DONE) { instance->SetData(TYPE_EVENT, 4000); - instance->SetBossState(BOSS_VALKIRIES, NOT_STARTED); + instance->SetBossState(DATA_TWIN_VALKIRIES, NOT_STARTED); } - else if (instance->GetBossState(BOSS_LICH_KING) != DONE) + else if (instance->GetBossState(DATA_LICH_KING) != DONE) { if (me->GetMap()->GetPlayers().getFirst()->GetSource()->GetTeam() == ALLIANCE) instance->SetData(TYPE_EVENT, 4020); else instance->SetData(TYPE_EVENT, 4030); - instance->SetBossState(BOSS_LICH_KING, NOT_STARTED); + instance->SetBossState(DATA_LICH_KING, NOT_STARTED); } me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); return true; @@ -305,7 +305,7 @@ class boss_lich_king_toc : public CreatureScript summoned->SetDisplayId(summoned->GetCreatureTemplate()->Modelid2); } - _instance->SetBossState(BOSS_LICH_KING, IN_PROGRESS); + _instance->SetBossState(DATA_LICH_KING, IN_PROGRESS); me->SetWalk(true); } @@ -376,15 +376,15 @@ class boss_lich_king_toc : public CreatureScript break; case 5080: { - if (GameObject* go = ObjectAccessor::GetGameObject(*me, _instance->GetGuidData(GO_ARGENT_COLISEUM_FLOOR))) + if (GameObject* go = _instance->GetGameObject(DATA_COLISEUM_FLOOR)) go->SetDestructibleState(GO_DESTRUCTIBLE_DAMAGED); me->CastSpell(me, SPELL_CORPSE_TELEPORT, false); me->CastSpell(me, SPELL_DESTROY_FLOOR_KNOCKUP, false); - _instance->SetBossState(BOSS_LICH_KING, DONE); + _instance->SetBossState(DATA_LICH_KING, DONE); - if (!ObjectAccessor::GetCreature(*me, _instance->GetGuidData(NPC_ANUBARAK))) + if (!_instance->GetCreature(DATA_ANUBARAK)) me->SummonCreature(NPC_ANUBARAK, AnubarakLoc[0], TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME); _instance->SetData(TYPE_EVENT, 0); @@ -429,7 +429,7 @@ class npc_fizzlebang_toc : public CreatureScript { Talk(SAY_STAGE_1_06, killer); _instance->SetData(TYPE_EVENT, 1180); - if (Creature* jaraxxus = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(NPC_JARAXXUS))) + if (Creature* jaraxxus = _instance->GetCreature(DATA_JARAXXUS)) { jaraxxus->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); jaraxxus->SetImmuneToPC(false); @@ -454,7 +454,7 @@ class npc_fizzlebang_toc : public CreatureScript { case 1: me->SetWalk(false); - _instance->DoUseDoorOrButton(_instance->GetGuidData(GO_MAIN_GATE_DOOR)); + _instance->DoUseDoorOrButton(_instance->GetGuidData(DATA_MAIN_GATE)); _instance->SetData(TYPE_EVENT, 1120); _instance->SetData(TYPE_EVENT_TIMER, 1*IN_MILLISECONDS); break; @@ -538,7 +538,7 @@ class npc_fizzlebang_toc : public CreatureScript _updateTimer = 5*IN_MILLISECONDS; break; case 1142: - if (Creature* jaraxxus = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(NPC_JARAXXUS))) + if (Creature* jaraxxus = _instance->GetCreature(DATA_JARAXXUS)) jaraxxus->SetTarget(me->GetGUID()); if (Creature* pTrigger = ObjectAccessor::GetCreature(*me, _triggerGUID)) pTrigger->DespawnOrUnsummon(); @@ -548,13 +548,13 @@ class npc_fizzlebang_toc : public CreatureScript _updateTimer = 10*IN_MILLISECONDS; break; case 1144: - if (Creature* jaraxxus = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(NPC_JARAXXUS))) + if (Creature* jaraxxus = _instance->GetCreature(DATA_JARAXXUS)) jaraxxus->AI()->Talk(SAY_STAGE_1_05); _instance->SetData(TYPE_EVENT, 1150); _updateTimer = 5*IN_MILLISECONDS; break; case 1150: - if (Creature* jaraxxus = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(NPC_JARAXXUS))) + if (Creature* jaraxxus = _instance->GetCreature(DATA_JARAXXUS)) { //1-shot Fizzlebang jaraxxus->CastSpell(me, 67888, false); // 67888 - Fel Lightning @@ -605,7 +605,7 @@ class npc_tirion_toc : public CreatureScript if (!_instance) return; - if (_instance->GetData(TYPE_EVENT_NPC) != NPC_TIRION) + if (_instance->GetData(TYPE_EVENT_NPC) != NPC_TIRION_FORDRING) return; uint32 _updateTimer = _instance->GetData(TYPE_EVENT_TIMER); @@ -627,9 +627,9 @@ class npc_tirion_toc : public CreatureScript break; case 150: me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE); - if (_instance->GetBossState(BOSS_BEASTS) != DONE) + if (_instance->GetBossState(DATA_NORTHREND_BEASTS) != DONE) { - _instance->DoUseDoorOrButton(_instance->GetGuidData(GO_MAIN_GATE_DOOR)); + _instance->DoUseDoorOrButton(_instance->GetGuidData(DATA_MAIN_GATE)); if (Creature* gormok = me->SummonCreature(NPC_GORMOK, ToCSpawnLoc[0].GetPositionX(), ToCSpawnLoc[0].GetPositionY(), ToCSpawnLoc[0].GetPositionZ(), 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30*IN_MILLISECONDS)) { @@ -649,9 +649,9 @@ class npc_tirion_toc : public CreatureScript break; case 200: Talk(SAY_STAGE_0_04); - if (_instance->GetBossState(BOSS_BEASTS) != DONE) + if (_instance->GetBossState(DATA_NORTHREND_BEASTS) != DONE) { - _instance->DoUseDoorOrButton(_instance->GetGuidData(GO_MAIN_GATE_DOOR)); + _instance->DoUseDoorOrButton(_instance->GetGuidData(DATA_MAIN_GATE)); if (Creature* dreadscale = me->SummonCreature(NPC_DREADSCALE, ToCSpawnLoc[1].GetPositionX(), ToCSpawnLoc[1].GetPositionY(), ToCSpawnLoc[1].GetPositionZ(), 5, TEMPSUMMON_MANUAL_DESPAWN)) { dreadscale->GetMotionMaster()->MovePoint(0, ToCCommonLoc[5].GetPositionX(), ToCCommonLoc[5].GetPositionY(), ToCCommonLoc[5].GetPositionZ()); @@ -667,9 +667,9 @@ class npc_tirion_toc : public CreatureScript break; case 300: Talk(SAY_STAGE_0_05); - if (_instance->GetBossState(BOSS_BEASTS) != DONE) + if (_instance->GetBossState(DATA_NORTHREND_BEASTS) != DONE) { - _instance->DoUseDoorOrButton(_instance->GetGuidData(GO_MAIN_GATE_DOOR)); + _instance->DoUseDoorOrButton(_instance->GetGuidData(DATA_MAIN_GATE)); if (Creature* icehowl = me->SummonCreature(NPC_ICEHOWL, ToCSpawnLoc[0].GetPositionX(), ToCSpawnLoc[0].GetPositionY(), ToCSpawnLoc[0].GetPositionZ(), 5, TEMPSUMMON_DEAD_DESPAWN)) { icehowl->GetMotionMaster()->MovePoint(2, ToCCommonLoc[5].GetPositionX(), ToCCommonLoc[5].GetPositionY(), ToCCommonLoc[5].GetPositionZ()); @@ -697,7 +697,7 @@ class npc_tirion_toc : public CreatureScript case 1010: Talk(SAY_STAGE_1_01); _updateTimer = 7*IN_MILLISECONDS; - _instance->DoUseDoorOrButton(_instance->GetGuidData(GO_MAIN_GATE_DOOR)); + _instance->DoUseDoorOrButton(_instance->GetGuidData(DATA_MAIN_GATE)); me->SummonCreature(NPC_FIZZLEBANG, ToCSpawnLoc[0].GetPositionX(), ToCSpawnLoc[0].GetPositionY(), ToCSpawnLoc[0].GetPositionZ(), 2, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME); _instance->SetData(TYPE_EVENT, 0); break; @@ -751,7 +751,7 @@ class npc_tirion_toc : public CreatureScript _instance->SetData(TYPE_EVENT, 3092); break; case 3092: - if (Creature* pChampionController = ObjectAccessor::GetCreature((*me), _instance->GetGuidData(NPC_CHAMPIONS_CONTROLLER))) + if (Creature* pChampionController = _instance->GetCreature(DATA_FACTION_CRUSADERS)) pChampionController->AI()->SetData(1, NOT_STARTED); _instance->SetData(TYPE_EVENT, 3095); break; @@ -768,14 +768,14 @@ class npc_tirion_toc : public CreatureScript break; case 4010: Talk(SAY_STAGE_3_02); - if (Creature* lightbane = me->SummonCreature(NPC_LIGHTBANE, ToCSpawnLoc[1].GetPositionX(), ToCSpawnLoc[1].GetPositionY(), ToCSpawnLoc[1].GetPositionZ(), 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME)) + if (Creature* lightbane = me->SummonCreature(NPC_FJOLA_LIGHTBANE, ToCSpawnLoc[1].GetPositionX(), ToCSpawnLoc[1].GetPositionY(), ToCSpawnLoc[1].GetPositionZ(), 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME)) { lightbane->SetVisible(false); lightbane->SetReactState(REACT_PASSIVE); lightbane->SummonCreature(NPC_LIGHT_ESSENCE, TwinValkyrsLoc[0].GetPositionX(), TwinValkyrsLoc[0].GetPositionY(), TwinValkyrsLoc[0].GetPositionZ()); lightbane->SummonCreature(NPC_LIGHT_ESSENCE, TwinValkyrsLoc[1].GetPositionX(), TwinValkyrsLoc[1].GetPositionY(), TwinValkyrsLoc[1].GetPositionZ()); } - if (Creature* darkbane = me->SummonCreature(NPC_DARKBANE, ToCSpawnLoc[2].GetPositionX(), ToCSpawnLoc[2].GetPositionY(), ToCSpawnLoc[2].GetPositionZ(), 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME)) + if (Creature* darkbane = me->SummonCreature(NPC_EYDIS_DARKBANE, ToCSpawnLoc[2].GetPositionX(), ToCSpawnLoc[2].GetPositionY(), ToCSpawnLoc[2].GetPositionZ(), 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME)) { darkbane->SetVisible(false); darkbane->SetReactState(REACT_PASSIVE); @@ -786,13 +786,13 @@ class npc_tirion_toc : public CreatureScript _instance->SetData(TYPE_EVENT, 4015); break; case 4015: - _instance->DoUseDoorOrButton(_instance->GetGuidData(GO_MAIN_GATE_DOOR)); - if (Creature* lightbane = ObjectAccessor::GetCreature((*me), _instance->GetGuidData(NPC_LIGHTBANE))) + _instance->DoUseDoorOrButton(_instance->GetGuidData(DATA_MAIN_GATE)); + if (Creature* lightbane = _instance->GetCreature(DATA_FJOLA_LIGHTBANE)) { lightbane->GetMotionMaster()->MovePoint(1, ToCCommonLoc[8].GetPositionX(), ToCCommonLoc[8].GetPositionY(), ToCCommonLoc[8].GetPositionZ()); lightbane->SetVisible(true); } - if (Creature* darkbane = ObjectAccessor::GetCreature((*me), _instance->GetGuidData(NPC_DARKBANE))) + if (Creature* darkbane = _instance->GetCreature(DATA_EYDIS_DARKBANE)) { darkbane->GetMotionMaster()->MovePoint(1, ToCCommonLoc[9].GetPositionX(), ToCCommonLoc[9].GetPositionY(), ToCCommonLoc[9].GetPositionZ()); darkbane->SetVisible(true); @@ -801,7 +801,7 @@ class npc_tirion_toc : public CreatureScript _instance->SetData(TYPE_EVENT, 4016); break; case 4016: - _instance->DoUseDoorOrButton(_instance->GetGuidData(GO_MAIN_GATE_DOOR)); + _instance->DoUseDoorOrButton(_instance->GetGuidData(DATA_MAIN_GATE)); _instance->SetData(TYPE_EVENT, 4017); break; case 4040: @@ -824,14 +824,14 @@ class npc_tirion_toc : public CreatureScript _instance->SetData(TYPE_EVENT, 0); break; case 6000: - me->SummonCreature(NPC_TIRION_FORDRING, EndSpawnLoc[0]); + me->SummonCreature(NPC_TIRION_FORDRING_ANUBARAK, EndSpawnLoc[0]); me->SummonCreature(NPC_ARGENT_MAGE, EndSpawnLoc[1]); me->SummonGameObject(GO_PORTAL_TO_DALARAN, EndSpawnLoc[2], QuaternionData(), 0); _updateTimer = 20*IN_MILLISECONDS; _instance->SetData(TYPE_EVENT, 6005); break; case 6005: - if (Creature* tirionFordring = ObjectAccessor::GetCreature((*me), _instance->GetGuidData(NPC_TIRION_FORDRING))) + if (Creature* tirionFordring = _instance->GetCreature(DATA_FORDRING_ANUBARAK)) tirionFordring->AI()->Talk(SAY_STAGE_4_06); _updateTimer = 20*IN_MILLISECONDS; _instance->SetData(TYPE_EVENT, 6010); @@ -839,10 +839,10 @@ class npc_tirion_toc : public CreatureScript case 6010: if (IsHeroic()) { - if (Creature* tirionFordring = ObjectAccessor::GetCreature((*me), _instance->GetGuidData(NPC_TIRION_FORDRING))) + if (Creature* tirionFordring = _instance->GetCreature(DATA_FORDRING_ANUBARAK)) tirionFordring->AI()->Talk(SAY_STAGE_4_07); _updateTimer = 1*MINUTE*IN_MILLISECONDS; - _instance->SetBossState(BOSS_ANUBARAK, SPECIAL); + _instance->SetBossState(DATA_ANUBARAK, SPECIAL); _instance->SetData(TYPE_EVENT, 6020); } else diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h index d744c7e1cd2..d3565fe27eb 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h @@ -25,19 +25,42 @@ #define DataHeader "TCR" struct Position; +uint32 const EncounterCount = 6; enum TCRDataTypes { - BOSS_BEASTS = 0, - BOSS_JARAXXUS = 1, - BOSS_CRUSADERS = 2, - BOSS_VALKIRIES = 3, - BOSS_LICH_KING = 4, // not really a boss but oh well - BOSS_ANUBARAK = 5, - MAX_ENCOUNTERS = 6, - - TYPE_COUNTER = 8, - TYPE_EVENT = 9, + // Encounter States + DATA_NORTHREND_BEASTS = 0, + DATA_JARAXXUS = 1, + DATA_FACTION_CRUSADERS = 2, + DATA_TWIN_VALKIRIES = 3, + DATA_LICH_KING = 4, + DATA_ANUBARAK = 5, + + // Additional Data + DATA_GORMOK_THE_IMPALER = 5, + DATA_ACIDMAW = 6, + DATA_DREADSCALE = 7, + DATA_ICEHOWL = 8, + DATA_FJOLA_LIGHTBANE = 9, + DATA_EYDIS_DARKBANE = 10, + DATA_BARRET_RAMSEY = 11, + DATA_FORDRING = 12, + DATA_FORDRING_ANUBARAK = 13, + DATA_VARIAN = 14, + DATA_GARROSH = 15, + DATA_FIZZLEBANG = 16, + DATA_FACTION_CHAMPIONS = 17, + + DATA_CRUSADERS_CHEST = 18, + DATA_COLISEUM_FLOOR = 19, + DATA_MAIN_GATE = 20, + DATA_EAST_PORTCULLIS = 21, + DATA_WEB_DOOR = 22, + DATA_TRIBUTE_CHEST = 23, + + TYPE_COUNTER = 24, + TYPE_EVENT = 25, TYPE_EVENT_TIMER = 101, TYPE_EVENT_NPC = 102, @@ -60,7 +83,7 @@ enum TCRSpellIds enum TCRMiscData { - DESPAWN_TIME = 1200000 + DESPAWN_TIME = 1200000 }; extern Position const ToCCommonLoc[]; @@ -68,121 +91,121 @@ extern Position const AnubarakLoc[]; enum TCRWorldStateIds { - UPDATE_STATE_UI_SHOW = 4390, - UPDATE_STATE_UI_COUNT = 4389 + UPDATE_STATE_UI_SHOW = 4390, + UPDATE_STATE_UI_COUNT = 4389 }; enum NorthrendBeasts { - GORMOK_IN_PROGRESS = 1000, - GORMOK_DONE = 1001, - SNAKES_IN_PROGRESS = 2000, - DREADSCALE_SUBMERGED = 2001, - ACIDMAW_SUBMERGED = 2002, - SNAKES_SPECIAL = 2003, - SNAKES_DONE = 2004, - ICEHOWL_IN_PROGRESS = 3000, - ICEHOWL_DONE = 3001 + GORMOK_IN_PROGRESS = 1000, + GORMOK_DONE = 1001, + SNAKES_IN_PROGRESS = 2000, + DREADSCALE_SUBMERGED = 2001, + ACIDMAW_SUBMERGED = 2002, + SNAKES_SPECIAL = 2003, + SNAKES_DONE = 2004, + ICEHOWL_IN_PROGRESS = 3000, + ICEHOWL_DONE = 3001 }; enum AnnouncerMessages { - MSG_BEASTS = 724001, - MSG_JARAXXUS = 724002, - MSG_CRUSADERS = 724003, - MSG_VALKIRIES = 724004, - MSG_LICH_KING = 724005, - MSG_ANUBARAK = 724006 + MSG_BEASTS = 724001, + MSG_JARAXXUS = 724002, + MSG_CRUSADERS = 724003, + MSG_VALKIRIES = 724004, + MSG_LICH_KING = 724005, + MSG_ANUBARAK = 724006 }; enum TCRCreatureIds { - NPC_BARRENT = 34816, - NPC_TIRION = 34996, - NPC_TIRION_FORDRING = 36095, - NPC_ARGENT_MAGE = 36097, - NPC_FIZZLEBANG = 35458, - NPC_GARROSH = 34995, - NPC_VARIAN = 34990, - NPC_LICH_KING = 35877, - - NPC_THRALL = 34994, - NPC_PROUDMOORE = 34992, - NPC_WILFRED_PORTAL = 17965, - NPC_TRIGGER = 35651, - - NPC_ICEHOWL = 34797, - NPC_GORMOK = 34796, - NPC_DREADSCALE = 34799, - NPC_ACIDMAW = 35144, - - NPC_JARAXXUS = 34780, - - NPC_CHAMPIONS_CONTROLLER = 34781, - - NPC_ALLIANCE_DEATH_KNIGHT = 34461, - NPC_ALLIANCE_DRUID_BALANCE = 34460, - NPC_ALLIANCE_DRUID_RESTORATION = 34469, - NPC_ALLIANCE_HUNTER = 34467, - NPC_ALLIANCE_MAGE = 34468, - NPC_ALLIANCE_PALADIN_HOLY = 34465, - NPC_ALLIANCE_PALADIN_RETRIBUTION = 34471, - NPC_ALLIANCE_PRIEST_DISCIPLINE = 34466, - NPC_ALLIANCE_PRIEST_SHADOW = 34473, - NPC_ALLIANCE_ROGUE = 34472, - NPC_ALLIANCE_SHAMAN_ENHANCEMENT = 34463, - NPC_ALLIANCE_SHAMAN_RESTORATION = 34470, - NPC_ALLIANCE_WARLOCK = 34474, - NPC_ALLIANCE_WARRIOR = 34475, - - NPC_HORDE_DEATH_KNIGHT = 34458, - NPC_HORDE_DRUID_BALANCE = 34451, - NPC_HORDE_DRUID_RESTORATION = 34459, - NPC_HORDE_HUNTER = 34448, - NPC_HORDE_MAGE = 34449, - NPC_HORDE_PALADIN_HOLY = 34445, - NPC_HORDE_PALADIN_RETRIBUTION = 34456, - NPC_HORDE_PRIEST_DISCIPLINE = 34447, - NPC_HORDE_PRIEST_SHADOW = 34441, - NPC_HORDE_ROGUE = 34454, - NPC_HORDE_SHAMAN_ENHANCEMENT = 34455, - NPC_HORDE_SHAMAN_RESTORATION = 34444, - NPC_HORDE_WARLOCK = 34450, - NPC_HORDE_WARRIOR = 34453, - - NPC_LIGHTBANE = 34497, - NPC_DARKBANE = 34496, - - NPC_DARK_ESSENCE = 34567, - NPC_LIGHT_ESSENCE = 34568, - - NPC_ANUBARAK = 34564 + NPC_BARRET_RAMSEY = 34816, + NPC_TIRION_FORDRING = 34996, + NPC_TIRION_FORDRING_ANUBARAK = 36095, + NPC_ARGENT_MAGE = 36097, + NPC_FIZZLEBANG = 35458, + NPC_GARROSH = 34995, + NPC_VARIAN = 34990, + NPC_LICH_KING = 35877, + + NPC_THRALL = 34994, + NPC_PROUDMOORE = 34992, + NPC_WILFRED_PORTAL = 17965, + NPC_TRIGGER = 35651, + + NPC_ICEHOWL = 34797, + NPC_GORMOK = 34796, + NPC_DREADSCALE = 34799, + NPC_ACIDMAW = 35144, + + NPC_JARAXXUS = 34780, + + NPC_CHAMPIONS_CONTROLLER = 34781, + + NPC_ALLIANCE_DEATH_KNIGHT = 34461, + NPC_ALLIANCE_DRUID_BALANCE = 34460, + NPC_ALLIANCE_DRUID_RESTORATION = 34469, + NPC_ALLIANCE_HUNTER = 34467, + NPC_ALLIANCE_MAGE = 34468, + NPC_ALLIANCE_PALADIN_HOLY = 34465, + NPC_ALLIANCE_PALADIN_RETRIBUTION = 34471, + NPC_ALLIANCE_PRIEST_DISCIPLINE = 34466, + NPC_ALLIANCE_PRIEST_SHADOW = 34473, + NPC_ALLIANCE_ROGUE = 34472, + NPC_ALLIANCE_SHAMAN_ENHANCEMENT = 34463, + NPC_ALLIANCE_SHAMAN_RESTORATION = 34470, + NPC_ALLIANCE_WARLOCK = 34474, + NPC_ALLIANCE_WARRIOR = 34475, + + NPC_HORDE_DEATH_KNIGHT = 34458, + NPC_HORDE_DRUID_BALANCE = 34451, + NPC_HORDE_DRUID_RESTORATION = 34459, + NPC_HORDE_HUNTER = 34448, + NPC_HORDE_MAGE = 34449, + NPC_HORDE_PALADIN_HOLY = 34445, + NPC_HORDE_PALADIN_RETRIBUTION = 34456, + NPC_HORDE_PRIEST_DISCIPLINE = 34447, + NPC_HORDE_PRIEST_SHADOW = 34441, + NPC_HORDE_ROGUE = 34454, + NPC_HORDE_SHAMAN_ENHANCEMENT = 34455, + NPC_HORDE_SHAMAN_RESTORATION = 34444, + NPC_HORDE_WARLOCK = 34450, + NPC_HORDE_WARRIOR = 34453, + + NPC_FJOLA_LIGHTBANE = 34497, + NPC_EYDIS_DARKBANE = 34496, + + NPC_DARK_ESSENCE = 34567, + NPC_LIGHT_ESSENCE = 34568, + + NPC_ANUBARAK = 34564 }; enum TCRGameObjectIds { - GO_CRUSADERS_CACHE_10 = 195631, - GO_CRUSADERS_CACHE_25 = 195632, - GO_CRUSADERS_CACHE_10_H = 195633, - GO_CRUSADERS_CACHE_25_H = 195635, + GO_CRUSADERS_CACHE_10 = 195631, + GO_CRUSADERS_CACHE_25 = 195632, + GO_CRUSADERS_CACHE_10_H = 195633, + GO_CRUSADERS_CACHE_25_H = 195635, // Tribute Chest (heroic) // 10-man modes - GO_TRIBUTE_CHEST_10H_25 = 195668, // 10man 01-24 attempts - GO_TRIBUTE_CHEST_10H_45 = 195667, // 10man 25-44 attempts - GO_TRIBUTE_CHEST_10H_50 = 195666, // 10man 45-49 attempts - GO_TRIBUTE_CHEST_10H_99 = 195665, // 10man 50 attempts + GO_TRIBUTE_CHEST_10H_25 = 195668, // 10man 01-24 attempts + GO_TRIBUTE_CHEST_10H_45 = 195667, // 10man 25-44 attempts + GO_TRIBUTE_CHEST_10H_50 = 195666, // 10man 45-49 attempts + GO_TRIBUTE_CHEST_10H_99 = 195665, // 10man 50 attempts // 25-man modes - GO_TRIBUTE_CHEST_25H_25 = 195672, // 25man 01-24 attempts - GO_TRIBUTE_CHEST_25H_45 = 195671, // 25man 25-44 attempts - GO_TRIBUTE_CHEST_25H_50 = 195670, // 25man 45-49 attempts - GO_TRIBUTE_CHEST_25H_99 = 195669, // 25man 50 attempts - - GO_ARGENT_COLISEUM_FLOOR = 195527, //20943 - GO_MAIN_GATE_DOOR = 195647, - GO_EAST_PORTCULLIS = 195648, - GO_WEB_DOOR = 195485, - GO_PORTAL_TO_DALARAN = 195682 + GO_TRIBUTE_CHEST_25H_25 = 195672, // 25man 01-24 attempts + GO_TRIBUTE_CHEST_25H_45 = 195671, // 25man 25-44 attempts + GO_TRIBUTE_CHEST_25H_50 = 195670, // 25man 45-49 attempts + GO_TRIBUTE_CHEST_25H_99 = 195669, // 25man 50 attempts + + GO_ARGENT_COLISEUM_FLOOR = 195527, //20943 + GO_MAIN_GATE_DOOR = 195647, + GO_EAST_PORTCULLIS = 195648, + GO_WEB_DOOR = 195485, + GO_PORTAL_TO_DALARAN = 195682 }; enum TCRAchievementData diff --git a/src/server/scripts/Northrend/DraktharonKeep/boss_novos.cpp b/src/server/scripts/Northrend/DraktharonKeep/boss_novos.cpp index 2bcfd7a70d6..bbfc6ac0924 100644 --- a/src/server/scripts/Northrend/DraktharonKeep/boss_novos.cpp +++ b/src/server/scripts/Northrend/DraktharonKeep/boss_novos.cpp @@ -243,7 +243,7 @@ public: if (Creature* crystalChannelTarget = crystal->FindNearestCreature(NPC_CRYSTAL_CHANNEL_TARGET, 5.0f)) { if (active) - crystalChannelTarget->CastSpell((Unit*)nullptr, SPELL_BEAM_CHANNEL); + crystalChannelTarget->CastSpell(nullptr, SPELL_BEAM_CHANNEL); else if (crystalChannelTarget->HasUnitState(UNIT_STATE_CASTING)) crystalChannelTarget->CastStop(); } @@ -384,7 +384,7 @@ class spell_novos_summon_minions : public SpellScriptLoader void HandleScript(SpellEffIndex /*effIndex*/) { for (uint8 i = 0; i < 2; ++i) - GetCaster()->CastSpell((Unit*)nullptr, SPELL_SUMMON_COPY_OF_MINIONS, true); + GetCaster()->CastSpell(nullptr, SPELL_SUMMON_COPY_OF_MINIONS, true); } void Register() override diff --git a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp index abab9f7ead7..e0ac981b69c 100644 --- a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp @@ -246,7 +246,7 @@ class npc_corrupted_soul_fragment : public CreatureScript if (instance->GetGuidData(DATA_BRONJAHM).GetCounter() != id) return; - me->CastSpell((Unit*)nullptr, SPELL_CONSUME_SOUL, true); + me->CastSpell(nullptr, SPELL_CONSUME_SOUL, true); me->DespawnOrUnsummon(); } diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp index 7d620ae5a60..0545d3d19f6 100644 --- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp @@ -2824,9 +2824,9 @@ class spell_hor_gunship_cannon_fire : public SpellScriptLoader if (!urand(0, 2)) { if (GetTarget()->GetEntry() == NPC_GUNSHIP_CANNON_HORDE) - GetTarget()->CastSpell((Unit*)nullptr, SPELL_GUNSHIP_CANNON_FIRE_MISSILE_HORDE, true); + GetTarget()->CastSpell(nullptr, SPELL_GUNSHIP_CANNON_FIRE_MISSILE_HORDE, true); else - GetTarget()->CastSpell((Unit*)nullptr, SPELL_GUNSHIP_CANNON_FIRE_MISSILE_ALLIANCE, true); + GetTarget()->CastSpell(nullptr, SPELL_GUNSHIP_CANNON_FIRE_MISSILE_ALLIANCE, true); } } diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp index 89f95a32cc8..ab439788c90 100644 --- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp @@ -346,7 +346,7 @@ class instance_halls_of_reflection : public InstanceMapScript if (Creature* lichking = instance->GetCreature(TheLichKingEscapeGUID)) { - lichking->CastSpell((Unit*)nullptr, SPELL_ACHIEV_CHECK, true); + lichking->CastSpell(nullptr, SPELL_ACHIEV_CHECK, true); lichking->DespawnOrUnsummon(1); } break; @@ -453,7 +453,7 @@ class instance_halls_of_reflection : public InstanceMapScript if (_quelDelarState == NOT_STARTED) { if (Creature* bunny = instance->GetCreature(FrostmourneAltarBunnyGUID)) - bunny->CastSpell((Unit*)nullptr, SPELL_ESSENCE_OF_CAPTURED); + bunny->CastSpell(nullptr, SPELL_ESSENCE_OF_CAPTURED); events.ScheduleEvent(EVENT_QUEL_DELAR_SUMMON_UTHER, 2000); } } diff --git a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_krickandick.cpp b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_krickandick.cpp index f21d4fa007c..8b558d8e913 100644 --- a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_krickandick.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_krickandick.cpp @@ -114,7 +114,9 @@ enum KrickPhase enum Actions { - ACTION_OUTRO = 1 + ACTION_OUTRO = 1, + ACTION_STORE_OLD_TARGET, + ACTION_RESET_THREAT }; enum Points @@ -144,13 +146,15 @@ class boss_ick : public CreatureScript { boss_ickAI(Creature* creature) : BossAI(creature, DATA_ICK) { - _tempThreat = 0; + _tempThreat = 0.0f; } void Reset() override { events.Reset(); instance->SetBossState(DATA_ICK, NOT_STARTED); + _oldTargetGUID.Clear(); + _tempThreat = 0.0f; } Creature* GetKrick() @@ -190,15 +194,29 @@ class boss_ick : public CreatureScript instance->SetBossState(DATA_ICK, DONE); } - void SetTempThreat(float threat) + void DoAction(int32 actionId) override { - _tempThreat = threat; - } + if (actionId == ACTION_STORE_OLD_TARGET) + { + if (Unit* victim = me->GetVictim()) + { + _oldTargetGUID = victim->GetGUID(); + _tempThreat = GetThreat(victim); + } + } + else if (actionId == ACTION_RESET_THREAT) + { + if (Unit* oldTarget = ObjectAccessor::GetUnit(*me, _oldTargetGUID)) + { + if (Unit* current = me->GetVictim()) + ModifyThreatByPercent(current, -100); - void _ResetThreat(Unit* target) - { - ModifyThreatByPercent(target, -100); - AddThreat(target, _tempThreat); + AddThreat(oldTarget, _tempThreat); + AttackStart(oldTarget); + _oldTargetGUID.Clear(); + _tempThreat = 0.0f; + } + } } void UpdateAI(uint32 diff) override @@ -262,7 +280,7 @@ class boss_ick : public CreatureScript case EVENT_PURSUIT: if (Creature* krick = GetKrick()) krick->AI()->Talk(SAY_KRICK_CHASE); - DoCast(me, SPELL_PURSUIT); + me->CastCustomSpell(SPELL_PURSUIT, SPELLVALUE_MAX_TARGETS, 1, me); break; default: break; @@ -277,6 +295,7 @@ class boss_ick : public CreatureScript private: float _tempThreat; + ObjectGuid _oldTargetGUID; }; CreatureAI* GetAI(Creature* creature) const override @@ -631,18 +650,15 @@ class spell_krick_pursuit : public SpellScriptLoader void HandleScriptEffect(SpellEffIndex /*effIndex*/) { - if (GetCaster()) - if (Creature* ick = GetCaster()->ToCreature()) - { - if (Unit* target = ick->AI()->SelectTarget(SELECT_TARGET_RANDOM, 0, 200.0f, true)) - { - ick->AI()->Talk(SAY_ICK_CHASE_1, target); - ick->AddAura(GetSpellInfo()->Id, target); - ENSURE_AI(boss_ick::boss_ickAI, ick->AI())->SetTempThreat(ick->GetThreatManager().GetThreat(target)); - ick->GetThreatManager().AddThreat(target, float(GetEffectValue()), GetSpellInfo(), true, true); - target->GetThreatManager().AddThreat(ick, float(GetEffectValue()), GetSpellInfo(), true, true); - } - } + Unit* target = GetHitUnit(); + if (Creature* ick = GetCaster()->ToCreature()) + { + ick->AI()->Talk(SAY_ICK_CHASE_1, target); + ick->AddAura(GetSpellInfo()->Id, target); + ick->AI()->DoAction(ACTION_STORE_OLD_TARGET); + ick->GetThreatManager().AddThreat(target, float(GetEffectValue()), GetSpellInfo(), true, true); + ick->AI()->AttackStart(target); + } } void Register() override @@ -659,7 +675,7 @@ class spell_krick_pursuit : public SpellScriptLoader { if (Unit* caster = GetCaster()) if (Creature* creCaster = caster->ToCreature()) - ENSURE_AI(boss_ick::boss_ickAI, creCaster->AI())->_ResetThreat(GetTarget()); + creCaster->AI()->DoAction(ACTION_RESET_THREAT); } void Register() override diff --git a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp index 4e62380b983..187ab353803 100644 --- a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp @@ -539,18 +539,18 @@ class spell_tyrannus_rimefang_icy_blast : public SpellScriptLoader } }; -class at_tyrannus_event_starter : public AreaTriggerScript +class at_tyrannus_event_starter : public OnlyOnceAreaTriggerScript { public: - at_tyrannus_event_starter() : AreaTriggerScript("at_tyrannus_event_starter") { } + at_tyrannus_event_starter() : OnlyOnceAreaTriggerScript("at_tyrannus_event_starter") { } - bool OnTrigger(Player* player, AreaTriggerEntry const* /*at*/) override + bool _OnTrigger(Player* player, AreaTriggerEntry const* /*at*/) override { InstanceScript* instance = player->GetInstanceScript(); if (player->IsGameMaster() || !instance) return false; - if (instance->GetBossState(DATA_TYRANNUS) != IN_PROGRESS && instance->GetBossState(DATA_TYRANNUS) != DONE) + if (instance->GetBossState(DATA_TYRANNUS) != DONE) if (Creature* tyrannus = ObjectAccessor::GetCreature(*player, instance->GetGuidData(DATA_TYRANNUS))) { tyrannus->AI()->DoAction(ACTION_START_INTRO); diff --git a/src/server/scripts/Northrend/Gundrak/instance_gundrak.cpp b/src/server/scripts/Northrend/Gundrak/instance_gundrak.cpp index c9e5848d2f5..4bd67f3e232 100644 --- a/src/server/scripts/Northrend/Gundrak/instance_gundrak.cpp +++ b/src/server/scripts/Northrend/Gundrak/instance_gundrak.cpp @@ -322,7 +322,7 @@ class instance_gundrak : public InstanceMapScript if (GameObject* altar = GetGameObject(altarId)) if (Creature* trigger = altar->FindNearestCreature(NPC_ALTAR_TRIGGER, 10.0f)) - trigger->CastSpell((Unit*)nullptr, spellId, true); + trigger->CastSpell(nullptr, spellId, true); // eventId equals statueId ToggleGameObject(eventId, GO_STATE_READY); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp index f038f653782..ffbc0901f31 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp @@ -222,7 +222,7 @@ class boss_blood_council_controller : public CreatureScript struct boss_blood_council_controllerAI : public BossAI { - boss_blood_council_controllerAI(Creature* creature) : BossAI(creature, DATA_BLOOD_PRINCE_COUNCIL), _intro(true) + boss_blood_council_controllerAI(Creature* creature) : BossAI(creature, DATA_BLOOD_PRINCE_COUNCIL) { Initialize(); SetCombatMovement(false); @@ -240,7 +240,7 @@ class boss_blood_council_controller : public CreatureScript Initialize(); me->SummonCreatureGroup(SUMMON_PRINCES_GROUP); - if (!_intro) + if (!instance->GetData(DATA_BLOOD_PRINCE_COUNCIL_INTRO)) for (uint32 bossData : PrincesData) if (Creature* prince = ObjectAccessor::GetCreature(*me, instance->GetGuidData(bossData))) { @@ -311,7 +311,7 @@ class boss_blood_council_controller : public CreatureScript uint32 GetData(uint32 data) const override { - if (data == DATA_INTRO && !_intro) + if (data == DATA_INTRO && !instance->GetData(DATA_BLOOD_PRINCE_COUNCIL_INTRO)) return DATA_INTRO_DONE; return 0; } @@ -338,9 +338,9 @@ class boss_blood_council_controller : public CreatureScript void DoAction(int32 actionId) override { - if (actionId == ACTION_START_INTRO && _intro && instance->GetBossState(DATA_BLOOD_PRINCE_COUNCIL) != DONE) + if (actionId == ACTION_START_INTRO && instance->GetData(DATA_BLOOD_PRINCE_COUNCIL_INTRO) && instance->GetBossState(DATA_BLOOD_PRINCE_COUNCIL) != DONE) { - _intro = false; + instance->SetData(DATA_BLOOD_PRINCE_COUNCIL_INTRO, 0); if (Creature* bloodQueen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_BLOOD_QUEEN_LANA_THEL_COUNCIL))) bloodQueen->AI()->DoAction(ACTION_START_INTRO); } @@ -425,7 +425,6 @@ class boss_blood_council_controller : public CreatureScript uint32 _invocationStage; uint32 _resetCounter; - bool _intro; }; CreatureAI* GetAI(Creature* creature) const override @@ -445,7 +444,7 @@ struct BloodPrincesBossAI : public BossAI { _spawnHealth = 1; if (!me->isDead()) - JustRespawned(); + JustAppeared(); } void Reset() override @@ -493,7 +492,7 @@ struct BloodPrincesBossAI : public BossAI } } - void JustRespawned() override + void JustAppeared() override { if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_BLOOD_PRINCES_CONTROL))) if (controller->AI()->GetData(DATA_INTRO) != DATA_INTRO_DONE) diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp index 41b836922e1..e344a3181fc 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp @@ -550,7 +550,7 @@ struct gunship_npc_AI : public ScriptedAI Instance(creature->GetInstanceScript()), Slot(nullptr), Index(uint32(-1)) { BurningPitchId = Instance->GetData(DATA_TEAM_IN_INSTANCE) == HORDE ? SPELL_BURNING_PITCH_A : SPELL_BURNING_PITCH_H; - me->setRegeneratingHealth(false); + me->SetRegenerateHealth(false); } void SetData(uint32 type, uint32 data) override @@ -676,7 +676,7 @@ class npc_gunship : public CreatureScript _teamInInstance(creature->GetInstanceScript()->GetData(DATA_TEAM_IN_INSTANCE)), _summonedFirstMage(false), _died(false) { - me->setRegeneratingHealth(false); + me->SetRegenerateHealth(false); } void DamageTaken(Unit* /*source*/, uint32& damage) override @@ -857,7 +857,7 @@ class npc_high_overlord_saurfang_igb : public CreatureScript { _controller.ResetSlots(HORDE); _controller.SetTransport(creature->GetTransport()); - me->setRegeneratingHealth(false); + me->SetRegenerateHealth(false); me->m_CombatDistance = 70.0f; _firstMageCooldown = time(nullptr) + 60; _axethrowersYellCooldown = time_t(0); @@ -1126,7 +1126,7 @@ class npc_muradin_bronzebeard_igb : public CreatureScript { _controller.ResetSlots(ALLIANCE); _controller.SetTransport(creature->GetTransport()); - me->setRegeneratingHealth(false); + me->SetRegenerateHealth(false); me->m_CombatDistance = 70.0f; _firstMageCooldown = time(nullptr) + 60; _riflemanYellCooldown = time_t(0); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp index 8a444b3d933..bf6920e741d 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp @@ -203,7 +203,7 @@ class boss_lady_deathwhisper : public CreatureScript struct boss_lady_deathwhisperAI : public BossAI { boss_lady_deathwhisperAI(Creature* creature) : BossAI(creature, DATA_LADY_DEATHWHISPER), - _dominateMindCount(RAID_MODE<uint8>(0, 1, 1, 3)), _introDone(false) + _dominateMindCount(RAID_MODE<uint8>(0, 1, 1, 3)) { Initialize(); } @@ -237,43 +237,39 @@ class boss_lady_deathwhisper : public CreatureScript if (action != ACTION_START_INTRO) return; - if (!_introDone) + Talk(SAY_INTRO_1); + _phase = PHASE_INTRO; + scheduler.Schedule(Seconds(10), GROUP_INTRO, [this](TaskContext context) { - _introDone = true; - Talk(SAY_INTRO_1); - _phase = PHASE_INTRO; - scheduler.Schedule(Seconds(10), GROUP_INTRO, [this](TaskContext context) + switch (context.GetRepeatCounter()) { - switch (context.GetRepeatCounter()) - { - case 0: - Talk(SAY_INTRO_2); - context.Repeat(Seconds(21)); - break; - case 1: - Talk(SAY_INTRO_3); - context.Repeat(Seconds(11)); - break; - case 2: - Talk(SAY_INTRO_4); - context.Repeat(Seconds(9)); - break; - case 3: - Talk(SAY_INTRO_5); - context.Repeat(Seconds(21)); - break; - case 4: - Talk(SAY_INTRO_6); - context.Repeat(Seconds(10)); - break; - case 5: - Talk(SAY_INTRO_7); - return; - default: - break; - } - }); - } + case 0: + Talk(SAY_INTRO_2); + context.Repeat(Seconds(21)); + break; + case 1: + Talk(SAY_INTRO_3); + context.Repeat(Seconds(11)); + break; + case 2: + Talk(SAY_INTRO_4); + context.Repeat(Seconds(9)); + break; + case 3: + Talk(SAY_INTRO_5); + context.Repeat(Seconds(21)); + break; + case 4: + Talk(SAY_INTRO_6); + context.Repeat(Seconds(10)); + break; + case 5: + Talk(SAY_INTRO_7); + return; + default: + break; + } + }); } void AttackStart(Unit* victim) override @@ -585,7 +581,6 @@ class boss_lady_deathwhisper : public CreatureScript uint32 _waveCounter; uint8 const _dominateMindCount; uint8 _phase; - bool _introDone; }; CreatureAI* GetAI(Creature* creature) const override @@ -1022,12 +1017,12 @@ class spell_deathwhisper_mana_barrier : public SpellScriptLoader } }; -class at_lady_deathwhisper_entrance : public AreaTriggerScript +class at_lady_deathwhisper_entrance : public OnlyOnceAreaTriggerScript { public: - at_lady_deathwhisper_entrance() : AreaTriggerScript("at_lady_deathwhisper_entrance") { } + at_lady_deathwhisper_entrance() : OnlyOnceAreaTriggerScript("at_lady_deathwhisper_entrance") { } - bool OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/) override + bool _OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/) override { if (InstanceScript* instance = player->GetInstanceScript()) if (instance->GetBossState(DATA_LADY_DEATHWHISPER) != DONE) diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp index ca8a9356db6..7e7b372337e 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp @@ -140,7 +140,6 @@ class boss_lord_marrowgar : public CreatureScript _boneStormDuration = RAID_MODE<uint32>(20000, 30000, 20000, 30000); _baseSpeed = creature->GetSpeedRate(MOVE_RUN); _coldflameLastPos.Relocate(creature); - _introDone = false; _boneSlice = false; } @@ -155,7 +154,6 @@ class boss_lord_marrowgar : public CreatureScript events.ScheduleEvent(EVENT_COLDFLAME, 5000, EVENT_GROUP_SPECIAL); events.ScheduleEvent(EVENT_WARN_BONE_STORM, urand(45000, 50000)); events.ScheduleEvent(EVENT_ENRAGE, 600000); - _introDone = false; _boneSlice = false; _boneSpikeImmune.clear(); } @@ -333,11 +331,7 @@ class boss_lord_marrowgar : public CreatureScript _boneSpikeImmune.clear(); break; case ACTION_TALK_ENTER_ZONE: - if (!_introDone) - { Talk(SAY_ENTER_ZONE); - _introDone = true; - } break; default: break; @@ -350,7 +344,6 @@ class boss_lord_marrowgar : public CreatureScript ObjectGuid _coldflameTarget; uint32 _boneStormDuration; float _baseSpeed; - bool _introDone; bool _boneSlice; }; @@ -654,6 +647,15 @@ class spell_marrowgar_bone_spike_graveyard : public SpellScriptLoader { Unit* target = *itr; target->CastSpell(target, BoneSpikeSummonId[i], true); + if (!target->IsAlive()) // make sure we don't get any stuck spikes on dead targets + { + if (Aura* aura = target->GetAura(SPELL_IMPALED)) + { + if (Creature* spike = ObjectAccessor::GetCreature(*target, aura->GetCasterGUID())) + spike->DespawnOrUnsummon(); + aura->Remove(); + } + } } marrowgarAI->Talk(SAY_BONESPIKE); @@ -752,12 +754,12 @@ class spell_marrowgar_bone_slice : public SpellScriptLoader } }; -class at_lord_marrowgar_entrance : public AreaTriggerScript +class at_lord_marrowgar_entrance : public OnlyOnceAreaTriggerScript { public: - at_lord_marrowgar_entrance() : AreaTriggerScript("at_lord_marrowgar_entrance") { } + at_lord_marrowgar_entrance() : OnlyOnceAreaTriggerScript("at_lord_marrowgar_entrance") { } - bool OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/) override + bool _OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/) override { if (InstanceScript* instance = player->GetInstanceScript()) if (Creature* lordMarrowgar = ObjectAccessor::GetCreature(*player, instance->GetGuidData(DATA_LORD_MARROWGAR))) diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp index b23b3ca9917..e19b4187138 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp @@ -1118,7 +1118,7 @@ class spell_putricide_ooze_tank_protection : public SpellScriptLoader PreventDefaultAction(); Unit* actionTarget = eventInfo.GetActionTarget(); - actionTarget->CastSpell((Unit*)nullptr, GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell, true, nullptr, aurEff); + actionTarget->CastSpell(nullptr, GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell, true, nullptr, aurEff); } void Register() override diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp index 370578a3c47..c64e42762d2 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp @@ -194,7 +194,7 @@ class FrostBombExplosion : public BasicEvent bool Execute(uint64 /*eventTime*/, uint32 /*updateTime*/) override { - _owner->CastSpell((Unit*)nullptr, SPELL_FROST_BOMB, false, nullptr, nullptr, _sindragosaGUID); + _owner->CastSpell(nullptr, SPELL_FROST_BOMB, false, nullptr, nullptr, _sindragosaGUID); _owner->RemoveAurasDueToSpell(SPELL_FROST_BOMB_VISUAL); return true; } @@ -226,7 +226,7 @@ class boss_sindragosa : public CreatureScript struct boss_sindragosaAI : public BossAI { - boss_sindragosaAI(Creature* creature) : BossAI(creature, DATA_SINDRAGOSA), _summoned(false) + boss_sindragosaAI(Creature* creature) : BossAI(creature, DATA_SINDRAGOSA) { Initialize(); } @@ -251,7 +251,7 @@ class boss_sindragosa : public CreatureScript events.ScheduleEvent(EVENT_AIR_PHASE, 50000); Initialize(); - if (!_summoned) + if (instance->GetData(DATA_SINDRAGOSA_INTRO)) { me->SetCanFly(true); me->SetDisableGravity(true); @@ -311,10 +311,8 @@ class boss_sindragosa : public CreatureScript { if (action == ACTION_START_FROSTWYRM) { - if (_summoned) - return; - _summoned = true; + instance->SetData(DATA_SINDRAGOSA_INTRO, 0); if (TempSummon* summon = me->ToTempSummon()) summon->SetTempSummonType(TEMPSUMMON_DEAD_DESPAWN); @@ -565,7 +563,6 @@ class boss_sindragosa : public CreatureScript uint8 _mysticBuffetStack; bool _isInAirPhase; bool _isThirdPhase; - bool _summoned; }; CreatureAI* GetAI(Creature* creature) const override @@ -688,9 +685,9 @@ class npc_spinestalker : public CreatureScript } } - void JustRespawned() override + void JustAppeared() override { - ScriptedAI::JustRespawned(); + ScriptedAI::JustAppeared(); _instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, me->GetSpawnId()); // this cannot be in Reset because reset also happens on evade } @@ -825,9 +822,9 @@ class npc_rimefang : public CreatureScript } } - void JustRespawned() override + void JustAppeared() override { - ScriptedAI::JustRespawned(); + ScriptedAI::JustAppeared(); _instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, me->GetSpawnId()); // this cannot be in Reset because reset also happens on evade } @@ -991,9 +988,9 @@ class npc_sindragosa_trash : public CreatureScript Initialize(); } - void JustRespawned() override + void JustAppeared() override { - ScriptedAI::JustRespawned(); + ScriptedAI::JustAppeared(); // Increase add count if (me->GetEntry() == NPC_FROSTWING_WHELP) @@ -1616,12 +1613,12 @@ public: } }; -class at_sindragosa_lair : public AreaTriggerScript +class at_sindragosa_lair : public OnlyOnceAreaTriggerScript { public: - at_sindragosa_lair() : AreaTriggerScript("at_sindragosa_lair") { } + at_sindragosa_lair() : OnlyOnceAreaTriggerScript("at_sindragosa_lair") { } - bool OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/) override + bool _OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/) override { if (InstanceScript* instance = player->GetInstanceScript()) { diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp index d00e56606b5..7b1de4c8bfe 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp @@ -268,7 +268,10 @@ enum Events // Strangulate Vehicle (Harvest Soul) EVENT_TELEPORT, EVENT_MOVE_TO_LICH_KING, - EVENT_DESPAWN_SELF + EVENT_DESPAWN_SELF, + + //Spirit Bomb + EVENT_BOMB_EXPLOSION }; enum EventGroups @@ -472,7 +475,7 @@ class VileSpiritActivateEvent : public BasicEvent { _owner->SetReactState(REACT_AGGRESSIVE); _owner->CastSpell(_owner, SPELL_VILE_SPIRIT_MOVE_SEARCH, true); - _owner->CastSpell((Unit*)nullptr, SPELL_VILE_SPIRIT_DAMAGE_SEARCH, true); + _owner->CastSpell(nullptr, SPELL_VILE_SPIRIT_DAMAGE_SEARCH, true); return true; } @@ -626,8 +629,8 @@ class boss_the_lich_king : public CreatureScript me->GetMap()->SetZoneOverrideLight(AREA_ICECROWN_CITADEL, 0, 5000); break; case ACTION_BREAK_FROSTMOURNE: - me->CastSpell((Unit*)nullptr, SPELL_SUMMON_BROKEN_FROSTMOURNE, TRIGGERED_IGNORE_CAST_IN_PROGRESS); - me->CastSpell((Unit*)nullptr, SPELL_SUMMON_BROKEN_FROSTMOURNE_2, TRIGGERED_IGNORE_CAST_IN_PROGRESS); + me->CastSpell(nullptr, SPELL_SUMMON_BROKEN_FROSTMOURNE, TRIGGERED_IGNORE_CAST_IN_PROGRESS); + me->CastSpell(nullptr, SPELL_SUMMON_BROKEN_FROSTMOURNE_2, TRIGGERED_IGNORE_CAST_IN_PROGRESS); SetEquipmentSlots(false, EQUIP_BROKEN_FROSTMOURNE); events.ScheduleEvent(EVENT_OUTRO_TALK_6, 2500, 0, PHASE_OUTRO); break; @@ -709,7 +712,7 @@ class boss_the_lich_king : public CreatureScript summons.DespawnAll(); me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, MUSIC_FURY_OF_FROSTMOURNE); me->InterruptNonMeleeSpells(true); - me->CastSpell((Unit*)nullptr, SPELL_FURY_OF_FROSTMOURNE, TRIGGERED_NONE); + me->CastSpell(nullptr, SPELL_FURY_OF_FROSTMOURNE, TRIGGERED_NONE); me->SetWalk(true); events.ScheduleEvent(EVENT_OUTRO_TALK_1, 2600, 0, PHASE_OUTRO); events.ScheduleEvent(EVENT_OUTRO_EMOTE_TALK, 6600, 0, PHASE_OUTRO); @@ -756,7 +759,7 @@ class boss_the_lich_king : public CreatureScript break; case NPC_FROSTMOURNE_TRIGGER: { - summon->CastSpell((Unit*)nullptr, SPELL_BROKEN_FROSTMOURNE, true); + summon->CastSpell(nullptr, SPELL_BROKEN_FROSTMOURNE, true); me->GetMap()->SetZoneOverrideLight(AREA_ICECROWN_CITADEL, LIGHT_SOULSTORM, 10000); me->GetMap()->SetZoneWeather(AREA_ICECROWN_CITADEL, WEATHER_STATE_BLACKSNOW, 0.5f); @@ -815,6 +818,7 @@ class boss_the_lich_king : public CreatureScript { me->GetMap()->SetZoneOverrideLight(AREA_ICECROWN_CITADEL, LIGHT_SNOWSTORM, 5000); me->GetMap()->SetZoneWeather(AREA_ICECROWN_CITADEL, WEATHER_STATE_LIGHT_SNOW, 0.5f); + summons.DespawnEntry(NPC_SHADOW_TRAP); } } @@ -842,8 +846,6 @@ class boss_the_lich_king : public CreatureScript Talk(SAY_LK_REMORSELESS_WINTER); me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, MUSIC_SPECIAL); DoCast(me, SPELL_REMORSELESS_WINTER_1); - summons.DespawnEntry(NPC_SHADOW_TRAP); - events.DelayEvents(62500, EVENT_GROUP_BERSERK); // delay berserk timer, its not ticking during phase transitions events.ScheduleEvent(EVENT_QUAKE, 62500, 0, PHASE_TRANSITION); events.ScheduleEvent(EVENT_PAIN_AND_SUFFERING, 4000, 0, PHASE_TRANSITION); events.ScheduleEvent(EVENT_SUMMON_ICE_SPHERE, 8000, 0, PHASE_TRANSITION); @@ -859,7 +861,6 @@ class boss_the_lich_king : public CreatureScript me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, MUSIC_SPECIAL); DoCast(me, SPELL_REMORSELESS_WINTER_2); summons.DespawnEntry(NPC_VALKYR_SHADOWGUARD); - events.DelayEvents(62500, EVENT_GROUP_BERSERK); // delay berserk timer, its not ticking during phase transitions events.ScheduleEvent(EVENT_QUAKE_2, 62500, 0, PHASE_TRANSITION); events.ScheduleEvent(EVENT_PAIN_AND_SUFFERING, 6000, 0, PHASE_TRANSITION); events.ScheduleEvent(EVENT_SUMMON_ICE_SPHERE, 8000, 0, PHASE_TRANSITION); @@ -963,7 +964,7 @@ class boss_the_lich_king : public CreatureScript events.ScheduleEvent(EVENT_NECROTIC_PLAGUE, urand(30000, 33000), 0, PHASE_ONE); break; case EVENT_SHADOW_TRAP: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, NonTankTargetSelector(me))) + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, SpellTargetSelector(me, SPELL_SHADOW_TRAP))) DoCast(target, SPELL_SHADOW_TRAP); events.ScheduleEvent(EVENT_SHADOW_TRAP, 15500, 0, PHASE_ONE); break; @@ -972,7 +973,7 @@ class boss_the_lich_king : public CreatureScript events.ScheduleEvent(EVENT_SOUL_REAPER, urand(33000, 35000), 0, PHASE_TWO_THREE); break; case EVENT_DEFILE: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true, true, -SPELL_HARVEST_SOUL_VALKYR)) + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true, true, -SPELL_HARVEST_SOUL_VALKYR)) { Talk(EMOTE_DEFILE_WARNING); DoCast(target, SPELL_DEFILE); @@ -1059,7 +1060,6 @@ class boss_the_lich_king : public CreatureScript summon->RemoveAurasDueToSpell(SPELL_VILE_SPIRIT_MOVE_SEARCH); summon->RemoveAurasDueToSpell(SPELL_VILE_SPIRIT_DAMAGE_SEARCH); summon->GetMotionMaster()->MoveTargetedHome(); - summon->GetMotionMaster()->MoveRandom(10.0f); } else if (summon->GetEntry() == NPC_RAGING_SPIRIT) summon->AI()->DoAction(ACTION_DISABLE_RAGING); @@ -1076,6 +1076,7 @@ class boss_the_lich_king : public CreatureScript { triggers.sort(Trinity::ObjectDistanceOrderPred(terenas, true)); Creature* spawner = triggers.front(); + spawner->setActive(true); spawner->CastSpell(spawner, SPELL_SUMMON_SPIRIT_BOMB_1, true); // summons bombs randomly spawner->CastSpell(spawner, SPELL_SUMMON_SPIRIT_BOMB_2, true); // summons bombs on players spawner->m_Events.AddEvent(new TriggerWickedSpirit(spawner), spawner->m_Events.CalculateTime(3000)); @@ -1119,11 +1120,11 @@ class boss_the_lich_king : public CreatureScript Talk(SAY_LK_OUTRO_6); if (Creature* tirion = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_HIGHLORD_TIRION_FORDRING))) tirion->SetFacingToObject(me); - me->CastSpell((Unit*)nullptr, SPELL_SUMMON_BROKEN_FROSTMOURNE_3, TRIGGERED_IGNORE_CAST_IN_PROGRESS); + me->CastSpell(nullptr, SPELL_SUMMON_BROKEN_FROSTMOURNE_3, TRIGGERED_IGNORE_CAST_IN_PROGRESS); SetEquipmentSlots(false, EQUIP_UNEQUIP); break; case EVENT_OUTRO_SOUL_BARRAGE: - me->CastSpell((Unit*)nullptr, SPELL_SOUL_BARRAGE, TRIGGERED_IGNORE_CAST_IN_PROGRESS); + me->CastSpell(nullptr, SPELL_SOUL_BARRAGE, TRIGGERED_IGNORE_CAST_IN_PROGRESS); sCreatureTextMgr->SendSound(me, SOUND_PAIN, CHAT_MSG_MONSTER_YELL, 0, TEXT_RANGE_NORMAL, TEAM_OTHER, false); // set flight me->SetDisableGravity(true); @@ -1693,7 +1694,7 @@ class npc_strangulate_vehicle : public CreatureScript { if (Unit* summoner = summ->GetSummoner()) { - summoner->CastSpell((Unit*)nullptr, SPELL_HARVEST_SOUL_VISUAL, true); + summoner->CastSpell(nullptr, SPELL_HARVEST_SOUL_VISUAL, true); summoner->ExitVehicle(summoner); if (!IsHeroic()) summoner->CastSpell(summoner, SPELL_HARVEST_SOUL_TELEPORT, true); @@ -1775,7 +1776,7 @@ class npc_terenas_menethil : public CreatureScript } break; case ACTION_TELEPORT_BACK: - me->CastSpell((Unit*)nullptr, SPELL_RESTORE_SOUL, TRIGGERED_NONE); + me->CastSpell(nullptr, SPELL_RESTORE_SOUL, TRIGGERED_NONE); me->DespawnOrUnsummon(3000); break; default: @@ -1805,7 +1806,7 @@ class npc_terenas_menethil : public CreatureScript _events.ScheduleEvent(EVENT_TELEPORT_BACK, 1000); if (Creature* warden = me->FindNearestCreature(NPC_SPIRIT_WARDEN, 20.0f)) { - warden->CastSpell((Unit*)nullptr, SPELL_DESTROY_SOUL, TRIGGERED_NONE); + warden->CastSpell(nullptr, SPELL_DESTROY_SOUL, TRIGGERED_NONE); warden->DespawnOrUnsummon(2000); } @@ -1863,7 +1864,7 @@ class npc_terenas_menethil : public CreatureScript case EVENT_DESTROY_SOUL: me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); if (Creature* warden = me->FindNearestCreature(NPC_SPIRIT_WARDEN, 20.0f)) - warden->CastSpell((Unit*)nullptr, SPELL_DESTROY_SOUL, TRIGGERED_NONE); + warden->CastSpell(nullptr, SPELL_DESTROY_SOUL, TRIGGERED_NONE); DoCast(SPELL_TERENAS_LOSES_INSIDE); _events.ScheduleEvent(EVENT_TELEPORT_BACK, 1000); break; @@ -1976,20 +1977,29 @@ class npc_spirit_bomb : public CreatureScript if (type != POINT_MOTION_TYPE || point != POINT_GROUND) return; - me->RemoveAllAuras(); - DoCastAOE(SPELL_EXPLOSION); - me->DespawnOrUnsummon(1000); + _events.ScheduleEvent(EVENT_BOMB_EXPLOSION, 3000); } void AttackStart(Unit* /*victim*/) override { } - void UpdateAI(uint32 /*diff*/) override + void UpdateAI(uint32 diff) override { UpdateVictim(); - // no melee attacks + + _events.Update(diff); + + if (_events.ExecuteEvent() == EVENT_BOMB_EXPLOSION) + { + me->RemoveAllAuras(); + DoCastAOE(SPELL_EXPLOSION); + me->DespawnOrUnsummon(1000); + } } + + private: + EventMap _events; }; CreatureAI* GetAI(Creature* creature) const override @@ -2318,7 +2328,7 @@ class spell_the_lich_king_shadow_trap_periodic : public SpellScriptLoader if (targets.empty()) return; - GetCaster()->CastSpell((Unit*)nullptr, SPELL_SHADOW_TRAP_KNOCKBACK, true); + GetCaster()->CastSpell(nullptr, SPELL_SHADOW_TRAP_KNOCKBACK, true); } void Register() override @@ -2511,8 +2521,9 @@ class spell_the_lich_king_summon_into_air : public SpellScriptLoader // spirit bombs get higher if (GetSpellInfo()->Effects[effIndex].MiscValue == NPC_SPIRIT_BOMB) { - dest->RelocateOffset(offset); - GetHitDest()->RelocateOffset(offset); + static Position const offsetExtra = { 0.0f, 0.0f, 5.0f, 0.0f }; + dest->RelocateOffset(offsetExtra); + GetHitDest()->RelocateOffset(offsetExtra); } } @@ -2700,7 +2711,7 @@ class spell_the_lich_king_vile_spirits : public SpellScriptLoader void OnPeriodic(AuraEffect const* aurEff) { if (_is25Man || ((aurEff->GetTickNumber() - 1) % 5)) - GetTarget()->CastSpell((Unit*)nullptr, GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell, true, nullptr, aurEff, GetCasterGUID()); + GetTarget()->CastSpell(nullptr, GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell, true, nullptr, aurEff, GetCasterGUID()); } void Register() override @@ -2823,7 +2834,7 @@ class spell_the_lich_king_vile_spirit_damage_target_search : public SpellScriptL if (TempSummon* summon = GetCaster()->ToTempSummon()) if (Unit* summoner = summon->GetSummoner()) summoner->GetAI()->SetData(DATA_VILE, 1); - GetCaster()->CastSpell((Unit*)nullptr, SPELL_SPIRIT_BURST, true); + GetCaster()->CastSpell(nullptr, SPELL_SPIRIT_BURST, true); GetCaster()->ToCreature()->DespawnOrUnsummon(3000); GetCaster()->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); } @@ -2858,7 +2869,7 @@ class spell_the_lich_king_harvest_soul : public SpellScriptLoader { // m_originalCaster to allow stacking from different casters, meh if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_DEATH) - GetTarget()->CastSpell((Unit*)nullptr, SPELL_HARVESTED_SOUL, true, nullptr, nullptr, GetTarget()->GetInstanceScript()->GetGuidData(DATA_THE_LICH_KING)); + GetTarget()->CastSpell(nullptr, SPELL_HARVESTED_SOUL, true, nullptr, nullptr, GetTarget()->GetInstanceScript()->GetGuidData(DATA_THE_LICH_KING)); } void Register() override @@ -3054,7 +3065,7 @@ class spell_the_lich_king_in_frostmourne_room : public SpellScriptLoader { // m_originalCaster to allow stacking from different casters, meh if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_DEATH) - GetTarget()->CastSpell((Unit*)nullptr, SPELL_HARVESTED_SOUL, true, nullptr, nullptr, GetTarget()->GetInstanceScript()->GetGuidData(DATA_THE_LICH_KING)); + GetTarget()->CastSpell(nullptr, SPELL_HARVESTED_SOUL, true, nullptr, nullptr, GetTarget()->GetInstanceScript()->GetGuidData(DATA_THE_LICH_KING)); } void Register() override @@ -3081,7 +3092,7 @@ class spell_the_lich_king_summon_spirit_bomb : public SpellScriptLoader void HandleScript(SpellEffIndex effIndex) { PreventHitDefaultEffect(effIndex); - GetHitUnit()->CastSpell((Unit*)nullptr, uint32(GetEffectValue()), true); + GetHitUnit()->CastSpell(nullptr, uint32(GetEffectValue()), true); } void Register() override @@ -3139,7 +3150,7 @@ class spell_the_lich_king_jump : public SpellScriptLoader { PreventHitDefaultEffect(effIndex); GetHitUnit()->RemoveAurasDueToSpell(SPELL_RAISE_DEAD); - GetHitUnit()->CastSpell((Unit*)nullptr, SPELL_JUMP_2, true); + GetHitUnit()->CastSpell(nullptr, SPELL_JUMP_2, true); if (Creature* creature = GetHitCreature()) creature->AI()->DoAction(ACTION_BREAK_FROSTMOURNE); } diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp index 493b759e0f7..d2cc08dcc6e 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp @@ -264,7 +264,7 @@ class ValithriaDespawner : public BasicEvent creature->SetRespawnDelay(10); if (CreatureData const* data = creature->GetCreatureData()) - creature->UpdatePosition(data->posX, data->posY, data->posZ, data->orientation); + creature->UpdatePosition(data->spawnPoint); creature->DespawnOrUnsummon(); creature->SetCorpseDelay(corpseDelay); @@ -1467,7 +1467,7 @@ class spell_dreamwalker_twisted_nightmares : public SpellScriptLoader // return; if (InstanceScript* instance = GetHitUnit()->GetInstanceScript()) - GetHitUnit()->CastSpell((Unit*)nullptr, GetSpellInfo()->Effects[effIndex].TriggerSpell, true, nullptr, nullptr, instance->GetGuidData(DATA_VALITHRIA_DREAMWALKER)); + GetHitUnit()->CastSpell(nullptr, GetSpellInfo()->Effects[effIndex].TriggerSpell, true, nullptr, nullptr, instance->GetGuidData(DATA_VALITHRIA_DREAMWALKER)); } void Register() override diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp index ed85ee3fa17..59a95ae0b9c 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp @@ -354,7 +354,7 @@ class FrostwingGauntletRespawner creature->SetRespawnDelay(2); if (CreatureData const* data = creature->GetCreatureData()) - creature->UpdatePosition(data->posX, data->posY, data->posZ, data->orientation); + creature->UpdatePosition(data->spawnPoint); creature->DespawnOrUnsummon(); creature->SetCorpseDelay(corpseDelay); @@ -955,9 +955,9 @@ class npc_crok_scourgebane : public CreatureScript public: npc_crok_scourgebane() : CreatureScript("npc_crok_scourgebane") { } - struct npc_crok_scourgebaneAI : public npc_escortAI + struct npc_crok_scourgebaneAI : public EscortAI { - npc_crok_scourgebaneAI(Creature* creature) : npc_escortAI(creature), + npc_crok_scourgebaneAI(Creature* creature) : EscortAI(creature), _instance(creature->GetInstanceScript()), _respawnTime(creature->GetRespawnDelay()), _corpseDelay(creature->GetCorpseDelay()) { @@ -1036,7 +1036,7 @@ class npc_crok_scourgebane : public CreatureScript } } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { switch (waypointId) { @@ -1067,7 +1067,7 @@ class npc_crok_scourgebane : public CreatureScript } } - void WaypointStart(uint32 waypointId) override + void WaypointStarted(uint32 waypointId, uint32 /*pathId*/) override { _currentWPid = waypointId; switch (waypointId) diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h index e40ba687312..a9ea390e834 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h +++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h @@ -120,7 +120,9 @@ enum ICDataTypes DATA_TERENAS_MENETHIL = 39, DATA_ENEMY_GUNSHIP = 40, DATA_UPPERSPIRE_TELE_ACT = 41, /// also used by conditions - DATA_BLOOD_QUEEN_LANA_THEL_COUNCIL = 42 + DATA_BLOOD_QUEEN_LANA_THEL_COUNCIL = 42, + DATA_BLOOD_PRINCE_COUNCIL_INTRO = 43, + DATA_SINDRAGOSA_INTRO = 44 }; enum ICCreaturesIds diff --git a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp index ffc899b4d0d..c986bb25c6b 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp @@ -147,6 +147,8 @@ class instance_icecrown_citadel : public InstanceMapScript UpperSpireTeleporterActiveState = NOT_STARTED; BloodQuickeningState = NOT_STARTED; BloodQuickeningMinutes = 0; + BloodPrinceIntro = 1; + SindragosaIntro = 1; } // A function to help reduce the number of lines for teleporter management. @@ -392,13 +394,13 @@ class instance_icecrown_citadel : public InstanceMapScript break; case NPC_ZAFOD_BOOMBOX: if (GameObjectTemplate const* go = sObjectMgr->GetGameObjectTemplate(GO_THE_SKYBREAKER_A)) - if ((TeamInInstance == ALLIANCE && data->mapid == go->moTransport.mapID) || - (TeamInInstance == HORDE && data->mapid != go->moTransport.mapID)) + if ((TeamInInstance == ALLIANCE && data->spawnPoint.GetMapId() == go->moTransport.mapID) || + (TeamInInstance == HORDE && data->spawnPoint.GetMapId() != go->moTransport.mapID)) return entry; return 0; case NPC_IGB_MURADIN_BRONZEBEARD: - if ((TeamInInstance == ALLIANCE && data->posX > 10.0f) || - (TeamInInstance == HORDE && data->posX < 10.0f)) + if ((TeamInInstance == ALLIANCE && data->spawnPoint.GetPositionX() > 10.0f) || + (TeamInInstance == HORDE && data->spawnPoint.GetPositionX() < 10.0f)) return entry; return 0; default: @@ -739,6 +741,10 @@ class instance_icecrown_citadel : public InstanceMapScript return BloodQuickeningState; case DATA_HEROIC_ATTEMPTS: return HeroicAttempts; + case DATA_BLOOD_PRINCE_COUNCIL_INTRO: + return BloodPrinceIntro; + case DATA_SINDRAGOSA_INTRO: + return SindragosaIntro; default: break; } @@ -1116,6 +1122,12 @@ class instance_icecrown_citadel : public InstanceMapScript SaveToDB(); } break; + case DATA_BLOOD_PRINCE_COUNCIL_INTRO: + BloodPrinceIntro = data; + break; + case DATA_SINDRAGOSA_INTRO: + SindragosaIntro = data; + break; default: break; } @@ -1308,7 +1320,7 @@ class instance_icecrown_citadel : public InstanceMapScript return; stalkers.sort(Trinity::ObjectDistanceOrderPred(teleporter)); - stalkers.front()->CastSpell((Unit*)nullptr, SPELL_ARTHAS_TELEPORTER_CEREMONY, false); + stalkers.front()->CastSpell(nullptr, SPELL_ARTHAS_TELEPORTER_CEREMONY, false); stalkers.pop_front(); for (std::list<Creature*>::iterator itr = stalkers.begin(); itr != stalkers.end(); ++itr) (*itr)->AI()->Reset(); @@ -1530,6 +1542,8 @@ class instance_icecrown_citadel : public InstanceMapScript uint32 BloodQuickeningState; uint32 HeroicAttempts; uint16 BloodQuickeningMinutes; + uint8 BloodPrinceIntro; + uint8 SindragosaIntro; bool IsBonedEligible; bool IsOozeDanceEligible; bool IsNauseaEligible; diff --git a/src/server/scripts/Northrend/Naxxramas/boss_anubrekhan.cpp b/src/server/scripts/Northrend/Naxxramas/boss_anubrekhan.cpp index 5454ff7c848..8a481bff9ce 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_anubrekhan.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_anubrekhan.cpp @@ -96,7 +96,7 @@ public: void InitializeAI() override { - if (!me->isDead()) + if (!me->isDead() && instance->GetBossState(BOSS_ANUBREKHAN) != DONE) { Reset(); SummonGuards(); @@ -239,20 +239,19 @@ public: }; -class at_anubrekhan_entrance : public AreaTriggerScript +class at_anubrekhan_entrance : public OnlyOnceAreaTriggerScript { public: - at_anubrekhan_entrance() : AreaTriggerScript("at_anubrekhan_entrance") { } + at_anubrekhan_entrance() : OnlyOnceAreaTriggerScript("at_anubrekhan_entrance") { } - bool OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/) override + bool _OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/) override { InstanceScript* instance = player->GetInstanceScript(); - if (!instance || instance->GetData(DATA_HAD_ANUBREKHAN_GREET) || instance->GetBossState(BOSS_ANUBREKHAN) != NOT_STARTED) + if (!instance || instance->GetBossState(BOSS_ANUBREKHAN) != NOT_STARTED) return true; if (Creature* anub = ObjectAccessor::GetCreature(*player, instance->GetGuidData(DATA_ANUBREKHAN))) anub->AI()->Talk(SAY_GREET); - instance->SetData(DATA_HAD_ANUBREKHAN_GREET, 1u); return true; } diff --git a/src/server/scripts/Northrend/Naxxramas/boss_faerlina.cpp b/src/server/scripts/Northrend/Naxxramas/boss_faerlina.cpp index da3d95a5173..9b7df0d4f40 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_faerlina.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_faerlina.cpp @@ -83,7 +83,7 @@ class boss_faerlina : public CreatureScript void InitializeAI() override { - if (!me->isDead()) + if (!me->isDead() && instance->GetBossState(BOSS_FAERLINA) != DONE) { Reset(); SummonAdds(); @@ -260,20 +260,19 @@ class achievement_momma_said_knock_you_out : public AchievementCriteriaScript } }; -class at_faerlina_entrance : public AreaTriggerScript +class at_faerlina_entrance : public OnlyOnceAreaTriggerScript { public: - at_faerlina_entrance() : AreaTriggerScript("at_faerlina_entrance") { } + at_faerlina_entrance() : OnlyOnceAreaTriggerScript("at_faerlina_entrance") { } - bool OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/) override + bool _OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/) override { InstanceScript* instance = player->GetInstanceScript(); - if (!instance || instance->GetData(DATA_HAD_FAERLINA_GREET) || instance->GetBossState(BOSS_FAERLINA) != NOT_STARTED) + if (!instance || instance->GetBossState(BOSS_FAERLINA) != NOT_STARTED) return true; if (Creature* faerlina = ObjectAccessor::GetCreature(*player, instance->GetGuidData(DATA_FAERLINA))) faerlina->AI()->Talk(SAY_GREET); - instance->SetData(DATA_HAD_FAERLINA_GREET, 1u); return true; } diff --git a/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp b/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp index 0fb00d18fd3..51deb5b4375 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp @@ -265,14 +265,9 @@ struct boss_four_horsemen_baseAI : public BossAI for (Horseman boss : horsemen) { if (Creature* cBoss = getHorsemanHandle(boss)) - { - cBoss->DespawnOrUnsummon(); - cBoss->SetRespawnTime(15); - } + cBoss->DespawnOrUnsummon(0, Seconds(15)); else - { TC_LOG_WARN("scripts", "FourHorsemenAI: Encounter resetting but horseman with id %u is not present", uint32(boss)); - } } } diff --git a/src/server/scripts/Northrend/Naxxramas/boss_heigan.cpp b/src/server/scripts/Northrend/Naxxramas/boss_heigan.cpp index add15715165..75e1a5b2386 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_heigan.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_heigan.cpp @@ -123,7 +123,7 @@ public: events.ScheduleEvent(EVENT_DISRUPT, randtime(Seconds(15), Seconds(20)), 0, PHASE_FIGHT); events.ScheduleEvent(EVENT_FEVER, randtime(Seconds(10), Seconds(20)), 0, PHASE_FIGHT); events.ScheduleEvent(EVENT_DANCE, Minutes(1) + Seconds(30), 0, PHASE_FIGHT); - events.ScheduleEvent(EVENT_ERUPT, Seconds(15), 0, PHASE_FIGHT); + events.ScheduleEvent(EVENT_ERUPT, Seconds(15)); _safetyDance = true; @@ -172,7 +172,7 @@ public: DoCast(SPELL_TELEPORT_SELF); DoCastAOE(SPELL_PLAGUE_CLOUD); events.ScheduleEvent(EVENT_DANCE_END, Seconds(45), 0, PHASE_DANCE); - events.ScheduleEvent(EVENT_ERUPT, Seconds(10)); + events.RescheduleEvent(EVENT_ERUPT, Seconds(10)); break; case EVENT_DANCE_END: events.SetPhase(PHASE_FIGHT); @@ -181,7 +181,7 @@ public: events.ScheduleEvent(EVENT_DISRUPT, randtime(Seconds(10), Seconds(25)), 0, PHASE_FIGHT); events.ScheduleEvent(EVENT_FEVER, randtime(Seconds(15), Seconds(20)), 0, PHASE_FIGHT); events.ScheduleEvent(EVENT_DANCE, Minutes(1) + Seconds(30), 0, PHASE_FIGHT); - events.ScheduleEvent(EVENT_ERUPT, Seconds(15), 0, PHASE_FIGHT); + events.RescheduleEvent(EVENT_ERUPT, Seconds(15)); me->CastStop(); me->SetReactState(REACT_AGGRESSIVE); DoZoneInCombat(); diff --git a/src/server/scripts/Northrend/Naxxramas/boss_patchwerk.cpp b/src/server/scripts/Northrend/Naxxramas/boss_patchwerk.cpp index 46ab982c8a9..adce3c76070 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_patchwerk.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_patchwerk.cpp @@ -127,29 +127,29 @@ public: auto list = mgr.GetModifiableThreatList(); auto it = list.begin(), end = list.end(); if (it == end) + { EnterEvadeMode(EVADE_REASON_NO_HOSTILES); + return; + } if ((*it)->GetVictim() != currentVictim) secondThreat = *it; - if ((!secondThreat || Is25ManRaid()) && (++it != end)) + if ((!secondThreat || Is25ManRaid()) && (++it != end && (*it)->IsAvailable())) { if ((*it)->GetVictim() != currentVictim) (secondThreat ? thirdThreat : secondThreat) = *it; - if (!thirdThreat && Is25ManRaid() && (++it != end)) + if (!thirdThreat && Is25ManRaid() && (++it != end && (*it)->IsAvailable())) thirdThreat = *it; } Unit* pHatefulTarget = nullptr; - if (!thirdThreat) + if (!secondThreat) + pHatefulTarget = currentVictim; + else if (!thirdThreat) pHatefulTarget = secondThreat->GetVictim(); - else if (secondThreat) + else pHatefulTarget = (secondThreat->GetVictim()->GetHealth() < thirdThreat->GetVictim()->GetHealth()) ? thirdThreat->GetVictim() : secondThreat->GetVictim(); - if (!pHatefulTarget) - pHatefulTarget = me->GetVictim(); - - DoCast(pHatefulTarget, SPELL_HATEFUL_STRIKE, true); - // add threat to highest threat targets AddThreat(currentVictim, HATEFUL_THREAT_AMT); if (secondThreat) @@ -157,6 +157,8 @@ public: if (thirdThreat) thirdThreat->AddThreat(HATEFUL_THREAT_AMT); + DoCast(pHatefulTarget, SPELL_HATEFUL_STRIKE, true); + events.Repeat(Seconds(1)); break; } diff --git a/src/server/scripts/Northrend/Naxxramas/boss_razuvious.cpp b/src/server/scripts/Northrend/Naxxramas/boss_razuvious.cpp index 58da5a92295..ac27c44d1de 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_razuvious.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_razuvious.cpp @@ -79,7 +79,7 @@ public: void InitializeAI() override { - if (!me->isDead()) + if (!me->isDead() && instance->GetBossState(BOSS_RAZUVIOUS) != DONE) { Reset(); SummonAdds(); diff --git a/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp b/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp index 9f82e3ce4b3..1f279323591 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp @@ -31,15 +31,12 @@ enum Phases PHASE_NOT_ENGAGED = 1, PHASE_PETS, PHASE_TRANSITION, - PHASE_THADDIUS, - PHASE_RESETTING + PHASE_THADDIUS }; enum AIActions { - ACTION_RESET_ENCOUNTER_TIMER = -1, // sent from instance AI ACTION_BEGIN_RESET_ENCOUNTER = 0, // sent from thaddius to pets to trigger despawn and encounter reset - ACTION_RESET_ENCOUNTER, // sent from thaddius to pets to trigger respawn and full reset ACTION_FEUGEN_DIED, // sent from respective pet to thaddius to indicate death ACTION_STALAGG_DIED, // ^ ACTION_FEUGEN_RESET, // pet to thaddius @@ -160,321 +157,291 @@ enum ThaddiusSpells SPELL_NEGATIVE_CHARGE_AMP = 29660, }; -class boss_thaddius : public CreatureScript +struct boss_thaddius : public BossAI { -public: - boss_thaddius() : CreatureScript("boss_thaddius") { } - - CreatureAI* GetAI(Creature* creature) const override - { - return GetNaxxramasAI<boss_thaddiusAI>(creature); - } - - struct boss_thaddiusAI : public BossAI - { - public: - boss_thaddiusAI(Creature* creature) : BossAI(creature, BOSS_THADDIUS), stalaggAlive(true), feugenAlive(true), ballLightningUnlocked(false), ballLightningEnabled(false), shockingEligibility(true) {} + public: + boss_thaddius(Creature* creature) : BossAI(creature, BOSS_THADDIUS), stalaggAlive(true), feugenAlive(true), ballLightningUnlocked(false), ballLightningEnabled(false), shockingEligibility(true) {} - void InitializeAI() override + void InitializeAI() override + { + if (instance->GetBossState(BOSS_THADDIUS) != DONE) { - if (instance->GetBossState(BOSS_THADDIUS) != DONE) - { - events.SetPhase(PHASE_NOT_ENGAGED); - SetCombatMovement(false); - - // initialize everything properly, and ensure that the coils are loaded by the time we initialize - BeginResetEncounter(true); - } + events.SetPhase(PHASE_NOT_ENGAGED); + SetCombatMovement(false); } + } - void KilledUnit(Unit* victim) override - { - if (victim->GetTypeId() == TYPEID_PLAYER) - Talk(SAY_SLAY); - } + void KilledUnit(Unit* victim) override + { + if (victim->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_SLAY); + } - void Reset() override { } + void Reset() override { } - void EnterEvadeMode(EvadeReason why) override + void EnterEvadeMode(EvadeReason why) override + { + if (!ballLightningEnabled && why == EVADE_REASON_NO_HOSTILES) { - if (!ballLightningEnabled && why == EVADE_REASON_NO_HOSTILES) - { - ballLightningEnabled = true; - return; // try again - } - if (events.IsInPhase(PHASE_TRANSITION) || (events.IsInPhase(PHASE_THADDIUS) && me->IsAlive())) - BeginResetEncounter(); + ballLightningEnabled = true; + return; // try again } + if (events.IsInPhase(PHASE_TRANSITION) || (events.IsInPhase(PHASE_THADDIUS) && me->IsAlive())) + BeginResetEncounter(); + } - bool CanAIAttack(Unit const* who) const override - { - if (ballLightningEnabled || me->IsWithinMeleeRange(who)) - return BossAI::CanAIAttack(who); - else - return false; - } + bool CanAIAttack(Unit const* who) const override + { + if (ballLightningEnabled || me->IsWithinMeleeRange(who)) + return BossAI::CanAIAttack(who); + else + return false; + } - void JustRespawned() override - { - if (events.IsInPhase(PHASE_RESETTING)) - ResetEncounter(); - } + void JustAppeared() override + { + if (instance->GetBossState(BOSS_THADDIUS) != DONE) + ResetEncounter(); + } - void JustDied(Unit* /*killer*/) override - { - _JustDied(); - me->setActive(false); - if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG))) - stalagg->setActive(false); - if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN))) - feugen->setActive(false); - Talk(SAY_DEATH); - } + void JustDied(Unit* /*killer*/) override + { + _JustDied(); + me->setActive(false); + if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG))) + stalagg->setActive(false); + if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN))) + feugen->setActive(false); + Talk(SAY_DEATH); + } - void DoAction(int32 action) override + void DoAction(int32 action) override + { + switch (action) { - switch (action) - { - case ACTION_RESET_ENCOUNTER_TIMER: - if (events.IsInPhase(PHASE_RESETTING)) - ResetEncounter(); - break; - case ACTION_FEUGEN_RESET: - case ACTION_STALAGG_RESET: - if (!events.IsInPhase(PHASE_NOT_ENGAGED) && !events.IsInPhase(PHASE_RESETTING)) - BeginResetEncounter(); - break; - case ACTION_FEUGEN_AGGRO: - case ACTION_STALAGG_AGGRO: - if (events.IsInPhase(PHASE_RESETTING)) - { - BeginResetEncounter(); - return; - } - if (!events.IsInPhase(PHASE_NOT_ENGAGED)) - return; - events.SetPhase(PHASE_PETS); - - shockingEligibility = true; - - if (!instance->CheckRequiredBosses(BOSS_THADDIUS)) - { - BeginResetEncounter(); - return; - } - instance->SetBossState(BOSS_THADDIUS, IN_PROGRESS); + case ACTION_FEUGEN_RESET: + case ACTION_STALAGG_RESET: + if (!events.IsInPhase(PHASE_NOT_ENGAGED)) + BeginResetEncounter(); + break; + case ACTION_FEUGEN_AGGRO: + case ACTION_STALAGG_AGGRO: + if (!events.IsInPhase(PHASE_NOT_ENGAGED)) + return; + events.SetPhase(PHASE_PETS); - me->setActive(true); - DoZoneInCombat(); - if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG))) - stalagg->setActive(true); - if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN))) - feugen->setActive(true); - break; - case ACTION_FEUGEN_DIED: - if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN))) - feugen->AI()->DoAction(ACTION_FEUGEN_REVIVING_FX); - feugenAlive = false; - if (stalaggAlive) - events.ScheduleEvent(EVENT_REVIVE_FEUGEN, Seconds(5), 0, PHASE_PETS); - else - Transition(); + shockingEligibility = true; - break; - case ACTION_STALAGG_DIED: - if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG))) - stalagg->AI()->DoAction(ACTION_STALAGG_REVIVING_FX); - stalaggAlive = false; - if (feugenAlive) - events.ScheduleEvent(EVENT_REVIVE_STALAGG, Seconds(5), 0, PHASE_PETS); - else - Transition(); - - break; + if (!instance->CheckRequiredBosses(BOSS_THADDIUS)) + { + BeginResetEncounter(); + return; + } + instance->SetBossState(BOSS_THADDIUS, IN_PROGRESS); + + me->setActive(true); + DoZoneInCombat(); + if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG))) + stalagg->setActive(true); + if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN))) + feugen->setActive(true); + break; + case ACTION_FEUGEN_DIED: + if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN))) + feugen->AI()->DoAction(ACTION_FEUGEN_REVIVING_FX); + feugenAlive = false; + if (stalaggAlive) + events.ScheduleEvent(EVENT_REVIVE_FEUGEN, Seconds(5), 0, PHASE_PETS); + else + Transition(); + + break; + case ACTION_STALAGG_DIED: + if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG))) + stalagg->AI()->DoAction(ACTION_STALAGG_REVIVING_FX); + stalaggAlive = false; + if (feugenAlive) + events.ScheduleEvent(EVENT_REVIVE_STALAGG, Seconds(5), 0, PHASE_PETS); + else + Transition(); - case ACTION_POLARITY_CROSSED: - shockingEligibility = false; - break; - default: - break; - } - } + break; - uint32 GetData(uint32 id) const override - { - return (id == DATA_POLARITY_CROSSED && shockingEligibility) ? 1u : 0u; + case ACTION_POLARITY_CROSSED: + shockingEligibility = false; + break; + default: + break; } + } - void Transition() // initiate transition between pet phase and thaddius phase - { - events.SetPhase(PHASE_TRANSITION); - - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - - events.ScheduleEvent(EVENT_TRANSITION_1, Seconds(10), 0, PHASE_TRANSITION); - events.ScheduleEvent(EVENT_TRANSITION_2, Seconds(12), 0, PHASE_TRANSITION); - events.ScheduleEvent(EVENT_TRANSITION_3, Seconds(14), 0, PHASE_TRANSITION); - } + uint32 GetData(uint32 id) const override + { + return (id == DATA_POLARITY_CROSSED && shockingEligibility) ? 1u : 0u; + } - void BeginResetEncounter(bool initial = false) - { - if (instance->GetBossState(BOSS_THADDIUS) == DONE) - return; - if (events.IsInPhase(PHASE_RESETTING)) - return; + void Transition() // initiate transition between pet phase and thaddius phase + { + events.SetPhase(PHASE_TRANSITION); - // remove polarity shift debuffs on reset - instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_POSITIVE_CHARGE_APPLY); - instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_NEGATIVE_CHARGE_APPLY); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->DespawnOrUnsummon(); - me->SetRespawnTime(initial ? 5 : 30); + events.ScheduleEvent(EVENT_TRANSITION_1, Seconds(10), 0, PHASE_TRANSITION); + events.ScheduleEvent(EVENT_TRANSITION_2, Seconds(12), 0, PHASE_TRANSITION); + events.ScheduleEvent(EVENT_TRANSITION_3, Seconds(14), 0, PHASE_TRANSITION); + } - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_STUNNED); - me->SetImmuneToPC(true); - events.SetPhase(PHASE_RESETTING); - if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN))) - feugen->AI()->DoAction(ACTION_BEGIN_RESET_ENCOUNTER); - if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG))) - stalagg->AI()->DoAction(ACTION_BEGIN_RESET_ENCOUNTER); + void BeginResetEncounter() + { + if (instance->GetBossState(BOSS_THADDIUS) == DONE) + return; + + // remove polarity shift debuffs on reset + instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_POSITIVE_CHARGE_APPLY); + instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_NEGATIVE_CHARGE_APPLY); + + me->DespawnOrUnsummon(0, Seconds(30)); + + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_STUNNED); + me->SetImmuneToPC(true); + me->setActive(false); + if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN))) + feugen->AI()->DoAction(ACTION_BEGIN_RESET_ENCOUNTER); + if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG))) + stalagg->AI()->DoAction(ACTION_BEGIN_RESET_ENCOUNTER); + } - me->setActive(false); - } + void ResetEncounter() + { + feugenAlive = true; + stalaggAlive = true; - void ResetEncounter() - { - feugenAlive = true; - stalaggAlive = true; + _Reset(); + events.SetPhase(PHASE_NOT_ENGAGED); + me->SetReactState(REACT_PASSIVE); - _Reset(); - events.SetPhase(PHASE_NOT_ENGAGED); - me->SetReactState(REACT_PASSIVE); + // @todo these guys should really be moved to a summon group - this is merely a hack to make them work in dynamic_spawning + instance->instance->RemoveRespawnTime(SPAWN_TYPE_CREATURE, 130958, true); // Stalagg + instance->instance->RemoveRespawnTime(SPAWN_TYPE_CREATURE, 130959, true); // Feugen + } - if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN))) - feugen->AI()->DoAction(ACTION_RESET_ENCOUNTER); - if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG))) - stalagg->AI()->DoAction(ACTION_RESET_ENCOUNTER); - } + void UpdateAI(uint32 diff) override + { + if (events.IsInPhase(PHASE_NOT_ENGAGED)) + return; + if (events.IsInPhase(PHASE_THADDIUS) && !UpdateVictim()) + return; - void UpdateAI(uint32 diff) override + events.Update(diff); + while (uint32 eventId = events.ExecuteEvent()) { - if (events.IsInPhase(PHASE_NOT_ENGAGED)) - return; - if (events.IsInPhase(PHASE_THADDIUS) && !UpdateVictim()) - return; - - events.Update(diff); - while (uint32 eventId = events.ExecuteEvent()) + switch (eventId) { - switch (eventId) - { - case EVENT_REVIVE_FEUGEN: - feugenAlive = true; - if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN))) - feugen->AI()->DoAction(ACTION_FEUGEN_REVIVED); - break; - case EVENT_REVIVE_STALAGG: - stalaggAlive = true; - if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG))) - stalagg->AI()->DoAction(ACTION_STALAGG_REVIVED); - break; - case EVENT_TRANSITION_1: // tesla coils overload - if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN))) - feugen->AI()->DoAction(ACTION_TRANSITION); - if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG))) - stalagg->AI()->DoAction(ACTION_TRANSITION); - break; - case EVENT_TRANSITION_2: // tesla coils shock thaddius - me->CastSpell(me, SPELL_THADDIUS_SPARK_VISUAL, true); - if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN))) - feugen->AI()->DoAction(ACTION_TRANSITION_2); - if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG))) - stalagg->AI()->DoAction(ACTION_TRANSITION_2); - break; - case EVENT_TRANSITION_3: // thaddius becomes active - me->CastSpell(me, SPELL_THADDIUS_SPARK_VISUAL, true); - ballLightningUnlocked = false; - me->RemoveAura(SPELL_THADDIUS_INACTIVE_VISUAL); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED); - me->SetImmuneToPC(false); - me->SetReactState(REACT_AGGRESSIVE); - - DoZoneInCombat(); - if (Unit* closest = SelectTarget(SELECT_TARGET_MINDISTANCE, 0, 500.0f)) - AttackStart(closest); - else // if there is no nearest target, then there is no target, meaning we should reset - { - BeginResetEncounter(); - return; - } + case EVENT_REVIVE_FEUGEN: + feugenAlive = true; + if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN))) + feugen->AI()->DoAction(ACTION_FEUGEN_REVIVED); + break; + case EVENT_REVIVE_STALAGG: + stalaggAlive = true; + if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG))) + stalagg->AI()->DoAction(ACTION_STALAGG_REVIVED); + break; + case EVENT_TRANSITION_1: // tesla coils overload + if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN))) + feugen->AI()->DoAction(ACTION_TRANSITION); + if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG))) + stalagg->AI()->DoAction(ACTION_TRANSITION); + break; + case EVENT_TRANSITION_2: // tesla coils shock thaddius + me->CastSpell(me, SPELL_THADDIUS_SPARK_VISUAL, true); + if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN))) + feugen->AI()->DoAction(ACTION_TRANSITION_2); + if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG))) + stalagg->AI()->DoAction(ACTION_TRANSITION_2); + break; + case EVENT_TRANSITION_3: // thaddius becomes active + me->CastSpell(me, SPELL_THADDIUS_SPARK_VISUAL, true); + ballLightningUnlocked = false; + me->RemoveAura(SPELL_THADDIUS_INACTIVE_VISUAL); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED); + me->SetImmuneToPC(false); + me->SetReactState(REACT_AGGRESSIVE); - if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN))) - feugen->AI()->DoAction(ACTION_TRANSITION_3); - if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG))) - stalagg->AI()->DoAction(ACTION_TRANSITION_3); + DoZoneInCombat(); + if (Unit* closest = SelectTarget(SELECT_TARGET_MINDISTANCE, 0, 500.0f)) + AttackStart(closest); + else // if there is no nearest target, then there is no target, meaning we should reset + { + BeginResetEncounter(); + return; + } - events.SetPhase(PHASE_THADDIUS); + if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN))) + feugen->AI()->DoAction(ACTION_TRANSITION_3); + if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG))) + stalagg->AI()->DoAction(ACTION_TRANSITION_3); - Talk(SAY_AGGRO); + events.SetPhase(PHASE_THADDIUS); - events.ScheduleEvent(EVENT_ENABLE_BALL_LIGHTNING, Seconds(5), 0, PHASE_THADDIUS); - events.ScheduleEvent(EVENT_SHIFT, Seconds(10), 0, PHASE_THADDIUS); - events.ScheduleEvent(EVENT_CHAIN, randtime(Seconds(10), Seconds(20)), 0, PHASE_THADDIUS); - events.ScheduleEvent(EVENT_BERSERK, Minutes(6), 0, PHASE_THADDIUS); + Talk(SAY_AGGRO); - break; - case EVENT_ENABLE_BALL_LIGHTNING: - ballLightningUnlocked = true; - break; - case EVENT_SHIFT: - me->CastStop(); // shift overrides all other spells - DoCastAOE(SPELL_POLARITY_SHIFT); - events.ScheduleEvent(EVENT_SHIFT_TALK, Seconds(3), PHASE_THADDIUS); - events.ScheduleEvent(EVENT_SHIFT, Seconds(30), PHASE_THADDIUS); - break; - case EVENT_SHIFT_TALK: - Talk(SAY_ELECT); - Talk(EMOTE_POLARITY_SHIFTED); - break; - case EVENT_CHAIN: - if (me->FindCurrentSpellBySpellId(SPELL_POLARITY_SHIFT)) // delay until shift is over - events.Repeat(Seconds(3)); - else - { - me->CastStop(); - DoCastVictim(SPELL_CHAIN_LIGHTNING); - events.Repeat(randtime(Seconds(10), Seconds(20))); - } - break; - case EVENT_BERSERK: + events.ScheduleEvent(EVENT_ENABLE_BALL_LIGHTNING, Seconds(5), 0, PHASE_THADDIUS); + events.ScheduleEvent(EVENT_SHIFT, Seconds(10), 0, PHASE_THADDIUS); + events.ScheduleEvent(EVENT_CHAIN, randtime(Seconds(10), Seconds(20)), 0, PHASE_THADDIUS); + events.ScheduleEvent(EVENT_BERSERK, Minutes(6), 0, PHASE_THADDIUS); + + break; + case EVENT_ENABLE_BALL_LIGHTNING: + ballLightningUnlocked = true; + break; + case EVENT_SHIFT: + me->CastStop(); // shift overrides all other spells + DoCastAOE(SPELL_POLARITY_SHIFT); + events.ScheduleEvent(EVENT_SHIFT_TALK, Seconds(3), PHASE_THADDIUS); + events.ScheduleEvent(EVENT_SHIFT, Seconds(30), PHASE_THADDIUS); + break; + case EVENT_SHIFT_TALK: + Talk(SAY_ELECT); + Talk(EMOTE_POLARITY_SHIFTED); + break; + case EVENT_CHAIN: + if (me->FindCurrentSpellBySpellId(SPELL_POLARITY_SHIFT)) // delay until shift is over + events.Repeat(Seconds(3)); + else + { me->CastStop(); - DoCast(me, SPELL_BERSERK); - break; - default: - break; - } + DoCastVictim(SPELL_CHAIN_LIGHTNING); + events.Repeat(randtime(Seconds(10), Seconds(20))); + } + break; + case EVENT_BERSERK: + me->CastStop(); + DoCast(me, SPELL_BERSERK); + break; + default: + break; } - if (events.IsInPhase(PHASE_THADDIUS) && !me->HasUnitState(UNIT_STATE_CASTING) && me->isAttackReady()) + } + if (events.IsInPhase(PHASE_THADDIUS) && !me->HasUnitState(UNIT_STATE_CASTING) && me->isAttackReady()) + { + if (me->IsWithinMeleeRange(me->GetVictim())) { - if (me->IsWithinMeleeRange(me->GetVictim())) - { - ballLightningEnabled = false; - DoMeleeAttackIfReady(); - } - else if (ballLightningUnlocked) - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) - DoCast(target, SPELL_BALL_LIGHTNING); + ballLightningEnabled = false; + DoMeleeAttackIfReady(); } + else if (ballLightningUnlocked) + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) + DoCast(target, SPELL_BALL_LIGHTNING); } + } - private: - bool stalaggAlive; - bool feugenAlive; - bool ballLightningUnlocked; // whether the initial ball lightning grace period has expired and we should proceed to exterminate with extreme prejudice - bool ballLightningEnabled; // switch that is flipped to true if we try to evade due to no eligible targets in melee range - bool shockingEligibility; - }; - + private: + bool stalaggAlive; + bool feugenAlive; + bool ballLightningUnlocked; // whether the initial ball lightning grace period has expired and we should proceed to exterminate with extreme prejudice + bool ballLightningEnabled; // switch that is flipped to true if we try to evade due to no eligible targets in melee range + bool shockingEligibility; }; class npc_stalagg : public CreatureScript @@ -527,7 +494,7 @@ public: { if (GameObject* coil = myCoilGO()) coil->SetGoState(GO_STATE_READY); - me->DespawnOrUnsummon(); + me->DespawnOrUnsummon(0, Hours(24*7)); // will be force respawned by thaddius me->setActive(false); } @@ -544,9 +511,6 @@ public: case ACTION_BEGIN_RESET_ENCOUNTER: BeginResetEncounter(); break; - case ACTION_RESET_ENCOUNTER: - ResetEncounter(); - break; case ACTION_STALAGG_REVIVING_FX: break; case ACTION_STALAGG_REVIVED: @@ -571,7 +535,7 @@ public: break; case ACTION_TRANSITION: me->KillSelf(); // true death - me->DespawnOrUnsummon(); + me->DespawnOrUnsummon(0, Hours(24*7)); if (Creature* coil = myCoil()) { @@ -793,16 +757,10 @@ public: { if (GameObject* coil = myCoilGO()) coil->SetGoState(GO_STATE_READY); - me->DespawnOrUnsummon(); + me->DespawnOrUnsummon(0, Hours(24*7)); // will be force respawned by thaddius me->setActive(false); } - void ResetEncounter() - { - me->Respawn(true); - Initialize(); - } - void DoAction(int32 action) override { switch (action) @@ -810,9 +768,6 @@ public: case ACTION_BEGIN_RESET_ENCOUNTER: BeginResetEncounter(); break; - case ACTION_RESET_ENCOUNTER: - ResetEncounter(); - break; case ACTION_FEUGEN_REVIVING_FX: break; case ACTION_FEUGEN_REVIVED: @@ -839,7 +794,7 @@ public: break; case ACTION_TRANSITION: me->KillSelf(); // true death this time around - me->DespawnOrUnsummon(); + me->DespawnOrUnsummon(0, Hours(24*7)); if (Creature* coil = myCoil()) { @@ -1270,20 +1225,19 @@ class spell_thaddius_magnetic_pull : public SpellScriptLoader } }; -class at_thaddius_entrance : public AreaTriggerScript +class at_thaddius_entrance : public OnlyOnceAreaTriggerScript { public: - at_thaddius_entrance() : AreaTriggerScript("at_thaddius_entrance") { } + at_thaddius_entrance() : OnlyOnceAreaTriggerScript("at_thaddius_entrance") { } - bool OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/) override + bool _OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/) override { InstanceScript* instance = player->GetInstanceScript(); - if (!instance || instance->GetData(DATA_HAD_THADDIUS_GREET) || instance->GetBossState(BOSS_THADDIUS) == DONE) + if (!instance || instance->GetBossState(BOSS_THADDIUS) == DONE) return true; if (Creature* thaddius = ObjectAccessor::GetCreature(*player, instance->GetGuidData(DATA_THADDIUS))) thaddius->AI()->Talk(SAY_GREET); - instance->SetData(DATA_HAD_THADDIUS_GREET, 1u); return true; } @@ -1303,7 +1257,7 @@ class achievement_thaddius_shocking : public AchievementCriteriaScript void AddSC_boss_thaddius() { - new boss_thaddius(); + RegisterNaxxramasCreatureAI(boss_thaddius); new npc_stalagg(); new npc_feugen(); new npc_tesla(); diff --git a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp index f8638a33fa0..3e06319a379 100644 --- a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp +++ b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp @@ -121,9 +121,6 @@ class instance_naxxramas : public InstanceMapScript LoadDoorData(doorData); LoadObjectData(nullptr, objectData); - hadAnubRekhanGreet = false; - hadFaerlinaGreet = false; - hadThaddiusGreet = false; hadSapphironBirth = false; CurrentWingTaunt = SAY_KELTHUZAD_FIRST_WING_TAUNT; @@ -279,15 +276,6 @@ class instance_naxxramas : public InstanceMapScript if (GameObject* gate = instance->GetGameObject(GothikGateGUID)) gate->SetGoState(GOState(value)); break; - case DATA_HAD_ANUBREKHAN_GREET: - hadAnubRekhanGreet = (value == 1u); - break; - case DATA_HAD_FAERLINA_GREET: - hadFaerlinaGreet = (value == 1u); - break; - case DATA_HAD_THADDIUS_GREET: - hadThaddiusGreet = (value == 1u); - break; case DATA_HAD_SAPPHIRON_BIRTH: hadSapphironBirth = (value == 1u); break; @@ -300,12 +288,6 @@ class instance_naxxramas : public InstanceMapScript { switch (id) { - case DATA_HAD_ANUBREKHAN_GREET: - return hadAnubRekhanGreet ? 1u : 0u; - case DATA_HAD_FAERLINA_GREET: - return hadFaerlinaGreet ? 1u : 0u; - case DATA_HAD_THADDIUS_GREET: - return hadThaddiusGreet ? 1u : 0u; case DATA_HAD_SAPPHIRON_BIRTH: return hadSapphironBirth ? 1u : 0u; default: @@ -625,9 +607,6 @@ class instance_naxxramas : public InstanceMapScript ObjectGuid PortalsGUID[4]; ObjectGuid KelthuzadDoorGUID; ObjectGuid LichKingGUID; - bool hadAnubRekhanGreet; - bool hadFaerlinaGreet; - bool hadThaddiusGreet; bool hadSapphironBirth; uint8 CurrentWingTaunt; diff --git a/src/server/scripts/Northrend/Naxxramas/naxxramas.h b/src/server/scripts/Northrend/Naxxramas/naxxramas.h index 2813e338245..64e313fea59 100644 --- a/src/server/scripts/Northrend/Naxxramas/naxxramas.h +++ b/src/server/scripts/Northrend/Naxxramas/naxxramas.h @@ -47,9 +47,6 @@ enum NAXEncounter enum NAXData { DATA_GOTHIK_GATE, - DATA_HAD_ANUBREKHAN_GREET, - DATA_HAD_FAERLINA_GREET, - DATA_HAD_THADDIUS_GREET, DATA_HAD_SAPPHIRON_BIRTH, DATA_HORSEMEN_CHECK_ACHIEVEMENT_CREDIT, @@ -224,5 +221,6 @@ inline AI* GetNaxxramasAI(T* obj) { return GetInstanceAI<AI>(obj, NaxxramasScriptName); } +#define RegisterNaxxramasCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetNaxxramasAI) #endif diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp index 8e51d79a87b..a7ea5b57fb0 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp @@ -2142,7 +2142,7 @@ class spell_alexstrasza_bunny_destroy_platform_event : public SpellScriptLoader void HandleScript(SpellEffIndex /*effIndex*/) { - GetCaster()->CastSpell((Unit*)nullptr, SPELL_SUMMON_RED_DRAGON_BUDDY_F_CAST); + GetCaster()->CastSpell(nullptr, SPELL_SUMMON_RED_DRAGON_BUDDY_F_CAST); } void Register() override @@ -2271,7 +2271,7 @@ class spell_malygos_surge_of_power_warning_selector_25 : public SpellScriptLoade void ExecuteMainSpell() { - GetCaster()->ToCreature()->CastSpell((Unit*)nullptr, SPELL_SURGE_OF_POWER_PHASE_3_25); + GetCaster()->ToCreature()->CastSpell(nullptr, SPELL_SURGE_OF_POWER_PHASE_3_25); } void Register() override diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_krystallus.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_krystallus.cpp index 338b273808f..a98fadd56d9 100644 --- a/src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_krystallus.cpp +++ b/src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_krystallus.cpp @@ -156,7 +156,7 @@ class spell_krystallus_shatter : public SpellScriptLoader if (Unit* target = GetHitUnit()) { target->RemoveAurasDueToSpell(SPELL_STONED); - target->CastSpell((Unit*)nullptr, SPELL_SHATTER_EFFECT, true); + target->CastSpell(nullptr, SPELL_SHATTER_EFFECT, true); } } diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfStone/halls_of_stone.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfStone/halls_of_stone.cpp index fc54e6fec54..80d59691fb5 100644 --- a/src/server/scripts/Northrend/Ulduar/HallsOfStone/halls_of_stone.cpp +++ b/src/server/scripts/Northrend/Ulduar/HallsOfStone/halls_of_stone.cpp @@ -271,9 +271,9 @@ class npc_brann_hos : public CreatureScript public: npc_brann_hos() : CreatureScript("npc_brann_hos") { } - struct npc_brann_hosAI : public npc_escortAI + struct npc_brann_hosAI : public EscortAI { - npc_brann_hosAI(Creature* creature) : npc_escortAI(creature) + npc_brann_hosAI(Creature* creature) : EscortAI(creature) { Initialize(); instance = creature->GetInstanceScript(); @@ -326,7 +326,7 @@ public: lDwarfGUIDList.clear(); } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { switch (waypointId) { diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp index 69d5fa4d2fb..868e337933d 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp @@ -254,7 +254,7 @@ class ActivateLivingConstellation : public BasicEvent if (!_instance || _instance->GetBossState(BOSS_ALGALON) != IN_PROGRESS) return true; // delete event - _owner->CastSpell((Unit*)nullptr, SPELL_TRIGGER_3_ADDS, TRIGGERED_FULL_MASK); + _owner->CastSpell(nullptr, SPELL_TRIGGER_3_ADDS, TRIGGERED_FULL_MASK); _owner->m_Events.AddEvent(this, execTime + urand(45000, 50000)); return false; } @@ -273,7 +273,7 @@ class CosmicSmashDamageEvent : public BasicEvent bool Execute(uint64 /*execTime*/, uint32 /*diff*/) override { - _caster->CastSpell((Unit*)nullptr, SPELL_COSMIC_SMASH_TRIGGERED, TRIGGERED_FULL_MASK); + _caster->CastSpell(nullptr, SPELL_COSMIC_SMASH_TRIGGERED, TRIGGERED_FULL_MASK); return true; } @@ -290,7 +290,7 @@ class SummonUnleashedDarkMatter : public BasicEvent bool Execute(uint64 execTime, uint32 /*diff*/) override { - _caster->CastSpell((Unit*)nullptr, SPELL_SUMMON_UNLEASHED_DARK_MATTER, TRIGGERED_FULL_MASK); + _caster->CastSpell(nullptr, SPELL_SUMMON_UNLEASHED_DARK_MATTER, TRIGGERED_FULL_MASK); _caster->m_Events.AddEvent(this, execTime + 30000); return false; } @@ -474,9 +474,9 @@ class boss_algalon_the_observer : public CreatureScript break; case NPC_BLACK_HOLE: summon->SetReactState(REACT_PASSIVE); - summon->CastSpell((Unit*)nullptr, SPELL_BLACK_HOLE_TRIGGER, TRIGGERED_FULL_MASK); + summon->CastSpell(nullptr, SPELL_BLACK_HOLE_TRIGGER, TRIGGERED_FULL_MASK); summon->CastSpell(summon, SPELL_CONSTELLATION_PHASE_TRIGGER, TRIGGERED_FULL_MASK); - summon->CastSpell((Unit*)nullptr, SPELL_BLACK_HOLE_EXPLOSION); + summon->CastSpell(nullptr, SPELL_BLACK_HOLE_EXPLOSION); summon->CastSpell(summon, SPELL_SUMMON_VOID_ZONE_VISUAL, TRIGGERED_FULL_MASK); break; case NPC_ALGALON_VOID_ZONE_VISUAL_STALKER: @@ -787,7 +787,7 @@ class npc_living_constellation : public CreatureScript me->DespawnOrUnsummon(1); if (InstanceScript* instance = me->GetInstanceScript()) instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, EVENT_ID_SUPERMASSIVE_START); - caster->CastSpell((Unit*)nullptr, SPELL_BLACK_HOLE_CREDIT, TRIGGERED_FULL_MASK); + caster->CastSpell(nullptr, SPELL_BLACK_HOLE_CREDIT, TRIGGERED_FULL_MASK); caster->ToCreature()->DespawnOrUnsummon(1); } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp index aa6e8e955b4..d2e8549a110 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp @@ -17,556 +17,646 @@ #include "ScriptMgr.h" #include "InstanceScript.h" +#include "MotionMaster.h" #include "ObjectAccessor.h" #include "ScriptedCreature.h" +#include "SpellAuras.h" #include "SpellScript.h" #include "ulduar.h" enum AuriayaSpells { // Auriaya - SPELL_SENTINEL_BLAST = 64389, - SPELL_SONIC_SCREECH = 64422, - SPELL_TERRIFYING_SCREECH = 64386, - SPELL_SUMMON_SWARMING_GUARDIAN = 64396, - SPELL_ACTIVATE_DEFENDER = 64449, - SPELL_DEFENDER_TRIGGER = 64448, - SPELL_SUMMON_DEFENDER = 64447, - SPELL_BERSERK = 47008, + SPELL_SENTINEL_BLAST = 64389, + SPELL_SONIC_SCREECH = 64422, + SPELL_TERRIFYING_SCREECH = 64386, + SPELL_SUMMON_SWARMING_GUARDIAN = 64396, + SPELL_ACTIVATE_DEFENDER = 64449, + SPELL_DEFENDER_TRIGGER = 64448, + SPELL_BERSERK = 47008, + SPELL_INSTAKILL_ARACHNOPOD = 64900, // Feral Defender - SPELL_FERAL_RUSH = 64496, - SPELL_FERAL_POUNCE = 64478, - SPELL_SEEPING_ESSENCE = 64458, - SPELL_SUMMON_ESSENCE = 64457, - SPELL_FERAL_ESSENCE = 64455, + SPELL_FERAL_RUSH = 64496, + SPELL_FERAL_RUSH_2 = 64489, + SPELL_FERAL_POUNCE = 64478, + SPELL_SUMMON_ESSENCE = 64457, + SPELL_FERAL_ESSENCE = 64455, + SPELL_SHADOW_PAWS = 64479, + SPELL_REDUCE_CRITCAL = 64481, + SPELL_RANDOM_AGRO_PERIODIC = 61906, + SPELL_PERMANENT_FEIGN_DEATH = 58951, + SPELL_FERAL_ESSENCE_APPLICATION_REMOVAL = 64456, + SPELL_CLEAR_ALL_DEBUFFS = 34098, + SPELL_DROWNED_STATE = 64462, + SPELL_FULL_HEAL = 64460, + + // Seeping Essence Stalker + SPELL_SEEPING_ESSENCE = 64458, // Sanctum Sentry - SPELL_SAVAGE_POUNCE = 64666, - SPELL_RIP_FLESH = 64375, - SPELL_STRENGHT_PACK = 64369, -}; + SPELL_SAVAGE_POUNCE = 64666, + SPELL_RIP_FLESH = 64375, + SPELL_STRENGHT_OF_THE_PACK = 64369, -enum AuriayaNPCs -{ - NPC_SANCTUM_SENTRY = 34014, - NPC_FERAL_DEFENDER = 34035, - NPC_FERAL_DEFENDER_TRIGGER = 34096, - NPC_SEEPING_TRIGGER = 34098, + // Swarming Guardian + SPELL_AGRO_CREATOR = 63709, + SPELL_POUNCE = 64399 }; enum AuriayaEvents { // Auriaya - EVENT_SCREECH = 1, - EVENT_BLAST = 2, - EVENT_TERRIFYING = 3, - EVENT_SUMMON = 4, - EVENT_DEFENDER = 5, - EVENT_ACTIVATE_DEFENDER = 6, - EVENT_RESPAWN_DEFENDER = 7, - EVENT_BERSERK = 8, + EVENT_SONIC_SCREECH = 1, + EVENT_BLAST, + EVENT_TERRIFYING_SCREECH, + EVENT_SWARNING_GUARDIAN, + EVENT_SUMMON_DEFENDER, + EVENT_ACTIVATE_DEFENDER, + EVENT_BERSERK, // Sanctum Sentry - EVENT_RIP = 9, - EVENT_POUNCE = 10, + EVENT_RIP, + EVENT_SAVAGE_POUNCE, // Feral Defender - EVENT_FERAL_POUNCE = 11, - EVENT_RUSH = 12, + EVENT_FERAL_POUNCE, + EVENT_RUSH, + EVENT_START_COMBAT, + EVENT_RESPAWN_DEFENDER, + EVENT_RESPAWN_DEFENDER_2, + EVENT_RESPAWN_DEFENDER_3 }; enum AuriayaYells { - SAY_AGGRO = 0, - SAY_SLAY = 1, - SAY_DEATH = 2, - SAY_BERSERK = 3, - EMOTE_FEAR = 4, - EMOTE_DEFENDER = 5 + SAY_AGGRO = 0, + SAY_SLAY = 1, + SAY_BERSERK = 2, + EMOTE_FEAR = 3, + EMOTE_DEFENDER = 4 }; enum AuriayaActions { - ACTION_CRAZY_CAT_LADY = 0, - ACTION_RESPAWN_DEFENDER + ACTION_CRAZY_CAT_LADY = 0, + ACTION_DEFENDER_DIED }; -#define SENTRY_NUMBER RAID_MODE<uint8>(2, 4) - -enum Mis +enum Misc { - DATA_NINE_LIVES = 30763077, - DATA_CRAZY_CAT_LADY = 30063007 + DATA_NINE_LIVES = 30763077, + DATA_CRAZY_CAT_LADY = 30063007, + PHASE_NONE = 1, + PHASE_COMBAT = 2, + SUMMON_GROUP_10_MAN = 1, + SUMMON_GROUP_25_MAN = 2, + AURIAYA_DEATH_SOUNDID = 15476, + NPC_SANCTUM_SENTRY = 34014 }; -class boss_auriaya : public CreatureScript +class CatsTargetSelector { - public: - boss_auriaya() : CreatureScript("boss_auriaya") { } +public: + CatsTargetSelector(Unit const* unit, float minDist, float maxDist) : _me(unit), _minDist(minDist), _maxDist(maxDist) { } + + bool operator()(Unit* unit) const + { + float dist = _me->GetDistance(unit); + return unit->GetTypeId() == TYPEID_PLAYER && dist >= _minDist && dist < _maxDist && _me->IsWithinLOSInMap(unit); + } + +private: + Unit const* _me; + float _minDist; + float _maxDist; +}; - struct boss_auriayaAI : public BossAI +struct boss_auriaya : public BossAI +{ + boss_auriaya(Creature* creature) : BossAI(creature, BOSS_AURIAYA), _crazyCatLady(true), _nineLives(false) { } + + void Reset() override + { + _Reset(); + _crazyCatLady = true; + _nineLives = false; + HandleCats(true); + } + + void HandleCats(bool isResetting) + { + std::list<Creature*> catList; + me->GetCreatureListWithEntryInGrid(catList, NPC_SANCTUM_SENTRY, 500.0f); + for (std::list<Creature*>::const_iterator itr = catList.begin(); itr != catList.end(); ++itr) { - boss_auriayaAI(Creature* creature) : BossAI(creature, BOSS_AURIAYA) - { - Initialize(); - } - - void Initialize() - { - DefenderGUID.Clear(); - defenderLives = 8; - crazyCatLady = true; - nineLives = false; - } - - void Reset() override - { - _Reset(); - Initialize(); - } - - void EnterCombat(Unit* /*who*/) override - { - _EnterCombat(); - Talk(SAY_AGGRO); - - events.ScheduleEvent(EVENT_SCREECH, urand(45000, 65000)); - events.ScheduleEvent(EVENT_BLAST, urand(20000, 25000)); - events.ScheduleEvent(EVENT_TERRIFYING, urand(20000, 30000)); - events.ScheduleEvent(EVENT_DEFENDER, urand(40000, 55000)); - events.ScheduleEvent(EVENT_SUMMON, urand(45000, 55000)); - events.ScheduleEvent(EVENT_BERSERK, 600000); - } - - void KilledUnit(Unit* who) override - { - if (who->GetTypeId() == TYPEID_PLAYER) - Talk(SAY_SLAY); - } - - void JustSummoned(Creature* summoned) override - { - summons.Summon(summoned); - - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) - { - summoned->AI()->AttackStart(target); - AddThreat(target, 250.0f, summoned); - DoZoneInCombat(summoned); - } - - if (summoned->GetEntry() == NPC_FERAL_DEFENDER) - { - if (!summoned->IsInCombat() && me->GetVictim()) - summoned->AI()->AttackStart(me->GetVictim()); - summoned->SetAuraStack(SPELL_FERAL_ESSENCE, summoned, 9); - DefenderGUID = summoned->GetGUID(); - DoZoneInCombat(summoned); - } - } - - void DoAction(int32 action) override - { - switch (action) - { - case ACTION_CRAZY_CAT_LADY: - SetData(DATA_CRAZY_CAT_LADY, 0); - break; - case ACTION_RESPAWN_DEFENDER: - --defenderLives; - if (!defenderLives) - { - SetData(DATA_NINE_LIVES, 1); - break; - } - events.ScheduleEvent(EVENT_RESPAWN_DEFENDER, 30000); - break; - default: - break; - } - } - - uint32 GetData(uint32 type) const override - { - switch (type) - { - case DATA_NINE_LIVES: - return nineLives ? 1 : 0; - case DATA_CRAZY_CAT_LADY: - return crazyCatLady ? 1 : 0; - } + if (isResetting) + (*itr)->Respawn(); + else + (*itr)->DespawnOrUnsummon(); + } + } + + void EnterCombat(Unit* /*who*/) override + { + _EnterCombat(); + Talk(SAY_AGGRO); + instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me); + events.ScheduleEvent(EVENT_SONIC_SCREECH, Seconds(48)); + events.ScheduleEvent(EVENT_TERRIFYING_SCREECH, Seconds(38)); + events.ScheduleEvent(EVENT_SUMMON_DEFENDER, Seconds(60)); + events.ScheduleEvent(EVENT_SWARNING_GUARDIAN, Seconds(51)); + events.ScheduleEvent(EVENT_BERSERK, Minutes(10)); + } + + void KilledUnit(Unit* who) override + { + if (who->GetTypeId() == TYPEID_PLAYER && roll_chance_i(50)) + Talk(SAY_SLAY); + } + + void DoAction(int32 action) override + { + switch (action) + { + case ACTION_CRAZY_CAT_LADY: + _crazyCatLady = false; + break; + case ACTION_DEFENDER_DIED: + _nineLives = true; + break; + default: + break; + } + } + uint32 GetData(uint32 type) const override + { + switch (type) + { + case DATA_NINE_LIVES: + return _nineLives ? 1 : 0; + case DATA_CRAZY_CAT_LADY: + return _crazyCatLady ? 1 : 0; + default: return 0; - } - - void SetData(uint32 id, uint32 data) override - { - switch (id) - { - case DATA_NINE_LIVES: - nineLives = data ? true : false; - break; - case DATA_CRAZY_CAT_LADY: - crazyCatLady = data ? true : false; - break; - } - } - - void JustDied(Unit* /*killer*/) override + } + } + + void JustDied(Unit* /*killer*/) override + { + _JustDied(); + DoPlaySoundToSet(me, AURIAYA_DEATH_SOUNDID); + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); + HandleCats(false); + } + + void EnterEvadeMode(EvadeReason /*why*/) override + { + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); + summons.DespawnAll(); + _DespawnAtEvade(Seconds(5)); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) { - _JustDied(); - Talk(SAY_DEATH); + case EVENT_SONIC_SCREECH: + DoCastVictim(SPELL_SONIC_SCREECH); + events.Repeat(Seconds(22), Seconds(30)); + break; + case EVENT_TERRIFYING_SCREECH: + Talk(EMOTE_FEAR); + DoCastSelf(SPELL_TERRIFYING_SCREECH); + events.ScheduleEvent(EVENT_BLAST, Milliseconds(1)); + events.Repeat(Seconds(36), Seconds(45)); + break; + case EVENT_BLAST: + DoCastAOE(SPELL_SENTINEL_BLAST); + break; + case EVENT_SUMMON_DEFENDER: + Talk(EMOTE_DEFENDER); + DoCastSelf(SPELL_DEFENDER_TRIGGER); + events.ScheduleEvent(EVENT_ACTIVATE_DEFENDER, Seconds(2)); + break; + case EVENT_ACTIVATE_DEFENDER: + DoCastSelf(SPELL_ACTIVATE_DEFENDER); + break; + case EVENT_SWARNING_GUARDIAN: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true)) + DoCast(target, SPELL_SUMMON_SWARMING_GUARDIAN); + events.Repeat(Seconds(25), Seconds(45)); + break; + case EVENT_BERSERK: + DoCastSelf(SPELL_BERSERK, true); + Talk(SAY_BERSERK); + break; + default: + break; } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_SCREECH: - DoCast(SPELL_SONIC_SCREECH); - events.ScheduleEvent(EVENT_SCREECH, urand(40000, 60000)); - break; - case EVENT_TERRIFYING: - Talk(EMOTE_FEAR); - DoCast(SPELL_TERRIFYING_SCREECH); - events.ScheduleEvent(EVENT_TERRIFYING, urand(20000, 30000)); - break; - case EVENT_BLAST: - DoCastAOE(SPELL_SENTINEL_BLAST); - events.ScheduleEvent(EVENT_BLAST, urand(25000, 35000)); - break; - case EVENT_DEFENDER: - Talk(EMOTE_DEFENDER); - DoCast(SPELL_DEFENDER_TRIGGER); - if (Creature* trigger = me->FindNearestCreature(NPC_FERAL_DEFENDER_TRIGGER, 15.0f, true)) - DoCast(trigger, SPELL_ACTIVATE_DEFENDER, true); - break; - case EVENT_RESPAWN_DEFENDER: - if (Creature* Defender = ObjectAccessor::GetCreature(*me, DefenderGUID)) - { - Defender->Respawn(); - if (defenderLives) - Defender->SetAuraStack(SPELL_FERAL_ESSENCE, Defender, defenderLives); - Defender->SetInCombatWithZone(); - if (!Defender->IsInCombat()) - Defender->AI()->AttackStart(me->GetVictim()); - events.CancelEvent(EVENT_RESPAWN_DEFENDER); - } - break; - case EVENT_SUMMON: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) - DoCast(target, SPELL_SUMMON_SWARMING_GUARDIAN); - events.ScheduleEvent(EVENT_SUMMON, urand(30000, 45000)); - break; - case EVENT_BERSERK: - DoCast(me, SPELL_BERSERK, true); - Talk(SAY_BERSERK); - events.CancelEvent(EVENT_BERSERK); - break; - } - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - } - - DoMeleeAttackIfReady(); - } + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + } - private: - ObjectGuid DefenderGUID; - uint8 defenderLives; - bool crazyCatLady; - bool nineLives; - }; + DoMeleeAttackIfReady(); + } - CreatureAI* GetAI(Creature* creature) const override - { - return GetUlduarAI<boss_auriayaAI>(creature); - } +private: + bool _crazyCatLady; + bool _nineLives; }; -class npc_auriaya_seeping_trigger : public CreatureScript +struct npc_sanctum_sentry : public ScriptedAI { - public: - npc_auriaya_seeping_trigger() : CreatureScript("npc_auriaya_seeping_trigger") { } - - struct npc_auriaya_seeping_triggerAI : public ScriptedAI + npc_sanctum_sentry(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { } + + void Reset() override + { + DoCastSelf(SPELL_STRENGHT_OF_THE_PACK, true); + me->SetWalk(true); + } + + void EnterCombat(Unit* /*who*/) override + { + _events.ScheduleEvent(EVENT_RIP, Seconds(6)); + _events.ScheduleEvent(EVENT_SAVAGE_POUNCE, Milliseconds(1)); + me->SetWalk(false); + } + + void JustDied(Unit* /*killer*/) override + { + if (Creature* auriaya = _instance->GetCreature(BOSS_AURIAYA)) + auriaya->AI()->DoAction(ACTION_CRAZY_CAT_LADY); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + _events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = _events.ExecuteEvent()) { - npc_auriaya_seeping_triggerAI(Creature* creature) : ScriptedAI(creature) + switch (eventId) { - instance = me->GetInstanceScript(); - } - - void Reset() override - { - me->DespawnOrUnsummon(600000); - DoCast(me, SPELL_SEEPING_ESSENCE); + case EVENT_RIP: + DoCastVictim(SPELL_RIP_FLESH); + _events.Repeat(Seconds(10), Seconds(12)); + break; + case EVENT_SAVAGE_POUNCE: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, CatsTargetSelector(me, 10.0f, 15.0f))) + { + DoCast(target, SPELL_SAVAGE_POUNCE); + _events.Repeat(Seconds(10)); + break; + } + _events.Repeat(Seconds(1)); + break; + default: + break; } - void UpdateAI(uint32 /*diff*/) override - { - if (instance->GetBossState(BOSS_AURIAYA) != IN_PROGRESS) - me->DespawnOrUnsummon(); - } + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + } - private: - InstanceScript* instance; - }; + DoMeleeAttackIfReady(); + } - CreatureAI* GetAI(Creature* creature) const override - { - return GetUlduarAI<npc_auriaya_seeping_triggerAI>(creature); - } +private: + InstanceScript* _instance; + EventMap _events; }; -class npc_sanctum_sentry : public CreatureScript +struct npc_feral_defender : public ScriptedAI { - public: - npc_sanctum_sentry() : CreatureScript("npc_sanctum_sentry") { } - - struct npc_sanctum_sentryAI : public ScriptedAI - { - npc_sanctum_sentryAI(Creature* creature) : ScriptedAI(creature) - { - instance = me->GetInstanceScript(); - } + npc_feral_defender(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { } - void Reset() override - { - events.ScheduleEvent(EVENT_RIP, urand(4000, 8000)); - events.ScheduleEvent(EVENT_POUNCE, urand(12000, 15000)); - } + void Reset() override + { + me->SetReactState(REACT_PASSIVE); + DoCastSelf(SPELL_SHADOW_PAWS, true); + DoCastSelf(SPELL_REDUCE_CRITCAL, true); + me->SetAuraStack(SPELL_FERAL_ESSENCE, me, 8); + DoCastSelf(SPELL_RANDOM_AGRO_PERIODIC, true); + _events.SetPhase(PHASE_NONE); + _events.ScheduleEvent(EVENT_START_COMBAT, Seconds(1)); - void EnterCombat(Unit* /*who*/) override - { - DoCast(me, SPELL_STRENGHT_PACK, true); - } + if (Creature* auriaya = _instance->GetCreature(BOSS_AURIAYA)) + auriaya->AI()->JustSummoned(me); + } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim() && !_events.IsInPhase(PHASE_NONE)) + return; - events.Update(diff); + _events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_START_COMBAT: + _events.SetPhase(PHASE_COMBAT); + me->SetReactState(REACT_AGGRESSIVE); + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) + AttackStart(target); + _events.ScheduleEvent(EVENT_RUSH, Seconds(1)); + break; + case EVENT_RUSH: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, CatsTargetSelector(me, 10.0f, 11.0f))) { - case EVENT_RIP: - DoCastVictim(SPELL_RIP_FLESH); - events.ScheduleEvent(EVENT_RIP, urand(12000, 15000)); - break; - case EVENT_POUNCE: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) - { - AddThreat(target, 100.0f); - AttackStart(target); - DoCast(target, SPELL_SAVAGE_POUNCE); - } - events.ScheduleEvent(EVENT_POUNCE, urand(12000, 17000)); - break; - default: - break; + DoCast(target, SPELL_FERAL_RUSH, true); + _events.Repeat(Seconds(5)); + break; } - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - } - - DoMeleeAttackIfReady(); + _events.Repeat(Seconds(1)); + break; + case EVENT_RESPAWN_DEFENDER: + me->SetDisableGravity(true); + me->SetHover(true); + DoCastSelf(SPELL_DROWNED_STATE, true); + _events.ScheduleEvent(EVENT_RESPAWN_DEFENDER_2, Seconds(3)); + _events.ScheduleEvent(EVENT_RESPAWN_DEFENDER_3, Seconds(5)); + break; + case EVENT_RESPAWN_DEFENDER_2: + me->RemoveAurasDueToSpell(SPELL_DROWNED_STATE); + break; + case EVENT_RESPAWN_DEFENDER_3: + me->RemoveAurasDueToSpell(SPELL_PERMANENT_FEIGN_DEATH); + DoCastSelf(SPELL_FULL_HEAL, true); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + me->SetReactState(REACT_AGGRESSIVE); + me->SetDisableGravity(false); + me->SetHover(false); + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) + AttackStart(target); + _events.ScheduleEvent(EVENT_RUSH, Seconds(1)); + break; + default: + break; } - void JustDied(Unit* /*killer*/) override - { - if (Creature* auriaya = instance->GetCreature(BOSS_AURIAYA)) - auriaya->AI()->DoAction(ACTION_CRAZY_CAT_LADY); - } + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + } - private: - InstanceScript* instance; - EventMap events; - }; + DoMeleeAttackIfReady(); + } - CreatureAI* GetAI(Creature* creature) const override + void DamageTaken(Unit* /*done_by*/, uint32 &damage) override + { + if (damage >= me->GetHealth() && me->HasAura(SPELL_FERAL_ESSENCE)) { - return GetUlduarAI<npc_sanctum_sentryAI>(creature); + damage = 0; + if (!me->HasAura(SPELL_PERMANENT_FEIGN_DEATH)) + { + me->SetReactState(REACT_PASSIVE); + me->AttackStop(); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + DoCastSelf(SPELL_PERMANENT_FEIGN_DEATH, true); + DoCastSelf(SPELL_FERAL_ESSENCE_APPLICATION_REMOVAL, true); + DoCastSelf(SPELL_SUMMON_ESSENCE, true); + DoCastSelf(SPELL_CLEAR_ALL_DEBUFFS, true); + ResetThreatList(); + _events.ScheduleEvent(EVENT_RESPAWN_DEFENDER, Seconds(30)); + _events.CancelEvent(EVENT_RUSH); + } } + } + + void JustDied(Unit* /*killer*/) override + { + DoCastSelf(SPELL_SUMMON_ESSENCE, true); + if (Creature* auriaya = _instance->GetCreature(BOSS_AURIAYA)) + auriaya->AI()->DoAction(ACTION_DEFENDER_DIED); + } + +private: + InstanceScript* _instance; + EventMap _events; }; -class npc_feral_defender : public CreatureScript +struct npc_swarming_guardian : public ScriptedAI { - public: - npc_feral_defender() : CreatureScript("npc_feral_defender") { } + npc_swarming_guardian(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { } - struct npc_feral_defenderAI : public ScriptedAI + void Reset() override + { + me->SetReactState(REACT_PASSIVE); + _scheduler.Schedule(Seconds(1), [this](TaskContext /*context*/) { - npc_feral_defenderAI(Creature* creature) : ScriptedAI(creature) - { - instance = me->GetInstanceScript(); - } - - void Reset() override - { - events.ScheduleEvent(EVENT_FERAL_POUNCE, 5000); - events.ScheduleEvent(EVENT_RUSH, 10000); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - events.Update(diff); + me->SetReactState(REACT_AGGRESSIVE); + DoCastSelf(SPELL_AGRO_CREATOR); + }); + if (Creature* auriaya = _instance->GetCreature(BOSS_AURIAYA)) + auriaya->AI()->JustSummoned(me); + } + + void UpdateAI(uint32 diff) override + { + _scheduler.Update(diff); + if (!UpdateVictim()) + return; + + DoMeleeAttackIfReady(); + } + +private: + InstanceScript* _instance; + TaskScheduler _scheduler; +}; - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; +struct npc_seeping_essence_stalker : public ScriptedAI +{ + npc_seeping_essence_stalker(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { } - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_FERAL_POUNCE: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) - { - AddThreat(target, 100.0f); - AttackStart(target); - DoCast(target, SPELL_FERAL_POUNCE); - } - events.ScheduleEvent(EVENT_FERAL_POUNCE, urand(10000, 12000)); - break; - case EVENT_RUSH: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) - { - AddThreat(target, 100.0f); - AttackStart(target); - DoCast(target, SPELL_FERAL_RUSH); - } - events.ScheduleEvent(EVENT_RUSH, urand(10000, 12000)); - break; - default: - break; - } + void Reset() override + { + DoCastSelf(SPELL_SEEPING_ESSENCE); + if (Creature* auriaya = _instance->GetCreature(BOSS_AURIAYA)) + auriaya->AI()->JustSummoned(me); + } - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - } + void UpdateAI(uint32 /*diff*/) override { } - DoMeleeAttackIfReady(); - } +private: + InstanceScript* _instance; +}; - void JustDied(Unit* /*killer*/) override - { - DoCast(me, SPELL_SUMMON_ESSENCE); - if (Creature* auriaya = instance->GetCreature(BOSS_AURIAYA)) - auriaya->AI()->DoAction(ACTION_RESPAWN_DEFENDER); - } +// 64381 - Strength of the Pack +class spell_auriaya_strenght_of_the_pack : public SpellScript +{ + PrepareSpellScript(spell_auriaya_strenght_of_the_pack); - private: - InstanceScript* instance; - EventMap events; - }; + void FilterTargets(std::list<WorldObject*>& unitList) + { + unitList.remove_if([](WorldObject* obj) { return obj->GetEntry() != NPC_SANCTUM_SENTRY; }); + } - CreatureAI* GetAI(Creature* creature) const override - { - return GetUlduarAI<npc_feral_defenderAI>(creature); - } + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_auriaya_strenght_of_the_pack::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY); + } }; -class SanctumSentryCheck +// 64392, 64679 - Sentinel Blast +class spell_auriaya_sentinel_blast : public SpellScript { - public: - bool operator()(WorldObject* object) const - { - if (object->GetEntry() == NPC_SANCTUM_SENTRY) - return false; - - return true; - } + PrepareSpellScript(spell_auriaya_sentinel_blast); + + void FilterTargets(std::list<WorldObject*>& unitList) + { + unitList.remove_if(PlayerOrPetCheck()); + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_auriaya_sentinel_blast::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_auriaya_sentinel_blast::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY); + } }; -class spell_auriaya_strenght_of_the_pack : public SpellScriptLoader +// 63709 - Aggro Creator +class spell_auriaya_agro_creator : public SpellScript { - public: - spell_auriaya_strenght_of_the_pack() : SpellScriptLoader("spell_auriaya_strenght_of_the_pack") { } + PrepareSpellScript(spell_auriaya_agro_creator); - class spell_auriaya_strenght_of_the_pack_SpellScript : public SpellScript - { - PrepareSpellScript(spell_auriaya_strenght_of_the_pack_SpellScript); + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_POUNCE }); + } - void FilterTargets(std::list<WorldObject*>& unitList) - { - unitList.remove_if(SanctumSentryCheck()); - } + void HandleDummyEffect(SpellEffIndex /*effIndex*/) + { + Creature* caster = GetCaster()->ToCreature(); + if (!caster || !caster->IsAIEnabled || caster->HasReactState(REACT_PASSIVE)) + return; - void Register() override - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_auriaya_strenght_of_the_pack_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY); - } - }; - - SpellScript* GetSpellScript() const override + if (Unit* target = caster->AI()->SelectTarget(SELECT_TARGET_RANDOM, 0, CatsTargetSelector(caster, 5.0f, 10.0f))) { - return new spell_auriaya_strenght_of_the_pack_SpellScript(); + caster->CastSpell(target, SPELL_POUNCE, true); + caster->GetThreatManager().AddThreat(target, 50000000.0f, nullptr, true); + caster->AI()->AttackStart(target); } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_auriaya_agro_creator::HandleDummyEffect, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; -class spell_auriaya_sentinel_blast : public SpellScriptLoader +// 61906 - Random Aggro Periodic (5 sec) +class spell_auriaya_random_agro_periodic : public AuraScript { - public: - spell_auriaya_sentinel_blast() : SpellScriptLoader("spell_auriaya_sentinel_blast") { } + PrepareAuraScript(spell_auriaya_random_agro_periodic); - class spell_auriaya_sentinel_blast_SpellScript : public SpellScript - { - PrepareSpellScript(spell_auriaya_sentinel_blast_SpellScript); + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_FERAL_POUNCE }); + } - void FilterTargets(std::list<WorldObject*>& unitList) - { - unitList.remove_if(PlayerOrPetCheck()); - } - - void Register() override - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_auriaya_sentinel_blast_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_auriaya_sentinel_blast_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY); - } - }; + void HandleEffectPeriodic(AuraEffect const* /*aurEff*/) + { + Creature* owner = GetUnitOwner()->ToCreature(); + if (!owner || !owner->IsAIEnabled || owner->HasReactState(REACT_PASSIVE)) + return; - SpellScript* GetSpellScript() const override + if (Unit* target = owner->AI()->SelectTarget(SELECT_TARGET_RANDOM, 0, CatsTargetSelector(owner, 15.0f, 25.0f))) { - return new spell_auriaya_sentinel_blast_SpellScript(); + owner->GetThreatManager().AddThreat(target, 3000000.0f, nullptr, true); + owner->CastSpell(target, SPELL_FERAL_POUNCE, true); + owner->AI()->AttackStart(target); } + else if (Unit* target = owner->AI()->SelectTarget(SELECT_TARGET_RANDOM, 0)) + { + owner->GetThreatManager().AddThreat(target, 3000000.0f); + owner->AI()->AttackStart(target); + } + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_auriaya_random_agro_periodic::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + } }; +// 64456 - Feral Essence Application Removal +class spell_auriaya_feral_essence_removal : public SpellScript +{ + PrepareSpellScript(spell_auriaya_feral_essence_removal); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_FERAL_ESSENCE }); + } + + void HandleScriptEffect(SpellEffIndex /*effIndex*/) + { + if (Aura* essence = GetCaster()->GetAura(SPELL_FERAL_ESSENCE)) + essence->ModStackAmount(-1); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_auriaya_feral_essence_removal::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } +}; + +// 64496, 64674 - Feral Rush +class spell_auriaya_feral_rush : public SpellScript +{ + PrepareSpellScript(spell_auriaya_feral_rush); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_FERAL_RUSH_2 }); + } + + void HandleOnHit(SpellEffIndex /*effIndex*/) + { + GetCaster()->CastSpell(GetCaster(), SPELL_FERAL_RUSH_2, true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_auriaya_feral_rush::HandleOnHit, EFFECT_1, SPELL_EFFECT_SCHOOL_DAMAGE); + } +}; class achievement_nine_lives : public AchievementCriteriaScript { public: - achievement_nine_lives() : AchievementCriteriaScript("achievement_nine_lives") - { - } + achievement_nine_lives() : AchievementCriteriaScript("achievement_nine_lives") { } bool OnCheck(Player* /*player*/, Unit* target) override { if (!target) return false; - if (Creature* Auriaya = target->ToCreature()) - if (Auriaya->AI()->GetData(DATA_NINE_LIVES)) + if (Creature* auriaya = target->ToCreature()) + if (auriaya->AI()->GetData(DATA_NINE_LIVES)) return true; return false; @@ -576,17 +666,15 @@ class achievement_nine_lives : public AchievementCriteriaScript class achievement_crazy_cat_lady : public AchievementCriteriaScript { public: - achievement_crazy_cat_lady() : AchievementCriteriaScript("achievement_crazy_cat_lady") - { - } + achievement_crazy_cat_lady() : AchievementCriteriaScript("achievement_crazy_cat_lady") { } bool OnCheck(Player* /*player*/, Unit* target) override { if (!target) return false; - if (Creature* Auriaya = target->ToCreature()) - if (Auriaya->AI()->GetData(DATA_CRAZY_CAT_LADY)) + if (Creature* auriaya = target->ToCreature()) + if (auriaya->AI()->GetData(DATA_CRAZY_CAT_LADY)) return true; return false; @@ -595,12 +683,17 @@ class achievement_crazy_cat_lady : public AchievementCriteriaScript void AddSC_boss_auriaya() { - new boss_auriaya(); - new npc_auriaya_seeping_trigger(); - new npc_feral_defender(); - new npc_sanctum_sentry(); - new spell_auriaya_strenght_of_the_pack(); - new spell_auriaya_sentinel_blast(); + RegisterUlduarCreatureAI(boss_auriaya); + RegisterUlduarCreatureAI(npc_feral_defender); + RegisterUlduarCreatureAI(npc_sanctum_sentry); + RegisterUlduarCreatureAI(npc_swarming_guardian); + RegisterUlduarCreatureAI(npc_seeping_essence_stalker); + RegisterSpellScript(spell_auriaya_strenght_of_the_pack); + RegisterSpellScript(spell_auriaya_sentinel_blast); + RegisterSpellScript(spell_auriaya_agro_creator); + RegisterAuraScript(spell_auriaya_random_agro_periodic); + RegisterSpellScript(spell_auriaya_feral_essence_removal); + RegisterSpellScript(spell_auriaya_feral_rush); new achievement_nine_lives(); new achievement_crazy_cat_lady(); } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp index dac2a8707d9..3925fd3b042 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp @@ -973,9 +973,9 @@ class npc_mimirons_inferno : public CreatureScript public: npc_mimirons_inferno() : CreatureScript("npc_mimirons_inferno") { } - struct npc_mimirons_infernoAI : public npc_escortAI + struct npc_mimirons_infernoAI : public EscortAI { - npc_mimirons_infernoAI(Creature* creature) : npc_escortAI(creature) + npc_mimirons_infernoAI(Creature* creature) : EscortAI(creature) { Initialize(); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); @@ -988,11 +988,6 @@ public: infernoTimer = 2000; } - void WaypointReached(uint32 /*waypointId*/) override - { - - } - void Reset() override { Initialize(); @@ -1002,7 +997,7 @@ public: void UpdateAI(uint32 diff) override { - npc_escortAI::UpdateAI(diff); + EscortAI::UpdateAI(diff); if (!HasEscortState(STATE_ESCORT_ESCORTING)) Start(false, true, ObjectGuid::Empty, nullptr, false, true); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp index fe0539fc407..8b5039b8326 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp @@ -610,7 +610,7 @@ class boss_freya : public CreatureScript /* 25N */ {62955, 62956, 62957, 62958} }; - me->CastSpell((Unit*)nullptr, summonSpell[me->GetMap()->GetDifficulty()][elderCount], true); + me->CastSpell(nullptr, summonSpell[me->GetMap()->GetDifficulty()][elderCount], true); Talk(SAY_DEATH); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp index 3b95b36c375..8200ea8ca06 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp @@ -2129,7 +2129,7 @@ class spell_mimiron_proximity_trigger : public SpellScriptLoader void HandleDummy(SpellEffIndex /*effIndex*/) { - GetCaster()->CastSpell((Unit*)nullptr, SPELL_PROXIMITY_MINE_EXPLOSION, true); + GetCaster()->CastSpell(nullptr, SPELL_PROXIMITY_MINE_EXPLOSION, true); } void Register() override @@ -2215,7 +2215,7 @@ class spell_mimiron_rocket_strike : public SpellScriptLoader void HandleDummy(SpellEffIndex /*effIndex*/) { - GetHitUnit()->CastSpell((Unit*)nullptr, SPELL_SCRIPT_EFFECT_ROCKET_STRIKE, true, nullptr, nullptr, GetCaster()->GetGUID()); + GetHitUnit()->CastSpell(nullptr, SPELL_SCRIPT_EFFECT_ROCKET_STRIKE, true, nullptr, nullptr, GetCaster()->GetGUID()); } void Register() override @@ -2262,7 +2262,7 @@ class spell_mimiron_rocket_strike_damage : public SpellScriptLoader void HandleFriendlyFire(SpellEffIndex /*effIndex*/) { - GetHitUnit()->CastSpell((Unit*)nullptr, SPELL_NOT_SO_FRIENDLY_FIRE, true); + GetHitUnit()->CastSpell(nullptr, SPELL_NOT_SO_FRIENDLY_FIRE, true); } void Register() override diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp index d571bd541df..41985059aae 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp @@ -15,15 +15,15 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/// @todo Harpoon chain from 62505 should not get removed when other chain is applied - #include "ScriptMgr.h" #include "GameObject.h" #include "GameObjectAI.h" #include "InstanceScript.h" #include "Map.h" #include "MotionMaster.h" +#include "MoveSplineInit.h" #include "ObjectAccessor.h" +#include "PassiveAI.h" #include "Player.h" #include "ScriptedCreature.h" #include "ScriptedGossip.h" @@ -31,1133 +31,1673 @@ #include "SpellScript.h" #include "TemporarySummon.h" #include "ulduar.h" +#include <G3D/Vector3.h> enum Says { // Expedition Commander - SAY_INTRO = 0, - SAY_GROUND_PHASE = 1, - SAY_AGGRO_2 = 2, + SAY_COMMANDER_AGGRO = 0, + SAY_COMMANDER_GROUND_PHASE = 1, + SAY_COMMANDER_ENGINEERS_DEAD = 2, // Expedition Engineer - SAY_AGGRO_1 = 0, - SAY_AGGRO_3 = 1, - SAY_TURRETS = 2, // unused + SAY_AGGRO = 0, + SAY_START_REPAIR = 1, + SAY_REBUILD_TURRETS = 2, // Razorscale Controller - EMOTE_HARPOON = 0, + EMOTE_HARPOON = 0, // Razorscale - EMOTE_PERMA = 0, - EMOTE_BREATH = 1 + EMOTE_PERMA_GROUND = 0, + EMOTE_BREATH = 1, + EMOTE_BERSERK = 2 }; enum Spells { - SPELL_FLAMEBUFFET = 64016, - SPELL_FIREBALL = 62796, - SPELL_FLAME_GROUND = 64734, - SPELL_WINGBUFFET = 62666, - SPELL_FLAMEBREATH = 63317, - SPELL_FUSEARMOR = 64771, - SPELL_FLAMED = 62696, - SPELL_STUN = 9032, - SPELL_BERSERK = 47008, - // Additonal Spells - // Devouring Flame Spells - SPELL_DEVOURING_FLAME = 63308, - SPELL_DEVOURING_FLAME_DAMAGE = 64704, - SPELL_DEVOURING_FLAME_TRIGGER = 64709, - // HarpoonSpells - SPELL_HARPOON_TRIGGER = 62505, - SPELL_HARPOON_SHOT_1 = 63658, - SPELL_HARPOON_SHOT_2 = 63657, - SPELL_HARPOON_SHOT_3 = 63659, - SPELL_HARPOON_SHOT_4 = 63524, - // MoleMachine Spells - SPELL_SUMMON_MOLE_MACHINE = 62899, - SPELL_SUMMON_IRON_DWARVES = 63116, - SPELL_SUMMON_IRON_DWARVES_2 = 63114, - SPELL_SUMMON_IRON_DWARVE_GUARDIAN = 62926, - SPELL_SUMMON_IRON_DWARVE_WATCHER = 63135, + SPELL_FIREBALL = 63815, + SPELL_DEVOURING_FLAME = 63236, + SPELL_WING_BUFFET = 62666, + SPELL_FIREBOLT = 62669, + SPELL_FUSE_ARMOR = 64821, + SPELL_FUSED_ARMOR = 64774, + SPELL_STUN_SELF = 62794, + SPELL_BERSERK = 47008, + + // Razorscale Harpoon Fire State + SPELL_HARPOON_FIRE_STATE = 62696, + + // Harpoon + SPELL_HARPOON_TRIGGER = 62505, + SPELL_HARPOON_SHOT_1 = 63658, + SPELL_HARPOON_SHOT_2 = 63657, + SPELL_HARPOON_SHOT_3 = 63659, + SPELL_HARPOON_SHOT_4 = 63524, + + // Razorscale Spawner + SPELL_SUMMON_MOLE_MACHINE = 62899, + SPELL_SUMMON_IRON_DWARF_GUARDIAN = 62926, + SPELL_TRIGGER_SUMMON_IRON_DWARVES = 63968, + SPELL_TRIGGER_SUMMON_IRON_DWARVES_2 = 63970, + SPELL_TRIGGER_SUMMON_IRON_DWARVES_3 = 63969, + SPELL_TRIGGER_SUMMON_IRON_VRYKUL = 63798, + SPELL_SUMMON_IRON_DWARF_WATCHER = 63135, + + // Dark Rune Guardian + SPELL_STORMSTRIKE = 64757, + + // Dark Rune Sentinel + SPELL_BATTLE_SHOUT = 46763, + SPELL_HEROIC_STRIKE = 45026, + SPELL_WHIRLWIND = 63808, + + // Expedition Defender + SPELL_THREAT = 65146, + + // Expedition Trapper + SPELL_SHACKLE = 62646 }; -enum NPC +#define DEVOURING_FLAME_GROUND RAID_MODE<uint32>(64709, 64734) +#define FLAME_BREATH RAID_MODE<uint32>(63317, 64021) +#define CHAIN_LIGHTNING RAID_MODE<uint32>(64758, 64759) +#define LIGHTNING_BOLT RAID_MODE<uint32>(63809, 64696) + +enum Actions { - NPC_DARK_RUNE_GUARDIAN = 33388, - NPC_DARK_RUNE_SENTINEL = 33846, - NPC_DARK_RUNE_WATCHER = 33453, - MOLE_MACHINE_TRIGGER = 33245, - NPC_COMMANDER = 33210, - NPC_ENGINEER = 33287, - NPC_DEFENDER = 33816, + ACTION_START_FIGHT = 1, + ACTION_FIX_HARPOONS, + ACTION_GROUND_PHASE, + ACTION_ENGINEER_DEAD, + ACTION_SHACKLE_RAZORSCALE, + ACTION_START_PERMA_GROUND, + ACTION_RETURN_TO_BASE, + ACTION_BUILD_HARPOON_1, + ACTION_BUILD_HARPOON_2, + ACTION_BUILD_HARPOON_3, + ACTION_BUILD_HARPOON_4, + ACTION_DESTROY_HARPOONS, + ACTION_STOP_CONTROLLERS, + ACTION_STOP_CAST }; -enum DarkRuneSpells +enum Events { + EVENT_BERSERK = 1, + EVENT_FIREBALL, + EVENT_DEVOURING_FLAME, + EVENT_SUMMON_MINIONS, + EVENT_SUMMON_MINIONS_2, + EVENT_FLAME_BREATH, + EVENT_FLAME_BREATH_GROUND, + EVENT_WING_BUFFET, + EVENT_RESUME_AIR_PHASE, + EVENT_FIREBOLT, + EVENT_FUSE_ARMOR, + EVENT_RESUME_MOVE_CHASE, + + // Expedition Commander + EVENT_BUILD_HARPOON_1, + EVENT_BUILD_HARPOON_2, + EVENT_BUILD_HARPOON_3, + EVENT_BUILD_HARPOON_4, + EVENT_HANDLE_DESTROY_HARPOON, + + // Dark Rune Sentinel + EVENT_START_COMBAT, + EVENT_HEROIC_STRIKE, + EVENT_BATTLE_SHOUT, + EVENT_WHIRLWIND, + // Dark Rune Watcher - SPELL_CHAIN_LIGHTNING = 64758, - SPELL_LIGHTNING_BOLT = 63809, + EVENT_LIGHTNING_BOLT, + EVENT_CHAIN_LIGHTNING, + // Dark Rune Guardian - SPELL_STORMSTRIKE = 64757, - // Dark Rune Sentinel - SPELL_BATTLE_SHOUT = 46763, - SPELL_HEROIC_STRIKE = 45026, - SPELL_WHIRLWIND = 63807, + EVENT_STORMSTRIKE }; -enum Actions +enum Misc { - ACTION_EVENT_START = 1, - ACTION_GROUND_PHASE = 2, - ACTION_HARPOON_BUILD = 3, - ACTION_PLACE_BROKEN_HARPOON = 4, - ACTION_COMMANDER_RESET = 7, + DATA_QUICK_SHAVE = 29192921, // 2919, 2921 are achievement IDs + DATA_IRON_DWARF_MEDIUM_RARE = 29232924, + GOSSIP_START_ENCOUNTER = 0, + DATA_EXPEDITION_NUMBER = 1, + RAZORSCALE_EXPEDITION_GROUP = 1, + RAZORSCALE_FIRE_STATE_10_GROUP = 2, + RAZORSCALE_FIRE_STATE_25_GROUP = 3, + ENGINEER_NORTH = 0, + ENGINEER_EAST = 1, + ENGINEER_WEST = 2, + HARPOON_1 = 0, + HARPOON_2 = 1, + HARPOON_3 = 2, + HARPOON_4 = 3, + WORLD_STATE_RAZORSCALE_MUSIC = 4162 }; -enum Phases +enum MovePoints { - PHASE_PERMAGROUND = 1, - PHASE_GROUND = 2, - PHASE_FLIGHT = 3, + POINT_DEFENDER_ATTACK = 1, + POINT_SHACKLE_RAZORSCALE, + POINT_BASE, + POINT_HARPOON_1, + POINT_HARPOON_1_25, + POINT_HARPOON_2, + POINT_HARPOON_2_25, + POINT_HARPOON_3, + POINT_HARPOON_4, + POINT_RAZORSCALE_FLIGHT, + POINT_RAZORSCALE_TAKEOFF, + POINT_RAZORSCALE_FLIGHT_2, + POINT_RAZORSCALE_LAND, + POINT_RAZORSCALE_GROUND, + POINT_START_WAYPOINT }; -enum Events +enum EngineersSplineMovements { - EVENT_BERSERK = 1, - EVENT_BREATH = 2, - EVENT_BUFFET = 3, - EVENT_FIREBALL = 5, - EVENT_FLIGHT = 6, - EVENT_DEVOURING = 7, - EVENT_FLAME = 8, - EVENT_LAND = 9, - EVENT_GROUND = 10, - EVENT_FUSE = 11, - EVENT_SUMMON = 12, - // Razorscale Controller - EVENT_BUILD_HARPOON_1 = 13, - EVENT_BUILD_HARPOON_2 = 14, - EVENT_BUILD_HARPOON_3 = 15, - EVENT_BUILD_HARPOON_4 = 16, + SPLINE_ENGINEER_NORTH_10_HARPOON_1 = 1, + SPLINE_ENGINEER_NORTH_10_HARPOON_2 = 2, + SPLINE_ENGINEER_NORTH_10_BASE = 3, + SPLINE_ENGINEER_NORTH_25_HARPOON_1 = 4, + SPLINE_ENGINEER_NORTH_25_HARPOON_2 = 5, + SPLINE_ENGINEER_NORTH_25_HARPOON_3 = 6, + SPLINE_ENGINEER_NORTH_25_HARPOON_4 = 7, + SPLINE_ENGINEER_NORTH_25_BASE = 8, + SPLINE_ENGINEER_EAST_10_HARPOON_1 = 9, + SPLINE_ENGINEER_EAST_10_HARPOON_2 = 10, + SPLINE_ENGINEER_EAST_10_BASE = 11, + SPLINE_ENGINEER_EAST_25_HARPOON_1 = 12, + SPLINE_ENGINEER_EAST_25_HARPOON_2 = 13, + SPLINE_ENGINEER_EAST_25_HARPOON_3 = 14, + SPLINE_ENGINEER_EAST_25_HARPOON_4 = 15, + SPLINE_ENGINEER_WEST_10_HARPOON_1 = 16, + SPLINE_ENGINEER_WEST_10_HARPOON_2 = 17, + SPLINE_ENGINEER_WEST_10_BASE = 18, + SPLINE_ENGINEER_WEST_25_HARPOON_1 = 19, + SPLINE_ENGINEER_WEST_25_HARPOON_2 = 20, + SPLINE_ENGINEER_WEST_25_HARPOON_3 = 21, + SPLINE_ENGINEER_WEST_25_HARPOON_4 = 22, + SPLINE_ENGINEER_WEST_25_BASE = 23 }; -#define GROUND_Z 391.517f -#define GOSSIP_ITEM_1 "Activate Harpoons!" - -enum Misc +enum RazorscalePhases { - DATA_QUICK_SHAVE = 29192921, // 2919, 2921 are achievement IDs - DATA_IRON_DWARF_MEDIUM_RARE = 29232924 + PHASE_NONE = 0, + PHASE_COMBAT, + PHASE_GROUND, + PHASE_AIR, + PHASE_PERMA_GROUND }; -const Position PosEngRepair[4] = +Position const PosBrokenHarpoon[4] = { - { 590.442f, -130.550f, GROUND_Z, 4.789f }, - { 574.850f, -133.687f, GROUND_Z, 4.252f }, - { 606.567f, -143.369f, GROUND_Z, 4.434f }, - { 560.609f, -142.967f, GROUND_Z, 5.074f }, + { 571.9465f, -136.0118f, 391.5171f, 2.286379f }, // 1 + { 589.9233f, -133.6223f, 391.8968f, 3.298687f }, // 2 + { 559.1199f, -140.5058f, 391.1803f, 4.049168f }, // 0 + { 606.2297f, -136.7212f, 391.1803f, 5.131269f } // 3 }; -const Position PosDefSpawn[4] = +Position const PosHarpoon[4] = { - { 600.75f, -104.850f, GROUND_Z, 0 }, - { 596.38f, -110.262f, GROUND_Z, 0 }, - { 566.47f, -103.633f, GROUND_Z, 0 }, - { 570.41f, -108.791f, GROUND_Z, 0 }, + { 571.9012f, -136.5541f, 391.5171f, 4.921829f }, // GO_RAZOR_HARPOON_1 + { 589.9233f, -133.6223f, 391.8968f, 4.81711f }, // GO_RAZOR_HARPOON_2 + { 559.1199f, -140.5058f, 391.1803f, 5.061456f }, // GO_RAZOR_HARPOON_3 + { 606.2297f, -136.7212f, 391.1803f, 4.537859f } // GO_RAZOR_HARPOON_4 }; -const Position PosDefCombat[4] = +Position const DefendersPosition[6] = { - { 614.975f, -155.138f, GROUND_Z, 4.154f }, - { 609.814f, -204.968f, GROUND_Z, 5.385f }, - { 563.531f, -201.557f, GROUND_Z, 4.108f }, - { 560.231f, -153.677f, GROUND_Z, 5.403f }, + { 624.3065f, -154.4163f, 391.6442f }, + { 611.6274f, -170.9375f, 391.8087f }, + { 572.1548f, -167.4471f, 391.8087f }, + { 558.4640f, -165.0114f, 391.8087f }, + { 603.3345f, -164.4297f, 391.8087f }, + { 549.1727f, -159.1180f, 391.8087f } }; -const Position PosHarpoon[4] = +Position const TrapperPosition[3] = { - { 571.901f, -136.554f, GROUND_Z, 0 }, - { 589.450f, -134.888f, GROUND_Z, 0 }, - { 559.119f, -140.505f, GROUND_Z, 0 }, - { 606.229f, -136.721f, GROUND_Z, 0 }, + { 574.9293f, -184.5150f, 391.8921f }, + { 539.7838f, -178.5337f, 391.3053f }, + { 627.1754f, -177.9638f, 391.5553f } }; -const Position RazorFlight = { 588.050f, -251.191f, 470.536f, 1.498f }; -const Position RazorGround = { 586.966f, -175.534f, GROUND_Z, 4.682f }; -const Position PosEngSpawn = { 591.951f, -95.9680f, GROUND_Z, 0.000f }; - -class boss_razorscale_controller : public CreatureScript +uint32 const SummonMinionsSpells[4] = { - public: - boss_razorscale_controller() : CreatureScript("boss_razorscale_controller") { } - - struct boss_razorscale_controllerAI : public ScriptedAI - { - boss_razorscale_controllerAI(Creature* creature) : ScriptedAI(creature), summons(me) - { - instance = creature->GetInstanceScript(); - me->SetDisplayId(me->GetCreatureTemplate()->Modelid2); - } - - InstanceScript* instance; - EventMap events; - SummonList summons; + SPELL_TRIGGER_SUMMON_IRON_DWARVES, + SPELL_TRIGGER_SUMMON_IRON_DWARVES_2, + SPELL_TRIGGER_SUMMON_IRON_DWARVES_3, + SPELL_TRIGGER_SUMMON_IRON_VRYKUL +}; - void Reset() override - { - events.Reset(); - summons.DespawnAll(); - me->SetReactState(REACT_PASSIVE); - } +uint32 const pathSize = 11; +G3D::Vector3 const RazorscalePath[pathSize] = +{ + { 657.0227f, -361.1278f, 519.5406f }, + { 698.9319f, -340.9654f, 520.4857f }, + { 713.8673f, -290.2219f, 518.4573f }, + { 711.1782f, -259.6798f, 524.6802f }, + { 695.5101f, -234.6734f, 529.1528f }, + { 666.9619f, -220.7599f, 531.4860f }, + { 629.2765f, -219.7951f, 528.9301f }, + { 597.4018f, -233.7745f, 526.6508f }, + { 577.5307f, -275.4489f, 528.1241f }, + { 583.1092f, -319.5873f, 527.9302f }, + { 611.5800f, -353.1930f, 526.2653f } +}; - void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override - { - switch (spell->Id) - { - case SPELL_FLAMED: - if (GameObject* harpoon = instance->GetGameObject(GO_RAZOR_HARPOON_1)) - harpoon->RemoveFromWorld(); - if (GameObject* harpoon = instance->GetGameObject(GO_RAZOR_HARPOON_2)) - harpoon->RemoveFromWorld(); - if (GameObject* harpoon = instance->GetGameObject(GO_RAZOR_HARPOON_3)) - harpoon->RemoveFromWorld(); - if (GameObject* harpoon = instance->GetGameObject(GO_RAZOR_HARPOON_4)) - harpoon->RemoveFromWorld(); - DoAction(ACTION_HARPOON_BUILD); - DoAction(ACTION_PLACE_BROKEN_HARPOON); - break; - case SPELL_HARPOON_SHOT_1: - case SPELL_HARPOON_SHOT_2: - case SPELL_HARPOON_SHOT_3: - case SPELL_HARPOON_SHOT_4: - DoCast(SPELL_HARPOON_TRIGGER); - break; - } - } +Position const RazorFlightPosition = { 585.3610f, -173.5592f, 456.8430f, 1.526665f }; +Position const RazorFlightPositionPhase2 = { 619.1450f, -238.0780f, 475.1800f, 1.423917f }; +Position const RazorscaleLand = { 585.4010f, -173.5430f, 408.5080f, 1.570796f }; +Position const RazorscaleGroundPosition = { 585.4010f, -173.5430f, 391.6421f, 1.570796f }; +Position const RazorscaleFirstPoint = { 657.0227f, -361.1278f, 519.5406f }; - void JustDied(Unit* /*killer*/) override +struct boss_razorscale : public BossAI +{ + boss_razorscale(Creature* creature) : BossAI(creature, BOSS_RAZORSCALE) + { + Initialize(); + } + + void Initialize() + { + _engineersCount = 3; + _defendersCount = 0; + _engineersSummonCount = 0; + _harpoonHitCount = 0; + _trappersCount = 0; + _permaGround = false; + _flyCount = 0; + me->SetDisableGravity(true); + me->SetByteFlag(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_ANIM_TIER, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER); + } + + void Reset() override + { + _Reset(); + Initialize(); + events.SetPhase(PHASE_NONE); + me->SummonCreatureGroup(RAZORSCALE_EXPEDITION_GROUP); + me->SummonCreatureGroup(RAZORSCALE_FIRE_STATE_10_GROUP); + if (Is25ManRaid()) + me->SummonCreatureGroup(RAZORSCALE_FIRE_STATE_25_GROUP); + // @Developer remove this comment when someone create a way to change view distance for objects + // me->GetMotionMaster()->MovePoint(POINT_START_WAYPOINT, RazorscaleFirstPoint); + // And apply it on DB: UPDATE `creature` SET `position_x`=699.7847, `position_y`=-424.8246, `position_z`=589.2745, `orientation`=1.972222 WHERE `guid`=137611; -- Razorscale + SetCombatMovement(false); + } + + void HandleInitialMovement() + { + Movement::PointsArray path(RazorscalePath, RazorscalePath + pathSize); + Movement::MoveSplineInit init(me); + init.MovebyPath(path, 0); + init.SetCyclic(); + init.SetFly(); + init.Launch(); + } + + bool CanAIAttack(Unit const* target) const override + { + switch (target->GetEntry()) + { + case NPC_EXPEDITION_DEFENDER: + case NPC_EXPEDITION_TRAPPER: + case NPC_EXPEDITION_COMMANDER: + case NPC_EXPEDITION_ENGINEER: + return false; + default: + return BossAI::CanAIAttack(target); + } + } + + void EnterCombat(Unit* /*who*/) override + { + _EnterCombat(); + instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me); + ScheduleAirPhaseEvents(); + summons.DoAction(ACTION_START_FIGHT, DummyEntryCheckPredicate()); + events.ScheduleEvent(EVENT_BERSERK, Minutes(15)); + HandleMusic(true); + me->SetByteFlag(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_ANIM_TIER, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER); + } + + void ScheduleAirPhaseEvents() + { + events.ScheduleEvent(EVENT_FIREBALL, Seconds(3), 0, PHASE_AIR); + events.ScheduleEvent(EVENT_DEVOURING_FLAME, Seconds(9), 0, PHASE_AIR); + events.ScheduleEvent(EVENT_SUMMON_MINIONS, Seconds(1), 0, PHASE_AIR); + } + + void ScheduleGroundPhaseEvents() + { + events.ScheduleEvent(EVENT_FIREBOLT, Seconds(3), 0, PHASE_PERMA_GROUND); + events.ScheduleEvent(EVENT_FUSE_ARMOR, Seconds(15), 0, PHASE_PERMA_GROUND); + events.ScheduleEvent(EVENT_FLAME_BREATH_GROUND, Seconds(18), 0, PHASE_PERMA_GROUND); + events.ScheduleEvent(EVENT_DEVOURING_FLAME, Seconds(22), 0, PHASE_PERMA_GROUND); + } + + void DoAction(int32 actionId) override + { + switch (actionId) + { + case ACTION_START_FIGHT: + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + me->SetSpeedRate(MOVE_RUN, 3.0f); + me->StopMoving(); + me->GetMotionMaster()->MovePoint(POINT_RAZORSCALE_FLIGHT, RazorFlightPosition); + break; + case ACTION_GROUND_PHASE: + me->InterruptNonMeleeSpells(false); + events.SetPhase(PHASE_GROUND); + _harpoonHitCount = 0; + me->SetSpeedRate(MOVE_RUN, 3.0f); + me->GetMotionMaster()->MovePoint(POINT_RAZORSCALE_LAND, RazorscaleLand); + break; + case ACTION_START_PERMA_GROUND: { - events.Reset(); - summons.DespawnAll(); + me->SetDisableGravity(false); + me->RemoveByteFlag(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_ANIM_TIER, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER); + me->RemoveAurasDueToSpell(SPELL_STUN_SELF); + Talk(EMOTE_PERMA_GROUND); + DoCastSelf(SPELL_WING_BUFFET); + EntryCheckPredicate pred(NPC_EXPEDITION_TRAPPER); + summons.DoAction(ACTION_STOP_CAST, pred); + events.ScheduleEvent(EVENT_RESUME_MOVE_CHASE, Milliseconds(1)); + ScheduleGroundPhaseEvents(); + break; } + default: + break; + } + } - void DoAction(int32 action) override - { - if (instance->GetBossState(BOSS_RAZORSCALE) != IN_PROGRESS) - return; + void MovementInform(uint32 type, uint32 pointId) override + { + if (type != POINT_MOTION_TYPE && type != EFFECT_MOTION_TYPE) + return; - switch (action) + switch (pointId) + { + case POINT_START_WAYPOINT: + HandleInitialMovement(); + break; + case POINT_RAZORSCALE_FLIGHT: + me->UpdateSpeed(MOVE_RUN); + me->SetFacingTo(RazorFlightPosition.GetOrientation()); + DoZoneInCombat(); + break; + case POINT_RAZORSCALE_GROUND: + me->SetDisableGravity(false); + me->RemoveByteFlag(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_ANIM_TIER, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER); + if (!_permaGround) { - case ACTION_HARPOON_BUILD: - events.ScheduleEvent(EVENT_BUILD_HARPOON_1, 50000); - if (me->GetMap()->GetSpawnMode() == RAID_DIFFICULTY_25MAN_NORMAL) - events.ScheduleEvent(EVENT_BUILD_HARPOON_3, 90000); - break; - case ACTION_PLACE_BROKEN_HARPOON: - for (uint8 n = 0; n < RAID_MODE(2, 4); n++) - me->SummonGameObject(GO_RAZOR_BROKEN_HARPOON, PosHarpoon[n].GetPositionX(), PosHarpoon[n].GetPositionY(), PosHarpoon[n].GetPositionZ(), 2.286f, QuaternionData(), 180); - break; + DoCastSelf(SPELL_STUN_SELF, true); + EntryCheckPredicate pred(NPC_EXPEDITION_TRAPPER); + summons.DoAction(ACTION_SHACKLE_RAZORSCALE, pred); + if (Creature* commander = instance->GetCreature(DATA_EXPEDITION_COMMANDER)) + commander->AI()->DoAction(ACTION_GROUND_PHASE); + events.ScheduleEvent(EVENT_FLAME_BREATH, Seconds(30), 0, PHASE_GROUND); } - } + break; + case POINT_RAZORSCALE_TAKEOFF: + me->SetSpeedRate(MOVE_RUN, 3.0f); + me->GetMotionMaster()->MovePoint(POINT_RAZORSCALE_FLIGHT_2, RazorFlightPositionPhase2); + break; + case POINT_RAZORSCALE_FLIGHT_2: + me->SetFacingTo(RazorFlightPositionPhase2.GetOrientation()); + me->SetReactState(REACT_AGGRESSIVE); + ScheduleAirPhaseEvents(); + ++_flyCount; + me->UpdateSpeed(MOVE_RUN); + break; + case POINT_RAZORSCALE_LAND: + me->UpdateSpeed(MOVE_RUN); + me->SetFacingTo(RazorscaleLand.GetOrientation()); + me->GetMotionMaster()->MoveLand(POINT_RAZORSCALE_GROUND, RazorscaleGroundPosition); + break; + default: + break; + } + } - void UpdateAI(uint32 Diff) override - { - events.Update(Diff); + void JustSummoned(Creature* summon) override + { + BossAI::JustSummoned(summon); - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_BUILD_HARPOON_1: - Talk(EMOTE_HARPOON); - if (GameObject* harpoon = me->SummonGameObject(GO_RAZOR_HARPOON_1, PosHarpoon[0].GetPositionX(), PosHarpoon[0].GetPositionY(), PosHarpoon[0].GetPositionZ(), 4.790f, QuaternionData(), uint32(me->GetRespawnTime()))) - { - if (GameObject* brokenHarpoon = harpoon->FindNearestGameObject(GO_RAZOR_BROKEN_HARPOON, 5.0f)) //only nearest broken harpoon - brokenHarpoon->RemoveFromWorld(); - events.ScheduleEvent(EVENT_BUILD_HARPOON_2, 20000); - events.CancelEvent(EVENT_BUILD_HARPOON_1); - } - return; - case EVENT_BUILD_HARPOON_2: - Talk(EMOTE_HARPOON); - if (GameObject* harpoon = me->SummonGameObject(GO_RAZOR_HARPOON_2, PosHarpoon[1].GetPositionX(), PosHarpoon[1].GetPositionY(), PosHarpoon[1].GetPositionZ(), 4.659f, QuaternionData(), uint32(me->GetRespawnTime()))) - { - if (GameObject* brokenHarpoon = harpoon->FindNearestGameObject(GO_RAZOR_BROKEN_HARPOON, 5.0f)) - brokenHarpoon->RemoveFromWorld(); - events.CancelEvent(EVENT_BUILD_HARPOON_2); - } - return; - case EVENT_BUILD_HARPOON_3: - Talk(EMOTE_HARPOON); - if (GameObject* harpoon = me->SummonGameObject(GO_RAZOR_HARPOON_3, PosHarpoon[2].GetPositionX(), PosHarpoon[2].GetPositionY(), PosHarpoon[2].GetPositionZ(), 5.382f, QuaternionData(), uint32(me->GetRespawnTime()))) - { - if (GameObject* brokenHarpoon = harpoon->FindNearestGameObject(GO_RAZOR_BROKEN_HARPOON, 5.0f)) - brokenHarpoon->RemoveFromWorld(); - events.ScheduleEvent(EVENT_BUILD_HARPOON_4, 20000); - events.CancelEvent(EVENT_BUILD_HARPOON_3); - } - return; - case EVENT_BUILD_HARPOON_4: - Talk(EMOTE_HARPOON); - if (GameObject* harpoon = me->SummonGameObject(GO_RAZOR_HARPOON_4, PosHarpoon[3].GetPositionX(), PosHarpoon[3].GetPositionY(), PosHarpoon[3].GetPositionZ(), 4.266f, QuaternionData(), uint32(me->GetRespawnTime()))) - { - if (GameObject* brokenHarpoon = harpoon->FindNearestGameObject(GO_RAZOR_BROKEN_HARPOON, 5.0f)) - brokenHarpoon->RemoveFromWorld(); - events.CancelEvent(EVENT_BUILD_HARPOON_4); - } - return; - } - } - } - }; - - CreatureAI* GetAI(Creature* creature) const override + switch (summon->GetEntry()) { - return GetUlduarAI<boss_razorscale_controllerAI>(creature); + case NPC_EXPEDITION_DEFENDER: + summon->AI()->SetData(DATA_EXPEDITION_NUMBER, _defendersCount); + ++_defendersCount; + break; + case NPC_EXPEDITION_ENGINEER: + summon->AI()->SetData(DATA_EXPEDITION_NUMBER, _engineersSummonCount); + ++_engineersSummonCount; + break; + case NPC_EXPEDITION_TRAPPER: + summon->AI()->SetData(DATA_EXPEDITION_NUMBER, _trappersCount); + ++_trappersCount; + break; + default: + break; } -}; + } -class go_razorscale_harpoon : public GameObjectScript -{ - public: - go_razorscale_harpoon() : GameObjectScript("go_razorscale_harpoon") { } - - struct go_razorscale_harpoonAI : public GameObjectAI + void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) override + { + if (summon->GetEntry() == NPC_EXPEDITION_ENGINEER) { - go_razorscale_harpoonAI(GameObject* go) : GameObjectAI(go), instance(go->GetInstanceScript()) { } - - InstanceScript* instance; - - bool GossipHello(Player* /*player*/) override - { - if (instance->GetCreature(BOSS_RAZORSCALE)) - me->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - return false; - } - }; + _engineersCount--; + if (_engineersCount == 0) + if (Creature* commander = instance->GetCreature(DATA_EXPEDITION_COMMANDER)) + commander->AI()->DoAction(ACTION_ENGINEER_DEAD); + } + } - GameObjectAI* GetAI(GameObject* go) const override + void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override + { + if (spell->Id == SPELL_HARPOON_TRIGGER) { - return GetUlduarAI<go_razorscale_harpoonAI>(go); + _harpoonHitCount++; + if (_harpoonHitCount == RAID_MODE(2, 4)) + DoAction(ACTION_GROUND_PHASE); } -}; - -class boss_razorscale : public CreatureScript -{ - public: - boss_razorscale() : CreatureScript("boss_razorscale") { } - - struct boss_razorscaleAI : public BossAI + } + + uint32 GetData(uint32 type) const override + { + if (type == DATA_QUICK_SHAVE && _flyCount <= 1) + return 1; + return 0; + } + + void EnterEvadeMode(EvadeReason why) override + { + if (why == EVADE_REASON_BOUNDARY && !events.IsInPhase(PHASE_PERMA_GROUND)) + return; + + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); + summons.DespawnAll(); + HandleMusic(false); + _EnterEvadeMode(); + _DespawnAtEvade(); + } + + void JustDied(Unit* /*killer*/) override + { + _JustDied(); + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); + HandleMusic(false); + } + + void HandleMusic(bool active) + { + uint32 enabled = active ? 1 : 0; + instance->DoUpdateWorldState(WORLD_STATE_RAZORSCALE_MUSIC, enabled); + } + + void SummonMinions() + { + float x = frand(540.0f, 640.0f); // Safe range is between 500 and 650 + float y = frand(-230.0f, -195.0f); // Safe range is between -235 and -145 + float z = 391.517f; // Ground level + me->SummonCreature(NPC_RAZORSCALE_SPAWNER, x, y, z, 0, TEMPSUMMON_TIMED_DESPAWN, 15000); + } + + void DamageTaken(Unit* /*done_by*/, uint32 &damage) override + { + if (!_permaGround && me->HealthBelowPctDamaged(50, damage) && events.IsInPhase(PHASE_GROUND)) { - boss_razorscaleAI(Creature* creature) : BossAI(creature, BOSS_RAZORSCALE) - { - Initialize(); - // Do not let Razorscale be affected by Battle Shout buff - me->ApplySpellImmune(0, IMMUNITY_ID, (SPELL_BATTLE_SHOUT), true); - FlyCount = 0; - EnrageTimer = 0; - Enraged = false; - phase = PHASE_GROUND; - } - - void Initialize() - { - PermaGround = false; - HarpoonCounter = 0; - } - - Phases phase; - - uint32 EnrageTimer; - uint8 FlyCount; - uint8 HarpoonCounter; - bool PermaGround; - bool Enraged; - - void Reset() override - { - _Reset(); - me->SetCanFly(true); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->SetReactState(REACT_PASSIVE); - Initialize(); - if (Creature* commander = instance->GetCreature(DATA_EXPEDITION_COMMANDER)) - commander->AI()->DoAction(ACTION_COMMANDER_RESET); - } - - void EnterCombat(Unit* /*who*/) override - { - _EnterCombat(); - if (Creature* controller = instance->GetCreature(DATA_RAZORSCALE_CONTROL)) - controller->AI()->DoAction(ACTION_HARPOON_BUILD); - me->SetSpeedRate(MOVE_FLIGHT, 3.0f); - me->SetReactState(REACT_PASSIVE); - phase = PHASE_GROUND; - events.SetPhase(PHASE_GROUND); - FlyCount = 0; - EnrageTimer = 600000; - Enraged = false; - events.ScheduleEvent(EVENT_FLIGHT, 0, 0, PHASE_GROUND); - } - - void JustDied(Unit* /*killer*/) override - { - _JustDied(); - if (Creature* controller = instance->GetCreature(DATA_RAZORSCALE_CONTROL)) - controller->AI()->Reset(); - } + _permaGround = true; + me->SetReactState(REACT_AGGRESSIVE); + events.SetPhase(PHASE_PERMA_GROUND); + DoAction(ACTION_START_PERMA_GROUND); + } + } - void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override - { - if (spell->Id == SPELL_HARPOON_TRIGGER) - ++HarpoonCounter; - } + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - void MovementInform(uint32 type, uint32 id) override - { - if (type == EFFECT_MOTION_TYPE && id == 1) - { - phase = PHASE_GROUND; - events.SetPhase(PHASE_GROUND); - events.ScheduleEvent(EVENT_LAND, 0, 0, PHASE_GROUND); - } - } + events.Update(diff); - uint32 GetData(uint32 type) const override - { - if (type == DATA_QUICK_SHAVE) - if (FlyCount <= 2) - return 1; + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - return 0; - } - - void UpdateAI(uint32 Diff) override + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) { - if (!UpdateVictim()) - return; - - events.Update(Diff); - - if (HealthBelowPct(50) && !PermaGround) - EnterPermaGround(); - - if (EnrageTimer <= Diff && !Enraged) - { - DoCast(me, SPELL_BERSERK); - Enraged = true; - } - else - EnrageTimer -= Diff; - - if (HarpoonCounter == RAID_MODE(2, 4)) + case EVENT_BERSERK: + DoCastSelf(SPELL_BERSERK, true); + Talk(EMOTE_BERSERK, me); + break; + case EVENT_FIREBALL: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) + DoCast(target, SPELL_FIREBALL); + events.Repeat(Seconds(2), Seconds(3)); + break; + case EVENT_DEVOURING_FLAME: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) + DoCast(target, SPELL_DEVOURING_FLAME); + if (_permaGround) + events.Repeat(Seconds(10), Seconds(12)); + else + events.Repeat(Seconds(6), Seconds(12)); + break; + case EVENT_SUMMON_MINIONS: { - HarpoonCounter = 0; - me->GetMotionMaster()->MoveLand(1, RazorGround); - } - - if (phase == PHASE_GROUND) - { - while (uint32 eventId = events.ExecuteEvent()) + uint8 random = urand(2, 4); + uint8 time = 5; + for (uint8 n = 0; n < random; ++n) { - switch (eventId) - { - case EVENT_FLIGHT: - phase = PHASE_FLIGHT; - events.SetPhase(PHASE_FLIGHT); - me->SetCanFly(true); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->SetReactState(REACT_PASSIVE); - me->AttackStop(); - me->GetMotionMaster()->MoveTakeoff(0, RazorFlight); - events.ScheduleEvent(EVENT_FIREBALL, 7000, 0, PHASE_FLIGHT); - events.ScheduleEvent(EVENT_DEVOURING, 10000, 0, PHASE_FLIGHT); - events.ScheduleEvent(EVENT_SUMMON, 5000, 0, PHASE_FLIGHT); - ++FlyCount; - return; - case EVENT_LAND: - me->SetCanFly(false); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED | UNIT_FLAG_PACIFIED); - if (Creature* commander = instance->GetCreature(DATA_EXPEDITION_COMMANDER)) - commander->AI()->DoAction(ACTION_GROUND_PHASE); - events.ScheduleEvent(EVENT_BREATH, 30000, 0, PHASE_GROUND); - events.ScheduleEvent(EVENT_BUFFET, 33000, 0, PHASE_GROUND); - events.ScheduleEvent(EVENT_FLIGHT, 35000, 0, PHASE_GROUND); - return; - case EVENT_BREATH: - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED | UNIT_FLAG_PACIFIED); - me->RemoveAllAuras(); - me->SetReactState(REACT_AGGRESSIVE); - Talk(EMOTE_BREATH); - DoCastAOE(SPELL_FLAMEBREATH); - events.CancelEvent(EVENT_BREATH); - return; - case EVENT_BUFFET: - DoCastAOE(SPELL_WINGBUFFET); - if (Creature* controller = instance->GetCreature(DATA_RAZORSCALE_CONTROL)) - controller->CastSpell(controller, SPELL_FLAMED, true); - events.CancelEvent(EVENT_BUFFET); - return; - } + events.ScheduleEvent(EVENT_SUMMON_MINIONS_2, Seconds(time), 0, PHASE_AIR); + time += 5; } + events.Repeat(Seconds(40)); + break; } - if (phase == PHASE_PERMAGROUND) + case EVENT_SUMMON_MINIONS_2: + SummonMinions(); + break; + case EVENT_FLAME_BREATH: + me->RemoveAurasDueToSpell(SPELL_STUN_SELF); + Talk(EMOTE_BREATH, me); + DoCastVictim(FLAME_BREATH); + events.ScheduleEvent(EVENT_WING_BUFFET, Seconds(2), 0, PHASE_GROUND); + break; + case EVENT_FLAME_BREATH_GROUND: + Talk(EMOTE_BREATH, me); + DoCastVictim(FLAME_BREATH); + events.Repeat(Seconds(15), Seconds(18)); + break; + case EVENT_WING_BUFFET: { - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_FLAME: - DoCastAOE(SPELL_FLAMEBUFFET); - events.ScheduleEvent(EVENT_FLAME, 10000, 0, PHASE_PERMAGROUND); - return; - case EVENT_BREATH: - Talk(EMOTE_BREATH); - DoCastVictim(SPELL_FLAMEBREATH); - events.ScheduleEvent(EVENT_BREATH, 20000, 0, PHASE_PERMAGROUND); - return; - case EVENT_FIREBALL: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 200.0f, true)) - DoCast(target, SPELL_FIREBALL); - events.ScheduleEvent(EVENT_FIREBALL, 3000, 0, PHASE_PERMAGROUND); - return; - case EVENT_DEVOURING: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 200.0f, true)) - DoCast(target, SPELL_DEVOURING_FLAME); - events.ScheduleEvent(EVENT_DEVOURING, 10000, 0, PHASE_PERMAGROUND); - return; - case EVENT_BUFFET: - DoCastAOE(SPELL_WINGBUFFET); - events.CancelEvent(EVENT_BUFFET); - return; - case EVENT_FUSE: - DoCastVictim(SPELL_FUSEARMOR); - events.ScheduleEvent(EVENT_FUSE, 10000, 0, PHASE_PERMAGROUND); - return; - } - } - - DoMeleeAttackIfReady(); + DoCastSelf(SPELL_WING_BUFFET); + events.ScheduleEvent(EVENT_FIREBOLT, Seconds(2), 0, PHASE_GROUND); + events.ScheduleEvent(EVENT_RESUME_AIR_PHASE, Seconds(4), 0, PHASE_GROUND); + EntryCheckPredicate pred(NPC_EXPEDITION_TRAPPER); + summons.DoAction(ACTION_STOP_CAST, pred); + break; } - else + case EVENT_RESUME_AIR_PHASE: { - if (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_FIREBALL: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 200.0f, true)) - DoCast(target, SPELL_FIREBALL); - events.ScheduleEvent(EVENT_FIREBALL, 3000, 0, PHASE_FLIGHT); - return; - case EVENT_DEVOURING: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 200.0f, true)) - me->CastSpell(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), SPELL_DEVOURING_FLAME, true); - events.ScheduleEvent(EVENT_DEVOURING, 10000, 0, PHASE_FLIGHT); - return; - case EVENT_SUMMON: - SummonMoleMachines(); - events.ScheduleEvent(EVENT_SUMMON, 45000, 0, PHASE_FLIGHT); - return; - } - } + me->SetDisableGravity(true); + me->SetByteFlag(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_ANIM_TIER, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER); + events.SetPhase(PHASE_AIR); + me->SetReactState(REACT_PASSIVE); + Position pos = me->GetPosition(); + pos.m_positionZ += 10.0f; + me->GetMotionMaster()->MoveTakeoff(POINT_RAZORSCALE_TAKEOFF, pos); + EntryCheckPredicate pred(NPC_EXPEDITION_ENGINEER); + summons.DoAction(ACTION_FIX_HARPOONS, pred); + break; } + case EVENT_FIREBOLT: + DoCastSelf(SPELL_FIREBOLT); + break; + case EVENT_FUSE_ARMOR: + DoCastVictim(SPELL_FUSE_ARMOR); + events.Repeat(Seconds(10), Seconds(15)); + break; + case EVENT_RESUME_MOVE_CHASE: + SetCombatMovement(true); + if (Unit* victim = me->GetVictim()) + me->GetMotionMaster()->MoveChase(victim); + break; + default: + break; } - void EnterPermaGround() - { - Talk(EMOTE_PERMA); - phase = PHASE_PERMAGROUND; - events.SetPhase(PHASE_PERMAGROUND); - me->SetCanFly(false); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_STUNNED | UNIT_FLAG_PACIFIED); - me->SetReactState(REACT_AGGRESSIVE); - me->RemoveAurasDueToSpell(SPELL_HARPOON_TRIGGER); - me->SetSpeedRate(MOVE_FLIGHT, 1.0f); - PermaGround = true; - DoCastAOE(SPELL_FLAMEBREATH); - events.ScheduleEvent(EVENT_FLAME, 15000, 0, PHASE_PERMAGROUND); - events.RescheduleEvent(EVENT_DEVOURING, 15000, 0, PHASE_PERMAGROUND); - events.RescheduleEvent(EVENT_BREATH, 20000, 0, PHASE_PERMAGROUND); - events.RescheduleEvent(EVENT_FIREBALL, 3000, 0, PHASE_PERMAGROUND); - events.RescheduleEvent(EVENT_DEVOURING, 6000, 0, PHASE_PERMAGROUND); - events.RescheduleEvent(EVENT_BUFFET, 2500, 0, PHASE_PERMAGROUND); - events.RescheduleEvent(EVENT_FUSE, 5000, 0, PHASE_PERMAGROUND); - } + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + } + + if (events.IsInPhase(PHASE_PERMA_GROUND)) + DoMeleeAttackIfReady(); + } + +private: + uint8 _engineersCount; + uint8 _engineersSummonCount; + uint8 _defendersCount; + uint8 _harpoonHitCount; + uint8 _trappersCount; + bool _permaGround; + uint32 _flyCount; +}; - void SummonMoleMachines() +struct npc_expedition_commander : public ScriptedAI +{ + npc_expedition_commander(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()), + _is25Man(Is25ManRaid()), _building(false), _destroy(false), _stopControllers(false) { } + + void Reset() override + { + _events.Reset(); + _events.SetPhase(PHASE_NONE); + BuildBrokenHarpoons(); + } + + bool GossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override + { + if (gossipListId == GOSSIP_START_ENCOUNTER) + { + CloseGossipMenuFor(player); + _events.SetPhase(PHASE_COMBAT); + me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + if (Creature* razorscale = _instance->GetCreature(BOSS_RAZORSCALE)) + razorscale->AI()->DoAction(ACTION_START_FIGHT); + return true; + } + return false; + } + + void BuildBrokenHarpoons() + { + uint8 harpoonNumber = _is25Man ? 4 : 2; + for (uint8 i = 0; i < harpoonNumber; ++i) + me->SummonGameObject(GO_RAZOR_BROKEN_HARPOON, PosBrokenHarpoon[i], QuaternionData(0.0f, 0.0f, -0.8987932f, 0.4383728f), WEEK); + } + + void DestroyHarpoons() + { + for (ObjectGuid harpoonGuid : _harpoons) + if (GameObject* harpoon = ObjectAccessor::GetGameObject(*me, harpoonGuid)) + harpoon->RemoveFromWorld(); + + _harpoons.clear(); + BuildBrokenHarpoons(); + _events.ScheduleEvent(EVENT_HANDLE_DESTROY_HARPOON, Seconds(10)); + } + + void HandleControllersStopCast() + { + std::list<Creature*> Controllers; + me->GetCreatureListWithEntryInGrid(Controllers, NPC_RAZORSCALE_CONTROLLER, 100.0f); + + for (Creature* controller : Controllers) + controller->InterruptNonMeleeSpells(false); + + _stopControllers = false; + } + + void BuildHarpoon(uint8 harpoonNumber) + { + + if (_is25Man) + { + switch (harpoonNumber) { - // Adds will come in waves from mole machines. One mole can spawn a Dark Rune Watcher - // with 1-2 Guardians, or a lone Sentinel. Up to 4 mole machines can spawn adds at any given time. - uint8 random = urand(2, 4); - for (uint8 n = 0; n < random; n++) - { - float x = float(irand(540, 640)); // Safe range is between 500 and 650 - float y = float(irand(-230, -195)); // Safe range is between -235 and -145 - float z = GROUND_Z; // Ground level - me->SummonCreature(MOLE_MACHINE_TRIGGER, x, y, z, 0, TEMPSUMMON_TIMED_DESPAWN, 15000); - } + case HARPOON_1: + if (GameObject* harpoon = me->SummonGameObject(GO_RAZOR_HARPOON_3, PosHarpoon[2], QuaternionData(0.0f, 0.0f, -0.573576f, 0.8191524f), WEEK)) + _harpoons.emplace_back(harpoon->GetGUID()); + break; + case HARPOON_2: + if (GameObject* harpoon = me->SummonGameObject(GO_RAZOR_HARPOON_1, PosHarpoon[0], QuaternionData(0.0f, 0.0f, -0.6293201f, 0.7771462f), WEEK)) + _harpoons.emplace_back(harpoon->GetGUID()); + break; + case HARPOON_3: + if (GameObject* harpoon = me->SummonGameObject(GO_RAZOR_HARPOON_2, PosHarpoon[1], QuaternionData(0.0f, 0.0f, -0.6691303f, 0.743145f), WEEK)) + _harpoons.emplace_back(harpoon->GetGUID()); + break; + case HARPOON_4: + if (GameObject* harpoon = me->SummonGameObject(GO_RAZOR_HARPOON_4, PosHarpoon[3], QuaternionData(0.0f, 0.0f, -0.7660437f, 0.6427886f), WEEK)) + _harpoons.emplace_back(harpoon->GetGUID()); + break; + default: + break; } - - void DoAction(int32 action) override + } + else + { + switch (harpoonNumber) { - switch (action) - { - case ACTION_EVENT_START: - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); - me->SetReactState(REACT_AGGRESSIVE); - DoZoneInCombat(me, 150.0f); - break; - } + case HARPOON_1: + if (GameObject* harpoon = me->SummonGameObject(GO_RAZOR_HARPOON_1, PosHarpoon[harpoonNumber], QuaternionData(0.0f, 0.0f, -0.6293201f, 0.7771462f), 0)) + _harpoons.emplace_back(harpoon->GetGUID()); + break; + case HARPOON_2: + if (GameObject* harpoon = me->SummonGameObject(GO_RAZOR_HARPOON_2, PosHarpoon[harpoonNumber], QuaternionData(0.0f, 0.0f, -0.6691303f, 0.743145f), 0)) + _harpoons.emplace_back(harpoon->GetGUID()); + break; + default: + break; } - }; + } + } + + void DoAction(int32 actionId) override + { + if (_building && actionId != ACTION_ENGINEER_DEAD) + return; - CreatureAI* GetAI(Creature* creature) const override + switch (actionId) { - return GetUlduarAI<boss_razorscaleAI>(creature); + case ACTION_START_FIGHT: + Talk(SAY_COMMANDER_AGGRO); + break; + case ACTION_GROUND_PHASE: + Talk(SAY_COMMANDER_GROUND_PHASE); + break; + case ACTION_ENGINEER_DEAD: + Talk(SAY_COMMANDER_ENGINEERS_DEAD); + _events.Reset(); + _building = false; + break; + case ACTION_BUILD_HARPOON_1: + _building = true; + _events.ScheduleEvent(EVENT_BUILD_HARPOON_1, Seconds(18)); + break; + case ACTION_BUILD_HARPOON_2: + _building = true; + _events.ScheduleEvent(EVENT_BUILD_HARPOON_2, Seconds(18)); + break; + case ACTION_BUILD_HARPOON_3: + _building = true; + _events.ScheduleEvent(EVENT_BUILD_HARPOON_3, Seconds(18)); + break; + case ACTION_BUILD_HARPOON_4: + _building = true; + _events.ScheduleEvent(EVENT_BUILD_HARPOON_4, Seconds(18)); + break; + case ACTION_DESTROY_HARPOONS: + if (_destroy) + return; + _destroy = true; + DestroyHarpoons(); + break; + case ACTION_STOP_CONTROLLERS: + if (_stopControllers) + return; + _stopControllers = true; + HandleControllersStopCast(); + break; + default: + break; } -}; + } -class npc_expedition_commander : public CreatureScript -{ - public: - npc_expedition_commander() : CreatureScript("npc_expedition_commander") { } + void UpdateAI(uint32 diff) override + { + if (!_events.IsInPhase(PHASE_COMBAT)) + return; - struct npc_expedition_commanderAI : public ScriptedAI - { - npc_expedition_commanderAI(Creature* creature) : ScriptedAI(creature), summons(creature) - { - Initialize(); - instance = me->GetInstanceScript(); - } + _events.Update(diff); - void Initialize() + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) { - AttackStartTimer = 0; - Phase = 0; - Greet = false; + case EVENT_BUILD_HARPOON_1: + BuildHarpoon(HARPOON_1); + _building = false; + break; + case EVENT_BUILD_HARPOON_2: + BuildHarpoon(HARPOON_2); + _building = false; + break; + case EVENT_BUILD_HARPOON_3: + BuildHarpoon(HARPOON_3); + _building = false; + break; + case EVENT_BUILD_HARPOON_4: + BuildHarpoon(HARPOON_4); + _building = false; + break; + case EVENT_HANDLE_DESTROY_HARPOON: + _destroy = false; + break; + default: + break; } + } + } + +private: + InstanceScript* _instance; + GuidVector _harpoons; + bool _is25Man; + bool _building; + bool _destroy; + bool _stopControllers; + EventMap _events; +}; - InstanceScript* instance; - SummonList summons; +struct npc_expedition_defender : public ScriptedAI +{ + npc_expedition_defender(Creature* creature) : ScriptedAI(creature), _myPositionNumber(0), _instance(creature->GetInstanceScript()) + { + me->SetRegenerateHealth(false); + } + + void Reset() override + { + DoCastSelf(SPELL_THREAT); + } + + bool CanAIAttack(Unit const* target) const override + { + if (target->GetEntry() == NPC_RAZORSCALE || target->GetEntry() == NPC_RAZORSCALE_SPAWNER) + return false; - bool Greet; - uint32 AttackStartTimer; - uint8 Phase; - ObjectGuid Engineer[4]; - ObjectGuid Defender[4]; + return ScriptedAI::CanAIAttack(target); + } + + void SetData(uint32 type, uint32 value) override + { + if (type == DATA_EXPEDITION_NUMBER) + _myPositionNumber = value; + } + + void DoAction(int32 actionId) override + { + if (actionId == ACTION_START_FIGHT) + me->GetMotionMaster()->MovePoint(POINT_DEFENDER_ATTACK, DefendersPosition[_myPositionNumber]); + } + + void MovementInform(uint32 type, uint32 pointId) override + { + if (type != POINT_MOTION_TYPE && pointId != POINT_DEFENDER_ATTACK) + return; + + me->SetHomePosition(DefendersPosition[_myPositionNumber]); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC); + } + +private: + uint8 _myPositionNumber; + InstanceScript* _instance; +}; - void Reset() override - { - Initialize(); - summons.DespawnAll(); - } +struct npc_expedition_trapper : public ScriptedAI +{ + npc_expedition_trapper(Creature* creature) : ScriptedAI(creature), _myPositionNumber(0), _instance(creature->GetInstanceScript()) + { + SetCombatMovement(false); + me->SetReactState(REACT_PASSIVE); + } + + void DoAction(int32 actionId) override + { + if (!me->IsAlive()) + return; + + switch (actionId) + { + case ACTION_SHACKLE_RAZORSCALE: + me->GetMotionMaster()->MovePoint(POINT_SHACKLE_RAZORSCALE, TrapperPosition[_myPositionNumber]); + break; + case ACTION_RETURN_TO_BASE: + me->GetMotionMaster()->MoveTargetedHome(); + break; + case ACTION_START_FIGHT: + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC); + break; + case ACTION_STOP_CAST: + me->InterruptNonMeleeSpells(false); + _scheduler.Schedule(Seconds(2), [this](TaskContext /*context*/) + { + me->GetMotionMaster()->MoveTargetedHome(); + }); + if (Creature* commander = _instance->GetCreature(DATA_EXPEDITION_COMMANDER)) + commander->AI()->DoAction(ACTION_STOP_CONTROLLERS); + break; + default: + break; + } + } + + void SetData(uint32 type, uint32 value) override + { + if (type == DATA_EXPEDITION_NUMBER) + _myPositionNumber = value; + } + + void MovementInform(uint32 type, uint32 pointId) override + { + if (type != POINT_MOTION_TYPE && pointId != POINT_SHACKLE_RAZORSCALE) + return; + + DoCastSelf(SPELL_SHACKLE); + } + + void UpdateAI(uint32 diff) override + { + _scheduler.Update(diff); + } + +private: + uint8 _myPositionNumber; + InstanceScript* _instance; + TaskScheduler _scheduler; +}; - void MoveInLineOfSight(Unit* who) override +struct npc_expedition_engineer : public ScriptedAI +{ + npc_expedition_engineer(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()), _myPositionNumber(0), _canUpdateAI(false) { } - { - if (!Greet && me->IsWithinDistInMap(who, 10.0f) && who->GetTypeId() == TYPEID_PLAYER) - { - Talk(SAY_INTRO); - Greet = true; - } - } + void Reset() override + { + me->SetReactState(REACT_PASSIVE); + _scheduler.CancelAll(); + } - void JustSummoned(Creature* summoned) override - { - summons.Summon(summoned); - } + void DoAction(int32 actionId) override + { + if (!me->IsAlive()) + return; - void DoAction(int32 action) override + if (actionId == ACTION_START_FIGHT) + { + _canUpdateAI = true; + if (_myPositionNumber == ENGINEER_EAST) + Talk(SAY_AGGRO); + _scheduler.Schedule(Seconds(28), [this](TaskContext /*context*/) { - switch (action) - { - case ACTION_GROUND_PHASE: - Talk(SAY_GROUND_PHASE); - break; - case ACTION_COMMANDER_RESET: - summons.DespawnAll(); - me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - break; - } - } - - void UpdateAI(uint32 Diff) override + HandleHarpoonMovement(); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC); + }); + } + else if (actionId == ACTION_FIX_HARPOONS) + { + if (_myPositionNumber == ENGINEER_EAST) + Talk(SAY_AGGRO); + _scheduler.Schedule(Seconds(28), [this](TaskContext /*context*/) { - if (AttackStartTimer <= Diff) - { - switch (Phase) - { - case 1: - instance->SetBossState(BOSS_RAZORSCALE, IN_PROGRESS); - summons.DespawnAll(); - AttackStartTimer = 1000; - Phase = 2; - break; - case 2: - for (uint8 n = 0; n < RAID_MODE(2, 4); n++) - { - if (Creature* summonedEngineer = me->SummonCreature(NPC_ENGINEER, PosEngSpawn, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 3000)) - { - summonedEngineer->SetWalk(false); - summonedEngineer->SetSpeedRate(MOVE_RUN, 0.5f); - summonedEngineer->SetHomePosition(PosEngRepair[n]); - summonedEngineer->GetMotionMaster()->MoveTargetedHome(); - Engineer[n] = summonedEngineer->GetGUID(); - } - } - if (Creature* firstSummon = ObjectAccessor::GetCreature(*me, Engineer[0])) - firstSummon->AI()->Talk(SAY_AGGRO_3); - Phase = 3; - AttackStartTimer = 14000; - break; - case 3: - for (uint8 n = 0; n < 4; n++) - { - if (Creature* summonedDefender = me->SummonCreature(NPC_DEFENDER, PosDefSpawn[n], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 3000)) - { - summonedDefender->SetWalk(false); - summonedDefender->SetHomePosition(PosDefCombat[n]); - summonedDefender->GetMotionMaster()->MoveTargetedHome(); - Defender[n] = summonedDefender->GetGUID(); - } - } - Phase = 4; - break; - case 4: - for (uint8 n = 0; n < RAID_MODE(2, 4); n++) - if (Creature* summonedEngineer = ObjectAccessor::GetCreature(*me, Engineer[n])) - summonedEngineer->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_USE_STANDING); - for (uint8 n = 0; n < 4; ++n) - if (Creature* summonedDefender = ObjectAccessor::GetCreature(*me, Defender[n])) - summonedDefender->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY2H); - Talk(SAY_AGGRO_2); - AttackStartTimer = 16000; - Phase = 5; - break; - case 5: - if (Creature* razorscale = instance->GetCreature(BOSS_RAZORSCALE)) - { - razorscale->AI()->DoAction(ACTION_EVENT_START); - me->SetInCombatWith(razorscale); - } - if (Creature* firstEngineer = ObjectAccessor::GetCreature(*me, Engineer[0])) - firstEngineer->AI()->Talk(SAY_AGGRO_1); - Phase = 6; - break; - } - } - else - AttackStartTimer -= Diff; - } + HandleHarpoonMovement(); + }); + } + } - bool GossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override - { - uint32 const action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId); - ClearGossipMenuFor(player); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF: - CloseGossipMenuFor(player); - Phase = 1; - break; - } - return true; - } + void ChangeOrientation(float orientation) + { + _scheduler.Schedule(Milliseconds(1), [this, orientation](TaskContext /*context*/) + { + me->SetFacingTo(orientation); + }); + } - bool GossipHello(Player* player) override - { - if (instance->GetBossState(BOSS_RAZORSCALE) == NOT_STARTED) - { - player->PrepareGossipMenu(me); + void HandleHarpoonMovement() + { + switch (_myPositionNumber) + { + case ENGINEER_NORTH: + if (Is25ManRaid()) + me->GetMotionMaster()->MoveAlongSplineChain(POINT_HARPOON_1_25, SPLINE_ENGINEER_NORTH_25_HARPOON_1, false); + else + me->GetMotionMaster()->MoveAlongSplineChain(POINT_HARPOON_1, SPLINE_ENGINEER_NORTH_10_HARPOON_1, false); + break; + case ENGINEER_EAST: + Talk(SAY_START_REPAIR); + if (Is25ManRaid()) + me->GetMotionMaster()->MoveAlongSplineChain(POINT_HARPOON_1_25, SPLINE_ENGINEER_EAST_25_HARPOON_1, false); + else + me->GetMotionMaster()->MoveAlongSplineChain(POINT_HARPOON_1, SPLINE_ENGINEER_EAST_10_HARPOON_1, false); + break; + case ENGINEER_WEST: + if (Is25ManRaid()) + me->GetMotionMaster()->MoveAlongSplineChain(POINT_HARPOON_1_25, SPLINE_ENGINEER_WEST_25_HARPOON_1, false); + else + me->GetMotionMaster()->MoveAlongSplineChain(POINT_HARPOON_1, SPLINE_ENGINEER_WEST_10_HARPOON_1, false); + break; + default: + break; + } + } - AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_ITEM_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - SendGossipMenuFor(player, 13853, me->GetGUID()); - } + void HandleSecondHarpoonMovement() + { + switch (_myPositionNumber) + { + case ENGINEER_NORTH: + if (Is25ManRaid()) + me->GetMotionMaster()->MoveAlongSplineChain(POINT_HARPOON_2_25, SPLINE_ENGINEER_NORTH_25_HARPOON_2, false); + else + me->GetMotionMaster()->MoveAlongSplineChain(POINT_HARPOON_2, SPLINE_ENGINEER_NORTH_10_HARPOON_2, false); + break; + case ENGINEER_EAST: + if (Is25ManRaid()) + me->GetMotionMaster()->MoveAlongSplineChain(POINT_HARPOON_2_25, SPLINE_ENGINEER_EAST_25_HARPOON_2, false); else - SendGossipMenuFor(player, 13910, me->GetGUID()); + me->GetMotionMaster()->MoveAlongSplineChain(POINT_HARPOON_2, SPLINE_ENGINEER_EAST_10_HARPOON_2, false); + break; + case ENGINEER_WEST: + if (Is25ManRaid()) + me->GetMotionMaster()->MoveAlongSplineChain(POINT_HARPOON_2_25, SPLINE_ENGINEER_WEST_25_HARPOON_2, false); + else + me->GetMotionMaster()->MoveAlongSplineChain(POINT_HARPOON_2, SPLINE_ENGINEER_WEST_10_HARPOON_2, false); + break; + default: + break; + } + } - return true; - } + void HandleThirdHarpoonMovement() + { + switch (_myPositionNumber) + { + case ENGINEER_NORTH: + if (Is25ManRaid()) + me->GetMotionMaster()->MoveAlongSplineChain(POINT_HARPOON_3, SPLINE_ENGINEER_NORTH_25_HARPOON_3, false); + else + me->GetMotionMaster()->MoveAlongSplineChain(POINT_BASE, SPLINE_ENGINEER_NORTH_10_BASE, false); + break; + case ENGINEER_EAST: + if (Is25ManRaid()) + me->GetMotionMaster()->MoveAlongSplineChain(POINT_HARPOON_3, SPLINE_ENGINEER_EAST_25_HARPOON_3, false); + else + me->GetMotionMaster()->MoveAlongSplineChain(POINT_BASE, SPLINE_ENGINEER_EAST_10_BASE, false); + break; + case ENGINEER_WEST: + if (Is25ManRaid()) + me->GetMotionMaster()->MoveAlongSplineChain(POINT_HARPOON_3, SPLINE_ENGINEER_WEST_25_HARPOON_3, false); + else + me->GetMotionMaster()->MoveAlongSplineChain(POINT_BASE, SPLINE_ENGINEER_WEST_10_BASE, false); + break; + default: + break; + } + } - }; + void HandleFourthHarpoonMovement() + { + switch (_myPositionNumber) + { + case ENGINEER_NORTH: + if (Is25ManRaid()) + me->GetMotionMaster()->MoveAlongSplineChain(POINT_HARPOON_4, SPLINE_ENGINEER_NORTH_25_HARPOON_4, false); + break; + case ENGINEER_EAST: + if (Is25ManRaid()) + me->GetMotionMaster()->MoveAlongSplineChain(POINT_HARPOON_4, SPLINE_ENGINEER_EAST_25_HARPOON_4, false); + break; + case ENGINEER_WEST: + if (Is25ManRaid()) + me->GetMotionMaster()->MoveAlongSplineChain(POINT_HARPOON_4, SPLINE_ENGINEER_WEST_25_HARPOON_4, false); + break; + default: + break; + } + } - CreatureAI* GetAI(Creature* creature) const override + void HandleBaseMovement() + { + switch (_myPositionNumber) { - return GetUlduarAI<npc_expedition_commanderAI>(creature); + case ENGINEER_NORTH: + if (Is25ManRaid()) + me->GetMotionMaster()->MoveAlongSplineChain(POINT_BASE, SPLINE_ENGINEER_NORTH_25_BASE, false); + break; + case ENGINEER_EAST: + if (Is25ManRaid()) + me->GetMotionMaster()->MovePoint(POINT_BASE, me->GetHomePosition()); + break; + case ENGINEER_WEST: + if (Is25ManRaid()) + me->GetMotionMaster()->MoveAlongSplineChain(POINT_BASE, SPLINE_ENGINEER_WEST_25_BASE, false); + break; + default: + break; } -}; + } -class npc_mole_machine_trigger : public CreatureScript -{ - public: - npc_mole_machine_trigger() : CreatureScript("npc_mole_machine_trigger") { } + void UpdateAI(uint32 diff) override + { + if (!_canUpdateAI) + return; - struct npc_mole_machine_triggerAI : public ScriptedAI - { - npc_mole_machine_triggerAI(Creature* creature) : ScriptedAI(creature) - { - Initialize(); - SetCombatMovement(false); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_PACIFIED); - } + _scheduler.Update(diff); + } - void Initialize() - { - SummonGobTimer = 2000; - SummonNpcTimer = 6000; - DissapearTimer = 10000; - GobSummoned = false; - NpcSummoned = false; - } + void SetData(uint32 type, uint32 value) override + { + if (type == DATA_EXPEDITION_NUMBER) + _myPositionNumber = value; + } - uint32 SummonGobTimer; - uint32 SummonNpcTimer; - uint32 DissapearTimer; - bool GobSummoned; - bool NpcSummoned; + void MovementInform(uint32 type, uint32 pointId) override + { + if (type != POINT_MOTION_TYPE && type != SPLINE_CHAIN_MOTION_TYPE) + return; - void Reset() override - { - Initialize(); - } + switch (pointId) + { + case POINT_HARPOON_1: + case POINT_HARPOON_1_25: + if (Creature* commander = _instance->GetCreature(DATA_EXPEDITION_COMMANDER)) + commander->AI()->DoAction(ACTION_BUILD_HARPOON_1); - void UpdateAI(uint32 Diff) override - { - if (!GobSummoned && SummonGobTimer <= Diff) + _scheduler. + Schedule(Seconds(3), [this](TaskContext /*context*/) { - DoCast(SPELL_SUMMON_MOLE_MACHINE); - GobSummoned = true; - } - else - SummonGobTimer -= Diff; - - if (!NpcSummoned && SummonNpcTimer <= Diff) + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_USE_STANDING); + }) + .Schedule(Seconds(18), [this](TaskContext /*context*/) { - switch (urand(0, 1 )) - { - case 0: - DoCast(SPELL_SUMMON_IRON_DWARVES); - break; - case 1: - DoCast(SPELL_SUMMON_IRON_DWARVES_2); - break; - } - - DoCast(SPELL_SUMMON_IRON_DWARVE_GUARDIAN); - DoCast(SPELL_SUMMON_IRON_DWARVE_WATCHER); - NpcSummoned = true; - } - else - SummonNpcTimer -= Diff; - - if (DissapearTimer <= Diff) + HandleSecondHarpoonMovement(); + }); + break; + case POINT_HARPOON_2: + case POINT_HARPOON_2_25: + if (Creature* commander = _instance->GetCreature(DATA_EXPEDITION_COMMANDER)) + commander->AI()->DoAction(ACTION_BUILD_HARPOON_2); + _scheduler.Schedule(Seconds(18), [this](TaskContext /*context*/) { - if (GameObject* molemachine = me->FindNearestGameObject(GO_MOLE_MACHINE, 1)) - molemachine->Delete(); - - me->DisappearAndDie(); - } - else - DissapearTimer -= Diff; - } + HandleThirdHarpoonMovement(); + }); + break; + case POINT_HARPOON_3: + if (Creature* commander = _instance->GetCreature(DATA_EXPEDITION_COMMANDER)) + commander->AI()->DoAction(ACTION_BUILD_HARPOON_3); + _scheduler.Schedule(Seconds(18), [this](TaskContext /*context*/) + { + HandleFourthHarpoonMovement(); + }); + break; + case POINT_HARPOON_4: + if (Creature* commander = _instance->GetCreature(DATA_EXPEDITION_COMMANDER)) + commander->AI()->DoAction(ACTION_BUILD_HARPOON_4); + _scheduler.Schedule(Seconds(18), [this](TaskContext /*context*/) + { + HandleBaseMovement(); + }); + break; + case POINT_BASE: + ChangeOrientation(4.61684f); + break; + default: + break; + } + } - void JustSummoned(Creature* summoned) override - { - summoned->AI()->DoZoneInCombat(); - } - }; +private: + InstanceScript* _instance; + TaskScheduler _scheduler; + uint8 _myPositionNumber; + bool _canUpdateAI; +}; - CreatureAI* GetAI(Creature* creature) const override +struct npc_razorscale_spawner : public ScriptedAI +{ + npc_razorscale_spawner(Creature* creature) : ScriptedAI(creature) { } + + void Reset() override + { + me->setActive(true); + me->SetReactState(REACT_PASSIVE); + _scheduler. + Schedule(Seconds(1), [this](TaskContext /*context*/) { - return GetUlduarAI<npc_mole_machine_triggerAI>(creature); - } + DoCastSelf(SPELL_SUMMON_MOLE_MACHINE); + }).Schedule(Seconds(6), [this](TaskContext /*context*/) + { + DoCastSelf(SummonMinionsSpells[urand(0, 3)]); + }); + } + + void UpdateAI(uint32 diff) override + { + _scheduler.Update(diff); + } + +private: + TaskScheduler _scheduler; }; -class npc_devouring_flame : public CreatureScript +struct npc_darkrune_watcher : public ScriptedAI { - public: - npc_devouring_flame() : CreatureScript("npc_devouring_flame") { } - - struct npc_devouring_flameAI : public ScriptedAI + npc_darkrune_watcher(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { } + + void Reset() override + { + _events.Reset(); + me->SetReactState(REACT_PASSIVE); + _events.ScheduleEvent(EVENT_START_COMBAT, Seconds(2)); + if (Creature* razorscale = _instance->GetCreature(BOSS_RAZORSCALE)) + razorscale->AI()->JustSummoned(me); + } + + void EnterCombat(Unit* /*who*/) override + { + _events.ScheduleEvent(EVENT_LIGHTNING_BOLT, Seconds(5)); + _events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, Seconds(34)); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + _events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = _events.ExecuteEvent()) { - npc_devouring_flameAI(Creature* creature) : ScriptedAI(creature) + switch (eventId) { - SetCombatMovement(false); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_PACIFIED); + case EVENT_START_COMBAT: + me->SetReactState(REACT_AGGRESSIVE); + me->SetInCombatWithZone(); + break; + case EVENT_LIGHTNING_BOLT: + DoCastVictim(LIGHTNING_BOLT); + _events.Repeat(Seconds(3)); + break; + case EVENT_CHAIN_LIGHTNING: + DoCastVictim(CHAIN_LIGHTNING); + _events.Repeat(Seconds(9), Seconds(15)); + break; + default: + break; } - void Reset() override - { - DoCast(SPELL_FLAME_GROUND); - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetUlduarAI<npc_devouring_flameAI>(creature); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; } + + DoMeleeAttackIfReady(); + } + +private: + InstanceScript* _instance; + EventMap _events; }; -class npc_darkrune_watcher : public CreatureScript +struct npc_darkrune_guardian : public ScriptedAI { - public: - npc_darkrune_watcher() : CreatureScript("npc_darkrune_watcher") { } - - struct npc_darkrune_watcherAI : public ScriptedAI + npc_darkrune_guardian(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()), _killedByBreath(false) { } + + void Reset() override + { + _events.Reset(); + me->SetReactState(REACT_PASSIVE); + _events.ScheduleEvent(EVENT_START_COMBAT, Seconds(2)); + if (Creature* razorscale = _instance->GetCreature(BOSS_RAZORSCALE)) + razorscale->AI()->JustSummoned(me); + } + + void EnterCombat(Unit* /*who*/) override + { + _events.ScheduleEvent(EVENT_STORMSTRIKE, Seconds(23)); + } + + uint32 GetData(uint32 type) const override + { + return type == DATA_IRON_DWARF_MEDIUM_RARE ? _killedByBreath : 0; + } + + void SetData(uint32 type, uint32 value) override + { + if (type == DATA_IRON_DWARF_MEDIUM_RARE) + _killedByBreath = value != 0; + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + _events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = _events.ExecuteEvent()) { - npc_darkrune_watcherAI(Creature* creature) : ScriptedAI(creature) + switch (eventId) { - Initialize(); + case EVENT_START_COMBAT: + me->SetReactState(REACT_AGGRESSIVE); + me->SetInCombatWithZone(); + break; + case EVENT_STORMSTRIKE: + DoCastVictim(SPELL_STORMSTRIKE); + _events.Repeat(Seconds(13), Seconds(25)); + break; + default: + break; } - void Initialize() - { - ChainTimer = urand(10000, 15000); - LightTimer = urand(1000, 3000); - } + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + } + + DoMeleeAttackIfReady(); + } - uint32 ChainTimer; - uint32 LightTimer; +private: + InstanceScript* _instance; + EventMap _events; + bool _killedByBreath; +}; - void Reset() override +struct npc_darkrune_sentinel : public ScriptedAI +{ + npc_darkrune_sentinel(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { } + + void Reset() override + { + _events.Reset(); + me->SetReactState(REACT_PASSIVE); + _events.ScheduleEvent(EVENT_START_COMBAT, Seconds(2)); + if (Creature* razorscale = _instance->GetCreature(BOSS_RAZORSCALE)) + razorscale->AI()->JustSummoned(me); + } + + void EnterCombat(Unit* /*who*/) override + { + _events.ScheduleEvent(EVENT_HEROIC_STRIKE, Seconds(9)); + _events.ScheduleEvent(EVENT_BATTLE_SHOUT, Seconds(15)); + _events.ScheduleEvent(EVENT_WHIRLWIND, Seconds(17)); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + _events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) { - Initialize(); + case EVENT_START_COMBAT: + me->SetReactState(REACT_AGGRESSIVE); + me->SetInCombatWithZone(); + break; + case EVENT_HEROIC_STRIKE: + DoCastVictim(SPELL_HEROIC_STRIKE); + _events.Repeat(Seconds(5), Seconds(9)); + break; + case EVENT_BATTLE_SHOUT: + DoCastSelf(SPELL_BATTLE_SHOUT); + _events.Repeat(Seconds(25)); + break; + case EVENT_WHIRLWIND: + DoCastSelf(SPELL_WHIRLWIND); + _events.Repeat(Seconds(10), Seconds(13)); + break; + default: + break; } - void UpdateAI(uint32 Diff) override - { - if (!UpdateVictim()) - return; + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + } - if (ChainTimer <= Diff) - { - DoCastVictim(SPELL_CHAIN_LIGHTNING); - ChainTimer = urand(10000, 15000); - } - else - ChainTimer -= Diff; + DoMeleeAttackIfReady(); + } - if (LightTimer <= Diff) - { - DoCastVictim(SPELL_LIGHTNING_BOLT); - LightTimer = urand(5000, 7000); - } - else - LightTimer -= Diff; +private: + InstanceScript* _instance; + EventMap _events; +}; - DoMeleeAttackIfReady(); - } - }; +struct npc_razorscale_harpoon_fire_state : public ScriptedAI +{ + npc_razorscale_harpoon_fire_state(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { } - CreatureAI* GetAI(Creature* creature) const override + void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override + { + if (spell->Id == SPELL_FIREBOLT) { - return GetUlduarAI<npc_darkrune_watcherAI>(creature); + DoCastSelf(SPELL_HARPOON_FIRE_STATE); + if (Creature* commander = _instance->GetCreature(DATA_EXPEDITION_COMMANDER)) + commander->AI()->DoAction(ACTION_DESTROY_HARPOONS); } + } + +private: + InstanceScript* _instance; }; -class npc_darkrune_guardian : public CreatureScript +struct npc_razorscale_devouring_flame : public ScriptedAI { - public: - npc_darkrune_guardian() : CreatureScript("npc_darkrune_guardian") { } + npc_razorscale_devouring_flame(Creature* creature) : ScriptedAI(creature) { } - struct npc_darkrune_guardianAI : public ScriptedAI - { - npc_darkrune_guardianAI(Creature* creature) : ScriptedAI(creature) - { - Initialize(); - } + void Reset() override + { + DoCastSelf(DEVOURING_FLAME_GROUND); + } +}; - void Initialize() - { - StormTimer = urand(3000, 6000); - killedByBreath = false; - } +class go_razorscale_harpoon : public GameObjectScript +{ +public: + go_razorscale_harpoon() : GameObjectScript("go_razorscale_harpoon") { } - uint32 StormTimer; + struct go_razorscale_harpoonAI : public GameObjectAI + { + go_razorscale_harpoonAI(GameObject* go) : GameObjectAI(go) { } - void Reset() override + void Reset() override + { + _scheduler.Schedule(Seconds(1), [this](TaskContext /*context*/) { - Initialize(); - } + if (Creature* controller = me->FindNearestCreature(NPC_RAZORSCALE_CONTROLLER, 5.0f)) + controller->AI()->Talk(EMOTE_HARPOON); - uint32 GetData(uint32 type) const override - { - return type == DATA_IRON_DWARF_MEDIUM_RARE ? killedByBreath : 0; - } + if (GameObject* brokenHarpoon = me->FindNearestGameObject(GO_RAZOR_BROKEN_HARPOON, 5.0f)) + brokenHarpoon->RemoveFromWorld(); + }); + } - void SetData(uint32 type, uint32 value) override + uint32 SelectRightSpell() + { + switch (me->GetEntry()) { - if (type == DATA_IRON_DWARF_MEDIUM_RARE) - killedByBreath = value != 0; + case GO_RAZOR_HARPOON_1: + return SPELL_HARPOON_SHOT_1; + case GO_RAZOR_HARPOON_2: + return SPELL_HARPOON_SHOT_2; + case GO_RAZOR_HARPOON_3: + return SPELL_HARPOON_SHOT_3; + case GO_RAZOR_HARPOON_4: + return SPELL_HARPOON_SHOT_4; + default: + return 0; } + } - - void UpdateAI(uint32 Diff) override + bool GossipHello(Player* /*player*/) override + { + me->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + if (Creature* controller = me->FindNearestCreature(NPC_RAZORSCALE_CONTROLLER, 5.0f)) { - if (!UpdateVictim()) - return; + // Prevent 2 players clicking at "same time" + if (controller->HasUnitState(UNIT_STATE_CASTING)) + return true; - if (StormTimer <= Diff) - { - DoCastVictim(SPELL_STORMSTRIKE); - StormTimer = urand(4000, 8000); - } - else - StormTimer -= Diff; - - DoMeleeAttackIfReady(); + uint32 spellId = SelectRightSpell(); + controller->CastSpell(nullptr, spellId, true); } - private: - bool killedByBreath; - }; + return true; + } - CreatureAI* GetAI(Creature* creature) const override + void UpdateAI(uint32 diff) override { - return GetUlduarAI<npc_darkrune_guardianAI>(creature); + _scheduler.Update(diff); } + + private: + TaskScheduler _scheduler; + }; + + GameObjectAI* GetAI(GameObject* go) const override + { + return GetUlduarAI<go_razorscale_harpoonAI>(go); + } }; -class npc_darkrune_sentinel : public CreatureScript +class go_razorscale_mole_machine : public GameObjectScript { - public: - npc_darkrune_sentinel() : CreatureScript("npc_darkrune_sentinel") { } +public: + go_razorscale_mole_machine() : GameObjectScript("go_razorscale_mole_machine") { } - struct npc_darkrune_sentinelAI : public ScriptedAI + struct go_razorscale_mole_machineAI : public GameObjectAI + { + go_razorscale_mole_machineAI(GameObject* go) : GameObjectAI(go) { } + + void Reset() override { - npc_darkrune_sentinelAI(Creature* creature) : ScriptedAI(creature) + me->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + _scheduler.Schedule(Seconds(1), [this](TaskContext /*context*/) { - Initialize(); - } - - void Initialize() + me->UseDoorOrButton(); + }); + _scheduler.Schedule(Seconds(10), [this](TaskContext /*context*/) { - HeroicTimer = urand(4000, 8000); - WhirlTimer = urand(20000, 25000); - ShoutTimer = urand(15000, 30000); - } - - uint32 HeroicTimer; - uint32 WhirlTimer; - uint32 ShoutTimer; - - void Reset() override - { - Initialize(); - } + me->Delete(); + }); + } - void UpdateAI(uint32 Diff) override - { - if (!UpdateVictim()) - return; + void UpdateAI(uint32 diff) override + { + _scheduler.Update(diff); + } - if (HeroicTimer <= Diff) - { - DoCastVictim(SPELL_HEROIC_STRIKE); - HeroicTimer = urand(4000, 6000); - } - else - HeroicTimer -= Diff; + private: + TaskScheduler _scheduler; + }; + GameObjectAI* GetAI(GameObject* go) const override + { + return GetUlduarAI<go_razorscale_mole_machineAI>(go); + } +}; - if (WhirlTimer <= Diff) - { - DoCastVictim(SPELL_WHIRLWIND); - WhirlTimer = urand(20000, 25000); - } - else - WhirlTimer -= Diff; +/* 63317 - Flame Breath + 64021 - Flame Breath */ +class spell_razorscale_flame_breath : public SpellScript +{ + PrepareSpellScript(spell_razorscale_flame_breath); - if (ShoutTimer <= Diff) - { - DoCast(me, SPELL_BATTLE_SHOUT); - ShoutTimer = urand(30000, 40000); - } - else - ShoutTimer -= Diff; + void CheckDamage() + { + Creature* target = GetHitCreature(); + if (!target || target->GetEntry() != NPC_DARK_RUNE_GUARDIAN || !target->IsAlive()) + return; - DoMeleeAttackIfReady(); - } - }; + if (GetHitDamage() >= int32(target->GetHealth())) + target->AI()->SetData(DATA_IRON_DWARF_MEDIUM_RARE, 1); + } - CreatureAI* GetAI(Creature* creature) const override + void FilterTargets(std::list<WorldObject*>& targets) + { + targets.remove_if([](WorldObject* obj) { - return GetUlduarAI<npc_darkrune_sentinelAI>(creature); - } + if (Creature* target = obj->ToCreature()) + if (target->IsTrigger()) + return true; + + return false; + }); + } + + void Register() override + { + OnHit += SpellHitFn(spell_razorscale_flame_breath::CheckDamage); + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_razorscale_flame_breath::FilterTargets, EFFECT_1, TARGET_UNIT_CONE_ENTRY); + } }; -class spell_razorscale_devouring_flame : public SpellScriptLoader +/* 63968 - Summon Iron Dwarves + 63970 - Summon Iron Dwarves + 63969 - Summon Iron Dwarves */ +class spell_razorscale_summon_iron_dwarves : public SpellScript { - public: - spell_razorscale_devouring_flame() : SpellScriptLoader("spell_razorscale_devouring_flame") { } + PrepareSpellScript(spell_razorscale_summon_iron_dwarves); - class spell_razorscale_devouring_flame_SpellScript : public SpellScript + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( { - PrepareSpellScript(spell_razorscale_devouring_flame_SpellScript); - - void HandleSummon(SpellEffIndex effIndex) - { - PreventHitDefaultEffect(effIndex); - Unit* caster = GetCaster(); - uint32 entry = uint32(GetSpellInfo()->Effects[effIndex].MiscValue); - WorldLocation const* summonLocation = GetExplTargetDest(); - if (!caster || !summonLocation) - return; - - caster->SummonCreature(entry, summonLocation->GetPositionX(), summonLocation->GetPositionY(), GROUND_Z, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 20000); - } - - void Register() override - { - OnEffectHit += SpellEffectFn(spell_razorscale_devouring_flame_SpellScript::HandleSummon, EFFECT_0, SPELL_EFFECT_SUMMON); - } - }; - - SpellScript* GetSpellScript() const override + SPELL_SUMMON_IRON_DWARF_GUARDIAN, + SPELL_SUMMON_IRON_DWARF_WATCHER + }); + } + + void HandleScriptEffect(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + switch (GetSpellInfo()->Id) { - return new spell_razorscale_devouring_flame_SpellScript(); + case SPELL_TRIGGER_SUMMON_IRON_DWARVES: + caster->CastSpell(caster, SPELL_SUMMON_IRON_DWARF_GUARDIAN, true); + caster->CastSpell(caster, SPELL_SUMMON_IRON_DWARF_GUARDIAN, true); + caster->CastSpell(caster, SPELL_SUMMON_IRON_DWARF_WATCHER, true); + break; + case SPELL_TRIGGER_SUMMON_IRON_DWARVES_2: + case SPELL_TRIGGER_SUMMON_IRON_DWARVES_3: + caster->CastSpell(caster, SPELL_SUMMON_IRON_DWARF_GUARDIAN, true); + caster->CastSpell(caster, SPELL_SUMMON_IRON_DWARF_WATCHER, true); + caster->CastSpell(caster, SPELL_SUMMON_IRON_DWARF_WATCHER, true); + break; + default: + break; } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_razorscale_summon_iron_dwarves::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } }; -class spell_razorscale_flame_breath : public SpellScriptLoader +// 64771 - Fuse Armor +class spell_razorscale_fuse_armor : public AuraScript { - public: - spell_razorscale_flame_breath() : SpellScriptLoader("spell_razorscale_flame_breath") { } - - class spell_razorscale_flame_breath_SpellScript : public SpellScript - { - PrepareSpellScript(spell_razorscale_flame_breath_SpellScript); - - void CheckDamage() - { - Creature* target = GetHitCreature(); - if (!target || target->GetEntry() != NPC_DARK_RUNE_GUARDIAN) - return; + PrepareAuraScript(spell_razorscale_fuse_armor); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_FUSED_ARMOR }); + } + + void HandleFused(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (GetStackAmount() == 5) + GetTarget()->CastSpell(GetTarget(), SPELL_FUSED_ARMOR, true); + } + + void Register() override + { + AfterEffectApply += AuraEffectRemoveFn(spell_razorscale_fuse_armor::HandleFused, EFFECT_1, SPELL_AURA_MOD_MELEE_HASTE, AURA_EFFECT_HANDLE_REAL); + } +}; - if (GetHitDamage() >= int32(target->GetHealth())) - target->AI()->SetData(DATA_IRON_DWARF_MEDIUM_RARE, 1); - } +// 62669 - Firebolt +class spell_razorscale_firebolt : public SpellScript +{ + PrepareSpellScript(spell_razorscale_firebolt); - void Register() override - { - OnHit += SpellHitFn(spell_razorscale_flame_breath_SpellScript::CheckDamage); - } - }; + void FilterTargets(std::list<WorldObject*>& targets) + { + targets.remove_if([](WorldObject* obj) { return obj->GetEntry() != NPC_RAZORSCALE_HARPOON_FIRE_STATE; }); + } - SpellScript* GetSpellScript() const override - { - return new spell_razorscale_flame_breath_SpellScript(); - } + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_razorscale_firebolt::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); + } }; class achievement_iron_dwarf_medium_rare : public AchievementCriteriaScript { public: - achievement_iron_dwarf_medium_rare() : AchievementCriteriaScript("achievement_iron_dwarf_medium_rare") - { - } + achievement_iron_dwarf_medium_rare() : AchievementCriteriaScript("achievement_iron_dwarf_medium_rare") { } bool OnCheck(Player* /*player*/, Unit* target) override { @@ -1183,17 +1723,23 @@ class achievement_quick_shave : public AchievementCriteriaScript void AddSC_boss_razorscale() { - new boss_razorscale_controller(); + RegisterUlduarCreatureAI(boss_razorscale); + RegisterUlduarCreatureAI(npc_expedition_defender); + RegisterUlduarCreatureAI(npc_expedition_trapper); + RegisterUlduarCreatureAI(npc_expedition_engineer); + RegisterUlduarCreatureAI(npc_expedition_commander); + RegisterUlduarCreatureAI(npc_razorscale_spawner); + RegisterUlduarCreatureAI(npc_darkrune_watcher); + RegisterUlduarCreatureAI(npc_darkrune_guardian); + RegisterUlduarCreatureAI(npc_darkrune_sentinel); + RegisterUlduarCreatureAI(npc_razorscale_harpoon_fire_state); + RegisterUlduarCreatureAI(npc_razorscale_devouring_flame); new go_razorscale_harpoon(); - new boss_razorscale(); - new npc_expedition_commander(); - new npc_mole_machine_trigger(); - new npc_devouring_flame(); - new npc_darkrune_watcher(); - new npc_darkrune_guardian(); - new npc_darkrune_sentinel(); - new spell_razorscale_devouring_flame(); - new spell_razorscale_flame_breath(); + new go_razorscale_mole_machine(); + RegisterSpellScript(spell_razorscale_flame_breath); + RegisterSpellScript(spell_razorscale_summon_iron_dwarves); + RegisterAuraScript(spell_razorscale_fuse_armor); + RegisterSpellScript(spell_razorscale_firebolt); new achievement_iron_dwarf_medium_rare(); new achievement_quick_shave(); } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp index 9c6cffcba13..8b618c8b271 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp @@ -375,7 +375,7 @@ class RunicSmashExplosionEvent : public BasicEvent bool Execute(uint64 /*eventTime*/, uint32 /*updateTime*/) override { - _owner->CastSpell((Unit*)nullptr, SPELL_RUNIC_SMASH); + _owner->CastSpell(nullptr, SPELL_RUNIC_SMASH); return true; } @@ -393,7 +393,7 @@ class TrashJumpEvent : public BasicEvent switch (_stage) { case 0: - _owner->CastSpell((Unit*)nullptr, SPELL_LEAP); + _owner->CastSpell(nullptr, SPELL_LEAP); ++_stage; _owner->m_Events.AddEvent(this, eventTime + 2000); return false; @@ -425,7 +425,7 @@ class LightningFieldEvent : public BasicEvent { if (instance->GetBossState(BOSS_THORIM) == IN_PROGRESS) { - _owner->CastSpell((Unit*)nullptr, SPELL_LIGHTNING_FIELD); + _owner->CastSpell(nullptr, SPELL_LIGHTNING_FIELD); _owner->m_Events.AddEvent(this, eventTime + 1000); return false; } @@ -515,7 +515,7 @@ class boss_thorim : public CreatureScript if (Creature* pillar = ObjectAccessor::GetCreature(*me, _activePillarGUID)) { pillar->CastSpell(pillar, SPELL_LIGHTNING_ORB_CHARGED, true); - pillar->CastSpell((Unit*)nullptr, SPELL_LIGHTNING_PILLAR_2); + pillar->CastSpell(nullptr, SPELL_LIGHTNING_PILLAR_2); events.ScheduleEvent(EVENT_LIGHTNING_CHARGE, 8000, 0, PHASE_2); } } @@ -1778,7 +1778,7 @@ class spell_thorim_charge_orb : public SpellScriptLoader void HandleScript() { if (Unit* target = GetHitUnit()) - target->CastSpell((Unit*)nullptr, SPELL_LIGHTNING_PILLAR_1, true); + target->CastSpell(nullptr, SPELL_LIGHTNING_PILLAR_1, true); } void Register() override diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp index c3817b0525b..2dbc0d0dfbb 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp @@ -558,7 +558,7 @@ class boss_voice_of_yogg_saron : public CreatureScript if (Creature* yogg = instance->GetCreature(BOSS_YOGG_SARON)) { yogg->AI()->Talk(EMOTE_YOGG_SARON_EXTINGUISH_ALL_LIFE, me); - yogg->CastSpell((Unit*)nullptr, SPELL_EXTINGUISH_ALL_LIFE, true); + yogg->CastSpell(nullptr, SPELL_EXTINGUISH_ALL_LIFE, true); } events.ScheduleEvent(EVENT_EXTINGUISH_ALL_LIFE, 10000); // cast it again after a short while, players can survive break; @@ -2340,7 +2340,7 @@ class spell_yogg_saron_empowering_shadows_missile : public SpellScriptLoader void HandleScript(SpellEffIndex /*effIndex*/) { if (Unit* target = GetHitUnit()) - target->CastSpell((Unit*)nullptr, SPELL_EMPOWERING_SHADOWS, true); + target->CastSpell(nullptr, SPELL_EMPOWERING_SHADOWS, true); } void Register() override @@ -2600,7 +2600,7 @@ class spell_yogg_saron_death_ray_warning_visual : public SpellScriptLoader / if (Unit* caster = GetCaster()) { caster->CastSpell(caster, SPELL_DEATH_RAY_PERIODIC, true); - caster->CastSpell((Unit*)nullptr, SPELL_DEATH_RAY_DAMAGE_VISUAL, true); + caster->CastSpell(nullptr, SPELL_DEATH_RAY_DAMAGE_VISUAL, true); // TODO: set better movement caster->GetMotionMaster()->MoveConfused(); } @@ -2778,7 +2778,7 @@ class spell_yogg_saron_induce_madness : public SpellScriptLoader // 64059 void ClearShatteredIllusion() { - GetCaster()->CastSpell((Unit*)nullptr, SPELL_SHATTERED_ILLUSION_REMOVE); + GetCaster()->CastSpell(nullptr, SPELL_SHATTERED_ILLUSION_REMOVE); if (InstanceScript* instance = GetCaster()->GetInstanceScript()) if (Creature* voice = instance->GetCreature(DATA_VOICE_OF_YOGG_SARON)) diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp index bd1d2b9c3b6..9c202f2066b 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp @@ -496,10 +496,6 @@ class instance_ulduar : public InstanceMapScript if (GetBossState(BOSS_LEVIATHAN) == DONE) gameObject->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE); break; - case GO_MOLE_MACHINE: - if (GetBossState(BOSS_RAZORSCALE) == IN_PROGRESS) - gameObject->SetGoState(GO_STATE_ACTIVE); - break; case GO_BRAIN_ROOM_DOOR_1: BrainRoomDoorGUIDs[0] = gameObject->GetGUID(); break; diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h index 4548eac4b97..1a0d57ab691 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h @@ -59,9 +59,7 @@ enum UlduarNPCs NPC_SALVAGED_CHOPPER = 33062, NPC_IGNIS = 33118, NPC_RAZORSCALE = 33186, - NPC_RAZORSCALE_CONTROLLER = 33233, NPC_STEELFORGED_DEFFENDER = 33236, - NPC_EXPEDITION_COMMANDER = 33210, NPC_XT002 = 33293, NPC_XT_TOY_PILE = 33337, NPC_STEELBREAKER = 32867, @@ -82,6 +80,18 @@ enum UlduarNPCs NPC_YOGG_SARON = 33288, NPC_ALGALON = 32871, + // Razorscale + NPC_DARK_RUNE_GUARDIAN = 33388, + NPC_DARK_RUNE_SENTINEL = 33846, + NPC_DARK_RUNE_WATCHER = 33453, + NPC_RAZORSCALE_SPAWNER = 33245, + NPC_EXPEDITION_COMMANDER = 33210, + NPC_EXPEDITION_ENGINEER = 33287, + NPC_EXPEDITION_DEFENDER = 33816, + NPC_EXPEDITION_TRAPPER = 33259, + NPC_RAZORSCALE_CONTROLLER = 33233, + NPC_RAZORSCALE_HARPOON_FIRE_STATE = 33282, + //XT002 NPC_XS013_SCRAPBOT = 33343, @@ -498,6 +508,8 @@ inline AI* GetUlduarAI(T* obj) return GetInstanceAI<AI, T>(obj, UlduarScriptName); } +#define RegisterUlduarCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetUlduarAI) + class KeeperDespawnEvent : public BasicEvent { public: diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp index 968210df209..3ead66593a6 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp @@ -342,7 +342,7 @@ public: void Reset() override { me->SetReactState(REACT_PASSIVE); - me->setRegeneratingHealth(false); + me->SetRegenerateHealth(false); me->SetSpeedRate(MOVE_RUN, 2.5f); } @@ -855,7 +855,7 @@ class spell_summon_gauntlet_mobs_periodic : public SpellScriptLoader for (uint8 i = 0; i < 2; ++i) { uint32 spellId = SummonSpellsList.front(); - GetTarget()->CastSpell((Unit*)nullptr, spellId, true); + GetTarget()->CastSpell(nullptr, spellId, true); SummonSpellsList.push_back(spellId); SummonSpellsList.pop_front(); } diff --git a/src/server/scripts/Northrend/VaultOfArchavon/boss_archavon.cpp b/src/server/scripts/Northrend/VaultOfArchavon/boss_archavon.cpp index 03ee2289818..ded80918b1c 100644 --- a/src/server/scripts/Northrend/VaultOfArchavon/boss_archavon.cpp +++ b/src/server/scripts/Northrend/VaultOfArchavon/boss_archavon.cpp @@ -243,12 +243,12 @@ class spell_archavon_rock_shards : public SpellScriptLoader for (uint8 i = 0; i < 3; ++i) { - caster->CastSpell((Unit*)nullptr, SPELL_ROCK_SHARDS_VISUAL_L, true); - caster->CastSpell((Unit*)nullptr, SPELL_ROCK_SHARDS_VISUAL_R, true); + caster->CastSpell(nullptr, SPELL_ROCK_SHARDS_VISUAL_L, true); + caster->CastSpell(nullptr, SPELL_ROCK_SHARDS_VISUAL_R, true); } - caster->CastSpell((Unit*)nullptr, SPELL_ROCK_SHARDS_DAMAGE_L, true); - caster->CastSpell((Unit*)nullptr, SPELL_ROCK_SHARDS_DAMAGE_R, true); + caster->CastSpell(nullptr, SPELL_ROCK_SHARDS_DAMAGE_L, true); + caster->CastSpell(nullptr, SPELL_ROCK_SHARDS_DAMAGE_R, true); } void Register() override diff --git a/src/server/scripts/Northrend/VaultOfArchavon/boss_toravon.cpp b/src/server/scripts/Northrend/VaultOfArchavon/boss_toravon.cpp index 0f785817e9b..d093bb65fa8 100644 --- a/src/server/scripts/Northrend/VaultOfArchavon/boss_toravon.cpp +++ b/src/server/scripts/Northrend/VaultOfArchavon/boss_toravon.cpp @@ -17,28 +17,26 @@ #include "ScriptMgr.h" #include "InstanceScript.h" -#include "ObjectAccessor.h" #include "ScriptedCreature.h" +#include "SpellScript.h" #include "vault_of_archavon.h" enum Spells { // Toravon - SPELL_FREEZING_GROUND = 72090, // don't know cd... using 20 secs. + SPELL_FREEZING_GROUND = 72090, SPELL_FROZEN_ORB = 72091, - SPELL_WHITEOUT = 72034, // Every 38 sec. cast. (after SPELL_FROZEN_ORB) + SPELL_WHITEOUT = 72034, SPELL_FROZEN_MALLET = 71993, - // Frost Warder - SPELL_FROST_BLAST = 72123, // don't know cd... using 20 secs. - SPELL_FROZEN_MALLET_2 = 72122, - // Frozen Orb - SPELL_FROZEN_ORB_DMG = 72081, // priodic dmg aura - SPELL_FROZEN_ORB_AURA = 72067, // make visible + SPELL_FROZEN_ORB_DMG = 72081, + SPELL_FROZEN_ORB_AURA = 72067, + SPELL_RANDOM_AGGRO = 72084, - // Frozen Orb Stalker - SPELL_FROZEN_ORB_SUMMON = 72093, // summon orb + // Frost Warder + SPELL_FROST_BLAST = 72123, // don't know cd... using 20 secs. + SPELL_FROZEN_MALLET_2 = 72122 }; enum Events @@ -47,256 +45,159 @@ enum Events EVENT_FROZEN_ORB = 2, EVENT_WHITEOUT = 3, - EVENT_FROST_BLAST = 4, + EVENT_FROST_BLAST = 4 }; -enum Creatures +struct boss_toravon : public BossAI { - NPC_FROZEN_ORB = 38456 // 1 in 10 mode and 3 in 25 mode + boss_toravon(Creature* creature) : BossAI(creature, DATA_TORAVON) { } -}; + void EnterCombat(Unit* /*who*/) override + { + DoCastSelf(SPELL_FROZEN_MALLET); -class boss_toravon : public CreatureScript -{ - public: - boss_toravon() : CreatureScript("boss_toravon") { } + events.ScheduleEvent(EVENT_FROZEN_ORB, Seconds(12)); + events.ScheduleEvent(EVENT_WHITEOUT, Seconds(25)); + events.ScheduleEvent(EVENT_FREEZING_GROUND, Seconds(7)); - struct boss_toravonAI : public BossAI - { - boss_toravonAI(Creature* creature) : BossAI(creature, DATA_TORAVON) - { - } + _EnterCombat(); + } - void EnterCombat(Unit* /*who*/) override - { - DoCast(me, SPELL_FROZEN_MALLET); + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - events.ScheduleEvent(EVENT_FROZEN_ORB, 11000); - events.ScheduleEvent(EVENT_WHITEOUT, 13000); - events.ScheduleEvent(EVENT_FREEZING_GROUND, 15000); + events.Update(diff); - _EnterCombat(); - } + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - void UpdateAI(uint32 diff) override + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) { - if (!UpdateVictim()) - return; - - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_FROZEN_ORB: - me->CastCustomSpell(SPELL_FROZEN_ORB, SPELLVALUE_MAX_TARGETS, 1, me); - events.ScheduleEvent(EVENT_FROZEN_ORB, 38000); - break; - case EVENT_WHITEOUT: - DoCast(me, SPELL_WHITEOUT); - events.ScheduleEvent(EVENT_WHITEOUT, 38000); - break; - case EVENT_FREEZING_GROUND: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1)) - DoCast(target, SPELL_FREEZING_GROUND); - events.ScheduleEvent(EVENT_FREEZING_GROUND, 20000); - break; - default: - break; - } - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - } - - DoMeleeAttackIfReady(); + case EVENT_FROZEN_ORB: + me->CastCustomSpell(SPELL_FROZEN_ORB, SPELLVALUE_MAX_TARGETS, RAID_MODE(1, 3), me); + events.Repeat(Seconds(32)); + break; + case EVENT_WHITEOUT: + DoCastSelf(SPELL_WHITEOUT); + events.Repeat(Seconds(38)); + break; + case EVENT_FREEZING_GROUND: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1)) + DoCast(target, SPELL_FREEZING_GROUND); + events.Repeat(Seconds(38)); + break; + default: + break; } - }; - CreatureAI* GetAI(Creature* creature) const override - { - return GetVaultOfArchavonAI<boss_toravonAI>(creature); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; } + + DoMeleeAttackIfReady(); + } }; -/*###### -## Mob Frost Warder -######*/ -class npc_frost_warder : public CreatureScript +struct npc_frost_warder : public ScriptedAI { - public: - npc_frost_warder() : CreatureScript("npc_frost_warder") { } - - struct npc_frost_warderAI : public ScriptedAI - { - npc_frost_warderAI(Creature* creature) : ScriptedAI(creature) { } - - void Reset() override - { - events.Reset(); - } - - void EnterCombat(Unit* /*who*/) override - { - DoZoneInCombat(); - - DoCast(me, SPELL_FROZEN_MALLET_2); + npc_frost_warder(Creature* creature) : ScriptedAI(creature) { } - events.ScheduleEvent(EVENT_FROST_BLAST, 5000); - } + void Reset() override + { + _events.Reset(); + } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; + void EnterCombat(Unit* /*who*/) override + { + DoZoneInCombat(); - events.Update(diff); + DoCastSelf(SPELL_FROZEN_MALLET_2); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + _events.ScheduleEvent(EVENT_FROST_BLAST, 5000); + } - if (events.ExecuteEvent() == EVENT_FROST_BLAST) - { - DoCastVictim(SPELL_FROST_BLAST); - events.ScheduleEvent(EVENT_FROST_BLAST, 20000); - } + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - DoMeleeAttackIfReady(); - } + _events.Update(diff); - private: - EventMap events; - }; + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - CreatureAI* GetAI(Creature* creature) const override + if (_events.ExecuteEvent() == EVENT_FROST_BLAST) { - return GetVaultOfArchavonAI<npc_frost_warderAI>(creature); + DoCastVictim(SPELL_FROST_BLAST); + _events.ScheduleEvent(EVENT_FROST_BLAST, 20000); } + + DoMeleeAttackIfReady(); + } + +private: + EventMap _events; }; -/*###### -## Mob Frozen Orb -######*/ -class npc_frozen_orb : public CreatureScript +struct npc_frozen_orb : public ScriptedAI { -public: - npc_frozen_orb() : CreatureScript("npc_frozen_orb") { } + npc_frozen_orb(Creature* creature) : ScriptedAI(creature) { } - struct npc_frozen_orbAI : public ScriptedAI + void IsSummonedBy(Unit* /*summoner*/) override { - npc_frozen_orbAI(Creature* creature) : ScriptedAI(creature) - { - Initialize(); - } + DoCastSelf(SPELL_FROZEN_ORB_AURA, true); + DoCastSelf(SPELL_FROZEN_ORB_DMG, true); + DoCastSelf(SPELL_RANDOM_AGGRO, true); - void Initialize() + if (Creature* toravon = me->GetInstanceScript()->GetCreature(DATA_TORAVON)) { - done = false; - killTimer = 60000; // if after this time there is no victim -> destroy! - } - - void Reset() override - { - Initialize(); - } - - void EnterCombat(Unit* /*who*/) override - { - DoZoneInCombat(); - } - - void UpdateAI(uint32 diff) override - { - if (!done) - { - DoCast(me, SPELL_FROZEN_ORB_AURA, true); - DoCast(me, SPELL_FROZEN_ORB_DMG, true); - done = true; - } - - if (killTimer <= diff) + if (toravon->IsInCombat()) { - if (!UpdateVictim()) - me->DespawnOrUnsummon(); - killTimer = 10000; + toravon->AI()->JustSummoned(me); + me->SetInCombatWithZone(); } else - killTimer -= diff; + me->DespawnOrUnsummon(); } - - private: - uint32 killTimer; - bool done; - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetVaultOfArchavonAI<npc_frozen_orbAI>(creature); } }; -/*###### -## Mob Frozen Orb Stalker -######*/ -class npc_frozen_orb_stalker : public CreatureScript +// 46523 - Random Aggro +class spell_toravon_random_aggro : public SpellScript { - public: - npc_frozen_orb_stalker() : CreatureScript("npc_frozen_orb_stalker") { } + PrepareSpellScript(spell_toravon_random_aggro); - struct npc_frozen_orb_stalkerAI : public ScriptedAI - { - npc_frozen_orb_stalkerAI(Creature* creature) : ScriptedAI(creature) - { - creature->SetVisible(false); - creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE); - me->SetControlled(true, UNIT_STATE_ROOT); - creature->SetReactState(REACT_PASSIVE); - - instance = creature->GetInstanceScript(); - spawned = false; + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_UNIT; + } - SetCombatMovement(false); - } + void HandleScript(SpellEffIndex /*effIndex*/) + { + Creature* caster = GetCaster()->ToCreature(); + if (!caster->IsAIEnabled) + return; - void UpdateAI(uint32 /*diff*/) override - { - if (spawned) - return; - - spawned = true; - Unit* toravon = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_TORAVON)); - if (!toravon) - return; - - uint8 num_orbs = RAID_MODE(1, 3); - for (uint8 i = 0; i < num_orbs; ++i) - { - Position pos; - me->GetNearPoint(toravon, pos.m_positionX, pos.m_positionY, pos.m_positionZ, 0.0f, 10.0f, 0.0f); - me->UpdatePosition(pos); - DoCast(me, SPELL_FROZEN_ORB_SUMMON); - } - } + caster->GetThreatManager().resetAllAggro(); - private: - InstanceScript* instance; - bool spawned; - }; + if (Unit* target = caster->AI()->SelectTarget(SELECT_TARGET_RANDOM, 1)) + caster->GetThreatManager().AddThreat(target, 1000000); + } - CreatureAI* GetAI(Creature* creature) const override - { - return GetVaultOfArchavonAI<npc_frozen_orb_stalkerAI>(creature); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_toravon_random_aggro::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; void AddSC_boss_toravon() { - new boss_toravon(); - new npc_frost_warder(); - new npc_frozen_orb(); - new npc_frozen_orb_stalker(); + RegisterVaultOfArchavonCreatureAI(boss_toravon); + RegisterVaultOfArchavonCreatureAI(npc_frost_warder); + RegisterVaultOfArchavonCreatureAI(npc_frozen_orb); + RegisterSpellScript(spell_toravon_random_aggro); } diff --git a/src/server/scripts/Northrend/VaultOfArchavon/instance_vault_of_archavon.cpp b/src/server/scripts/Northrend/VaultOfArchavon/instance_vault_of_archavon.cpp index f399449932f..df562d81546 100644 --- a/src/server/scripts/Northrend/VaultOfArchavon/instance_vault_of_archavon.cpp +++ b/src/server/scripts/Northrend/VaultOfArchavon/instance_vault_of_archavon.cpp @@ -16,7 +16,6 @@ */ #include "ScriptMgr.h" -#include "Creature.h" #include "InstanceScript.h" #include "Map.h" #include "vault_of_archavon.h" @@ -28,6 +27,15 @@ 4 - Toravon the Ice Watcher event */ +ObjectData const creatureData[] = +{ + { NPC_ARCHAVON, DATA_ARCHAVON }, + { NPC_EMALON, DATA_EMALON }, + { NPC_KORALON, DATA_KORALON }, + { NPC_TORAVON, DATA_TORAVON }, + { 0, 0, } +}; + class instance_vault_of_archavon : public InstanceMapScript { public: @@ -39,42 +47,13 @@ class instance_vault_of_archavon : public InstanceMapScript { SetHeaders(DataHeader); SetBossNumber(EncounterCount); + LoadObjectData(creatureData, nullptr); ArchavonDeath = 0; EmalonDeath = 0; KoralonDeath = 0; } - void OnCreatureCreate(Creature* creature) override - { - switch (creature->GetEntry()) - { - case NPC_EMALON: - EmalonGUID = creature->GetGUID(); - break; - case NPC_TORAVON: - ToravonGUID = creature->GetGUID(); - break; - default: - break; - } - } - - ObjectGuid GetGuidData(uint32 identifier) const override - { - switch (identifier) - { - case DATA_EMALON: - return EmalonGUID; - case DATA_TORAVON: - return ToravonGUID; - default: - break; - } - - return ObjectGuid::Empty; - } - bool SetBossState(uint32 type, EncounterState state) override { if (!InstanceScript::SetBossState(type, state)) @@ -127,8 +106,6 @@ class instance_vault_of_archavon : public InstanceMapScript } private: - ObjectGuid EmalonGUID; - ObjectGuid ToravonGUID; time_t ArchavonDeath; time_t EmalonDeath; time_t KoralonDeath; diff --git a/src/server/scripts/Northrend/VaultOfArchavon/vault_of_archavon.h b/src/server/scripts/Northrend/VaultOfArchavon/vault_of_archavon.h index d4f252d3715..491ef5dd82d 100644 --- a/src/server/scripts/Northrend/VaultOfArchavon/vault_of_archavon.h +++ b/src/server/scripts/Northrend/VaultOfArchavon/vault_of_archavon.h @@ -30,7 +30,7 @@ enum VAData DATA_ARCHAVON = 0, DATA_EMALON = 1, DATA_KORALON = 2, - DATA_TORAVON = 3, + DATA_TORAVON = 3 }; enum VACreatureIds @@ -44,12 +44,12 @@ enum VACreatureIds enum VAAchievementCriteriaIds { CRITERIA_EARTH_WIND_FIRE_10 = 12018, - CRITERIA_EARTH_WIND_FIRE_25 = 12019, + CRITERIA_EARTH_WIND_FIRE_25 = 12019 }; enum VAAchievementSpells { - SPELL_EARTH_WIND_FIRE_ACHIEVEMENT_CHECK = 68308, + SPELL_EARTH_WIND_FIRE_ACHIEVEMENT_CHECK = 68308 }; template <class AI, class T> @@ -58,4 +58,6 @@ inline AI* GetVaultOfArchavonAI(T* obj) return GetInstanceAI<AI>(obj, VoAScriptName); } +#define RegisterVaultOfArchavonCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetVaultOfArchavonAI) + #endif diff --git a/src/server/scripts/Northrend/VioletHold/violet_hold.cpp b/src/server/scripts/Northrend/VioletHold/violet_hold.cpp index e06087a738b..3675973c6e9 100644 --- a/src/server/scripts/Northrend/VioletHold/violet_hold.cpp +++ b/src/server/scripts/Northrend/VioletHold/violet_hold.cpp @@ -820,9 +820,9 @@ class npc_violet_hold_teleportation_portal_intro : public CreatureScript } }; -struct violet_hold_trashAI : public npc_escortAI +struct violet_hold_trashAI : public EscortAI { - violet_hold_trashAI(Creature* creature) : npc_escortAI(creature) + violet_hold_trashAI(Creature* creature) : EscortAI(creature) { _instance = creature->GetInstanceScript(); @@ -898,7 +898,7 @@ struct violet_hold_trashAI : public npc_escortAI } } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { if (waypointId == _lastWaypointId) CreatureStartAttackDoor(); @@ -906,7 +906,7 @@ struct violet_hold_trashAI : public npc_escortAI void EnterCombat(Unit* who) override { - npc_escortAI::EnterCombat(who); + EscortAI::EnterCombat(who); ScheduledTasks(); } @@ -919,7 +919,7 @@ struct violet_hold_trashAI : public npc_escortAI return; _scheduler.Update(diff, - std::bind(&npc_escortAI::DoMeleeAttackIfReady, this)); + std::bind(&EscortAI::DoMeleeAttackIfReady, this)); } virtual void ScheduledTasks() { } diff --git a/src/server/scripts/Northrend/zone_borean_tundra.cpp b/src/server/scripts/Northrend/zone_borean_tundra.cpp index fccc0a8f437..4b32348ab54 100644 --- a/src/server/scripts/Northrend/zone_borean_tundra.cpp +++ b/src/server/scripts/Northrend/zone_borean_tundra.cpp @@ -571,9 +571,9 @@ class npc_lurgglbr : public CreatureScript public: npc_lurgglbr() : CreatureScript("npc_lurgglbr") { } - struct npc_lurgglbrAI : public npc_escortAI + struct npc_lurgglbrAI : public EscortAI { - npc_lurgglbrAI(Creature* creature) : npc_escortAI(creature) + npc_lurgglbrAI(Creature* creature) : EscortAI(creature) { Initialize(); } @@ -593,7 +593,7 @@ public: Initialize(); } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { switch (waypointId) { @@ -602,6 +602,7 @@ public: IntroTimer = 2000; break; case 41: + SetEscortPaused(true); IntroPhase = 4; IntroTimer = 2000; break; @@ -628,7 +629,7 @@ public: IntroTimer = 7500; break; case 3: - me->SetReactState(REACT_AGGRESSIVE); + me->SetReactState(REACT_DEFENSIVE); IntroPhase = 0; IntroTimer = 0; break; @@ -643,14 +644,12 @@ public: IntroPhase = 6; IntroTimer = 2500; break; - case 6: if (Player* player = GetPlayerForEscort()) player->AreaExploredOrEventHappens(QUEST_ESCAPE_WINTERFIN_CAVERNS); IntroPhase = 7; IntroTimer = 2500; break; - case 7: me->DespawnOrUnsummon(); IntroPhase = 0; @@ -659,7 +658,7 @@ public: } } else IntroTimer -= diff; } - npc_escortAI::UpdateAI(diff); + EscortAI::UpdateAI(diff); if (!UpdateVictim()) return; @@ -672,8 +671,7 @@ public: if (GameObject* go = me->FindNearestGameObject(GO_CAGE, 5.0f)) { go->SetRespawnTime(0); - go->SetGoType(GAMEOBJECT_TYPE_BUTTON); - go->UseDoorOrButton(20); + go->UseDoorOrButton(20000); } Start(true, false, player->GetGUID()); @@ -794,9 +792,9 @@ class npc_thassarian : public CreatureScript public: npc_thassarian() : CreatureScript("npc_thassarian") { } - struct npc_thassarianAI : public npc_escortAI + struct npc_thassarianAI : public EscortAI { - npc_thassarianAI(Creature* creature) : npc_escortAI(creature) + npc_thassarianAI(Creature* creature) : EscortAI(creature) { Initialize(); } @@ -838,7 +836,7 @@ public: Initialize(); } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { Player* player = GetPlayerForEscort(); if (!player) @@ -873,7 +871,7 @@ public: void UpdateAI(uint32 diff) override { - npc_escortAI::UpdateAI(diff); + EscortAI::UpdateAI(diff); if (arthasInPosition && talbotInPosition) { @@ -1638,9 +1636,9 @@ class npc_mootoo_the_younger : public CreatureScript public: npc_mootoo_the_younger() : CreatureScript("npc_mootoo_the_younger") { } - struct npc_mootoo_the_youngerAI : public npc_escortAI + struct npc_mootoo_the_youngerAI : public EscortAI { - npc_mootoo_the_youngerAI(Creature* creature) : npc_escortAI(creature) { } + npc_mootoo_the_youngerAI(Creature* creature) : EscortAI(creature) { } void Reset() override { @@ -1653,7 +1651,7 @@ public: player->FailQuest(QUEST_ESCAPING_THE_MIST); } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { Player* player = GetPlayerForEscort(); if (!player) @@ -1727,9 +1725,9 @@ class npc_bonker_togglevolt : public CreatureScript public: npc_bonker_togglevolt() : CreatureScript("npc_bonker_togglevolt") { } - struct npc_bonker_togglevoltAI : public npc_escortAI + struct npc_bonker_togglevoltAI : public EscortAI { - npc_bonker_togglevoltAI(Creature* creature) : npc_escortAI(creature) + npc_bonker_togglevoltAI(Creature* creature) : EscortAI(creature) { Initialize(); } @@ -1767,7 +1765,7 @@ public: else Bonker_agro=0; } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { Player* player = GetPlayerForEscort(); if (!player) @@ -2384,6 +2382,108 @@ public: } }; +enum BloodsporeRuination +{ + NPC_BLOODMAGE_LAURITH = 25381, + SAY_BLOODMAGE_LAURITH = 0, + EVENT_TALK = 1, + EVENT_RESET_ORIENTATION +}; + +class spell_q11719_bloodspore_ruination_45997 : public SpellScriptLoader +{ +public: + spell_q11719_bloodspore_ruination_45997() : SpellScriptLoader("spell_q11719_bloodspore_ruination_45997") { } + + class spell_q11719_bloodspore_ruination_45997_SpellScript : public SpellScript + { + PrepareSpellScript(spell_q11719_bloodspore_ruination_45997_SpellScript); + + void HandleEffect(SpellEffIndex /*effIndex*/) + { + if (Unit* caster = GetCaster()) + if (Creature* laurith = caster->FindNearestCreature(NPC_BLOODMAGE_LAURITH, 100.0f)) + laurith->AI()->SetGUID(caster->GetGUID()); + } + + void Register() override + { + OnEffectHit += SpellEffectFn(spell_q11719_bloodspore_ruination_45997_SpellScript::HandleEffect, EFFECT_1, SPELL_EFFECT_SEND_EVENT); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_q11719_bloodspore_ruination_45997_SpellScript(); + } +}; + +class npc_bloodmage_laurith : public CreatureScript +{ +public: + npc_bloodmage_laurith() : CreatureScript("npc_bloodmage_laurith") { } + + struct npc_bloodmage_laurithAI : public ScriptedAI + { + npc_bloodmage_laurithAI(Creature* creature) : ScriptedAI(creature) { } + + void Reset() override + { + _events.Reset(); + _playerGUID.Clear(); + } + + void SetGUID(ObjectGuid guid, int32 /*action*/) override + { + if (!_playerGUID.IsEmpty()) + return; + + _playerGUID = guid; + + if (Player* player = ObjectAccessor::GetPlayer(*me, _playerGUID)) + me->SetFacingToObject(player); + + _events.ScheduleEvent(EVENT_TALK, Seconds(1)); + } + + void UpdateAI(uint32 diff) override + { + if (UpdateVictim()) + { + DoMeleeAttackIfReady(); + return; + } + + _events.Update(diff); + + if (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_TALK: + if (Player* player = ObjectAccessor::GetPlayer(*me, _playerGUID)) + Talk(SAY_BLOODMAGE_LAURITH, player); + _playerGUID.Clear(); + _events.ScheduleEvent(EVENT_RESET_ORIENTATION, Seconds(5)); + break; + case EVENT_RESET_ORIENTATION: + me->SetFacingTo(me->GetHomePosition().GetOrientation()); + break; + } + } + } + + private: + EventMap _events; + ObjectGuid _playerGUID; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return new npc_bloodmage_laurithAI(creature); + } +}; + void AddSC_borean_tundra() { new npc_sinkhole_kill_credit(); @@ -2409,4 +2509,6 @@ void AddSC_borean_tundra() new npc_warmage_coldarra(); new npc_hidden_cultist(); new spell_windsoul_totem_aura(); + new spell_q11719_bloodspore_ruination_45997(); + new npc_bloodmage_laurith(); } diff --git a/src/server/scripts/Northrend/zone_dalaran.cpp b/src/server/scripts/Northrend/zone_dalaran.cpp index a8920ff3a07..4702d10ed4b 100644 --- a/src/server/scripts/Northrend/zone_dalaran.cpp +++ b/src/server/scripts/Northrend/zone_dalaran.cpp @@ -135,14 +135,18 @@ enum MinigobData { ZONE_DALARAN = 4395, - SPELL_MANABONKED = 61834, + SPELL_MANABONKED = 61839, SPELL_TELEPORT_VISUAL = 51347, SPELL_IMPROVED_BLINK = 61995, EVENT_SELECT_TARGET = 1, - EVENT_BLINK = 2, - EVENT_DESPAWN_VISUAL = 3, - EVENT_DESPAWN = 4, + EVENT_LAUGH_1 = 2, + EVENT_WANDER = 3, + EVENT_PAUSE = 4, + EVENT_CAST = 5, + EVENT_LAUGH_2 = 6, + EVENT_BLINK = 7, + EVENT_DESPAWN = 8, MAIL_MINIGOB_ENTRY = 264, MAIL_DELIVER_DELAY_MIN = 5*MINUTE, @@ -163,26 +167,29 @@ class npc_minigob_manabonk : public CreatureScript void Reset() override { + playerGuid = ObjectGuid(); me->SetVisible(false); - events.ScheduleEvent(EVENT_SELECT_TARGET, IN_MILLISECONDS); + events.ScheduleEvent(EVENT_SELECT_TARGET, Seconds(1)); } - Player* SelectTargetInDalaran() + void GetPlayersInDalaran(std::vector<Player*>& playerList) const { - std::vector<Player*> PlayerInDalaranList; - Map::PlayerList const& players = me->GetMap()->GetPlayers(); for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) if (Player* player = itr->GetSource()->ToPlayer()) if (player->GetZoneId() == ZONE_DALARAN && !player->IsFlying() && !player->IsMounted() && !player->IsGameMaster()) - PlayerInDalaranList.push_back(player); + playerList.push_back(player); + } + static Player* SelectTargetInDalaran(std::vector<Player*>& PlayerInDalaranList) + { if (PlayerInDalaranList.empty()) return nullptr; + return Trinity::Containers::SelectRandomContainerElement(PlayerInDalaranList); } - void SendMailToPlayer(Player* player) + void SendMailToPlayer(Player* player) const { SQLTransaction trans = CharacterDatabase.BeginTransaction(); int16 deliverDelay = irand(MAIL_DELIVER_DELAY_MIN, MAIL_DELIVER_DELAY_MAX); @@ -199,30 +206,61 @@ class npc_minigob_manabonk : public CreatureScript switch (eventId) { case EVENT_SELECT_TARGET: + { + std::vector<Player*> PlayerInDalaranList; + GetPlayersInDalaran(PlayerInDalaranList); + + // Increases chance of event based on player count in Dalaran (100 players or more = 100% else player count%) + if (PlayerInDalaranList.empty() || urand(1, 100) > PlayerInDalaranList.size()) + me->AddObjectToRemoveList(); + me->SetVisible(true); - DoCast(me, SPELL_TELEPORT_VISUAL); - if (Player* player = SelectTargetInDalaran()) + DoCastSelf(SPELL_TELEPORT_VISUAL); + if (Player* player = SelectTargetInDalaran(PlayerInDalaranList)) + { + playerGuid = player->GetGUID(); + Position pos = player->GetPosition(); + float dist = frand(10.0f, 30.0f); + float angle = frand(0.0f, 1.0f) * M_PI * 2.0f; + player->MovePositionToFirstCollision(pos, dist, angle); + me->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation()); + } + events.ScheduleEvent(EVENT_LAUGH_1, Seconds(2)); + break; + } + case EVENT_LAUGH_1: + me->HandleEmoteCommand(EMOTE_ONESHOT_LAUGH_NO_SHEATHE); + events.ScheduleEvent(EVENT_WANDER, Seconds(3)); + break; + case EVENT_WANDER: + me->GetMotionMaster()->MoveRandom(8); + events.ScheduleEvent(EVENT_PAUSE, Minutes(1)); + break; + case EVENT_PAUSE: + me->GetMotionMaster()->MoveIdle(); + events.ScheduleEvent(EVENT_CAST, Seconds(2)); + break; + case EVENT_CAST: + if (Player* player = me->GetMap()->GetPlayer(playerGuid)) { - me->NearTeleportTo(player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), 0.0f); DoCast(player, SPELL_MANABONKED); SendMailToPlayer(player); } - events.ScheduleEvent(EVENT_BLINK, 3*IN_MILLISECONDS); + else + me->AddObjectToRemoveList(); + + events.ScheduleEvent(EVENT_LAUGH_2, Seconds(8)); break; - case EVENT_BLINK: - { - DoCast(me, SPELL_IMPROVED_BLINK); - Position pos = me->GetRandomNearPosition(frand(15, 40)); - me->GetMotionMaster()->MovePoint(0, pos.m_positionX, pos.m_positionY, pos.m_positionZ); - events.ScheduleEvent(EVENT_DESPAWN, 3 * IN_MILLISECONDS); - events.ScheduleEvent(EVENT_DESPAWN_VISUAL, 2.5*IN_MILLISECONDS); + case EVENT_LAUGH_2: + me->HandleEmoteCommand(EMOTE_ONESHOT_LAUGH_NO_SHEATHE); + events.ScheduleEvent(EVENT_BLINK, Seconds(3)); break; - } - case EVENT_DESPAWN_VISUAL: - DoCast(me, SPELL_TELEPORT_VISUAL); + case EVENT_BLINK: + DoCastSelf(SPELL_IMPROVED_BLINK); + events.ScheduleEvent(EVENT_DESPAWN, Seconds(4)); break; case EVENT_DESPAWN: - me->DespawnOrUnsummon(); + me->AddObjectToRemoveList(); break; default: break; @@ -231,6 +269,8 @@ class npc_minigob_manabonk : public CreatureScript } private: + + ObjectGuid playerGuid; EventMap events; }; diff --git a/src/server/scripts/Northrend/zone_dragonblight.cpp b/src/server/scripts/Northrend/zone_dragonblight.cpp index 43983271833..6af5973eab0 100644 --- a/src/server/scripts/Northrend/zone_dragonblight.cpp +++ b/src/server/scripts/Northrend/zone_dragonblight.cpp @@ -411,7 +411,7 @@ public: tree->AI()->Talk(SAY_WALKER_FRIENDLY, player); tree->DespawnOrUnsummon(1000); } - else if (roll == 0) // enemy version + else // enemy version { tree->AI()->Talk(SAY_WALKER_ENEMY, player); tree->SetFaction(FACTION_MONSTER); diff --git a/src/server/scripts/Northrend/zone_grizzly_hills.cpp b/src/server/scripts/Northrend/zone_grizzly_hills.cpp index f4749ef74f4..6809dce26c2 100644 --- a/src/server/scripts/Northrend/zone_grizzly_hills.cpp +++ b/src/server/scripts/Northrend/zone_grizzly_hills.cpp @@ -64,9 +64,9 @@ class npc_emily : public CreatureScript public: npc_emily() : CreatureScript("npc_emily") { } - struct npc_emilyAI : public npc_escortAI + struct npc_emilyAI : public EscortAI { - npc_emilyAI(Creature* creature) : npc_escortAI(creature) { } + npc_emilyAI(Creature* creature) : EscortAI(creature) { } void JustSummoned(Creature* summoned) override { @@ -76,7 +76,7 @@ public: summoned->AI()->AttackStart(me->GetVictim()); } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { Player* player = GetPlayerForEscort(); if (!player) @@ -564,6 +564,11 @@ public: { npc_venture_co_stragglerAI(Creature* creature) : ScriptedAI(creature) { } + void EnterCombat(Unit* /*who*/) override + { + _events.ScheduleEvent(EVENT_CHOP, Seconds(3), Seconds(6)); + } + void Reset() override { _playerGUID.Clear(); @@ -602,7 +607,7 @@ public: case EVENT_CHOP: if (UpdateVictim()) DoCastVictim(SPELL_CHOP); - _events.ScheduleEvent(EVENT_CHOP, 10000, 12000); + _events.Repeat(Seconds(10), Seconds(12)); break; default: break; @@ -611,7 +616,6 @@ public: if (!UpdateVictim()) return; - DoMeleeAttackIfReady(); } diff --git a/src/server/scripts/Northrend/zone_howling_fjord.cpp b/src/server/scripts/Northrend/zone_howling_fjord.cpp index aeb2fa3e59a..e2df8f6ca96 100644 --- a/src/server/scripts/Northrend/zone_howling_fjord.cpp +++ b/src/server/scripts/Northrend/zone_howling_fjord.cpp @@ -80,9 +80,9 @@ class npc_apothecary_hanes : public CreatureScript public: npc_apothecary_hanes() : CreatureScript("npc_apothecary_hanes") { } - struct npc_Apothecary_HanesAI : public npc_escortAI + struct npc_Apothecary_HanesAI : public EscortAI { - npc_Apothecary_HanesAI(Creature* creature) : npc_escortAI(creature) + npc_Apothecary_HanesAI(Creature* creature) : EscortAI(creature) { Initialize(); } @@ -133,7 +133,7 @@ public: if (GetAttack() && UpdateVictim()) DoMeleeAttackIfReady(); - npc_escortAI::UpdateAI(diff); + EscortAI::UpdateAI(diff); if (me->IsInCombat()) return; @@ -156,7 +156,7 @@ public: events.Reset(); me->SetFaction(FACTION_ESCORTEE_H_PASSIVE); me->SetReactState(REACT_AGGRESSIVE); - ENSURE_AI(npc_escortAI, (me->AI()))->Start(true, true, _player); + ENSURE_AI(EscortAI, (me->AI()))->Start(true, true, _player); break; case EVENT_TALK_1: if (Player* player = ObjectAccessor::GetPlayer(*me, _player)) @@ -202,7 +202,7 @@ public: } } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { Player* player = GetPlayerForEscort(); if (!player) @@ -272,9 +272,9 @@ class npc_plaguehound_tracker : public CreatureScript public: npc_plaguehound_tracker() : CreatureScript("npc_plaguehound_tracker") { } - struct npc_plaguehound_trackerAI : public npc_escortAI + struct npc_plaguehound_trackerAI : public EscortAI { - npc_plaguehound_trackerAI(Creature* creature) : npc_escortAI(creature) { } + npc_plaguehound_trackerAI(Creature* creature) : EscortAI(creature) { } void Reset() override { @@ -292,7 +292,7 @@ public: Start(false, false, summonerGUID); } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { if (waypointId != 26) return; diff --git a/src/server/scripts/Northrend/zone_icecrown.cpp b/src/server/scripts/Northrend/zone_icecrown.cpp index b7f60c8e9d2..ab3b83857d8 100644 --- a/src/server/scripts/Northrend/zone_icecrown.cpp +++ b/src/server/scripts/Northrend/zone_icecrown.cpp @@ -433,7 +433,7 @@ public: void Reset() override { - me->setRegeneratingHealth(false); + me->SetRegenerateHealth(false); DoCast(SPELL_THREAT_PULSE); Talk(BANNER_SAY); events.ScheduleEvent(EVENT_SPAWN, 3000); diff --git a/src/server/scripts/Northrend/zone_sholazar_basin.cpp b/src/server/scripts/Northrend/zone_sholazar_basin.cpp index 118aae0da83..e96c8d2f17d 100644 --- a/src/server/scripts/Northrend/zone_sholazar_basin.cpp +++ b/src/server/scripts/Northrend/zone_sholazar_basin.cpp @@ -18,14 +18,18 @@ /* ScriptData SDName: Sholazar_Basin SD%Complete: 100 -SDComment: Quest support: 12573, 12621, 12726 +SDComment: Quest support: 12550, 12645, 12688, 12726, 13957 SDCategory: Sholazar_Basin EndScriptData */ /* ContentData -npc_vekjik -avatar_of_freya +npc_engineer_helice +npc_jungle_punch_target +spell_q12620_the_lifewarden_wrath +spell_q12589_shoot_rjr npc_haiphoon (Quest: "Song of Wind and Water") +npc_vics_flying_machine +spell_shango_tracks EndContentData */ #include "ScriptMgr.h" @@ -36,196 +40,11 @@ EndContentData */ #include "ObjectMgr.h" #include "Player.h" #include "ScriptedEscortAI.h" -#include "ScriptedGossip.h" #include "SpellAuras.h" #include "SpellScript.h" -#include "TemporarySummon.h" #include "Vehicle.h" /*###### -## npc_vekjik -######*/ - -#define GOSSIP_VEKJIK_ITEM1 "Shaman Vekjik, I have spoken with the big-tongues and they desire peace. I have brought this offering on their behalf." -#define GOSSIP_VEKJIK_ITEM2 "No no... I had no intentions of betraying your people. I was only defending myself. it was all a misunderstanding." - -enum Vekjik -{ - GOSSIP_TEXTID_VEKJIK1 = 13137, - GOSSIP_TEXTID_VEKJIK2 = 13138, - - SAY_TEXTID_VEKJIK1 = 0, - - SPELL_FREANZYHEARTS_FURY = 51469, - - QUEST_MAKING_PEACE = 12573 -}; - -class npc_vekjik : public CreatureScript -{ -public: - npc_vekjik() : CreatureScript("npc_vekjik") { } - - struct npc_vekjikAI : public ScriptedAI - { - npc_vekjikAI(Creature* creature) : ScriptedAI(creature) { } - - bool GossipHello(Player* player) override - { - if (me->IsQuestGiver()) - player->PrepareQuestMenu(me->GetGUID()); - - if (player->GetQuestStatus(QUEST_MAKING_PEACE) == QUEST_STATUS_INCOMPLETE) - { - AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_VEKJIK_ITEM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - SendGossipMenuFor(player, GOSSIP_TEXTID_VEKJIK1, me->GetGUID()); - return true; - } - - SendGossipMenuFor(player, player->GetGossipTextId(me), me->GetGUID()); - return true; - } - - bool GossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override - { - uint32 const action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId); - ClearGossipMenuFor(player); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF + 1: - AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_VEKJIK_ITEM2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - SendGossipMenuFor(player, GOSSIP_TEXTID_VEKJIK2, me->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 2: - CloseGossipMenuFor(player); - Talk(SAY_TEXTID_VEKJIK1, player); - player->AreaExploredOrEventHappens(QUEST_MAKING_PEACE); - DoCast(player, SPELL_FREANZYHEARTS_FURY, false); - break; - } - - return true; - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_vekjikAI(creature); - } -}; - -/*###### -## avatar_of_freya -######*/ - -#define GOSSIP_ITEM_AOF1 "I want to stop the Scourge as much as you do. How can I help?" -#define GOSSIP_ITEM_AOF2 "You can trust me. I am no friend of the Lich King." -#define GOSSIP_ITEM_AOF3 "I will not fail." - -enum Freya -{ - QUEST_FREYA_PACT = 12621, - - SPELL_FREYA_CONVERSATION = 52045, - - GOSSIP_TEXTID_AVATAR1 = 13303, - GOSSIP_TEXTID_AVATAR2 = 13304, - GOSSIP_TEXTID_AVATAR3 = 13305 -}; - -class npc_avatar_of_freya : public CreatureScript -{ -public: - npc_avatar_of_freya() : CreatureScript("npc_avatar_of_freya") { } - - struct npc_avatar_of_freyaAI : public ScriptedAI - { - npc_avatar_of_freyaAI(Creature* creature) : ScriptedAI(creature) { } - - bool GossipHello(Player* player) override - { - if (me->IsQuestGiver()) - player->PrepareQuestMenu(me->GetGUID()); - - if (player->GetQuestStatus(QUEST_FREYA_PACT) == QUEST_STATUS_INCOMPLETE) - AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_ITEM_AOF1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - - player->PlayerTalkClass->SendGossipMenu(GOSSIP_TEXTID_AVATAR1, me->GetGUID()); - return true; - } - - bool GossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override - { - uint32 const action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId); - ClearGossipMenuFor(player); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF + 1: - AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_ITEM_AOF2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - player->PlayerTalkClass->SendGossipMenu(GOSSIP_TEXTID_AVATAR2, me->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 2: - AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_ITEM_AOF3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); - player->PlayerTalkClass->SendGossipMenu(GOSSIP_TEXTID_AVATAR3, me->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 3: - player->CastSpell(player, SPELL_FREYA_CONVERSATION, true); - CloseGossipMenuFor(player); - break; - } - return true; - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_avatar_of_freyaAI(creature); - } -}; - -/*###### -## npc_bushwhacker -######*/ - -class npc_bushwhacker : public CreatureScript -{ -public: - npc_bushwhacker() : CreatureScript("npc_bushwhacker") { } - - struct npc_bushwhackerAI : public ScriptedAI - { - npc_bushwhackerAI(Creature* creature) : ScriptedAI(creature) - { - } - - void InitializeAI() override - { - if (me->isDead()) - return; - - if (TempSummon* summ = me->ToTempSummon()) - if (Unit* summoner = summ->GetSummoner()) - me->GetMotionMaster()->MovePoint(0, summoner->GetPositionX(), summoner->GetPositionY(), summoner->GetPositionZ()); - - Reset(); - } - - void UpdateAI(uint32 /*uiDiff*/) override - { - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_bushwhackerAI(creature); - } -}; - -/*###### ## npc_engineer_helice ######*/ @@ -253,9 +72,9 @@ class npc_engineer_helice : public CreatureScript public: npc_engineer_helice() : CreatureScript("npc_engineer_helice") { } - struct npc_engineer_heliceAI : public npc_escortAI + struct npc_engineer_heliceAI : public EscortAI { - npc_engineer_heliceAI(Creature* creature) : npc_escortAI(creature) + npc_engineer_heliceAI(Creature* creature) : EscortAI(creature) { Initialize(); } @@ -267,7 +86,7 @@ public: uint32 m_uiChatTimer; - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { Player* player = GetPlayerForEscort(); @@ -322,7 +141,7 @@ public: void UpdateAI(uint32 uiDiff) override { - npc_escortAI::UpdateAI(uiDiff); + EscortAI::UpdateAI(uiDiff); if (HasEscortState(STATE_ESCORT_ESCORTING)) { @@ -550,96 +369,6 @@ public: }; /*###### -## npc_adventurous_dwarf -######*/ - -#define GOSSIP_OPTION_ORANGE "Can you spare an orange?" -#define GOSSIP_OPTION_BANANAS "Have a spare bunch of bananas?" -#define GOSSIP_OPTION_PAPAYA "I could really use a papaya." - -enum AdventurousDwarf -{ - QUEST_12634 = 12634, - - ITEM_BANANAS = 38653, - ITEM_PAPAYA = 38655, - ITEM_ORANGE = 38656, - - SPELL_ADD_ORANGE = 52073, - SPELL_ADD_BANANAS = 52074, - SPELL_ADD_PAPAYA = 52076, - - GOSSIP_MENU_DWARF = 13307, - - SAY_DWARF_OUCH = 0, - SAY_DWARF_HELP = 1 -}; - -class npc_adventurous_dwarf : public CreatureScript -{ -public: - npc_adventurous_dwarf() : CreatureScript("npc_adventurous_dwarf") { } - - struct npc_adventurous_dwarfAI : public ScriptedAI - { - npc_adventurous_dwarfAI(Creature* creature) : ScriptedAI(creature) - { - Talk(SAY_DWARF_OUCH); - } - - bool GossipHello(Player* player) override - { - if (player->GetQuestStatus(QUEST_12634) != QUEST_STATUS_INCOMPLETE) - return false; - - if (player->GetItemCount(ITEM_ORANGE) < 1) - AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_OPTION_ORANGE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - - if (player->GetItemCount(ITEM_BANANAS) < 2) - AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_OPTION_BANANAS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - - if (player->GetItemCount(ITEM_PAPAYA) < 1) - AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_OPTION_PAPAYA, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); - - player->PlayerTalkClass->SendGossipMenu(GOSSIP_MENU_DWARF, me->GetGUID()); - return true; - } - - bool GossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override - { - uint32 const action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId); - ClearGossipMenuFor(player); - uint32 spellId = 0; - - switch (action) - { - case GOSSIP_ACTION_INFO_DEF + 1: - spellId = SPELL_ADD_ORANGE; - break; - case GOSSIP_ACTION_INFO_DEF + 2: - spellId = SPELL_ADD_BANANAS; - break; - case GOSSIP_ACTION_INFO_DEF + 3: - spellId = SPELL_ADD_PAPAYA; - break; - } - - if (spellId) - player->CastSpell(player, spellId, true); - - Talk(SAY_DWARF_HELP); - me->DespawnOrUnsummon(); - return true; - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_adventurous_dwarfAI(creature); - } -}; - -/*###### ## Quest The Lifewarden's Wrath ######*/ @@ -1044,11 +773,7 @@ public: void AddSC_sholazar_basin() { - new npc_vekjik(); - new npc_avatar_of_freya(); - new npc_bushwhacker(); new npc_engineer_helice(); - new npc_adventurous_dwarf(); new npc_jungle_punch_target(); new spell_q12620_the_lifewarden_wrath(); new spell_q12589_shoot_rjr(); diff --git a/src/server/scripts/Northrend/zone_storm_peaks.cpp b/src/server/scripts/Northrend/zone_storm_peaks.cpp index efe1691d479..c0c22a43696 100644 --- a/src/server/scripts/Northrend/zone_storm_peaks.cpp +++ b/src/server/scripts/Northrend/zone_storm_peaks.cpp @@ -48,11 +48,11 @@ class npc_injured_goblin : public CreatureScript public: npc_injured_goblin() : CreatureScript("npc_injured_goblin") { } - struct npc_injured_goblinAI : public npc_escortAI + struct npc_injured_goblinAI : public EscortAI { - npc_injured_goblinAI(Creature* creature) : npc_escortAI(creature) { } + npc_injured_goblinAI(Creature* creature) : EscortAI(creature) { } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { Player* player = GetPlayerForEscort(); if (!player) @@ -82,7 +82,7 @@ public: void UpdateAI(uint32 uiDiff) override { - npc_escortAI::UpdateAI(uiDiff); + EscortAI::UpdateAI(uiDiff); if (!UpdateVictim()) return; DoMeleeAttackIfReady(); @@ -211,7 +211,7 @@ public: me->CastSpell(me, SPELL_ICE_PRISON, true); } - void JustRespawned() override + void JustAppeared() override { Reset(); } @@ -346,9 +346,9 @@ class npc_icefang : public CreatureScript public: npc_icefang() : CreatureScript("npc_icefang") { } - struct npc_icefangAI : public npc_escortAI + struct npc_icefangAI : public EscortAI { - npc_icefangAI(Creature* creature) : npc_escortAI(creature) { } + npc_icefangAI(Creature* creature) : EscortAI(creature) { } void AttackStart(Unit* /*who*/) override { } void EnterCombat(Unit* /*who*/) override { } @@ -363,13 +363,12 @@ public: } } - void WaypointReached(uint32 /*waypointId*/) override { } void JustDied(Unit* /*killer*/) override { } void OnCharmed(bool /*apply*/) override { } void UpdateAI(uint32 diff) override { - npc_escortAI::UpdateAI(diff); + EscortAI::UpdateAI(diff); if (!UpdateVictim()) return; @@ -1045,7 +1044,7 @@ class spell_close_rift : public SpellScriptLoader void HandlePeriodic(AuraEffect const* /* aurEff */) { if (++_counter == 5) - GetTarget()->CastSpell((Unit*)nullptr, SPELL_DESPAWN_RIFT, true); + GetTarget()->CastSpell(nullptr, SPELL_DESPAWN_RIFT, true); } void Register() override @@ -1241,7 +1240,7 @@ class spell_low_health_trigger : public SpellScriptLoader void HandleScript(SpellEffIndex /*effIndex*/) { - GetHitUnit()->CastSpell((Unit*)nullptr, GetEffectValue(), true); + GetHitUnit()->CastSpell(nullptr, GetEffectValue(), true); } void Register() override @@ -1312,7 +1311,7 @@ class spell_claw_swipe_check : public SpellScriptLoader } } - GetTarget()->CastSpell((Unit*)nullptr, aurEff->GetAmount(), false); + GetTarget()->CastSpell(nullptr, aurEff->GetAmount(), false); } void Register() override @@ -1355,7 +1354,7 @@ class spell_fatal_strike : public SpellScriptLoader return; } - GetCaster()->CastSpell((Unit*)nullptr, SPELL_FATAL_STRIKE_DAMAGE, true); + GetCaster()->CastSpell(nullptr, SPELL_FATAL_STRIKE_DAMAGE, true); } void Register() override @@ -1422,7 +1421,7 @@ class spell_player_mount_wyrm : public SpellScriptLoader void HandleDummy(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { - GetTarget()->CastSpell((Unit*)nullptr, SPELL_FIGHT_WYRM, true); + GetTarget()->CastSpell(nullptr, SPELL_FIGHT_WYRM, true); } void Register() override diff --git a/src/server/scripts/Northrend/zone_zuldrak.cpp b/src/server/scripts/Northrend/zone_zuldrak.cpp index 607e6845157..30ae441d7ce 100644 --- a/src/server/scripts/Northrend/zone_zuldrak.cpp +++ b/src/server/scripts/Northrend/zone_zuldrak.cpp @@ -924,7 +924,7 @@ public: me->CastSpell(me, STORM_VISUAL, true); } - void JustRespawned() override + void JustAppeared() override { Reset(); } diff --git a/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_talon_king_ikiss.cpp b/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_talon_king_ikiss.cpp index a6340227270..1573fb3bcf7 100644 --- a/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_talon_king_ikiss.cpp +++ b/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_talon_king_ikiss.cpp @@ -178,6 +178,9 @@ class spell_talon_king_ikiss_blink : public SpellScriptLoader void FilterTargets(std::list<WorldObject*>& targets) { + if (targets.empty()) + return; + WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets); targets.clear(); targets.push_back(target); diff --git a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_ambassador_hellmaw.cpp b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_ambassador_hellmaw.cpp index c12dd178729..945edfe3772 100644 --- a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_ambassador_hellmaw.cpp +++ b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_ambassador_hellmaw.cpp @@ -57,9 +57,9 @@ class boss_ambassador_hellmaw : public CreatureScript public: boss_ambassador_hellmaw() : CreatureScript("boss_ambassador_hellmaw") { } - struct boss_ambassador_hellmawAI : public npc_escortAI + struct boss_ambassador_hellmawAI : public EscortAI { - boss_ambassador_hellmawAI(Creature* creature) : npc_escortAI(creature) + boss_ambassador_hellmawAI(Creature* creature) : EscortAI(creature) { _instance = creature->GetInstanceScript(); _intro = false; @@ -86,11 +86,7 @@ class boss_ambassador_hellmaw : public CreatureScript if (me->HasAura(SPELL_BANISH)) return; - npc_escortAI::MoveInLineOfSight(who); - } - - void WaypointReached(uint32 /*waypointId*/) override - { + EscortAI::MoveInLineOfSight(who); } void DoAction(int32 actionId) override diff --git a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_blackheart_the_inciter.cpp b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_blackheart_the_inciter.cpp index e5458ac1b10..04cc23136d9 100644 --- a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_blackheart_the_inciter.cpp +++ b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_blackheart_the_inciter.cpp @@ -16,16 +16,15 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* -Name: Boss_Blackheart_the_Inciter -%Complete: 75 -Comment: Incite Chaos not functional since core lacks Mind Control support -Category: Auchindoun, Shadow Labyrinth -*/ - -#include "ScriptMgr.h" +#include "InstanceScript.h" +#include "Map.h" #include "ObjectAccessor.h" +#include "PassiveAI.h" +#include "Player.h" +#include "PlayerAI.h" +#include "ScriptMgr.h" #include "ScriptedCreature.h" +#include "SpellScript.h" #include "shadow_labyrinth.h" enum BlackheartTheInciter @@ -56,94 +55,178 @@ enum Events EVENT_WAR_STOMP = 3 }; -class boss_blackheart_the_inciter : public CreatureScript +class BlackheartCharmedPlayerAI : public SimpleCharmedPlayerAI { - public: - boss_blackheart_the_inciter() : CreatureScript("boss_blackheart_the_inciter") { } - - struct boss_blackheart_the_inciterAI : public BossAI + using SimpleCharmedPlayerAI::SimpleCharmedPlayerAI; + void OnCharmed(bool apply) override + { + SimpleCharmedPlayerAI::OnCharmed(apply); + if (!me->GetMap()->IsDungeon()) + return; + if (Creature* blackheart = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(DATA_BLACKHEART_THE_INCITER))) { - boss_blackheart_the_inciterAI(Creature* creature) : BossAI(creature, DATA_BLACKHEART_THE_INCITER) { } - - void Reset() override - { - _Reset(); - } - - void EnterCombat(Unit* /*who*/) override - { - _EnterCombat(); - events.ScheduleEvent(EVENT_INCITE_CHAOS, 20000); - events.ScheduleEvent(EVENT_CHARGE_ATTACK, 5000); - events.ScheduleEvent(EVENT_WAR_STOMP, 15000); - - Talk(SAY_AGGRO); - } - - void KilledUnit(Unit* who) override - { - if (who->GetTypeId() == TYPEID_PLAYER) - Talk(SAY_SLAY); - } + blackheart->AI()->SetData(0, apply); + blackheart->GetThreatManager().AddThreat(me, 0.0f); + } + } +}; - void JustDied(Unit* /*killer*/) override +struct boss_blackheart_the_inciter : public BossAI +{ + boss_blackheart_the_inciter(Creature* creature) : BossAI(creature, DATA_BLACKHEART_THE_INCITER) { } + + void Reset() override + { + me->SetReactState(REACT_AGGRESSIVE); + _Reset(); + } + + void EnterCombat(Unit* /*who*/) override + { + _EnterCombat(); + events.ScheduleEvent(EVENT_INCITE_CHAOS, 20000); + events.ScheduleEvent(EVENT_CHARGE_ATTACK, 5000); + events.ScheduleEvent(EVENT_WAR_STOMP, 15000); + + Talk(SAY_AGGRO); + } + + void KilledUnit(Unit* who) override + { + if (who->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_SLAY); + } + + void JustDied(Unit* /*killer*/) override + { + _JustDied(); + Talk(SAY_DEATH); + } + + uint8 charmCount = 0; + void SetData(uint32 /*index*/, uint32 data) override + { + if (data) + ++charmCount; + else + { + if (!charmCount) + EnterEvadeMode(EVADE_REASON_OTHER); // sanity check + --charmCount; + } + if (charmCount) + me->SetReactState(REACT_PASSIVE); + else + me->SetReactState(REACT_AGGRESSIVE); + } + + void UpdateAI(uint32 diff) override + { + events.Update(diff); + if (me->HasReactState(REACT_PASSIVE) || !UpdateVictim()) + return; + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) { - _JustDied(); - Talk(SAY_DEATH); + case EVENT_INCITE_CHAOS: + { + if (me->GetThreatManager().GetThreatListSize() > 1) + { + ResetThreatList(); + DoCast(me, SPELL_INCITE_CHAOS); + } + events.ScheduleEvent(EVENT_INCITE_CHAOS, 40000); + break; + } + case EVENT_CHARGE_ATTACK: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) + DoCast(target, SPELL_CHARGE); + events.ScheduleEvent(EVENT_CHARGE, urand(15000, 25000)); + break; + case EVENT_WAR_STOMP: + DoCast(me, SPELL_WAR_STOMP); + events.ScheduleEvent(EVENT_WAR_STOMP, urand(18000, 24000)); + break; } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - events.Update(diff); + if (me->HasReactState(REACT_PASSIVE) || me->HasUnitState(UNIT_STATE_CASTING)) + return; + } - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + DoMeleeAttackIfReady(); + } +}; - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) +struct boss_blackheart_the_inciter_mc_dummy : public NullCreatureAI +{ + using NullCreatureAI::NullCreatureAI; + void InitializeAI() override { me->SetReactState(REACT_PASSIVE); } + static const uint32 FIRST_DUMMY = NPC_BLACKHEART_DUMMY1, LAST_DUMMY = NPC_BLACKHEART_DUMMY5; + void IsSummonedBy(Unit* who) override + { + me->CastSpell(who, SPELL_INCITE_CHAOS_B, true); + + // ensure everyone is in combat with everyone + if (auto* dummies = GetBlackheartDummies(me->GetInstanceScript())) + for (ObjectGuid const& guid : *dummies) + if (Creature* trigger = ObjectAccessor::GetCreature(*me, guid)) + if (me->GetEntry() != trigger->GetEntry()) { - case EVENT_INCITE_CHAOS: + me->GetThreatManager().AddThreat(trigger, 0.0f); + trigger->GetThreatManager().AddThreat(who, 0.0f); + for (Unit* other : trigger->m_Controlled) { - DoCast(me, SPELL_INCITE_CHAOS); - - for (ThreatReference const* ref : me->GetThreatManager().GetUnsortedThreatList()) - if (ref->GetVictim()->GetTypeId() == TYPEID_PLAYER) - me->CastSpell(ref->GetVictim(), SPELL_INCITE_CHAOS_B, true); - - ResetThreatList(); - events.ScheduleEvent(EVENT_INCITE_CHAOS, 40000); - break; + me->GetThreatManager().AddThreat(other, 0.0f); + other->GetThreatManager().AddThreat(who, 0.0f); } - case EVENT_CHARGE_ATTACK: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(target, SPELL_CHARGE); - events.ScheduleEvent(EVENT_CHARGE, urand(15000, 25000)); - break; - case EVENT_WAR_STOMP: - DoCast(me, SPELL_WAR_STOMP); - events.ScheduleEvent(EVENT_WAR_STOMP, urand(18000, 24000)); - break; } + } + void UpdateAI(uint32 /*diff*/) override + { + if (me->m_Controlled.empty()) + me->DespawnOrUnsummon(); + } + PlayerAI* GetAIForCharmedPlayer(Player* player) override + { + return new BlackheartCharmedPlayerAI(player); + } +}; - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - } - - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const override +class spell_blackheart_incite_chaos : public SpellScript +{ + PrepareSpellScript(spell_blackheart_incite_chaos); + bool Validate(SpellInfo const* /*spell*/) override + { + return ValidateSpellInfo({ SPELL_INCITE_CHAOS_B }); + } + + static const uint8 NUM_INCITE_SPELLS = 5; + static const uint32 INCITE_SPELLS[NUM_INCITE_SPELLS]; + uint8 i=0; + void HandleDummy(SpellEffIndex /*effIndex*/) + { + if (Unit* target = GetHitUnit()) { - return GetShadowLabyrinthAI<boss_blackheart_the_inciterAI>(creature); + target->CastSpell(nullptr, INCITE_SPELLS[i], true); + i = (i + 1) % NUM_INCITE_SPELLS; } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_blackheart_incite_chaos::HandleDummy, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } }; +const uint32 spell_blackheart_incite_chaos::INCITE_SPELLS[spell_blackheart_incite_chaos::NUM_INCITE_SPELLS] = { 33677,33680,33681,33682,33683 }; void AddSC_boss_blackheart_the_inciter() { - new boss_blackheart_the_inciter(); + RegisterCreatureAIWithFactory(boss_blackheart_the_inciter, GetShadowLabyrinthAI); + RegisterCreatureAIWithFactory(boss_blackheart_the_inciter_mc_dummy, GetShadowLabyrinthAI); + RegisterSpellScript(spell_blackheart_incite_chaos); } diff --git a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_murmur.cpp b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_murmur.cpp index edaab7cd9cb..1d415bed072 100644 --- a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_murmur.cpp +++ b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_murmur.cpp @@ -185,7 +185,7 @@ class spell_murmur_sonic_boom : public SpellScriptLoader void HandleEffect(SpellEffIndex /*effIndex*/) { - GetCaster()->CastSpell((Unit*)nullptr, SPELL_SONIC_BOOM_EFFECT, true); + GetCaster()->CastSpell(nullptr, SPELL_SONIC_BOOM_EFFECT, true); } void Register() override diff --git a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/instance_shadow_labyrinth.cpp b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/instance_shadow_labyrinth.cpp index c5ddb8e6b50..709b3569134 100644 --- a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/instance_shadow_labyrinth.cpp +++ b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/instance_shadow_labyrinth.cpp @@ -53,6 +53,16 @@ class instance_shadow_labyrinth : public InstanceMapScript case NPC_AMBASSADOR_HELLMAW: AmbassadorHellmawGUID = creature->GetGUID(); break; + case NPC_BLACKHEART: + BlackheartGUID = creature->GetGUID(); + break; + case NPC_BLACKHEART_DUMMY1: + case NPC_BLACKHEART_DUMMY2: + case NPC_BLACKHEART_DUMMY3: + case NPC_BLACKHEART_DUMMY4: + case NPC_BLACKHEART_DUMMY5: + BlackheartDummyGUIDs.insert(creature->GetGUID()); + break; case NPC_GRANDMASTER_VORPIL: GrandmasterVorpilGUID = creature->GetGUID(); break; @@ -69,6 +79,22 @@ class instance_shadow_labyrinth : public InstanceMapScript } } + void OnCreatureRemove(Creature* creature) override + { + switch (creature->GetEntry()) + { + case NPC_BLACKHEART_DUMMY1: + case NPC_BLACKHEART_DUMMY2: + case NPC_BLACKHEART_DUMMY3: + case NPC_BLACKHEART_DUMMY4: + case NPC_BLACKHEART_DUMMY5: + BlackheartDummyGUIDs.erase(creature->GetGUID()); + break; + default: + break; + } + } + void OnGameObjectCreate(GameObject* go) override { switch (go->GetEntry()) @@ -128,6 +154,8 @@ class instance_shadow_labyrinth : public InstanceMapScript { switch (type) { + case DATA_BLACKHEART_THE_INCITER: + return BlackheartGUID; case DATA_GRANDMASTER_VORPIL: return GrandmasterVorpilGUID; default: @@ -136,8 +164,12 @@ class instance_shadow_labyrinth : public InstanceMapScript return ObjectGuid::Empty; } + GuidUnorderedSet const& GetBlackheartDummies() const { return BlackheartDummyGUIDs; } + protected: ObjectGuid AmbassadorHellmawGUID; + ObjectGuid BlackheartGUID; + GuidUnorderedSet BlackheartDummyGUIDs; ObjectGuid GrandmasterVorpilGUID; uint32 FelOverseerCount; }; @@ -148,6 +180,14 @@ class instance_shadow_labyrinth : public InstanceMapScript } }; +GuidUnorderedSet const* GetBlackheartDummies(InstanceScript const* s) +{ + if (auto* script = dynamic_cast<instance_shadow_labyrinth::instance_shadow_labyrinth_InstanceMapScript const*>(s)) + return &script->GetBlackheartDummies(); + return nullptr; + +} + void AddSC_instance_shadow_labyrinth() { new instance_shadow_labyrinth(); diff --git a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/shadow_labyrinth.h b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/shadow_labyrinth.h index 0c7e7b5afca..262a7b9c494 100644 --- a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/shadow_labyrinth.h +++ b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/shadow_labyrinth.h @@ -19,6 +19,7 @@ #define SHADOW_LABYRINTH_H_ #include "CreatureAIImpl.h" +#include "ObjectGuid.h" #define SLScriptName "instance_shadow_labyrinth" #define DataHeader "SL" @@ -40,6 +41,12 @@ enum SLDataTypes enum SLCreatureIds { NPC_AMBASSADOR_HELLMAW = 18731, + NPC_BLACKHEART = 18667, + NPC_BLACKHEART_DUMMY1 = 19300, + NPC_BLACKHEART_DUMMY2 = 19301, + NPC_BLACKHEART_DUMMY3 = 19302, + NPC_BLACKHEART_DUMMY4 = 19303, + NPC_BLACKHEART_DUMMY5 = 19304, NPC_GRANDMASTER_VORPIL = 18732, NPC_FEL_OVERSEER = 18796 }; @@ -56,6 +63,8 @@ enum SLMisc ACTION_AMBASSADOR_HELLMAW_BANISH = 2, }; +GuidUnorderedSet const* GetBlackheartDummies(InstanceScript const* s); + template <class AI, class T> inline AI* GetShadowLabyrinthAI(T* obj) { diff --git a/src/server/scripts/Outland/BlackTemple/black_temple.cpp b/src/server/scripts/Outland/BlackTemple/black_temple.cpp index 08b00caa519..693d2be970d 100644 --- a/src/server/scripts/Outland/BlackTemple/black_temple.cpp +++ b/src/server/scripts/Outland/BlackTemple/black_temple.cpp @@ -57,274 +57,226 @@ enum Misc GROUP_OUT_OF_COMBAT = 1 }; -// ######################################################## -// Wrathbone Flayer -// ######################################################## - -class npc_wrathbone_flayer : public CreatureScript +struct npc_wrathbone_flayer : public ScriptedAI { -public: - npc_wrathbone_flayer() : CreatureScript("npc_wrathbone_flayer") { } + npc_wrathbone_flayer(Creature* creature) : ScriptedAI(creature) + { + Initialize(); + _instance = creature->GetInstanceScript(); + } - struct npc_wrathbone_flayerAI : public ScriptedAI + void Initialize() { - npc_wrathbone_flayerAI(Creature* creature) : ScriptedAI(creature) - { - Initialize(); - _instance = creature->GetInstanceScript(); - } + _enteredCombat = false; + } - void Initialize() - { - _enteredCombat = false; - } + void Reset() override + { + _events.ScheduleEvent(EVENT_GET_CHANNELERS, 3000); + Initialize(); + _bloodmageList.clear(); + _deathshaperList.clear(); + } - void Reset() override - { - _events.ScheduleEvent(EVENT_GET_CHANNELERS, 3000); - Initialize(); - _bloodmageList.clear(); - _deathshaperList.clear(); - } + void JustDied(Unit* /*killer*/) override { } - void JustDied(Unit* /*killer*/) override { } + void EnterCombat(Unit* /*who*/) override + { + _events.ScheduleEvent(EVENT_CLEAVE, 5000); + _events.ScheduleEvent(EVENT_IGNORED, 7000); + _enteredCombat = true; + } - void EnterCombat(Unit* /*who*/) override + void UpdateAI(uint32 diff) override + { + if (!_enteredCombat) { - _events.ScheduleEvent(EVENT_CLEAVE, 5000); - _events.ScheduleEvent(EVENT_IGNORED, 7000); - _enteredCombat = true; - } + _events.Update(diff); - void UpdateAI(uint32 diff) override - { - if (!_enteredCombat) + while (uint32 eventId = _events.ExecuteEvent()) { - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) + switch (eventId) { - switch (eventId) + case EVENT_GET_CHANNELERS: { - case EVENT_GET_CHANNELERS: - { - std::list<Creature*> BloodMageList; - me->GetCreatureListWithEntryInGrid(BloodMageList, NPC_BLOOD_MAGE, 15.0f); - - if (!BloodMageList.empty()) - for (std::list<Creature*>::const_iterator itr = BloodMageList.begin(); itr != BloodMageList.end(); ++itr) - { - _bloodmageList.push_back((*itr)->GetGUID()); - if ((*itr)->isDead()) - (*itr)->Respawn(); - } - - std::list<Creature*> DeathShaperList; - me->GetCreatureListWithEntryInGrid(DeathShaperList, NPC_DEATHSHAPER, 15.0f); - - if (!DeathShaperList.empty()) - for (std::list<Creature*>::const_iterator itr = DeathShaperList.begin(); itr != DeathShaperList.end(); ++itr) - { - _deathshaperList.push_back((*itr)->GetGUID()); - if ((*itr)->isDead()) - (*itr)->Respawn(); - } - - _events.ScheduleEvent(EVENT_SET_CHANNELERS, 3000); - - break; - } - case EVENT_SET_CHANNELERS: - { - for (ObjectGuid guid : _bloodmageList) - if (Creature* bloodmage = ObjectAccessor::GetCreature(*me, guid)) - bloodmage->CastSpell((Unit*)nullptr, SPELL_SUMMON_CHANNEL); - - for (ObjectGuid guid : _deathshaperList) - if (Creature* deathshaper = ObjectAccessor::GetCreature(*me, guid)) - deathshaper->CastSpell((Unit*)nullptr, SPELL_SUMMON_CHANNEL); - - _events.ScheduleEvent(EVENT_SET_CHANNELERS, 12000); - - break; - } - default: - break; + std::list<Creature*> BloodMageList; + me->GetCreatureListWithEntryInGrid(BloodMageList, NPC_BLOOD_MAGE, 15.0f); + + if (!BloodMageList.empty()) + for (std::list<Creature*>::const_iterator itr = BloodMageList.begin(); itr != BloodMageList.end(); ++itr) + { + _bloodmageList.push_back((*itr)->GetGUID()); + if ((*itr)->isDead()) + (*itr)->Respawn(); + } + + std::list<Creature*> DeathShaperList; + me->GetCreatureListWithEntryInGrid(DeathShaperList, NPC_DEATHSHAPER, 15.0f); + + if (!DeathShaperList.empty()) + for (std::list<Creature*>::const_iterator itr = DeathShaperList.begin(); itr != DeathShaperList.end(); ++itr) + { + _deathshaperList.push_back((*itr)->GetGUID()); + if ((*itr)->isDead()) + (*itr)->Respawn(); + } + + _events.ScheduleEvent(EVENT_SET_CHANNELERS, 3000); + + break; } - } - } + case EVENT_SET_CHANNELERS: + { + for (ObjectGuid guid : _bloodmageList) + if (Creature* bloodmage = ObjectAccessor::GetCreature(*me, guid)) + bloodmage->CastSpell(nullptr, SPELL_SUMMON_CHANNEL); - if (!UpdateVictim()) - return; + for (ObjectGuid guid : _deathshaperList) + if (Creature* deathshaper = ObjectAccessor::GetCreature(*me, guid)) + deathshaper->CastSpell(nullptr, SPELL_SUMMON_CHANNEL); - _events.Update(diff); + _events.ScheduleEvent(EVENT_SET_CHANNELERS, 12000); - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_CLEAVE: - DoCastVictim(SPELL_CLEAVE); - _events.ScheduleEvent(EVENT_CLEAVE, urand (1000, 2000)); - break; - case EVENT_IGNORED: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(target, SPELL_IGNORED); - _events.ScheduleEvent(EVENT_IGNORED, 10000); break; + } default: break; } } - DoMeleeAttackIfReady(); } - private: - InstanceScript* _instance; - EventMap _events; - GuidList _bloodmageList; - GuidList _deathshaperList; - bool _enteredCombat; - }; + if (!UpdateVictim()) + return; - CreatureAI* GetAI(Creature* creature) const override - { - return GetBlackTempleAI<npc_wrathbone_flayerAI>(creature); + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_CLEAVE: + DoCastVictim(SPELL_CLEAVE); + _events.ScheduleEvent(EVENT_CLEAVE, urand(1000, 2000)); + break; + case EVENT_IGNORED: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) + DoCast(target, SPELL_IGNORED); + _events.ScheduleEvent(EVENT_IGNORED, 10000); + break; + default: + break; + } + } + DoMeleeAttackIfReady(); } + +private: + InstanceScript* _instance; + EventMap _events; + GuidList _bloodmageList; + GuidList _deathshaperList; + bool _enteredCombat; }; -class npc_angered_soul_fragment : public CreatureScript +struct npc_angered_soul_fragment : public ScriptedAI { -public: - npc_angered_soul_fragment() : CreatureScript("npc_angered_soul_fragment") { } + npc_angered_soul_fragment(Creature* creature) : ScriptedAI(creature) { } - struct npc_angered_soul_fragmentAI : public ScriptedAI + void Reset() override { - npc_angered_soul_fragmentAI(Creature* creature) : ScriptedAI(creature) { } + _scheduler.CancelAll(); - void Reset() override + _scheduler.Schedule(Seconds(1), GROUP_OUT_OF_COMBAT, [this](TaskContext invi) { - _scheduler.CancelAll(); + DoCastSelf(SPELL_GREATER_INVISIBILITY); - _scheduler.Schedule(Seconds(1), GROUP_OUT_OF_COMBAT, [this](TaskContext invi) + /* Workaround - On Retail creature appear and "vanish" again periodically, but i cant find packets + with UPDATE_AURA on sniffs about it */ + _scheduler.Schedule(Seconds(5), Seconds(10), GROUP_OUT_OF_COMBAT, [this](TaskContext /*context*/) { - DoCastSelf(SPELL_GREATER_INVISIBILITY); - - /* Workaround - On Retail creature appear and "vanish" again periodically, but i cant find packets - with UPDATE_AURA on sniffs about it */ - _scheduler.Schedule(Seconds(5), Seconds(10), GROUP_OUT_OF_COMBAT, [this](TaskContext /*context*/) - { - me->RemoveAurasDueToSpell(SPELL_GREATER_INVISIBILITY); - }); - - invi.Repeat(Seconds(15), Seconds(25)); + me->RemoveAurasDueToSpell(SPELL_GREATER_INVISIBILITY); }); - } - void EnterCombat(Unit* /*who*/) override - { - me->RemoveAurasDueToSpell(SPELL_GREATER_INVISIBILITY); + invi.Repeat(Seconds(15), Seconds(25)); + }); + } - _scheduler.CancelGroup(GROUP_OUT_OF_COMBAT); - _scheduler.Schedule(Seconds(1), [this](TaskContext anger) - { - Unit* target = me->GetVictim(); - if (target && me->IsWithinMeleeRange(target)) - DoCastSelf(SPELL_ANGER); - else - anger.Repeat(Seconds(1)); - }); - } + void EnterCombat(Unit* /*who*/) override + { + me->RemoveAurasDueToSpell(SPELL_GREATER_INVISIBILITY); - void UpdateAI(uint32 diff) override + _scheduler.CancelGroup(GROUP_OUT_OF_COMBAT); + _scheduler.Schedule(Seconds(1), [this](TaskContext anger) { - _scheduler.Update(diff); - - if (!UpdateVictim()) - return; + Unit* target = me->GetVictim(); + if (target && me->IsWithinMeleeRange(target)) + DoCastSelf(SPELL_ANGER); + else + anger.Repeat(Seconds(1)); + }); + } - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + void UpdateAI(uint32 diff) override + { + _scheduler.Update(diff); - DoMeleeAttackIfReady(); - } + if (!UpdateVictim()) + return; - private: - TaskScheduler _scheduler; - }; + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - CreatureAI* GetAI(Creature* creature) const override - { - return GetBlackTempleAI<npc_angered_soul_fragmentAI>(creature); + DoMeleeAttackIfReady(); } + +private: + TaskScheduler _scheduler; }; // 41986 - Anger -class spell_soul_fragment_anger : public SpellScriptLoader +class spell_soul_fragment_anger : public SpellScript { - public: - spell_soul_fragment_anger() : SpellScriptLoader("spell_soul_fragment_anger") { } - - class spell_soul_fragment_anger_SpellScript : public SpellScript - { - PrepareSpellScript(spell_soul_fragment_anger_SpellScript); + PrepareSpellScript(spell_soul_fragment_anger); - void HandleKill() - { - if (Creature* caster = GetCaster()->ToCreature()) - caster->DespawnOrUnsummon(Milliseconds(200)); - } - - void Register() override - { - AfterCast += SpellCastFn(spell_soul_fragment_anger_SpellScript::HandleKill); - } - }; + void HandleKill() + { + if (Creature* caster = GetCaster()->ToCreature()) + caster->DespawnOrUnsummon(Milliseconds(200)); + } - SpellScript* GetSpellScript() const override - { - return new spell_soul_fragment_anger_SpellScript(); - } + void Register() override + { + AfterCast += SpellCastFn(spell_soul_fragment_anger::HandleKill); + } }; // 39645 - Shadow Inferno -class spell_illidari_nightlord_shadow_inferno : public SpellScriptLoader +class spell_illidari_nightlord_shadow_inferno : public AuraScript { - public: - spell_illidari_nightlord_shadow_inferno() : SpellScriptLoader("spell_illidari_nightlord_shadow_inferno") { } - - class spell_illidari_nightlord_shadow_inferno_AuraScript : public AuraScript - { - PrepareAuraScript(spell_illidari_nightlord_shadow_inferno_AuraScript); + PrepareAuraScript(spell_illidari_nightlord_shadow_inferno); - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_SHADOW_INFERNO_DAMAGE }); - } - - void OnPeriodic(AuraEffect const* aurEffect) - { - PreventDefaultAction(); - int32 bp = aurEffect->GetTickNumber() * aurEffect->GetAmount(); - GetUnitOwner()->CastCustomSpell(SPELL_SHADOW_INFERNO_DAMAGE, SPELLVALUE_BASE_POINT0, bp, GetUnitOwner(), true); - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SHADOW_INFERNO_DAMAGE }); + } - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_illidari_nightlord_shadow_inferno_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); - } - }; + void OnPeriodic(AuraEffect const* aurEffect) + { + PreventDefaultAction(); + int32 bp = aurEffect->GetTickNumber() * aurEffect->GetAmount(); + GetUnitOwner()->CastCustomSpell(SPELL_SHADOW_INFERNO_DAMAGE, SPELLVALUE_BASE_POINT0, bp, GetUnitOwner(), true); + } - AuraScript* GetAuraScript() const override - { - return new spell_illidari_nightlord_shadow_inferno_AuraScript(); - } + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_illidari_nightlord_shadow_inferno::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } }; void AddSC_black_temple() { - new npc_wrathbone_flayer(); - new npc_angered_soul_fragment(); - new spell_soul_fragment_anger(); - new spell_illidari_nightlord_shadow_inferno(); + RegisterBlackTempleCreatureAI(npc_wrathbone_flayer); + RegisterBlackTempleCreatureAI(npc_angered_soul_fragment); + RegisterSpellScript(spell_soul_fragment_anger); + RegisterAuraScript(spell_illidari_nightlord_shadow_inferno); } diff --git a/src/server/scripts/Outland/BlackTemple/black_temple.h b/src/server/scripts/Outland/BlackTemple/black_temple.h index bdade01ab33..02b587d374f 100644 --- a/src/server/scripts/Outland/BlackTemple/black_temple.h +++ b/src/server/scripts/Outland/BlackTemple/black_temple.h @@ -40,25 +40,22 @@ enum BTDataTypes // Additional Data DATA_AKAMA_SHADE = 9, - DATA_AKAMA = 10, DATA_MAIEV = 11, DATA_GO_ILLIDAN_GATE = 12, DATA_BLACK_TEMPLE_TRIGGER = 13, - DATA_GATHIOS_THE_SHATTERER = 14, DATA_HIGH_NETHERMANCER_ZEREVOR = 15, DATA_LADY_MALANDE = 16, DATA_VERAS_DARKSHADOW = 17, DATA_BLOOD_ELF_COUNCIL_VOICE = 18, - DATA_GO_DEN_OF_MORTAL_DOOR = 19, - DATA_ESSENCE_OF_SUFFERING = 20, DATA_ESSENCE_OF_DESIRE = 21, DATA_ESSENCE_OF_ANGER = 22, - DATA_ILLIDAN_MUSIC_CONTROLLER = 23, + DATA_TERON_GOREFIEND_INTRO = 24, + DATA_AKAMA_ILLIDAN_INTRO = 25 }; enum TriggerEmotes @@ -108,7 +105,8 @@ enum BTCreatureIds NPC_ILLIDARI_ELITE = 23226, NPC_GLAIVE_TARGET = 23448, NPC_GLAIVE_WORLD_TRIGGER = 22515, - NPC_DEMON_FIRE = 23069 + NPC_DEMON_FIRE = 23069, + NPC_PARASITIC_SHADOWFIEND = 23498 }; enum BTGameObjectIds @@ -146,4 +144,6 @@ inline AI* GetBlackTempleAI(T* obj) return GetInstanceAI<AI>(obj, BTScriptName); } +#define RegisterBlackTempleCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetBlackTempleAI) + #endif // BLACK_TEMPLE_H_ diff --git a/src/server/scripts/Outland/BlackTemple/boss_gurtogg_bloodboil.cpp b/src/server/scripts/Outland/BlackTemple/boss_gurtogg_bloodboil.cpp index 037eaa82d99..7e743b1c62e 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_gurtogg_bloodboil.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_gurtogg_bloodboil.cpp @@ -89,322 +89,279 @@ enum Events EVENT_CHARGE_PLAYER }; -class boss_gurtogg_bloodboil : public CreatureScript + +struct boss_gurtogg_bloodboil : public BossAI { -public: - boss_gurtogg_bloodboil() : CreatureScript("boss_gurtogg_bloodboil") { } + boss_gurtogg_bloodboil(Creature* creature) : BossAI(creature, DATA_GURTOGG_BLOODBOIL) + { + Initialize(); + } - struct boss_gurtogg_bloodboilAI : public BossAI + void Reset() override { - boss_gurtogg_bloodboilAI(Creature* creature) : BossAI(creature, DATA_GURTOGG_BLOODBOIL) - { - Initialize(); - } + _Reset(); + Initialize(); + events.SetPhase(PHASE_1); + me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, false); + me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, false); + } - void Reset() override - { - _Reset(); - Initialize(); - events.SetPhase(PHASE_1); - me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, false); - me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, false); - } + void Initialize() + { + _oldThreat = 0.0f; + _oldTargetGUID.Clear(); + _targetGUID.Clear(); + } - void Initialize() - { - _oldThreat = 0.0f; - _oldTargetGUID.Clear(); - _targetGUID.Clear(); - } + bool CanAIAttack(Unit const* who) const override + { + return BossAI::CanAIAttack(who) && !who->HasAura(SPELL_BEWILDERING_STRIKE); + } - bool CanAIAttack(Unit const* who) const override - { - return BossAI::CanAIAttack(who) && !who->HasAura(SPELL_BEWILDERING_STRIKE); - } + void AttackStart(Unit* who) override + { + if (!CanAIAttack(who)) + return; - void AttackStart(Unit* who) override - { - if (!CanAIAttack(who)) - return; + BossAI::AttackStart(who); + } - BossAI::AttackStart(who); - } + void EnterCombat(Unit* /*who*/) override + { + Talk(SAY_AGGRO); + _EnterCombat(); + events.ScheduleEvent(EVENT_BERSERK, Minutes(10)); + events.ScheduleEvent(EVENT_CHANGE_PHASE, Seconds(60)); + ScheduleEvents(); + } - void EnterCombat(Unit* /*who*/) override - { - Talk(SAY_AGGRO); - _EnterCombat(); - events.ScheduleEvent(EVENT_BERSERK, Minutes(10)); - events.ScheduleEvent(EVENT_CHANGE_PHASE, Seconds(60)); - ScheduleEvents(); - } + void EnterEvadeMode(EvadeReason /*why*/) override + { + _DespawnAtEvade(); + } - void EnterEvadeMode(EvadeReason /*why*/) override + void ScheduleEvents() + { + if (events.IsInPhase(PHASE_1)) { - _DespawnAtEvade(); + events.ScheduleEvent(EVENT_BLOODBOIL, Seconds(10), GROUP_PHASE_1, PHASE_1); + events.ScheduleEvent(EVENT_ARCING_SMASH, Seconds(10), GROUP_PHASE_1, PHASE_1); + events.ScheduleEvent(EVENT_FEL_ACID_BREATH, Seconds(25), GROUP_PHASE_1, PHASE_1); + events.ScheduleEvent(EVENT_EJECT, Seconds(35), GROUP_PHASE_1, PHASE_1); + events.ScheduleEvent(EVENT_BEWILDERING_STRIKE, Seconds(47), GROUP_PHASE_1, PHASE_1); } - - void ScheduleEvents() + else if (events.IsInPhase(PHASE_2)) { - if (events.IsInPhase(PHASE_1)) - { - events.ScheduleEvent(EVENT_BLOODBOIL, Seconds(10), GROUP_PHASE_1, PHASE_1); - events.ScheduleEvent(EVENT_ARCING_SMASH, Seconds(10), GROUP_PHASE_1, PHASE_1); - events.ScheduleEvent(EVENT_FEL_ACID_BREATH, Seconds(25), GROUP_PHASE_1, PHASE_1); - events.ScheduleEvent(EVENT_EJECT, Seconds(35), GROUP_PHASE_1, PHASE_1); - events.ScheduleEvent(EVENT_BEWILDERING_STRIKE, Seconds(47), GROUP_PHASE_1, PHASE_1); - } - else if (events.IsInPhase(PHASE_2)) - { - events.ScheduleEvent(EVENT_START_PHASE_2, Milliseconds(100), GROUP_PHASE_2, PHASE_2); - events.ScheduleEvent(EVENT_EJECT_2, Seconds(14), GROUP_PHASE_2, PHASE_2); - events.ScheduleEvent(EVENT_FEL_ACID_BREATH_2, Seconds(16), GROUP_PHASE_2, PHASE_2); - events.ScheduleEvent(EVENT_ARCING_SMASH_2, Seconds(8), GROUP_PHASE_2, PHASE_2); - } + events.ScheduleEvent(EVENT_START_PHASE_2, Milliseconds(100), GROUP_PHASE_2, PHASE_2); + events.ScheduleEvent(EVENT_EJECT_2, Seconds(14), GROUP_PHASE_2, PHASE_2); + events.ScheduleEvent(EVENT_FEL_ACID_BREATH_2, Seconds(16), GROUP_PHASE_2, PHASE_2); + events.ScheduleEvent(EVENT_ARCING_SMASH_2, Seconds(8), GROUP_PHASE_2, PHASE_2); } + } - void KilledUnit(Unit* victim) override - { - if (victim->GetTypeId() == TYPEID_PLAYER) - Talk(SAY_SLAY); - } + void KilledUnit(Unit* victim) override + { + if (victim->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_SLAY); + } - void JustDied(Unit* /*killer*/) override - { - _JustDied(); - DoPlaySoundToSet(me, SOUND_ID_DEATH); - } + void JustDied(Unit* /*killer*/) override + { + _JustDied(); + DoPlaySoundToSet(me, SOUND_ID_DEATH); + } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - events.Update(diff); + events.Update(diff); - while (uint32 eventId = events.ExecuteEvent()) + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) { - switch (eventId) - { - case EVENT_BLOODBOIL: - DoCast(SPELL_BLOODBOIL); - events.Repeat(Seconds(10)); - break; - case EVENT_ARCING_SMASH: - DoCastVictim(SPELL_ARCING_SMASH); - events.Repeat(Seconds(10)); - break; - case EVENT_FEL_ACID_BREATH: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, me->GetCombatReach())) - DoCast(target, SPELL_FEL_ACID_BREATH); - events.Repeat(Seconds(25), Seconds(30)); - break; - case EVENT_EJECT: - Talk(SAY_SPECIAL); - DoCastVictim(SPELL_EJECT); - break; - case EVENT_BEWILDERING_STRIKE: - DoCastVictim(SPELL_BEWILDERING_STRIKE); - break; - case EVENT_CHANGE_PHASE: - ChangePhase(); - break; - case EVENT_START_PHASE_2: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1)) - { - if (Unit* oldTarget = me->GetVictim()) - { - _oldTargetGUID = oldTarget->GetGUID(); - _oldThreat = GetThreat(oldTarget); - } - _targetGUID = target->GetGUID(); - DoCastSelf(SPELL_FEL_RAGE_SELF, true); - DoCast(target, SPELL_FEL_RAGE_TARGET, true); - DoCast(target, SPELL_FEL_RAGE_2, true); - DoCast(target, SPELL_FEL_RAGE_3, true); - DoCast(target, SPELL_FEL_GEYSER, true); - DoCast(target, SPELL_FEL_RAGE_TARGET_2, true); - target->CastSpell(target, SPELL_FEL_RAGE_P, true); - target->CastSpell(target, SPELL_TAUNT_GURTOGG, true); - DoCastAOE(SPELL_INSIGNIFIGANCE, true); - - events.ScheduleEvent(EVENT_CHARGE_PLAYER, Seconds(2), GROUP_PHASE_2, PHASE_2); - - me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true); - me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, true); - } - else // If no other targets are found, reset phase 1 + case EVENT_BLOODBOIL: + DoCast(SPELL_BLOODBOIL); + events.Repeat(Seconds(10)); + break; + case EVENT_ARCING_SMASH: + DoCastVictim(SPELL_ARCING_SMASH); + events.Repeat(Seconds(10)); + break; + case EVENT_FEL_ACID_BREATH: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, me->GetCombatReach())) + DoCast(target, SPELL_FEL_ACID_BREATH); + events.Repeat(Seconds(25), Seconds(30)); + break; + case EVENT_EJECT: + Talk(SAY_SPECIAL); + DoCastVictim(SPELL_EJECT); + break; + case EVENT_BEWILDERING_STRIKE: + DoCastVictim(SPELL_BEWILDERING_STRIKE); + break; + case EVENT_CHANGE_PHASE: + ChangePhase(); + break; + case EVENT_START_PHASE_2: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1)) + { + if (Unit* oldTarget = me->GetVictim()) { - events.SetPhase(PHASE_1); - events.CancelEventGroup(GROUP_PHASE_2); - ScheduleEvents(); - events.RescheduleEvent(EVENT_CHANGE_PHASE, Seconds(60)); + _oldTargetGUID = oldTarget->GetGUID(); + _oldThreat = GetThreat(oldTarget); } - break; - case EVENT_CHARGE_PLAYER: - if (Unit* target = ObjectAccessor::GetUnit(*me, _targetGUID)) - DoCast(target, SPELL_CHARGE); - break; - case EVENT_EJECT_2: - DoCastVictim(SPELL_EJECT_2); - break; - case EVENT_FEL_ACID_BREATH_2: - DoCastVictim(SPELL_FEL_ACID_BREATH_2); - break; - case EVENT_ARCING_SMASH_2: - DoCastVictim(SPELL_ARCING_SMASH_2); - events.Repeat(Seconds(13)); - break; - case EVENT_BERSERK: - DoCast(SPELL_BERSERK); - roll_chance_i(50) ? Talk(SAY_ENRAGE) : DoPlaySoundToSet(me, SOUND_ID_ENRAGE); - break; - default: - break; - } - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - } - - DoMeleeAttackIfReady(); - } - - void ChangePhase() - { - if (events.IsInPhase(PHASE_1)) - { - events.SetPhase(PHASE_2); - events.CancelEventGroup(GROUP_PHASE_1); - events.ScheduleEvent(EVENT_CHANGE_PHASE, Seconds(30)); - ScheduleEvents(); - } - else if (events.IsInPhase(PHASE_2)) - { - events.SetPhase(PHASE_1); - events.CancelEventGroup(GROUP_PHASE_2); - events.ScheduleEvent(EVENT_CHANGE_PHASE, Seconds(60)); - me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, false); - me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, false); - ScheduleEvents(); - - // Attack the stored target - if (Unit* oldTarget = ObjectAccessor::GetUnit(*me, _oldTargetGUID)) - if (Unit* currentTarget = ObjectAccessor::GetUnit(*me, _targetGUID)) + _targetGUID = target->GetGUID(); + DoCastSelf(SPELL_FEL_RAGE_SELF, true); + DoCast(target, SPELL_FEL_RAGE_TARGET, true); + DoCast(target, SPELL_FEL_RAGE_2, true); + DoCast(target, SPELL_FEL_RAGE_3, true); + DoCast(target, SPELL_FEL_GEYSER, true); + DoCast(target, SPELL_FEL_RAGE_TARGET_2, true); + target->CastSpell(target, SPELL_FEL_RAGE_P, true); + target->CastSpell(target, SPELL_TAUNT_GURTOGG, true); + DoCastAOE(SPELL_INSIGNIFIGANCE, true); + + events.ScheduleEvent(EVENT_CHARGE_PLAYER, Seconds(2), GROUP_PHASE_2, PHASE_2); + + me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true); + me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, true); + } + else // If no other targets are found, reset phase 1 { - ModifyThreatByPercent(currentTarget, -100); - AttackStart(oldTarget); - AddThreat(oldTarget, _oldThreat); - Initialize(); + events.SetPhase(PHASE_1); + events.CancelEventGroup(GROUP_PHASE_2); + ScheduleEvents(); + events.RescheduleEvent(EVENT_CHANGE_PHASE, Seconds(60)); } + break; + case EVENT_CHARGE_PLAYER: + if (Unit* target = ObjectAccessor::GetUnit(*me, _targetGUID)) + DoCast(target, SPELL_CHARGE); + break; + case EVENT_EJECT_2: + DoCastVictim(SPELL_EJECT_2); + break; + case EVENT_FEL_ACID_BREATH_2: + DoCastVictim(SPELL_FEL_ACID_BREATH_2); + break; + case EVENT_ARCING_SMASH_2: + DoCastVictim(SPELL_ARCING_SMASH_2); + events.Repeat(Seconds(13)); + break; + case EVENT_BERSERK: + DoCast(SPELL_BERSERK); + roll_chance_i(50) ? Talk(SAY_ENRAGE) : DoPlaySoundToSet(me, SOUND_ID_ENRAGE); + break; + default: + break; } + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; } - private: - ObjectGuid _targetGUID; - ObjectGuid _oldTargetGUID; - float _oldThreat; - }; + DoMeleeAttackIfReady(); + } - CreatureAI* GetAI(Creature* creature) const override + void ChangePhase() { - return GetBlackTempleAI<boss_gurtogg_bloodboilAI>(creature); + if (events.IsInPhase(PHASE_1)) + { + events.SetPhase(PHASE_2); + events.CancelEventGroup(GROUP_PHASE_1); + events.ScheduleEvent(EVENT_CHANGE_PHASE, Seconds(30)); + ScheduleEvents(); + } + else if (events.IsInPhase(PHASE_2)) + { + events.SetPhase(PHASE_1); + events.CancelEventGroup(GROUP_PHASE_2); + events.ScheduleEvent(EVENT_CHANGE_PHASE, Seconds(60)); + me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, false); + me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, false); + ScheduleEvents(); + + // Attack the stored target + if (Unit* oldTarget = ObjectAccessor::GetUnit(*me, _oldTargetGUID)) + if (Unit* currentTarget = ObjectAccessor::GetUnit(*me, _targetGUID)) + { + ModifyThreatByPercent(currentTarget, -100); + AttackStart(oldTarget); + AddThreat(oldTarget, _oldThreat); + Initialize(); + } + } } + +private: + ObjectGuid _targetGUID; + ObjectGuid _oldTargetGUID; + float _oldThreat; }; -class npc_fel_geyser : public CreatureScript +struct npc_fel_geyser : public PassiveAI { -public: - npc_fel_geyser() : CreatureScript("npc_fel_geyser") { } - - struct npc_fel_geyserAI : public PassiveAI - { - npc_fel_geyserAI(Creature* creature) : PassiveAI(creature) { } - - void Reset() override - { - DoCastSelf(SPELL_FEL_GEYSER_2, true); - DoCastSelf(SPELL_BIRTH, true); - } - }; + npc_fel_geyser(Creature* creature) : PassiveAI(creature) { } - CreatureAI* GetAI(Creature* creature) const override + void Reset() override { - return GetBlackTempleAI<npc_fel_geyserAI>(creature); + DoCastSelf(SPELL_FEL_GEYSER_2, true); + DoCastSelf(SPELL_BIRTH, true); } }; // 42005 - Bloodboil -class spell_gurtogg_bloodboil_bloodboil : public SpellScriptLoader +class spell_gurtogg_bloodboil_bloodboil : public SpellScript { - public: - spell_gurtogg_bloodboil_bloodboil() : SpellScriptLoader("spell_gurtogg_bloodboil_bloodboil") { } - - class spell_gurtogg_bloodboil_bloodboil_SpellScript : public SpellScript - { - PrepareSpellScript(spell_gurtogg_bloodboil_bloodboil_SpellScript); - - void FilterTargets(std::list<WorldObject*>& targets) - { - if (targets.size() <= 5) - return; + PrepareSpellScript(spell_gurtogg_bloodboil_bloodboil); - // Sort the list of players - targets.sort(Trinity::ObjectDistanceOrderPred(GetCaster(), false)); - // Resize so we only get top 5 - targets.resize(5); - } + void FilterTargets(std::list<WorldObject*>& targets) + { + if (targets.size() <= 5) + return; - void Register() override - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_gurtogg_bloodboil_bloodboil_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); - } - }; + // Sort the list of players + targets.sort(Trinity::ObjectDistanceOrderPred(GetCaster(), false)); + // Resize so we only get top 5 + targets.resize(5); + } - SpellScript* GetSpellScript() const override - { - return new spell_gurtogg_bloodboil_bloodboil_SpellScript(); - } + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_gurtogg_bloodboil_bloodboil::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + } }; // 40618 - Insignificance -class spell_gurtogg_bloodboil_insignificance : public SpellScriptLoader +class spell_gurtogg_bloodboil_insignificance : public SpellScript { -public: - spell_gurtogg_bloodboil_insignificance() : SpellScriptLoader("spell_gurtogg_bloodboil_insignificance") { } + PrepareSpellScript(spell_gurtogg_bloodboil_insignificance); - class spell_gurtogg_bloodboil_insignificance_SpellScript : public SpellScript + bool Validate(SpellInfo const* /*spell*/) override { - PrepareSpellScript(spell_gurtogg_bloodboil_insignificance_SpellScript); - - bool Validate(SpellInfo const* /*spell*/) override - { - return ValidateSpellInfo({ SPELL_FEL_RAGE_TARGET }); - } - - void FilterTargets(std::list<WorldObject*>& targets) - { - targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_FEL_RAGE_TARGET)); - } + return ValidateSpellInfo({ SPELL_FEL_RAGE_TARGET }); + } - void Register() override - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_gurtogg_bloodboil_insignificance_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); - } - }; + void FilterTargets(std::list<WorldObject*>& targets) + { + targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_FEL_RAGE_TARGET)); + } - SpellScript* GetSpellScript() const override + void Register() override { - return new spell_gurtogg_bloodboil_insignificance_SpellScript(); + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_gurtogg_bloodboil_insignificance::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); } }; void AddSC_boss_gurtogg_bloodboil() { - new boss_gurtogg_bloodboil(); - new npc_fel_geyser(); - new spell_gurtogg_bloodboil_bloodboil(); - new spell_gurtogg_bloodboil_insignificance(); + RegisterBlackTempleCreatureAI(boss_gurtogg_bloodboil); + RegisterBlackTempleCreatureAI(npc_fel_geyser); + RegisterSpellScript(spell_gurtogg_bloodboil_bloodboil); + RegisterSpellScript(spell_gurtogg_bloodboil_insignificance); } diff --git a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp index fc6a92e203f..181a01f6745 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp @@ -159,6 +159,8 @@ enum IllidanSpells SPELL_DRAW_SOUL = 40904, SPELL_DRAW_SOUL_HEAL = 40903, SPELL_PARASITIC_SHADOWFIEND = 41917, + SPELL_PARASITIC_SHADOWFIEND_2 = 41914, + SPELL_REMOVE_PARASITIC_SHADOWFIEND = 41923, SPELL_AGONIZING_FLAMES = 40932, SPELL_AGONIZING_FLAMES_SELECTOR = 40834, SPELL_FRENZY = 40683, @@ -211,6 +213,7 @@ enum IllidanActions ACTION_FLAME_DEAD, ACTION_FINALIZE_AIR_PHASE, ACTION_START_PHASE_4, + ACTION_RESUME_COMBAT, ACTION_ILLIDAN_CAGED, ACTION_START_OUTRO, ACTION_MAIEV_DOWN_FADE @@ -404,6 +407,12 @@ Position const IllidanDBTargetPoints[4] = { 660.3492f, 345.5749f, 353.2961f } }; +Position const BladesPositions[2] = +{ + { 676.226013f, 325.230988f }, + { 678.059998f, 285.220001f } +}; + uint32 const SummonCageTrapSpells[8] = { SPELL_SUMMON_CAGE_TRAP_1, @@ -435,2118 +444,1880 @@ private: class ChargeTargetSelector : public std::unary_function<Unit*, bool> { public: - ChargeTargetSelector(Unit const* unit) : _me(unit) { } + ChargeTargetSelector() { } bool operator()(Unit* unit) const { - return unit->GetTypeId() == TYPEID_PLAYER && _me->GetDistance2d(unit) > 25.0f; + return unit->GetTypeId() == TYPEID_PLAYER + && unit->GetDistance2d(BladesPositions[0].GetPositionX(), BladesPositions[0].GetPositionY()) > 25.0f + && unit->GetDistance2d(BladesPositions[1].GetPositionX(), BladesPositions[1].GetPositionY()) > 25.0f; } - -private: - Unit const* _me; }; -class boss_illidan_stormrage : public CreatureScript +struct boss_illidan_stormrage : public BossAI { -public: - boss_illidan_stormrage() : CreatureScript("boss_illidan_stormrage") { } + boss_illidan_stormrage(Creature* creature) : BossAI(creature, DATA_ILLIDAN_STORMRAGE), + _minionsCount(0), _flameCount(0), _orientation(0.0f), _pillarIndex(0), _phase(0), _dead(false), _isDemon(false) { } + + void Reset() override + { + _Reset(); + specialEvents.Reset(); + me->SummonCreatureGroup(SUMMON_GROUP); + me->LoadEquipment(1, true); + me->SetSheath(SHEATH_STATE_UNARMED); + me->SetControlled(false, UNIT_STATE_ROOT); + me->SetDisableGravity(false); + _dead = false; + _minionsCount = 0; + _flameCount = 0; + _phase = PHASE_1; + _isDemon = false; + if (instance->GetData(DATA_AKAMA_ILLIDAN_INTRO) && instance->GetBossState(DATA_ILLIDARI_COUNCIL) == DONE) + if (Creature* akama = instance->GetCreature(DATA_AKAMA)) + akama->AI()->DoAction(ACTION_ACTIVE_AKAMA_INTRO); + } + + void EnterCombat(Unit* /*who*/) override + { + _EnterCombat(); + me->SetCanDualWield(true); + if (GameObject* musicController = instance->GetGameObject(DATA_ILLIDAN_MUSIC_CONTROLLER)) + musicController->PlayDirectMusic(EVENT_BT_SUMMIT_WALK_3_SOUND_ID); + specialEvents.ScheduleEvent(EVENT_EVADE_CHECK, Seconds(10)); + specialEvents.ScheduleEvent(EVENT_BERSERK, Minutes(25)); + ScheduleEvents(GROUP_PHASE_1, GROUP_PHASE_1); + events.ScheduleEvent(EVENT_TAUNT, Seconds(30), Seconds(60), GROUP_PHASE_ALL); + } + + void JustSummoned(Creature* summon) override + { + if (summon->GetEntry() == NPC_PARASITIC_SHADOWFIEND) + summons.Summon(summon); + else + BossAI::JustSummoned(summon); + } - struct boss_illidan_stormrageAI : public BossAI + void ChangeOrientation(float orientation) { - boss_illidan_stormrageAI(Creature* creature) : BossAI(creature, DATA_ILLIDAN_STORMRAGE), - _intro(true), _minionsCount(0), _flameCount(0), _orientation(0.0f), _pillarIndex(0), _phase(0), _dead(false), _isDemon(false) { } + _orientation = orientation; + events.ScheduleEvent(EVENT_CHANGE_ORIENTATION, Milliseconds(1), GROUP_PHASE_ALL); + } + + void KilledUnit(Unit* victim) override + { + if (victim->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_ILLIDAN_KILL); + } + + void ScheduleEvents(uint8 phase, uint8 group) + { + switch (phase) + { + case GROUP_PHASE_1: + events.ScheduleEvent(EVENT_FLAME_CRASH, Seconds(30), group); + events.ScheduleEvent(EVENT_DRAW_SOUL, Seconds(34), group); + events.ScheduleEvent(EVENT_SHEAR, Seconds(10), group); + events.ScheduleEvent(EVENT_PARASITIC_SHADOWFIEND, Seconds(26), group); + break; + case GROUP_PHASE_2: + events.ScheduleEvent(EVENT_FIREBALL, Seconds(1), Seconds(8), group); + events.ScheduleEvent(EVENT_EYE_BLAST, Seconds(1), Seconds(30), group); + if (roll_chance_i(50)) + events.ScheduleEvent(EVENT_DARK_BARRAGE, Seconds(1), Seconds(20), group); + break; + case GROUP_PHASE_3: + ScheduleEvents(GROUP_PHASE_1, group); + events.ScheduleEvent(EVENT_AGONIZING_FLAMES, Seconds(21), group); + events.ScheduleEvent(EVENT_DEMON, Seconds(60), group); + break; + case GROUP_PHASE_DEMON: + events.ScheduleEvent(EVENT_SHADOW_BLAST, Seconds(1), group); + events.ScheduleEvent(EVENT_FLAME_BURST, Seconds(6), group); + events.ScheduleEvent(EVENT_SHADOW_DEMON, Seconds(18), Seconds(30), group); + break; + case GROUP_PHASE_4: + ScheduleEvents(GROUP_PHASE_3, group); + events.ScheduleEvent(EVENT_FRENZY, Seconds(40), group); + break; + default: + break; + } + } - void Reset() override + void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) override + { + if (summon->GetEntry() == NPC_ILLIDARI_ELITE) + _minionsCount--; + } + + void EnterEvadeMode(EvadeReason /*why*/) override + { + summons.DespawnAll(); + specialEvents.Reset(); + _DespawnAtEvade(); + } + + void DoAction(int32 actionId) override + { + switch (actionId) { - _Reset(); - specialEvents.Reset(); - me->SummonCreatureGroup(SUMMON_GROUP); - me->LoadEquipment(1, true); - me->SetSheath(SHEATH_STATE_UNARMED); - me->SetControlled(false, UNIT_STATE_ROOT); - me->SetDisableGravity(false); - _dead = false; - _minionsCount = 0; - _flameCount = 0; - _phase = PHASE_1; - _isDemon = false; - if (_intro && instance->GetBossState(DATA_ILLIDARI_COUNCIL) == DONE) + case ACTION_START_ENCOUNTER: + events.SetPhase(PHASE_INTRO); + me->RemoveAurasDueToSpell(SPELL_KNEEL); + events.ScheduleEvent(EVENT_START_INTRO, Seconds(2), GROUP_PHASE_ALL); + events.ScheduleEvent(EVENT_UNCONVINCED, Seconds(24), GROUP_PHASE_ALL); + if (Creature* akama = instance->GetCreature(DATA_AKAMA)) + akama->AI()->DoAction(ACTION_FREE); + break; + case ACTION_INTRO_DONE: + instance->SetData(DATA_AKAMA_ILLIDAN_INTRO, 0); + break; + case ACTION_START_MINIONS: + Talk(SAY_ILLIDAN_MINION); if (Creature* akama = instance->GetCreature(DATA_AKAMA)) - akama->AI()->DoAction(ACTION_ACTIVE_AKAMA_INTRO); + akama->AI()->DoAction(ACTION_START_MINIONS); + break; + case ACTION_START_MINIONS_WEAVE: + events.ScheduleEvent(EVENT_MINIONS_WEAVE, Milliseconds(1), GROUP_PHASE_ALL); + break; + case ACTION_START_PHASE_2: + { + me->SetReactState(REACT_PASSIVE); + me->AttackStop(); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); + me->SetDisableGravity(true); + DoPlaySoundToSet(me, ILLIDAN_TAKEOFF_SOUND_ID); + events.ScheduleEvent(EVENT_FLY, Seconds(1), GROUP_PHASE_ALL); + events.CancelEventGroup(GROUP_PHASE_1); + break; + } + case ACTION_FLAME_DEAD: + _flameCount++; + if (_flameCount == 2) + { + _flameCount = 0; + DoAction(ACTION_FINALIZE_AIR_PHASE); + } + break; + case ACTION_FINALIZE_AIR_PHASE: + me->InterruptNonMeleeSpells(false); + me->GetMotionMaster()->Clear(); + events.CancelEventGroup(GROUP_PHASE_2); + _phase = PHASE_3; + events.CancelEvent(EVENT_FLY_TO_RANDOM_PILLAR); + me->GetMotionMaster()->MovePoint(POINT_ILLIDAN_MIDDLE, IllidanMiddlePoint); + break; + case ACTION_START_PHASE_4: + events.CancelEventGroup(GROUP_PHASE_3); + DoCastSelf(SPELL_SHADOW_PRISON, true); + summons.DoAction(ACTION_START_PHASE_4, EntryCheckPredicate(NPC_PARASITIC_SHADOWFIEND)); + me->SetReactState(REACT_PASSIVE); + me->AttackStop(); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + events.ScheduleEvent(EVENT_SHADOW_PRISON_TEXT, Milliseconds(500), GROUP_PHASE_ALL); + break; + case ACTION_ILLIDAN_CAGED: + for (uint32 summonSpell : SummonCageTrapSpells) + DoCastSelf(summonSpell, true); + DoCastSelf(SPELL_CAGE_TRAP, true); + break; + case ACTION_START_OUTRO: + me->AttackStop(); + events.Reset(); + specialEvents.Reset(); + DoCastSelf(SPELL_DEATH, true); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + events.ScheduleEvent(EVENT_DEFEATED_TEXT, Seconds(4)); + break; + default: + break; } + } + + void JustDied(Unit* /*killer*/) override + { + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + instance->SetBossState(DATA_ILLIDAN_STORMRAGE, DONE); + events.Reset(); + } - void EnterCombat(Unit* /*who*/) override + void MovementInform(uint32 type, uint32 pointId) override + { + if (type != POINT_MOTION_TYPE && type != EFFECT_MOTION_TYPE) + return; + + switch (pointId) { - _EnterCombat(); - me->SetCanDualWield(true); - if (GameObject* musicController = instance->GetGameObject(DATA_ILLIDAN_MUSIC_CONTROLLER)) - musicController->PlayDirectMusic(EVENT_BT_SUMMIT_WALK_3_SOUND_ID); - specialEvents.ScheduleEvent(EVENT_EVADE_CHECK, Seconds(10)); - specialEvents.ScheduleEvent(EVENT_BERSERK, Minutes(25)); - ScheduleEvents(GROUP_PHASE_1, GROUP_PHASE_1); - events.ScheduleEvent(EVENT_TAUNT, Seconds(30), Seconds(60), GROUP_PHASE_ALL); + case POINT_THROW_GLAIVE: + DoPlaySoundToSet(me, ILLIDAN_WARGLAIVE_SOUND_ID); + events.ScheduleEvent(EVENT_THROW_WARGLAIVE, Seconds(2), GROUP_PHASE_ALL); + events.ScheduleEvent(EVENT_FACE_MIDDLE, Milliseconds(1), GROUP_PHASE_ALL); + break; + case POINT_RANDOM_PILLAR: + { + float orientation = IllidanPhase2Positions[_pillarIndex].GetOrientation(); + ChangeOrientation(orientation); + ScheduleEvents(GROUP_PHASE_2, GROUP_PHASE_2); + break; + } + case POINT_ILLIDAN_MIDDLE: + { + float orientation = IllidanMiddlePoint.GetOrientation(); + ChangeOrientation(orientation); + + std::list<Creature*> triggers; + GetCreatureListWithEntryInGrid(triggers, me, NPC_BLADE_OF_AZZINOTH, 150.0f); + for (Creature* trigger : triggers) + trigger->CastSpell(trigger, SPELL_GLAIVE_RETURNS, true); + + events.ScheduleEvent(EVENT_GLAIVE_EMOTE, Seconds(3), GROUP_PHASE_ALL); + break; + } + default: + break; } + } + + void EnterEvadeModeIfNeeded() + { + Map::PlayerList const& players = me->GetMap()->GetPlayers(); + for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i) + if (Player* player = i->GetSource()) + if (player->IsAlive() && !player->IsGameMaster() && CheckBoundary(player)) + return; - void ChangeOrientation(float orientation) + EnterEvadeMode(EVADE_REASON_NO_HOSTILES); + } + + void SummonMinions() + { + uint8 needSummon = MAX_MINIONS_NUMBER - _minionsCount; + for (uint8 i = 0; i < needSummon; ++i) { - _orientation = orientation; - events.ScheduleEvent(EVENT_CHANGE_ORIENTATION, Milliseconds(1), GROUP_PHASE_ALL); + _minionsCount++; + me->SummonCreature(NPC_ILLIDARI_ELITE, MinionsSpawnPositions[i], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 6000); } + } - void KilledUnit(Unit* victim) override + void DamageTaken(Unit* who, uint32 &damage) override + { + + if (damage >= me->GetHealth() && who->GetGUID() != me->GetGUID()) { - if (victim->GetTypeId() == TYPEID_PLAYER) - Talk(SAY_ILLIDAN_KILL); + damage = me->GetHealth() - 1; + if (!_dead) + { + if (_isDemon) + { + events.Reset(); + specialEvents.Reset(); + DoCastSelf(SPELL_DEMON_TRANSFORM_1); + return; + } + _dead = true; + summons.DespawnEntry(NPC_PARASITIC_SHADOWFIEND); + DoCastSelf(SPELL_REMOVE_PARASITIC_SHADOWFIEND, true); + DoAction(ACTION_START_OUTRO); + if (Creature* maiev = instance->GetCreature(DATA_MAIEV)) + maiev->AI()->DoAction(ACTION_START_OUTRO); + } + } + else if (me->HealthBelowPct(90) && _phase < PHASE_MINIONS) + { + _phase = PHASE_MINIONS; + DoAction(ACTION_START_MINIONS); + } + else if (me->HealthBelowPct(65) && _phase < PHASE_2) + { + _phase = PHASE_2; + DoAction(ACTION_START_PHASE_2); } + else if (me->HealthBelowPct(30) && _phase < PHASE_4) + { + _phase = PHASE_4; - void ScheduleEvents(uint8 phase, uint8 group) + if (_isDemon) + { + _isDemon = false; + me->SetControlled(false, UNIT_STATE_ROOT); + events.CancelEventGroup(GROUP_PHASE_DEMON); + me->InterruptNonMeleeSpells(false); + DoCastSelf(SPELL_DEMON_TRANSFORM_1, true); + events.ScheduleEvent(EVENT_PHASE_4_DELAYED, Seconds(12), GROUP_PHASE_ALL); + } + else + DoAction(ACTION_START_PHASE_4); + } + } + + void ExecuteSpecialEvents() + { + while (uint32 eventId = specialEvents.ExecuteEvent()) { - switch (phase) + switch (eventId) { - case GROUP_PHASE_1: - events.ScheduleEvent(EVENT_FLAME_CRASH, Seconds(30), group); - events.ScheduleEvent(EVENT_DRAW_SOUL, Seconds(34), group); - events.ScheduleEvent(EVENT_SHEAR, Seconds(10), group); - events.ScheduleEvent(EVENT_PARASITIC_SHADOWFIEND, Seconds(26), group); - break; - case GROUP_PHASE_2: - events.ScheduleEvent(EVENT_FIREBALL, Seconds(1), Seconds(8), group); - events.ScheduleEvent(EVENT_EYE_BLAST, Seconds(1), Seconds(30), group); - if (roll_chance_i(50)) - events.ScheduleEvent(EVENT_DARK_BARRAGE, Seconds(1), Seconds(20), group); - break; - case GROUP_PHASE_3: - ScheduleEvents(GROUP_PHASE_1, group); - events.ScheduleEvent(EVENT_AGONIZING_FLAMES, Seconds(21), group); - events.ScheduleEvent(EVENT_DEMON, Seconds(60), group); - break; - case GROUP_PHASE_DEMON: - events.ScheduleEvent(EVENT_SHADOW_BLAST, Seconds(1), group); - events.ScheduleEvent(EVENT_FLAME_BURST, Seconds(6), group); - events.ScheduleEvent(EVENT_SHADOW_DEMON, Seconds(18), Seconds(30), group); - break; - case GROUP_PHASE_4: - ScheduleEvents(GROUP_PHASE_3, group); - events.ScheduleEvent(EVENT_FRENZY, Seconds(40), group); + case EVENT_BERSERK: + Talk(SAY_ILLIDAN_ENRAGE); + DoCastSelf(SPELL_BERSERK, true); + break; + case EVENT_CANCEL_DEMON_FORM: + me->InterruptNonMeleeSpells(false); + me->SetControlled(false, UNIT_STATE_ROOT); + events.CancelEventGroup(GROUP_PHASE_DEMON); + DoCastSelf(SPELL_DEMON_TRANSFORM_1, true); + events.ScheduleEvent(EVENT_RESUME_COMBAT_DEMON, Seconds(12), GROUP_PHASE_ALL); + _isDemon = false; + break; + case EVENT_EVADE_CHECK: + EnterEvadeModeIfNeeded(); + specialEvents.Repeat(Seconds(10)); break; default: break; } } + } - void JustSummoned(Creature* summon) override - { - BossAI::JustSummoned(summon); - if (summon->GetEntry() == NPC_ILLIDARI_ELITE) - if (Creature* akama = instance->GetCreature(DATA_AKAMA)) - AddThreat(akama, 1000.0f, summon); - } + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim() && !events.IsInPhase(PHASE_INTRO)) + return; - void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) override - { - if (summon->GetEntry() == NPC_ILLIDARI_ELITE) - _minionsCount--; - } + specialEvents.Update(diff); - void EnterEvadeMode(EvadeReason /*why*/) override - { - summons.DespawnAll(); - specialEvents.Reset(); - _DespawnAtEvade(); - } + ExecuteSpecialEvents(); - void DoAction(int32 actionId) override + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + events.Update(diff); + + while (uint32 eventId = events.ExecuteEvent()) { - switch (actionId) + switch (eventId) { - case ACTION_START_ENCOUNTER: - events.SetPhase(PHASE_INTRO); - me->RemoveAurasDueToSpell(SPELL_KNEEL); - events.ScheduleEvent(EVENT_START_INTRO, Seconds(2), GROUP_PHASE_ALL); - events.ScheduleEvent(EVENT_UNCONVINCED, Seconds(24), GROUP_PHASE_ALL); - if (Creature* akama = instance->GetCreature(DATA_AKAMA)) - akama->AI()->DoAction(ACTION_FREE); + case EVENT_START_INTRO: + Talk(SAY_ILLIDAN_DUPLICITY); + break; + case EVENT_UNCONVINCED: + Talk(SAY_ILLIDAN_UNCONVINCED); + events.ScheduleEvent(EVENT_PREPARED, Seconds(14), GROUP_PHASE_ALL); break; - case ACTION_INTRO_DONE: - _intro = false; + case EVENT_PREPARED: + Talk(SAY_ILLIDAN_PREPARED); + me->SetSheath(SHEATH_STATE_MELEE); + events.ScheduleEvent(EVENT_ENCOUNTER_START, Seconds(3), GROUP_PHASE_ALL); break; - case ACTION_START_MINIONS: - Talk(SAY_ILLIDAN_MINION); + case EVENT_ENCOUNTER_START: + me->SetImmuneToAll(false); + DoZoneInCombat(); if (Creature* akama = instance->GetCreature(DATA_AKAMA)) - akama->AI()->DoAction(ACTION_START_MINIONS); + akama->AI()->DoAction(ACTION_START_ENCOUNTER); break; - case ACTION_START_MINIONS_WEAVE: - events.ScheduleEvent(EVENT_MINIONS_WEAVE, Milliseconds(1), GROUP_PHASE_ALL); + case EVENT_FLAME_CRASH: + DoCastVictim(SPELL_FLAME_CRASH); + events.Repeat(Seconds(30)); break; - case ACTION_START_PHASE_2: - { - me->SetReactState(REACT_PASSIVE); - me->AttackStop(); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); - me->SetDisableGravity(true); - DoPlaySoundToSet(me, ILLIDAN_TAKEOFF_SOUND_ID); - events.ScheduleEvent(EVENT_FLY, Seconds(1), GROUP_PHASE_ALL); - events.CancelEventGroup(GROUP_PHASE_1); + case EVENT_DRAW_SOUL: + DoCastAOE(SPELL_DRAW_SOUL); + events.Repeat(Seconds(34)); break; - } - case ACTION_FLAME_DEAD: - _flameCount++; - if (_flameCount == 2) - { - _flameCount = 0; - DoAction(ACTION_FINALIZE_AIR_PHASE); - } + case EVENT_SHEAR: + DoCastVictim(SPELL_SHEAR); + events.Repeat(Seconds(12)); break; - case ACTION_FINALIZE_AIR_PHASE: - me->InterruptNonMeleeSpells(false); - me->GetMotionMaster()->Clear(); - events.CancelEventGroup(GROUP_PHASE_2); - _phase = PHASE_3; - events.CancelEvent(EVENT_FLY_TO_RANDOM_PILLAR); - me->GetMotionMaster()->MovePoint(POINT_ILLIDAN_MIDDLE, IllidanMiddlePoint); + case EVENT_PARASITIC_SHADOWFIEND: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) + DoCast(target, SPELL_PARASITIC_SHADOWFIEND); + events.Repeat(Seconds(30)); break; - case ACTION_START_PHASE_4: - events.CancelEventGroup(GROUP_PHASE_3); - DoCastSelf(SPELL_SHADOW_PRISON, true); - me->SetReactState(REACT_PASSIVE); - me->AttackStop(); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - events.ScheduleEvent(EVENT_SHADOW_PRISON_TEXT, Milliseconds(500), GROUP_PHASE_ALL); + case EVENT_MINIONS_WEAVE: + if (_dead) + return; + SummonMinions(); + events.Repeat(Seconds(30)); break; - case ACTION_ILLIDAN_CAGED: - for (uint32 summonSpell : SummonCageTrapSpells) - DoCastSelf(summonSpell, true); - DoCastSelf(SPELL_CAGE_TRAP, true); + case EVENT_MOVE_TO_WARGLAIVE_POINT: + { + Position pos; + std::list<Creature*> triggers; + GetCreatureListWithEntryInGrid(triggers, me, NPC_GLAIVE_WORLD_TRIGGER, 150.0f); + triggers.remove_if([](WorldObject* unit) + { + return unit->GetPositionZ() < 355.0f || unit->GetPositionZ() > 365.0f; + }); + + if (triggers.empty()) + break; + + triggers.sort(Trinity::ObjectDistanceOrderPred(me)); + pos.Relocate(triggers.front()); + pos.SetOrientation(0.0f); + me->GetMotionMaster()->MovePoint(POINT_THROW_GLAIVE, pos); + if (GameObject* musicController = instance->GetGameObject(DATA_ILLIDAN_MUSIC_CONTROLLER)) + musicController->PlayDirectMusic(EVENT_BT_STORM_WALK_HERO_2_SOUND_ID); break; - case ACTION_START_OUTRO: - me->AttackStop(); - events.Reset(); - specialEvents.Reset(); - DoCastSelf(SPELL_DEATH, true); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - events.ScheduleEvent(EVENT_DEFEATED_TEXT, Seconds(4)); + } + case EVENT_THROW_WARGLAIVE: + DoCastAOE(SPELL_THROW_GLAIVE); + events.ScheduleEvent(EVENT_THROW_WARGLAIVE_2, Seconds(1), GROUP_PHASE_ALL); break; - default: + case EVENT_THROW_WARGLAIVE_2: + DoCastAOE(SPELL_THROW_GLAIVE2); + me->SetSheath(SHEATH_STATE_UNARMED); + events.ScheduleEvent(EVENT_FLY_TO_RANDOM_PILLAR, Seconds(2), GROUP_PHASE_ALL); break; - } - } - - void JustDied(Unit* /*killer*/) override - { - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - instance->SetBossState(DATA_ILLIDAN_STORMRAGE, DONE); - events.Reset(); - } - - void MovementInform(uint32 type, uint32 pointId) override - { - if (type != POINT_MOTION_TYPE && type != EFFECT_MOTION_TYPE) - return; - - switch (pointId) - { - case POINT_THROW_GLAIVE: - DoPlaySoundToSet(me, ILLIDAN_WARGLAIVE_SOUND_ID); - events.ScheduleEvent(EVENT_THROW_WARGLAIVE, Seconds(2), GROUP_PHASE_ALL); - events.ScheduleEvent(EVENT_FACE_MIDDLE, Milliseconds(1), GROUP_PHASE_ALL); + case EVENT_CHANGE_ORIENTATION: + me->SetFacingTo(_orientation); break; - case POINT_RANDOM_PILLAR: + case EVENT_FLY: + ChangeOrientation(3.137039f); + events.ScheduleEvent(EVENT_MOVE_TO_WARGLAIVE_POINT, Seconds(6), GROUP_PHASE_ALL); + break; + case EVENT_FLY_TO_RANDOM_PILLAR: { - float orientation = IllidanPhase2Positions[_pillarIndex].GetOrientation(); - ChangeOrientation(orientation); - ScheduleEvents(GROUP_PHASE_2, GROUP_PHASE_2); + events.CancelEventGroup(GROUP_PHASE_2); + _pillarIndex = urand(0, 3); + me->GetMotionMaster()->MovePoint(POINT_RANDOM_PILLAR, IllidanPhase2Positions[_pillarIndex]); + events.Repeat(Seconds(30)); break; } - case POINT_ILLIDAN_MIDDLE: + case EVENT_FACE_MIDDLE: { - float orientation = IllidanMiddlePoint.GetOrientation(); - ChangeOrientation(orientation); - - std::list<Creature*> triggers; - GetCreatureListWithEntryInGrid(triggers, me, NPC_BLADE_OF_AZZINOTH, 150.0f); - for (Creature* trigger : triggers) - trigger->CastSpell(trigger, SPELL_GLAIVE_RETURNS, true); - - events.ScheduleEvent(EVENT_GLAIVE_EMOTE, Seconds(3), GROUP_PHASE_ALL); + float angle = me->GetAngle(IllidanMiddlePoint); + me->SetFacingTo(angle); break; } - default: - break; - } - } - - void EnterEvadeModeIfNeeded() - { - Map::PlayerList const& players = me->GetMap()->GetPlayers(); - for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i) - if (Player* player = i->GetSource()) - if (player->IsAlive() && !player->IsGameMaster() && CheckBoundary(player)) - return; - - EnterEvadeMode(EVADE_REASON_NO_HOSTILES); - } - - void SummonMinions() - { - uint8 needSummon = MAX_MINIONS_NUMBER - _minionsCount; - for (uint8 i = 0; i < needSummon; ++i) - { - _minionsCount++; - me->SummonCreature(NPC_ILLIDARI_ELITE, MinionsSpawnPositions[i], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 6000); - } - } - - void DamageTaken(Unit* who, uint32 &damage) override - { - - if (damage >= me->GetHealth() && who->GetGUID() != me->GetGUID()) - { - damage = me->GetHealth() - 1; - if (!_dead) + case EVENT_EYE_BLAST: { - if (_isDemon) + events.CancelEvent(EVENT_DARK_BARRAGE); + Position pos = IllidanDBTargetSpawnPositions[_pillarIndex]; + if (TempSummon* dbTarget = me->SummonCreature(NPC_ILLIDAN_DB_TARGET, pos, TEMPSUMMON_MANUAL_DESPAWN)) { - events.Reset(); - specialEvents.Reset(); - DoCastSelf(SPELL_DEMON_TRANSFORM_1); - return; + Talk(SAY_ILLIDAN_EYE_BLAST); + DoCast(dbTarget, SPELL_EYE_BLAST); + dbTarget->GetMotionMaster()->MovePoint(POINT_DB_TARGET, IllidanDBTargetPoints[_pillarIndex]); } - _dead = true; - DoAction(ACTION_START_OUTRO); - if (Creature* maiev = instance->GetCreature(DATA_MAIEV)) - maiev->AI()->DoAction(ACTION_START_OUTRO); + break; } - } - else if (me->HealthBelowPct(90) && _phase < PHASE_MINIONS) - { - _phase = PHASE_MINIONS; - DoAction(ACTION_START_MINIONS); - } - else if (me->HealthBelowPct(65) && _phase < PHASE_2) - { - _phase = PHASE_2; - DoAction(ACTION_START_PHASE_2); - } - else if (me->HealthBelowPct(30) && _phase < PHASE_4) - { - _phase = PHASE_4; - - if (_isDemon) + case EVENT_DARK_BARRAGE: { - _isDemon = false; - me->SetControlled(false, UNIT_STATE_ROOT); - events.CancelEventGroup(GROUP_PHASE_DEMON); - me->InterruptNonMeleeSpells(false); + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 150.0f, true)) + DoCast(target, SPELL_DARK_BARRAGE); + events.RescheduleEvent(EVENT_EYE_BLAST, Seconds(5), GROUP_PHASE_2); + uint32 currentTime = events.GetNextEventTime(EVENT_FLY_TO_RANDOM_PILLAR); + events.RescheduleEvent(EVENT_FLY_TO_RANDOM_PILLAR, Seconds(currentTime) + Seconds(30), GROUP_PHASE_2); + break; + } + case EVENT_FIREBALL: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 150.0f, true)) + DoCast(target, SPELL_FIREBALL); + events.Repeat(Seconds(2), Seconds(4)); + break; + case EVENT_GLAIVE_EMOTE: + me->SetDisableGravity(false); + me->HandleEmoteCommand(EMOTE_ONESHOT_LAND); + me->SetSheath(SHEATH_STATE_MELEE); + events.ScheduleEvent(EVENT_RESUME_COMBAT, Seconds(3), GROUP_PHASE_ALL); + break; + case EVENT_RESUME_COMBAT: + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + me->SetReactState(REACT_AGGRESSIVE); + ScheduleEvents(GROUP_PHASE_3, GROUP_PHASE_3); + if (GameObject* musicController = instance->GetGameObject(DATA_ILLIDAN_MUSIC_CONTROLLER)) + musicController->PlayDirectMusic(EVENT_BT_STORM_WALK_UNI_3_SOUND_ID); + break; + case EVENT_AGONIZING_FLAMES: + DoCastSelf(SPELL_AGONIZING_FLAMES_SELECTOR); + events.Repeat(Seconds(53)); + break; + case EVENT_DEMON: + me->SetControlled(true, UNIT_STATE_ROOT); + _isDemon = true; + events.CancelEventGroup(_phase == PHASE_3 ? GROUP_PHASE_3 : GROUP_PHASE_4); + me->LoadEquipment(0, true); DoCastSelf(SPELL_DEMON_TRANSFORM_1, true); - events.ScheduleEvent(EVENT_PHASE_4_DELAYED, Seconds(12), GROUP_PHASE_ALL); + events.ScheduleEvent(EVENT_DEMON_TEXT, Seconds(2), GROUP_PHASE_ALL); + specialEvents.ScheduleEvent(EVENT_CANCEL_DEMON_FORM, Minutes(1) + Seconds(12)); + events.ScheduleEvent(EVENT_SCHEDULE_DEMON_SPELLS, Seconds(15)); + break; + case EVENT_SCHEDULE_DEMON_SPELLS: + ResetThreatList(); + ScheduleEvents(GROUP_PHASE_DEMON, GROUP_PHASE_DEMON); + break; + case EVENT_DEMON_TEXT: + Talk(SAY_ILLIDAN_MORPH); + break; + case EVENT_RESUME_COMBAT_DEMON: + { + uint8 group = _phase == PHASE_3 ? GROUP_PHASE_3 : GROUP_PHASE_4; + ResetThreatList(); + ScheduleEvents(group, group); + me->LoadEquipment(1, true); + break; } - else + case EVENT_FLAME_BURST: + DoCastSelf(SPELL_FLAME_BURST); + events.Repeat(Seconds(22)); + break; + case EVENT_SHADOW_DEMON: + DoCastSelf(SPELL_SUMMON_SHADOWDEMON); + break; + case EVENT_SHADOW_BLAST: + DoCastVictim(SPELL_SHADOW_BLAST); + events.Repeat(Seconds(2)); + break; + case EVENT_PHASE_4_DELAYED: DoAction(ACTION_START_PHASE_4); - } - } - - void ExecuteSpecialEvents() - { - while (uint32 eventId = specialEvents.ExecuteEvent()) - { - switch (eventId) + break; + case EVENT_SHADOW_PRISON_TEXT: + Talk(SAY_ILLIDAN_SHADOW_PRISON); + events.ScheduleEvent(EVENT_SUMMON_MAIEV, Seconds(9), GROUP_PHASE_ALL); + break; + case EVENT_SUMMON_MAIEV: + DoCastSelf(SPELL_SUMMON_MAIEV); + if (Creature* maiev = instance->GetCreature(DATA_MAIEV)) + me->SetFacingToObject(maiev); + events.ScheduleEvent(EVENT_CONFRONT_MAIEV_TEXT, Seconds(9), GROUP_PHASE_ALL); + break; + case EVENT_CONFRONT_MAIEV_TEXT: + Talk(SAY_ILLIDAN_CONFRONT_MAIEV); + events.ScheduleEvent(EVENT_RESUME_COMBAT_PHASE_4, Seconds(13), GROUP_PHASE_ALL); + break; + case EVENT_RESUME_COMBAT_PHASE_4: + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + me->SetReactState(REACT_AGGRESSIVE); + ScheduleEvents(GROUP_PHASE_4, GROUP_PHASE_4); + summons.DoAction(ACTION_RESUME_COMBAT, EntryCheckPredicate(NPC_PARASITIC_SHADOWFIEND)); + break; + case EVENT_FRENZY: + DoCastSelf(SPELL_FRENZY); + Talk(SAY_ILLIDAN_FRENZY); + events.Repeat(Seconds(40)); + break; + case EVENT_TAUNT: + Talk(SAY_ILLIDAN_TAUNT); + events.Repeat(Seconds(30), Seconds(60)); + break; + case EVENT_DEFEATED_TEXT: + Talk(SAY_ILLIDAN_DEFEATED); + if (GameObject* musicController = instance->GetGameObject(DATA_ILLIDAN_MUSIC_CONTROLLER)) + musicController->PlayDirectMusic(EVENT_BT_ARRIVAL_WALK_HERO_1_SOUND_ID); + events.ScheduleEvent(EVENT_QUIET_SUICIDE, Seconds(18)); + break; + case EVENT_QUIET_SUICIDE: { - case EVENT_BERSERK: - Talk(SAY_ILLIDAN_ENRAGE); - DoCastSelf(SPELL_BERSERK, true); - break; - case EVENT_CANCEL_DEMON_FORM: - me->InterruptNonMeleeSpells(false); - me->SetControlled(false, UNIT_STATE_ROOT); - events.CancelEventGroup(GROUP_PHASE_DEMON); - DoCastSelf(SPELL_DEMON_TRANSFORM_1, true); - events.ScheduleEvent(EVENT_RESUME_COMBAT_DEMON, Seconds(12), GROUP_PHASE_ALL); - _isDemon = false; - break; - case EVENT_EVADE_CHECK: - EnterEvadeModeIfNeeded(); - specialEvents.Repeat(Seconds(10)); - break; - default: - break; + DoCastSelf(SPELL_QUIET_SUICIDE, true); + if (Creature* akama = instance->GetCreature(DATA_AKAMA)) + akama->AI()->DoAction(ACTION_START_OUTRO); + ObjectGuid _akamaGUID = instance->GetGuidData(DATA_AKAMA); + ObjectGuid _maievGUID = instance->GetGuidData(DATA_MAIEV); + summons.DespawnIf([_akamaGUID, _maievGUID](ObjectGuid unitGuid) + { + return unitGuid != _akamaGUID && unitGuid != _maievGUID; + }); + break; } + default: + break; } - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim() && !events.IsInPhase(PHASE_INTRO)) - return; - - specialEvents.Update(diff); - - ExecuteSpecialEvents(); if (me->HasUnitState(UNIT_STATE_CASTING)) return; + } - events.Update(diff); + DoMeleeAttackIfReady(); + } - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_START_INTRO: - Talk(SAY_ILLIDAN_DUPLICITY); - break; - case EVENT_UNCONVINCED: - Talk(SAY_ILLIDAN_UNCONVINCED); - events.ScheduleEvent(EVENT_PREPARED, Seconds(14), GROUP_PHASE_ALL); - break; - case EVENT_PREPARED: - Talk(SAY_ILLIDAN_PREPARED); - me->SetSheath(SHEATH_STATE_MELEE); - events.ScheduleEvent(EVENT_ENCOUNTER_START, Seconds(3), GROUP_PHASE_ALL); - break; - case EVENT_ENCOUNTER_START: - me->SetImmuneToAll(false); - DoZoneInCombat(); - if (Creature* akama = instance->GetCreature(DATA_AKAMA)) - akama->AI()->DoAction(ACTION_START_ENCOUNTER); - break; - case EVENT_FLAME_CRASH: - DoCastVictim(SPELL_FLAME_CRASH); - events.Repeat(Seconds(30)); - break; - case EVENT_DRAW_SOUL: - DoCastAOE(SPELL_DRAW_SOUL); - events.Repeat(Seconds(34)); - break; - case EVENT_SHEAR: - DoCastVictim(SPELL_SHEAR); - events.Repeat(Seconds(12)); - break; - case EVENT_PARASITIC_SHADOWFIEND: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1)) - DoCast(target, SPELL_PARASITIC_SHADOWFIEND); - events.Repeat(Seconds(30)); - break; - case EVENT_MINIONS_WEAVE: - SummonMinions(); - events.Repeat(Seconds(30)); - break; - case EVENT_MOVE_TO_WARGLAIVE_POINT: - { - Position pos; - std::list<Creature*> triggers; - GetCreatureListWithEntryInGrid(triggers, me, NPC_GLAIVE_WORLD_TRIGGER, 150.0f); - triggers.remove_if([](WorldObject* unit) - { - return unit->GetPositionZ() < 355.0f || unit->GetPositionZ() > 365.0f; - }); +private: + uint8 _minionsCount; + uint8 _flameCount; + float _orientation; + uint8 _pillarIndex; + uint8 _phase; + bool _dead; + bool _isDemon; + EventMap specialEvents; +}; - if (triggers.empty()) - break; +struct npc_akama_illidan : public ScriptedAI +{ + npc_akama_illidan(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()), + _orientation(0.0f), _isTeleportToMinions(false) { } - triggers.sort(Trinity::ObjectDistanceOrderPred(me)); - pos.Relocate(triggers.front()); - pos.SetOrientation(0.0f); - me->GetMotionMaster()->MovePoint(POINT_THROW_GLAIVE, pos); - if (GameObject* musicController = instance->GetGameObject(DATA_ILLIDAN_MUSIC_CONTROLLER)) - musicController->PlayDirectMusic(EVENT_BT_STORM_WALK_HERO_2_SOUND_ID); - break; - } - case EVENT_THROW_WARGLAIVE: - DoCastAOE(SPELL_THROW_GLAIVE); - events.ScheduleEvent(EVENT_THROW_WARGLAIVE_2, Seconds(1), GROUP_PHASE_ALL); - break; - case EVENT_THROW_WARGLAIVE_2: - DoCastAOE(SPELL_THROW_GLAIVE2); - me->SetSheath(SHEATH_STATE_UNARMED); - events.ScheduleEvent(EVENT_FLY_TO_RANDOM_PILLAR, Seconds(2), GROUP_PHASE_ALL); - break; - case EVENT_CHANGE_ORIENTATION: - me->SetFacingTo(_orientation); - break; - case EVENT_FLY: - ChangeOrientation(3.137039f); - events.ScheduleEvent(EVENT_MOVE_TO_WARGLAIVE_POINT, Seconds(6), GROUP_PHASE_ALL); - break; - case EVENT_FLY_TO_RANDOM_PILLAR: - { - events.CancelEventGroup(GROUP_PHASE_2); - _pillarIndex = urand(0, 3); - me->GetMotionMaster()->MovePoint(POINT_RANDOM_PILLAR, IllidanPhase2Positions[_pillarIndex]); - events.Repeat(Seconds(30)); - break; - } - case EVENT_FACE_MIDDLE: - { - float angle = me->GetAngle(IllidanMiddlePoint); - me->SetFacingTo(angle); - break; - } - case EVENT_EYE_BLAST: - { - events.CancelEvent(EVENT_DARK_BARRAGE); - Position pos = IllidanDBTargetSpawnPositions[_pillarIndex]; - if (TempSummon* dbTarget = me->SummonCreature(NPC_ILLIDAN_DB_TARGET, pos, TEMPSUMMON_MANUAL_DESPAWN)) - { - Talk(SAY_ILLIDAN_EYE_BLAST); - DoCast(dbTarget, SPELL_EYE_BLAST); - dbTarget->GetMotionMaster()->MovePoint(POINT_DB_TARGET, IllidanDBTargetPoints[_pillarIndex]); - } - break; - } - case EVENT_DARK_BARRAGE: - { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 150.0f, true)) - DoCast(target, SPELL_DARK_BARRAGE); - events.RescheduleEvent(EVENT_EYE_BLAST, Seconds(5), GROUP_PHASE_2); - uint32 currentTime = events.GetNextEventTime(EVENT_FLY_TO_RANDOM_PILLAR); - events.RescheduleEvent(EVENT_FLY_TO_RANDOM_PILLAR, Seconds(currentTime) + Seconds(30), GROUP_PHASE_2); - break; - } - case EVENT_FIREBALL: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 150.0f, true)) - DoCast(target, SPELL_FIREBALL); - events.Repeat(Seconds(2), Seconds(4)); - break; - case EVENT_GLAIVE_EMOTE: - me->SetDisableGravity(false); - me->HandleEmoteCommand(EMOTE_ONESHOT_LAND); - me->SetSheath(SHEATH_STATE_MELEE); - events.ScheduleEvent(EVENT_RESUME_COMBAT, Seconds(3), GROUP_PHASE_ALL); - break; - case EVENT_RESUME_COMBAT: - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->SetReactState(REACT_AGGRESSIVE); - ScheduleEvents(GROUP_PHASE_3, GROUP_PHASE_3); - if (GameObject* musicController = instance->GetGameObject(DATA_ILLIDAN_MUSIC_CONTROLLER)) - musicController->PlayDirectMusic(EVENT_BT_STORM_WALK_UNI_3_SOUND_ID); - break; - case EVENT_AGONIZING_FLAMES: - DoCastSelf(SPELL_AGONIZING_FLAMES_SELECTOR); - events.Repeat(Seconds(53)); - break; - case EVENT_DEMON: - me->SetControlled(true, UNIT_STATE_ROOT); - _isDemon = true; - events.CancelEventGroup(_phase == PHASE_3 ? GROUP_PHASE_3 : GROUP_PHASE_4); - me->LoadEquipment(0, true); - DoCastSelf(SPELL_DEMON_TRANSFORM_1, true); - events.ScheduleEvent(EVENT_DEMON_TEXT, Seconds(2), GROUP_PHASE_ALL); - specialEvents.ScheduleEvent(EVENT_CANCEL_DEMON_FORM, Minutes(1) + Seconds(12)); - events.ScheduleEvent(EVENT_SCHEDULE_DEMON_SPELLS, Seconds(15)); - break; - case EVENT_SCHEDULE_DEMON_SPELLS: - ResetThreatList(); - ScheduleEvents(GROUP_PHASE_DEMON, GROUP_PHASE_DEMON); - break; - case EVENT_DEMON_TEXT: - Talk(SAY_ILLIDAN_MORPH); - break; - case EVENT_RESUME_COMBAT_DEMON: - { - uint8 group = _phase == PHASE_3 ? GROUP_PHASE_3 : GROUP_PHASE_4; - ResetThreatList(); - ScheduleEvents(group, group); - me->LoadEquipment(1, true); - break; - } - case EVENT_FLAME_BURST: - DoCastSelf(SPELL_FLAME_BURST); - events.Repeat(Seconds(22)); - break; - case EVENT_SHADOW_DEMON: - DoCastSelf(SPELL_SUMMON_SHADOWDEMON); - break; - case EVENT_SHADOW_BLAST: - DoCastVictim(SPELL_SHADOW_BLAST); - events.Repeat(Seconds(2)); - break; - case EVENT_PHASE_4_DELAYED: - DoAction(ACTION_START_PHASE_4); - break; - case EVENT_SHADOW_PRISON_TEXT: - Talk(SAY_ILLIDAN_SHADOW_PRISON); - events.ScheduleEvent(EVENT_SUMMON_MAIEV, Seconds(9), GROUP_PHASE_ALL); - break; - case EVENT_SUMMON_MAIEV: - DoCastSelf(SPELL_SUMMON_MAIEV); - if (Creature* maiev = instance->GetCreature(DATA_MAIEV)) - me->SetFacingToObject(maiev); - events.ScheduleEvent(EVENT_CONFRONT_MAIEV_TEXT, Seconds(9), GROUP_PHASE_ALL); - break; - case EVENT_CONFRONT_MAIEV_TEXT: - Talk(SAY_ILLIDAN_CONFRONT_MAIEV); - events.ScheduleEvent(EVENT_RESUME_COMBAT_PHASE_4, Seconds(13), GROUP_PHASE_ALL); - break; - case EVENT_RESUME_COMBAT_PHASE_4: - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->SetReactState(REACT_AGGRESSIVE); - ScheduleEvents(GROUP_PHASE_4, GROUP_PHASE_4); - break; - case EVENT_FRENZY: - DoCastSelf(SPELL_FRENZY); - Talk(SAY_ILLIDAN_FRENZY); - events.Repeat(Seconds(40)); - break; - case EVENT_TAUNT: - Talk(SAY_ILLIDAN_TAUNT); - events.Repeat(Seconds(30), Seconds(60)); - break; - case EVENT_DEFEATED_TEXT: - Talk(SAY_ILLIDAN_DEFEATED); - if (GameObject* musicController = instance->GetGameObject(DATA_ILLIDAN_MUSIC_CONTROLLER)) - musicController->PlayDirectMusic(EVENT_BT_ARRIVAL_WALK_HERO_1_SOUND_ID); - events.ScheduleEvent(EVENT_QUIET_SUICIDE, Seconds(18)); - break; - case EVENT_QUIET_SUICIDE: - { - DoCastSelf(SPELL_QUIET_SUICIDE, true); - if (Creature* akama = instance->GetCreature(DATA_AKAMA)) - akama->AI()->DoAction(ACTION_START_OUTRO); - ObjectGuid _akamaGUID = instance->GetGuidData(DATA_AKAMA); - ObjectGuid _maievGUID = instance->GetGuidData(DATA_MAIEV); - summons.DespawnIf([_akamaGUID, _maievGUID](ObjectGuid unitGuid) - { - return unitGuid != _akamaGUID && unitGuid != _maievGUID; - }); - break; - } - default: - break; - } + void Reset() override + { + _events.Reset(); + _spiritOfUdaloGUID.Clear(); + _spiritOfOlumGUID.Clear(); + _isTeleportToMinions = false; + } - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - } + bool GossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override + { + if (gossipListId == GOSSIP_START_INTRO) + { + _instance->SetData(DATA_AKAMA, AKAMA_FIGHT); + me->GetMotionMaster()->MoveAlongSplineChain(POINT_STAIRS, SPLINE_STAIRS, false); + me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + if (Creature* illidan = _instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) + illidan->AI()->DoAction(ACTION_INTRO_DONE); + CloseGossipMenuFor(player); - DoMeleeAttackIfReady(); } + else if (gossipListId == GOSSIP_START_FIGHT) + { + _events.SetPhase(PHASE_INTRO); + me->GetMotionMaster()->MoveAlongSplineChain(POINT_FACE_ILLIDAN, SPLINE_FACE_ILLIDAN, false); + me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + CloseGossipMenuFor(player); + } + return false; + } - private: - bool _intro; - uint8 _minionsCount; - uint8 _flameCount; - float _orientation; - uint8 _pillarIndex; - uint8 _phase; - bool _dead; - bool _isDemon; - EventMap specialEvents; - }; + bool CanAIAttack(Unit const* who) const override + { + if (_events.IsInPhase(PHASE_MINIONS) && who->GetEntry() == NPC_ILLIDAN_STORMRAGE) + return false; + return ScriptedAI::CanAIAttack(who); + } - CreatureAI* GetAI(Creature* creature) const override + uint32 GetData(uint32 /*data*/) const override { - return GetBlackTempleAI<boss_illidan_stormrageAI>(creature); + return _isTeleportToMinions ? 1 : 0; } -}; -class npc_akama : public CreatureScript -{ -public: - npc_akama() : CreatureScript("npc_akama_illidan") { } + void EnterEvadeMode(EvadeReason /*why*/) override { } - struct npc_akamaAI : public ScriptedAI + void JustSummoned(Creature* summon) override { - npc_akamaAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()), _orientation(0.0f), _isTeleportToMinions(false) { } - - void Reset() override + if (summon->GetEntry() == NPC_SPIRIT_OF_UDALO) { - _events.Reset(); - _spiritOfUdaloGUID.Clear(); - _spiritOfOlumGUID.Clear(); - _isTeleportToMinions = false; + _spiritOfUdaloGUID = summon->GetGUID(); + summon->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); } - - bool GossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override + else if (summon->GetEntry() == NPC_SPIRIT_OF_OLUM) { - if (gossipListId == GOSSIP_START_INTRO) - { - _instance->SetData(DATA_AKAMA, AKAMA_FIGHT); - me->GetMotionMaster()->MoveAlongSplineChain(POINT_STAIRS, SPLINE_STAIRS, false); - me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - if (Creature* illidan = _instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) - illidan->AI()->DoAction(ACTION_INTRO_DONE); - CloseGossipMenuFor(player); + _spiritOfOlumGUID = summon->GetGUID(); + summon->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + } + } - } - else if (gossipListId == GOSSIP_START_FIGHT) - { + void DoAction(int32 actionId) override + { + switch (actionId) + { + case ACTION_ACTIVE_AKAMA_INTRO: _events.SetPhase(PHASE_INTRO); - me->GetMotionMaster()->MoveAlongSplineChain(POINT_FACE_ILLIDAN, SPLINE_FACE_ILLIDAN, false); me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - CloseGossipMenuFor(player); - } - return false; + _events.SetPhase(PHASE_INTRO); + _events.ScheduleEvent(EVENT_TELEPORT, Seconds(1)); + _events.ScheduleEvent(EVENT_MOVE_TO_ILLIDARI_ROOM, Seconds(1) + Milliseconds(500)); + break; + case ACTION_OPEN_DOOR: + _instance->SetData(ACTION_OPEN_DOOR, 0); + _events.ScheduleEvent(EVENT_AKAMA_THANKS, Seconds(2)); + break; + case ACTION_FREE: + _events.ScheduleEvent(EVENT_FREE, Seconds(14)); + break; + case ACTION_START_ENCOUNTER: + DoZoneInCombat(); + _events.ScheduleEvent(EVENT_HEALING_POTION, Seconds(1)); + break; + case ACTION_START_MINIONS: + _events.ScheduleEvent(EVENT_AKAMA_MINIONS, Seconds(8)); + break; + case ACTION_START_OUTRO: + me->SetReactState(REACT_PASSIVE); + me->AttackStop(); + _events.Reset(); + _events.ScheduleEvent(EVENT_AKAMA_MOVE_BACK, Seconds(2)); + break; + default: + break; } + } - bool CanAIAttack(Unit const* who) const override - { - if (_events.IsInPhase(PHASE_MINIONS) && who->GetEntry() == NPC_ILLIDAN_STORMRAGE) - return false; - return ScriptedAI::CanAIAttack(who); - } + void ChangeOrientation(float orientation) + { + _orientation = orientation; + _events.ScheduleEvent(EVENT_CHANGE_ORIENTATION, Milliseconds(1)); + } - uint32 GetData(uint32 /*data*/) const override - { - return _isTeleportToMinions ? 1 : 0; + void MovementInform(uint32 type, uint32 pointId) override + { + if (type != POINT_MOTION_TYPE && type != SPLINE_CHAIN_MOTION_TYPE) + return; + + switch (pointId) + { + case POINT_ILLIDARI_COUNCIL: + Talk(SAY_AKAMA_FINISH); + me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + break; + case POINT_STAIRS: + ChangeOrientation(6.265732f); + _events.ScheduleEvent(EVENT_AKAMA_SAY_DOOR, Seconds(5)); + break; + case POINT_ILLIDAN_ROOM: + ChangeOrientation(2.129302f); + Talk(SAY_AKAMA_BETRAYER); + me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + break; + case POINT_FACE_ILLIDAN: + ChangeOrientation(3.140537f); + _events.ScheduleEvent(EVENT_START_ILLIDAN, Seconds(2)); + break; + case POINT_TELEPORT: + DoCastSelf(SPELL_AKAMA_TELEPORT); + _events.ScheduleEvent(EVENT_AKAMA_MINIONS_MOVE_2, Milliseconds(500)); + break; + case POINT_MINIONS: + _events.SetPhase(PHASE_MINIONS); + me->SetImmuneToNPC(false); + me->SetReactState(REACT_AGGRESSIVE); + if (Creature* illidan = _instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) + illidan->AI()->DoAction(ACTION_START_MINIONS_WEAVE); + _events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, Seconds(2)); + break; + case POINT_MOVE_BACK: + _events.ScheduleEvent(EVENT_AKAMA_MOVE_TO_ILLIDAN, Milliseconds(1)); + break; + case POINT_ILLIDAN: + _events.ScheduleEvent(EVENT_AKAMA_LIGHT_TEXT, Seconds(1)); + break; + default: + break; } + } - void EnterEvadeMode(EvadeReason /*why*/) override { } + void DamageTaken(Unit* /*who*/, uint32 &damage) override + { + if (damage >= me->GetHealth()) + damage = me->GetHealth() - 1; + } - void JustSummoned(Creature* summon) override - { - if (summon->GetEntry() == NPC_SPIRIT_OF_UDALO) - { - _spiritOfUdaloGUID = summon->GetGUID(); - summon->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - } - else if (summon->GetEntry() == NPC_SPIRIT_OF_OLUM) - { - _spiritOfOlumGUID = summon->GetGUID(); - summon->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - } - } + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim() && !_events.IsInPhase(PHASE_INTRO)) + return; + + _events.Update(diff); - void DoAction(int32 actionId) override + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = _events.ExecuteEvent()) { - switch (actionId) + switch (eventId) { - case ACTION_ACTIVE_AKAMA_INTRO: - _events.SetPhase(PHASE_INTRO); - me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - _events.SetPhase(PHASE_INTRO); - _events.ScheduleEvent(EVENT_TELEPORT, Seconds(1)); - _events.ScheduleEvent(EVENT_MOVE_TO_ILLIDARI_ROOM, Seconds(1) + Milliseconds(500)); + case EVENT_TELEPORT: + DoCastSelf(SPELL_AKAMA_TELEPORT, true); break; - case ACTION_OPEN_DOOR: - _instance->SetData(ACTION_OPEN_DOOR, 0); - _events.ScheduleEvent(EVENT_AKAMA_THANKS, Seconds(2)); + case EVENT_MOVE_TO_ILLIDARI_ROOM: + me->GetMotionMaster()->MoveAlongSplineChain(POINT_ILLIDARI_COUNCIL, SPLINE_ILLIDARI_COUNCIL, false); break; - case ACTION_FREE: - _events.ScheduleEvent(EVENT_FREE, Seconds(14)); + case EVENT_AKAMA_SAY_DOOR: + Talk(SAY_AKAMA_DOOR); + _events.ScheduleEvent(EVENT_AKAMA_DOOR_FAIL, Seconds(4)); break; - case ACTION_START_ENCOUNTER: - DoZoneInCombat(); - _events.ScheduleEvent(EVENT_HEALING_POTION, Seconds(1)); + case EVENT_AKAMA_DOOR_FAIL: + DoCastSelf(SPELL_AKAMA_DOOR_FAIL); + _events.ScheduleEvent(EVENT_AKAMA_SAY_ALONE, Seconds(10)); + break; + case EVENT_AKAMA_SAY_ALONE: + Talk(SAY_AKAMA_ALONE); + _events.ScheduleEvent(EVENT_SUMMON_SPIRITS, Seconds(7)); + break; + case EVENT_SUMMON_SPIRITS: + me->SummonCreatureGroup(SUMMON_GROUP); + _events.ScheduleEvent(EVENT_SPIRIT_SAY_1, Seconds(1)); + break; + case EVENT_SPIRIT_SAY_1: + if (Creature* undalo = ObjectAccessor::GetCreature(*me, _spiritOfUdaloGUID)) + undalo->AI()->Talk(SAY_SPIRIT_ALONE); + _events.ScheduleEvent(EVENT_SPIRIT_SAY_2, Seconds(6)); break; - case ACTION_START_MINIONS: - _events.ScheduleEvent(EVENT_AKAMA_MINIONS, Seconds(8)); + case EVENT_SPIRIT_SAY_2: + if (Creature* olum = ObjectAccessor::GetCreature(*me, _spiritOfOlumGUID)) + olum->AI()->Talk(SAY_SPIRIT_ALONE); + _events.ScheduleEvent(EVENT_AKAMA_DOOR_SUCCESS, Seconds(6)); break; - case ACTION_START_OUTRO: + case EVENT_AKAMA_DOOR_SUCCESS: + DoCastSelf(SPELL_AKAMA_DOOR_CHANNEL); + if (Creature* undalo = ObjectAccessor::GetCreature(*me, _spiritOfUdaloGUID)) + undalo->CastSpell((Unit*) nullptr, SPELL_DEATHSWORN_DOOR_CHANNEL); + if (Creature* olum = ObjectAccessor::GetCreature(*me, _spiritOfOlumGUID)) + olum->CastSpell((Unit*) nullptr, SPELL_DEATHSWORN_DOOR_CHANNEL); + _events.ScheduleEvent(EVENT_AKAMA_START_SOUND, Seconds(5)); + break; + case EVENT_AKAMA_START_SOUND: + if (GameObject* musicController = _instance->GetGameObject(DATA_ILLIDAN_MUSIC_CONTROLLER)) + musicController->PlayDirectMusic(EVENT_BT_SUMMIT_WALK_SOUND_ID); + break; + case EVENT_AKAMA_THANKS: + Talk(SAY_AKAMA_SALUTE); + _events.ScheduleEvent(EVENT_SPIRIT_SALUTE, Seconds(3)); + _events.ScheduleEvent(EVENT_RUN_FROM_ILLIDAN_ROOM, Seconds(7)); + break; + case EVENT_SPIRIT_SALUTE: + if (Creature* undalo = ObjectAccessor::GetCreature(*me, _spiritOfUdaloGUID)) + { + undalo->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE); + undalo->DespawnOrUnsummon(Seconds(7)); + } + if (Creature* olum = ObjectAccessor::GetCreature(*me, _spiritOfOlumGUID)) + { + olum->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE); + olum->DespawnOrUnsummon(Seconds(7)); + } + break; + case EVENT_RUN_FROM_ILLIDAN_ROOM: + me->GetMotionMaster()->MoveAlongSplineChain(POINT_ILLIDAN_ROOM, SPLINE_ILLIDAN_ROOM, false); + break; + case EVENT_START_ILLIDAN: + if (Creature* illidan = _instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) + illidan->AI()->DoAction(ACTION_START_ENCOUNTER); + break; + case EVENT_FREE: + Talk(SAY_AKAMA_FREE); + _events.ScheduleEvent(EVENT_TIME_HAS_COME, Seconds(18)); + break; + case EVENT_TIME_HAS_COME: + Talk(SAY_AKAMA_TIME_HAS_COME); + _events.ScheduleEvent(EVENT_ROAR, Seconds(2)); + break; + case EVENT_ROAR: + me->HandleEmoteCommand(EMOTE_ONESHOT_ROAR); + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY1H); + break; + case EVENT_CHANGE_ORIENTATION: + me->SetFacingTo(_orientation); + break; + case EVENT_HEALING_POTION: + if (me->HealthBelowPct(20)) + DoCastSelf(SPELL_HEALING_POTION); + _events.Repeat(Seconds(1)); + break; + case EVENT_AKAMA_MINIONS: + Talk(SAY_AKAMA_MINIONS); + _events.ScheduleEvent(EVENT_AKAMA_MINIONS_EMOTE, Seconds(2)); + break; + case EVENT_AKAMA_MINIONS_EMOTE: me->SetReactState(REACT_PASSIVE); me->AttackStop(); - _events.Reset(); - _events.ScheduleEvent(EVENT_AKAMA_MOVE_BACK, Seconds(2)); + me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION); + me->SetImmuneToNPC(true); + _events.ScheduleEvent(EVENT_AKAMA_MINIONS_MOVE, Seconds(4)); break; - default: + case EVENT_AKAMA_MINIONS_MOVE: + _isTeleportToMinions = true; + me->GetMotionMaster()->MoveAlongSplineChain(POINT_TELEPORT, SPLINE_TELEPORT, false); break; - } - } - - void ChangeOrientation(float orientation) - { - _orientation = orientation; - _events.ScheduleEvent(EVENT_CHANGE_ORIENTATION, Milliseconds(1)); - } - - void MovementInform(uint32 type, uint32 pointId) override - { - if (type != POINT_MOTION_TYPE && type != SPLINE_CHAIN_MOTION_TYPE) - return; - - switch (pointId) - { - case POINT_ILLIDARI_COUNCIL: - Talk(SAY_AKAMA_FINISH); - me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - break; - case POINT_STAIRS: - ChangeOrientation(6.265732f); - _events.ScheduleEvent(EVENT_AKAMA_SAY_DOOR, Seconds(5)); - break; - case POINT_ILLIDAN_ROOM: - ChangeOrientation(2.129302f); - Talk(SAY_AKAMA_BETRAYER); - me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - break; - case POINT_FACE_ILLIDAN: - ChangeOrientation(3.140537f); - _events.ScheduleEvent(EVENT_START_ILLIDAN, Seconds(2)); - break; - case POINT_TELEPORT: - DoCastSelf(SPELL_AKAMA_TELEPORT); - _events.ScheduleEvent(EVENT_AKAMA_MINIONS_MOVE_2, Milliseconds(500)); - break; - case POINT_MINIONS: - _events.SetPhase(PHASE_MINIONS); - me->SetImmuneToNPC(false); - me->SetReactState(REACT_AGGRESSIVE); + case EVENT_AKAMA_MINIONS_MOVE_2: + me->GetMotionMaster()->MoveAlongSplineChain(POINT_MINIONS, SPLINE_MINIONS, false); + break; + case EVENT_CHAIN_LIGHTNING: + DoCastVictim(SPELL_CHAIN_LIGHTNING); + _events.Repeat(Seconds(8) + Milliseconds(500)); + break; + case EVENT_AKAMA_MOVE_BACK: + me->GetMotionMaster()->MoveAlongSplineChain(POINT_MOVE_BACK, SPLINE_MOVE_BACK, false); + break; + case EVENT_AKAMA_MOVE_TO_ILLIDAN: if (Creature* illidan = _instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) - illidan->AI()->DoAction(ACTION_START_MINIONS_WEAVE); - _events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, Seconds(2)); + me->GetMotionMaster()->MoveCloserAndStop(POINT_ILLIDAN, illidan, 5.0f); + break; + case EVENT_AKAMA_LIGHT_TEXT: + Talk(SAY_AKAMA_LIGHT); + _events.ScheduleEvent(EVENT_FINAL_SALUTE, Seconds(4)); break; - case POINT_MOVE_BACK: - _events.ScheduleEvent(EVENT_AKAMA_MOVE_TO_ILLIDAN, Milliseconds(1)); + case EVENT_FINAL_SALUTE: + me->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE); + _events.ScheduleEvent(EVENT_AKAMA_DESPAWN, Seconds(5)); break; - case POINT_ILLIDAN: - _events.ScheduleEvent(EVENT_AKAMA_LIGHT_TEXT, Seconds(1)); + case EVENT_AKAMA_DESPAWN: + DoCastSelf(SPELL_AKAMA_DESPAWN, true); break; default: break; } - } - - void DamageTaken(Unit* /*who*/, uint32 &damage) override - { - if (damage >= me->GetHealth()) - damage = me->GetHealth() - 1; - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim() && !_events.IsInPhase(PHASE_INTRO)) - return; - - _events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) return; - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_TELEPORT: - DoCastSelf(SPELL_AKAMA_TELEPORT, true); - break; - case EVENT_MOVE_TO_ILLIDARI_ROOM: - me->GetMotionMaster()->MoveAlongSplineChain(POINT_ILLIDARI_COUNCIL, SPLINE_ILLIDARI_COUNCIL, false); - break; - case EVENT_AKAMA_SAY_DOOR: - Talk(SAY_AKAMA_DOOR); - _events.ScheduleEvent(EVENT_AKAMA_DOOR_FAIL, Seconds(4)); - break; - case EVENT_AKAMA_DOOR_FAIL: - DoCastSelf(SPELL_AKAMA_DOOR_FAIL); - _events.ScheduleEvent(EVENT_AKAMA_SAY_ALONE, Seconds(10)); - break; - case EVENT_AKAMA_SAY_ALONE: - Talk(SAY_AKAMA_ALONE); - _events.ScheduleEvent(EVENT_SUMMON_SPIRITS, Seconds(7)); - break; - case EVENT_SUMMON_SPIRITS: - me->SummonCreatureGroup(SUMMON_GROUP); - _events.ScheduleEvent(EVENT_SPIRIT_SAY_1, Seconds(1)); - break; - case EVENT_SPIRIT_SAY_1: - if (Creature* undalo = ObjectAccessor::GetCreature(*me, _spiritOfUdaloGUID)) - undalo->AI()->Talk(SAY_SPIRIT_ALONE); - _events.ScheduleEvent(EVENT_SPIRIT_SAY_2, Seconds(6)); - break; - case EVENT_SPIRIT_SAY_2: - if (Creature* olum = ObjectAccessor::GetCreature(*me, _spiritOfOlumGUID)) - olum->AI()->Talk(SAY_SPIRIT_ALONE); - _events.ScheduleEvent(EVENT_AKAMA_DOOR_SUCCESS, Seconds(6)); - break; - case EVENT_AKAMA_DOOR_SUCCESS: - DoCastSelf(SPELL_AKAMA_DOOR_CHANNEL); - if (Creature* undalo = ObjectAccessor::GetCreature(*me, _spiritOfUdaloGUID)) - undalo->CastSpell((Unit*) nullptr, SPELL_DEATHSWORN_DOOR_CHANNEL); - if (Creature* olum = ObjectAccessor::GetCreature(*me, _spiritOfOlumGUID)) - olum->CastSpell((Unit*) nullptr, SPELL_DEATHSWORN_DOOR_CHANNEL); - _events.ScheduleEvent(EVENT_AKAMA_START_SOUND, Seconds(5)); - break; - case EVENT_AKAMA_START_SOUND: - if (GameObject* musicController = _instance->GetGameObject(DATA_ILLIDAN_MUSIC_CONTROLLER)) - musicController->PlayDirectMusic(EVENT_BT_SUMMIT_WALK_SOUND_ID); - break; - case EVENT_AKAMA_THANKS: - Talk(SAY_AKAMA_SALUTE); - _events.ScheduleEvent(EVENT_SPIRIT_SALUTE, Seconds(3)); - _events.ScheduleEvent(EVENT_RUN_FROM_ILLIDAN_ROOM, Seconds(7)); - break; - case EVENT_SPIRIT_SALUTE: - if (Creature* undalo = ObjectAccessor::GetCreature(*me, _spiritOfUdaloGUID)) - { - undalo->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE); - undalo->DespawnOrUnsummon(Seconds(7)); - } - if (Creature* olum = ObjectAccessor::GetCreature(*me, _spiritOfOlumGUID)) - { - olum->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE); - olum->DespawnOrUnsummon(Seconds(7)); - } - break; - case EVENT_RUN_FROM_ILLIDAN_ROOM: - me->GetMotionMaster()->MoveAlongSplineChain(POINT_ILLIDAN_ROOM, SPLINE_ILLIDAN_ROOM, false); - break; - case EVENT_START_ILLIDAN: - if (Creature* illidan = _instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) - illidan->AI()->DoAction(ACTION_START_ENCOUNTER); - break; - case EVENT_FREE: - Talk(SAY_AKAMA_FREE); - _events.ScheduleEvent(EVENT_TIME_HAS_COME, Seconds(18)); - break; - case EVENT_TIME_HAS_COME: - Talk(SAY_AKAMA_TIME_HAS_COME); - _events.ScheduleEvent(EVENT_ROAR, Seconds(2)); - break; - case EVENT_ROAR: - me->HandleEmoteCommand(EMOTE_ONESHOT_ROAR); - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY1H); - break; - case EVENT_CHANGE_ORIENTATION: - me->SetFacingTo(_orientation); - break; - case EVENT_HEALING_POTION: - if (me->HealthBelowPct(20)) - DoCastSelf(SPELL_HEALING_POTION); - _events.Repeat(Seconds(1)); - break; - case EVENT_AKAMA_MINIONS: - Talk(SAY_AKAMA_MINIONS); - _events.ScheduleEvent(EVENT_AKAMA_MINIONS_EMOTE, Seconds(2)); - break; - case EVENT_AKAMA_MINIONS_EMOTE: - me->SetReactState(REACT_PASSIVE); - me->AttackStop(); - me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION); - me->SetImmuneToNPC(true); - _events.ScheduleEvent(EVENT_AKAMA_MINIONS_MOVE, Seconds(4)); - break; - case EVENT_AKAMA_MINIONS_MOVE: - _isTeleportToMinions = true; - me->GetMotionMaster()->MoveAlongSplineChain(POINT_TELEPORT, SPLINE_TELEPORT, false); - break; - case EVENT_AKAMA_MINIONS_MOVE_2: - me->GetMotionMaster()->MoveAlongSplineChain(POINT_MINIONS, SPLINE_MINIONS, false); - break; - case EVENT_CHAIN_LIGHTNING: - DoCastVictim(SPELL_CHAIN_LIGHTNING); - _events.Repeat(Seconds(8) + Milliseconds(500)); - break; - case EVENT_AKAMA_MOVE_BACK: - me->GetMotionMaster()->MoveAlongSplineChain(POINT_MOVE_BACK, SPLINE_MOVE_BACK, false); - break; - case EVENT_AKAMA_MOVE_TO_ILLIDAN: - if (Creature* illidan = _instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) - me->GetMotionMaster()->MoveCloserAndStop(POINT_ILLIDAN, illidan, 5.0f); - break; - case EVENT_AKAMA_LIGHT_TEXT: - Talk(SAY_AKAMA_LIGHT); - _events.ScheduleEvent(EVENT_FINAL_SALUTE, Seconds(4)); - break; - case EVENT_FINAL_SALUTE: - me->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE); - _events.ScheduleEvent(EVENT_AKAMA_DESPAWN, Seconds(5)); - break; - case EVENT_AKAMA_DESPAWN: - DoCastSelf(SPELL_AKAMA_DESPAWN, true); - break; - default: - break; - } - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - } - - DoMeleeAttackIfReady(); } - private: - InstanceScript* _instance; - EventMap _events; - ObjectGuid _spiritOfUdaloGUID; - ObjectGuid _spiritOfOlumGUID; - float _orientation; - bool _isTeleportToMinions; - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetBlackTempleAI<npc_akamaAI>(creature); + DoMeleeAttackIfReady(); } + +private: + InstanceScript* _instance; + EventMap _events; + ObjectGuid _spiritOfUdaloGUID; + ObjectGuid _spiritOfOlumGUID; + float _orientation; + bool _isTeleportToMinions; }; -class npc_parasitic_shadowfiend : public CreatureScript +struct npc_parasitic_shadowfiend : public ScriptedAI { -public: - npc_parasitic_shadowfiend() : CreatureScript("npc_parasitic_shadowfiend") { } + npc_parasitic_shadowfiend(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { } - struct npc_parasitic_shadowfiendAI : public ScriptedAI + void Reset() override { - npc_parasitic_shadowfiendAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { } + if (_instance->GetBossState(DATA_ILLIDAN_STORMRAGE) != IN_PROGRESS) + { + me->DespawnOrUnsummon(); + return; + } - void Reset() override + if (Creature* illidan = _instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) + illidan->AI()->JustSummoned(me); + me->SetReactState(REACT_DEFENSIVE); + _scheduler.Schedule(Seconds(2), [this](TaskContext /*context*/) { - if (_instance->GetBossState(DATA_ILLIDAN_STORMRAGE) != IN_PROGRESS) - { - me->DespawnOrUnsummon(); - return; - } + me->SetReactState(REACT_AGGRESSIVE); + me->SetInCombatWithZone(); + }); + } - if (Creature* illidan = _instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) - illidan->AI()->JustSummoned(me); - me->SetReactState(REACT_DEFENSIVE); + void DoAction(int32 action) override + { + if (action == ACTION_START_PHASE_4) + { + me->SetReactState(REACT_PASSIVE); + me->AttackStop(); + } + else if (action == ACTION_RESUME_COMBAT) _scheduler.Schedule(Seconds(2), [this](TaskContext /*context*/) { me->SetReactState(REACT_AGGRESSIVE); me->SetInCombatWithZone(); }); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + } - _scheduler.Update(diff, [this] - { - DoMeleeAttackIfReady(); - }); - } + void UpdateAI(uint32 diff) override + { + _scheduler.Update(diff); - private: - InstanceScript* _instance; - TaskScheduler _scheduler; - }; + if (!UpdateVictim()) + return; - CreatureAI* GetAI(Creature* creature) const override - { - return GetBlackTempleAI<npc_parasitic_shadowfiendAI>(creature); + DoMeleeAttackIfReady(); } + +private: + InstanceScript* _instance; + TaskScheduler _scheduler; }; -class npc_blade_of_azzinoth : public CreatureScript +struct npc_blade_of_azzinoth : public NullCreatureAI { -public: - npc_blade_of_azzinoth() : CreatureScript("npc_blade_of_azzinoth") { } + npc_blade_of_azzinoth(Creature* creature) : NullCreatureAI(creature), _instance(creature->GetInstanceScript()) { } - struct npc_blade_of_azzinothAI : public NullCreatureAI + void Reset() override { - npc_blade_of_azzinothAI(Creature* creature) : NullCreatureAI(creature), _instance(creature->GetInstanceScript()) { } - - void Reset() override - { - if (_instance->GetBossState(DATA_ILLIDAN_STORMRAGE) != IN_PROGRESS) - { - me->DespawnOrUnsummon(); - return; - } - - if (Creature* illidan = _instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) - illidan->AI()->JustSummoned(me); - _flameGuid.Clear(); - me->PlayDirectSound(WARGLAIVE_SPAWN_SOUND_ID); - DoCastSelf(SPELL_BIRTH, true); - _scheduler.Schedule(Seconds(3), [this](TaskContext /*context*/) - { - DoCastSelf(SPELL_SUMMON_TEAR_OF_AZZINOTH); - _scheduler.Schedule(Milliseconds(500), [this](TaskContext /*context*/) - { - if (Creature* flame = ObjectAccessor::GetCreature(*me, _flameGuid)) - DoCast(flame, SPELL_AZZINOTH_CHANNEL); - }); - }); - } - - void JustSummoned(Creature* summon) override + if (_instance->GetBossState(DATA_ILLIDAN_STORMRAGE) != IN_PROGRESS) { - if (summon->GetEntry() == NPC_FLAME_OF_AZZINOTH) - _flameGuid = summon->GetGUID(); + me->DespawnOrUnsummon(); + return; } - void UpdateAI(uint32 diff) override + if (Creature* illidan = _instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) + illidan->AI()->JustSummoned(me); + _flameGuid.Clear(); + me->PlayDirectSound(WARGLAIVE_SPAWN_SOUND_ID); + DoCastSelf(SPELL_BIRTH, true); + _scheduler.Schedule(Seconds(3), [this](TaskContext /*context*/) { - _scheduler.Update(diff); - } + DoCastSelf(SPELL_SUMMON_TEAR_OF_AZZINOTH); + _scheduler.Schedule(Milliseconds(500), [this](TaskContext /*context*/) + { + if (Creature* flame = ObjectAccessor::GetCreature(*me, _flameGuid)) + DoCast(flame, SPELL_AZZINOTH_CHANNEL); + }); + }); + } - private: - InstanceScript* _instance; - TaskScheduler _scheduler; - ObjectGuid _flameGuid; - }; + void JustSummoned(Creature* summon) override + { + if (summon->GetEntry() == NPC_FLAME_OF_AZZINOTH) + _flameGuid = summon->GetGUID(); + } - CreatureAI* GetAI(Creature* creature) const override + void UpdateAI(uint32 diff) override { - return GetBlackTempleAI<npc_blade_of_azzinothAI>(creature); + _scheduler.Update(diff); } + +private: + InstanceScript* _instance; + TaskScheduler _scheduler; + ObjectGuid _flameGuid; }; -class npc_flame_of_azzinoth : public CreatureScript +struct npc_flame_of_azzinoth : public ScriptedAI { -public: - npc_flame_of_azzinoth() : CreatureScript("npc_flame_of_azzinoth") { } + npc_flame_of_azzinoth(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) + { + SetBoundary(_instance->GetBossBoundary(DATA_ILLIDAN_STORMRAGE)); + } - struct npc_flame_of_azzinothAI : public ScriptedAI + void Reset() override { - npc_flame_of_azzinothAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) + if (_instance->GetBossState(DATA_ILLIDAN_STORMRAGE) != IN_PROGRESS) { - SetBoundary(_instance->GetBossBoundary(DATA_ILLIDAN_STORMRAGE)); + me->DespawnOrUnsummon(); + return; } - void Reset() override - { - if (_instance->GetBossState(DATA_ILLIDAN_STORMRAGE) != IN_PROGRESS) - { - me->DespawnOrUnsummon(); - return; - } - - if (Creature* illidan = _instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) - illidan->AI()->JustSummoned(me); - DoCastSelf(SPELL_FLAME_TEAR_OF_AZZINOTH, true); // Idk what this spell should do - me->SetReactState(REACT_PASSIVE); - _events.ScheduleEvent(EVENT_ENGAGE, Seconds(3)); - _events.ScheduleEvent(EVENT_FLAME_BLAST, Seconds(11)); - } + if (Creature* illidan = _instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) + illidan->AI()->JustSummoned(me); + DoCastSelf(SPELL_FLAME_TEAR_OF_AZZINOTH, true); // Idk what this spell should do + me->SetReactState(REACT_PASSIVE); + _events.ScheduleEvent(EVENT_ENGAGE, Seconds(3)); + _events.ScheduleEvent(EVENT_FLAME_BLAST, Seconds(11)); + } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - _events.Update(diff); + _events.Update(diff); - while (uint32 eventId = _events.ExecuteEvent()) + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) { - switch (eventId) - { - case EVENT_ENGAGE: - me->SetReactState(REACT_AGGRESSIVE); - me->SetInCombatWithZone(); - _events.ScheduleEvent(EVENT_FLAME_CHARGE, Seconds(5)); - break; - case EVENT_FLAME_CHARGE: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, ChargeTargetSelector(me))) - { - DoCast(target, SPELL_CHARGE); - _events.Repeat(Seconds(5)); - } - else - _events.Repeat(Seconds(1)); - break; - case EVENT_FLAME_BLAST: - DoCastAOE(SPELL_FLAME_BLAST); - _events.Repeat(Seconds(12)); - break; - default: - break; - } - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + case EVENT_ENGAGE: + me->SetReactState(REACT_AGGRESSIVE); + me->SetInCombatWithZone(); + _events.ScheduleEvent(EVENT_FLAME_CHARGE, Seconds(5)); + break; + case EVENT_FLAME_CHARGE: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, ChargeTargetSelector())) + { + DoCast(target, SPELL_CHARGE); + _events.Repeat(Seconds(5)); + } + else + _events.Repeat(Seconds(1)); + break; + case EVENT_FLAME_BLAST: + DoCastAOE(SPELL_FLAME_BLAST); + _events.Repeat(Seconds(12)); + break; + default: + break; } - DoMeleeAttackIfReady(); - } - - void JustDied(Unit* /*killer*/) override - { - if (Creature* illidan = _instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) - illidan->AI()->DoAction(ACTION_FLAME_DEAD); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; } - private: - InstanceScript* _instance; - EventMap _events; - }; + DoMeleeAttackIfReady(); + } - CreatureAI* GetAI(Creature* creature) const override + void JustDied(Unit* /*killer*/) override { - return GetBlackTempleAI<npc_flame_of_azzinothAI>(creature); + if (Creature* illidan = _instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) + illidan->AI()->DoAction(ACTION_FLAME_DEAD); } + +private: + InstanceScript* _instance; + EventMap _events; }; -class npc_illidan_db_target : public CreatureScript +struct npc_illidan_db_target : public NullCreatureAI { -public: - npc_illidan_db_target() : CreatureScript("npc_illidan_db_target") { } + npc_illidan_db_target(Creature* creature) : NullCreatureAI(creature) { } - struct npc_illidan_db_targetAI : public NullCreatureAI + void Reset() override { - npc_illidan_db_targetAI(Creature* creature) : NullCreatureAI(creature) { } - - void Reset() override - { - DoCastSelf(SPELL_EYE_BLAST_TRIGGER); - } + DoCastSelf(SPELL_EYE_BLAST_TRIGGER); + } - void JustSummoned(Creature* summon) override - { - if (summon->GetEntry() == NPC_DEMON_FIRE) - summon->SetReactState(REACT_PASSIVE); - } + void JustSummoned(Creature* summon) override + { + if (summon->GetEntry() == NPC_DEMON_FIRE) + summon->SetReactState(REACT_PASSIVE); + } - void MovementInform(uint32 type, uint32 pointId) override + void MovementInform(uint32 type, uint32 pointId) override + { + if (type == POINT_MOTION_TYPE && pointId == POINT_DB_TARGET) { - if (type == POINT_MOTION_TYPE && pointId == POINT_DB_TARGET) - { - me->RemoveAurasDueToSpell(SPELL_EYE_BLAST_TRIGGER); - me->RemoveAurasDueToSpell(SPELL_EYE_BLAST); - } + me->RemoveAurasDueToSpell(SPELL_EYE_BLAST_TRIGGER); + me->RemoveAurasDueToSpell(SPELL_EYE_BLAST); } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetBlackTempleAI<npc_illidan_db_targetAI>(creature); } }; -class npc_illidan_shadow_demon : public CreatureScript +struct npc_shadow_demon : public PassiveAI { -public: - npc_illidan_shadow_demon() : CreatureScript("npc_shadow_demon") { } + npc_shadow_demon(Creature* creature) : PassiveAI(creature), _instance(creature->GetInstanceScript()) { } - struct npc_illidan_shadow_demonAI : public PassiveAI + void Reset() override { - npc_illidan_shadow_demonAI(Creature* creature) : PassiveAI(creature), _instance(creature->GetInstanceScript()) { } - - void Reset() override + if (_instance->GetBossState(DATA_ILLIDAN_STORMRAGE) != IN_PROGRESS) { - if (_instance->GetBossState(DATA_ILLIDAN_STORMRAGE) != IN_PROGRESS) - { - me->DespawnOrUnsummon(); - return; - } - - DoCastSelf(SPELL_SHADOW_DEMON_PASSIVE); - DoCastSelf(SPELL_FIND_TARGET); - _scheduler.Schedule(Seconds(1), [this](TaskContext checkTarget) - { - if (Unit* target = ObjectAccessor::GetUnit(*me, _targetGUID)) - { - if (!target->IsAlive()) - DoCastSelf(SPELL_FIND_TARGET); - else if (me->IsWithinMeleeRange(target)) - { - me->InterruptNonMeleeSpells(false); - DoCast(target, SPELL_CONSUME_SOUL, true); - } - } - checkTarget.Repeat(); - }); + me->DespawnOrUnsummon(); + return; } - void SetGUID(ObjectGuid guid, int32 /*id*/) override + DoCastSelf(SPELL_SHADOW_DEMON_PASSIVE); + DoCastSelf(SPELL_FIND_TARGET); + _scheduler.Schedule(Seconds(1), [this](TaskContext checkTarget) { - _targetGUID = guid; if (Unit* target = ObjectAccessor::GetUnit(*me, _targetGUID)) - me->GetMotionMaster()->MoveChase(target); - } - - void UpdateAI(uint32 diff) override - { - _scheduler.Update(diff); - } + { + if (!target->IsAlive()) + DoCastSelf(SPELL_FIND_TARGET); + else if (me->IsWithinMeleeRange(target)) + { + me->InterruptNonMeleeSpells(false); + DoCast(target, SPELL_CONSUME_SOUL, true); + } + } + checkTarget.Repeat(); + }); + } - private: - InstanceScript* _instance; - TaskScheduler _scheduler; - ObjectGuid _targetGUID; - }; + void SetGUID(ObjectGuid guid, int32 /*id*/) override + { + _targetGUID = guid; + if (Unit* target = ObjectAccessor::GetUnit(*me, _targetGUID)) + me->GetMotionMaster()->MoveChase(target); + } - CreatureAI* GetAI(Creature* creature) const override + void UpdateAI(uint32 diff) override { - return GetBlackTempleAI<npc_illidan_shadow_demonAI>(creature); + _scheduler.Update(diff); } + +private: + InstanceScript* _instance; + TaskScheduler _scheduler; + ObjectGuid _targetGUID; }; -class npc_maiev : public CreatureScript +struct npc_maiev : public ScriptedAI { -public: - npc_maiev() : CreatureScript("npc_maiev") { } + npc_maiev(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()), _canDown(true) { } + + void Reset() override + { + if (Creature* illidan = _instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) + me->SetFacingToObject(illidan); + me->SetReactState(REACT_PASSIVE); + _events.SetPhase(PHASE_INTRO); + _events.ScheduleEvent(EVENT_MAIEV_APPEAR, Seconds(1)); + _events.ScheduleEvent(EVENT_MAIEV_EXCLAMATION, Seconds(2)); + _events.ScheduleEvent(EVENT_MAIEV_JUSTICE_TEXT, Seconds(14)); + _events.ScheduleEvent(EVENT_TAUNT, Seconds(20), Seconds(60)); + _canDown = true; + } - struct npc_maievAI : public ScriptedAI + void EnterCombat(Unit* /*who*/) override { - npc_maievAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()), _canDown(true) { } + _events.SetPhase(PHASE_1); + _events.ScheduleEvent(EVENT_CAGE_TRAP, Seconds(30)); + _events.ScheduleEvent(EVENT_SHADOW_STRIKE, Seconds(50)); + _events.ScheduleEvent(EVENT_THROW_DAGGER, Seconds(1)); + } - void Reset() override + void DoAction(int32 actionId) override + { + if (actionId == ACTION_START_OUTRO) { + _events.Reset(); + me->SetReactState(REACT_PASSIVE); + me->AttackStop(); if (Creature* illidan = _instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) me->SetFacingToObject(illidan); - me->SetReactState(REACT_PASSIVE); - _events.SetPhase(PHASE_INTRO); - _events.ScheduleEvent(EVENT_MAIEV_APPEAR, Seconds(1)); - _events.ScheduleEvent(EVENT_MAIEV_EXCLAMATION, Seconds(2)); - _events.ScheduleEvent(EVENT_MAIEV_JUSTICE_TEXT, Seconds(14)); - _events.ScheduleEvent(EVENT_TAUNT, Seconds(20), Seconds(60)); - _canDown = true; + Talk(SAY_MAIEV_SHADOWSONG_FINISHED); + _events.ScheduleEvent(EVENT_MAIEV_OUTRO_TEXT, Seconds(28)); } + else if (actionId == ACTION_MAIEV_DOWN_FADE) + _canDown = true; + } - void EnterCombat(Unit* /*who*/) override + void DamageTaken(Unit* /*who*/, uint32 &damage) override + { + if (damage >= me->GetHealth() && _canDown) { - _events.SetPhase(PHASE_1); - _events.ScheduleEvent(EVENT_CAGE_TRAP, Seconds(30)); - _events.ScheduleEvent(EVENT_SHADOW_STRIKE, Seconds(50)); - _events.ScheduleEvent(EVENT_THROW_DAGGER, Seconds(1)); + damage = me->GetHealth() - 1; + _canDown = false; + DoCastSelf(SPELL_MAIEV_DOWN, true); + Talk(SAY_MAIEV_SHADOWSONG_DOWN, me); } + } - void DoAction(int32 actionId) override - { - if (actionId == ACTION_START_OUTRO) - { - _events.Reset(); - me->SetReactState(REACT_PASSIVE); - me->AttackStop(); - if (Creature* illidan = _instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) - me->SetFacingToObject(illidan); - Talk(SAY_MAIEV_SHADOWSONG_FINISHED); - _events.ScheduleEvent(EVENT_MAIEV_OUTRO_TEXT, Seconds(28)); - } - else if (actionId == ACTION_MAIEV_DOWN_FADE) - _canDown = true; - } + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim() && !_events.IsInPhase(PHASE_INTRO)) + return; + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + _events.Update(diff); - void DamageTaken(Unit* /*who*/, uint32 &damage) override + while (uint32 eventId = _events.ExecuteEvent()) { - if (damage >= me->GetHealth() && _canDown) + switch (eventId) { - damage = me->GetHealth() - 1; - _canDown = false; - DoCastSelf(SPELL_MAIEV_DOWN, true); - Talk(SAY_MAIEV_SHADOWSONG_DOWN, me); + case EVENT_MAIEV_APPEAR: + Talk(SAY_MAIEV_SHADOWSONG_APPEAR); + break; + case EVENT_MAIEV_EXCLAMATION: + me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION); + break; + case EVENT_MAIEV_JUSTICE_TEXT: + Talk(SAY_MAIEV_SHADOWSONG_JUSTICE); + _events.ScheduleEvent(EVENT_MAIEV_YES, Seconds(2)); + break; + case EVENT_MAIEV_YES: + me->HandleEmoteCommand(EMOTE_ONESHOT_YES); + _events.ScheduleEvent(EVENT_MAIEV_ROAR, Seconds(3)); + break; + case EVENT_MAIEV_ROAR: + me->HandleEmoteCommand(EMOTE_ONESHOT_ROAR); + _events.ScheduleEvent(EVENT_MAIEV_COMBAT, Seconds(3)); + break; + case EVENT_MAIEV_COMBAT: + me->SetReactState(REACT_AGGRESSIVE); + if (Creature* illidan = _instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) + AttackStart(illidan); + break; + case EVENT_CAGE_TRAP: + if (Creature* illidan = _instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) + illidan->CastSpell(illidan, SPELL_CAGED_TRAP_TELEPORT, true); + DoCastSelf(SPELL_CAGE_TRAP_SUMMON); + Talk(SAY_MAIEV_SHADOWSONG_TRAP); + _events.Repeat(Seconds(30)); + break; + case EVENT_SHADOW_STRIKE: + DoCastVictim(SPELL_SHADOW_STRIKE); + _events.Repeat(Seconds(50)); + break; + case EVENT_THROW_DAGGER: + if (Unit* target = me->GetVictim()) + if (!me->IsWithinMeleeRange(target)) + { + DoCastVictim(SPELL_THROW_DAGGER); + _events.Repeat(Seconds(5)); + break; + } + _events.Repeat(Seconds(1)); + break; + case EVENT_TAUNT: + Talk(SAY_MAIEV_SHADOWSONG_TAUNT); + _events.Repeat(Seconds(30), Seconds(60)); + break; + case EVENT_MAIEV_OUTRO_TEXT: + Talk(SAY_MAIEV_SHADOWSONG_OUTRO); + _events.ScheduleEvent(EVENT_MAIEV_FAREWELL_TEXT, Seconds(11)); + break; + case EVENT_MAIEV_FAREWELL_TEXT: + Talk(SAY_MAIEV_SHADOWSONG_FAREWELL); + _events.ScheduleEvent(EVENT_MAIEV_TELEPORT_DESPAWN, Seconds(3)); + break; + case EVENT_MAIEV_TELEPORT_DESPAWN: + DoCastSelf(SPELL_TELEPORT_VISUAL); + me->DespawnOrUnsummon(Seconds(1)); + break; + default: + break; } - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim() && !_events.IsInPhase(PHASE_INTRO)) - return; if (me->HasUnitState(UNIT_STATE_CASTING)) return; + } - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_MAIEV_APPEAR: - Talk(SAY_MAIEV_SHADOWSONG_APPEAR); - break; - case EVENT_MAIEV_EXCLAMATION: - me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION); - break; - case EVENT_MAIEV_JUSTICE_TEXT: - Talk(SAY_MAIEV_SHADOWSONG_JUSTICE); - _events.ScheduleEvent(EVENT_MAIEV_YES, Seconds(2)); - break; - case EVENT_MAIEV_YES: - me->HandleEmoteCommand(EMOTE_ONESHOT_YES); - _events.ScheduleEvent(EVENT_MAIEV_ROAR, Seconds(3)); - break; - case EVENT_MAIEV_ROAR: - me->HandleEmoteCommand(EMOTE_ONESHOT_ROAR); - _events.ScheduleEvent(EVENT_MAIEV_COMBAT, Seconds(3)); - break; - case EVENT_MAIEV_COMBAT: - me->SetReactState(REACT_AGGRESSIVE); - if (Creature* illidan = _instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) - AttackStart(illidan); - break; - case EVENT_CAGE_TRAP: - if (Creature* illidan = _instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) - illidan->CastSpell(illidan, SPELL_CAGED_TRAP_TELEPORT, true); - DoCastSelf(SPELL_CAGE_TRAP_SUMMON); - Talk(SAY_MAIEV_SHADOWSONG_TRAP); - _events.Repeat(Seconds(30)); - break; - case EVENT_SHADOW_STRIKE: - DoCastVictim(SPELL_SHADOW_STRIKE); - _events.Repeat(Seconds(50)); - break; - case EVENT_THROW_DAGGER: - if (Unit* target = me->GetVictim()) - if (!me->IsWithinMeleeRange(target)) - { - DoCastVictim(SPELL_THROW_DAGGER); - _events.Repeat(Seconds(5)); - break; - } - _events.Repeat(Seconds(1)); - break; - case EVENT_TAUNT: - Talk(SAY_MAIEV_SHADOWSONG_TAUNT); - _events.Repeat(Seconds(30), Seconds(60)); - break; - case EVENT_MAIEV_OUTRO_TEXT: - Talk(SAY_MAIEV_SHADOWSONG_OUTRO); - _events.ScheduleEvent(EVENT_MAIEV_FAREWELL_TEXT, Seconds(11)); - break; - case EVENT_MAIEV_FAREWELL_TEXT: - Talk(SAY_MAIEV_SHADOWSONG_FAREWELL); - _events.ScheduleEvent(EVENT_MAIEV_TELEPORT_DESPAWN, Seconds(3)); - break; - case EVENT_MAIEV_TELEPORT_DESPAWN: - DoCastSelf(SPELL_TELEPORT_VISUAL); - me->DespawnOrUnsummon(Seconds(1)); - break; - default: - break; - } + DoMeleeAttackIfReady(); + } - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - } +private: + EventMap _events; + InstanceScript* _instance; + bool _canDown; +}; - DoMeleeAttackIfReady(); - } +struct npc_cage_trap_trigger : public PassiveAI +{ + npc_cage_trap_trigger(Creature* creature) : PassiveAI(creature) { } - private: - EventMap _events; - InstanceScript* _instance; - bool _canDown; - }; + void Reset() override + { + _scheduler.Schedule(Seconds(1), [this](TaskContext checkTarget) + { + DoCastSelf(SPELL_CAGE_TRAP_PERIODIC); + checkTarget.Repeat(); + }); + } - CreatureAI* GetAI(Creature* creature) const override + void UpdateAI(uint32 diff) override { - return GetBlackTempleAI<npc_maievAI>(creature); + _scheduler.Update(diff); } + +private: + TaskScheduler _scheduler; }; -class npc_cage_trap_trigger : public CreatureScript +struct npc_illidari_elite : public ScriptedAI { -public: - npc_cage_trap_trigger() : CreatureScript("npc_cage_trap_trigger") { } + npc_illidari_elite(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { } - struct npc_cage_trap_triggerAI : public PassiveAI + void Reset() override { - npc_cage_trap_triggerAI(Creature* creature) : PassiveAI(creature) { } - - void Reset() override + if (Creature* akama = _instance->GetCreature(DATA_AKAMA)) { - _scheduler.Schedule(Seconds(1), [this](TaskContext checkTarget) - { - DoCastSelf(SPELL_CAGE_TRAP_PERIODIC); - checkTarget.Repeat(); - }); + AttackStart(akama); + AddThreat(akama, 1000.0f); } + } - void UpdateAI(uint32 diff) override - { - _scheduler.Update(diff); - } - - private: - TaskScheduler _scheduler; - }; - - CreatureAI* GetAI(Creature* creature) const override + bool CanAIAttack(Unit const* who) const override { - return GetBlackTempleAI<npc_cage_trap_triggerAI>(creature); + if (who->GetEntry() == NPC_AKAMA) + return true; + return false; } + +private: + InstanceScript* _instance; }; // 41077 - Akama Teleport -class spell_illidan_akama_teleport : public SpellScriptLoader +class spell_illidan_akama_teleport : public SpellScript { - public: - spell_illidan_akama_teleport() : SpellScriptLoader("spell_illidan_akama_teleport") { } - - class spell_illidan_akama_teleport_SpellScript : public SpellScript - { - PrepareSpellScript(spell_illidan_akama_teleport_SpellScript); - - void SetDest(SpellDestination& dest) - { - if (Creature* caster = GetCaster()->ToCreature()) - { - uint32 destination = caster->AI()->GetData(DATA_AKAMA_TELEPORT_POSITION); - dest.Relocate(AkamaTeleportPositions[destination]); - } - } - - void Register() override - { - OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_illidan_akama_teleport_SpellScript::SetDest, EFFECT_0, TARGET_DEST_NEARBY_ENTRY); - } - }; + PrepareSpellScript(spell_illidan_akama_teleport); - SpellScript* GetSpellScript() const override + void SetDest(SpellDestination& dest) + { + if (Creature* caster = GetCaster()->ToCreature()) { - return new spell_illidan_akama_teleport_SpellScript(); + uint32 destination = caster->AI()->GetData(DATA_AKAMA_TELEPORT_POSITION); + dest.Relocate(AkamaTeleportPositions[destination]); } + } + + void Register() override + { + OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_illidan_akama_teleport::SetDest, EFFECT_0, TARGET_DEST_NEARBY_ENTRY); + } }; // 41268 - Quest - Black Temple - Akama - Door Open -class spell_illidan_akama_door_channel : public SpellScriptLoader +class spell_illidan_akama_door_channel : public AuraScript { - public: - spell_illidan_akama_door_channel() : SpellScriptLoader("spell_illidan_akama_door_channel") { } - - class spell_illidan_akama_door_channel_AuraScript : public AuraScript - { - PrepareAuraScript(spell_illidan_akama_door_channel_AuraScript); + PrepareAuraScript(spell_illidan_akama_door_channel); - bool Validate(SpellInfo const* /*spell*/) override - { - return ValidateSpellInfo({ SPELL_ARCANE_EXPLOSION }); - } - - void OnRemoveDummy(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - Unit* target = GetTarget(); - target->CastSpell(target, SPELL_ARCANE_EXPLOSION, true); + bool Validate(SpellInfo const* /*spell*/) override + { + return ValidateSpellInfo({ SPELL_ARCANE_EXPLOSION }); + } - if (InstanceScript* instance = target->GetInstanceScript()) - if (Creature* akama = instance->GetCreature(DATA_AKAMA)) - akama->AI()->DoAction(ACTION_OPEN_DOOR); - } + void OnRemoveDummy(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + target->CastSpell(target, SPELL_ARCANE_EXPLOSION, true); - void Register() override - { - AfterEffectRemove += AuraEffectRemoveFn(spell_illidan_akama_door_channel_AuraScript::OnRemoveDummy, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - } - }; + if (InstanceScript* instance = target->GetInstanceScript()) + if (Creature* akama = instance->GetCreature(DATA_AKAMA)) + akama->AI()->DoAction(ACTION_OPEN_DOOR); + } - AuraScript* GetAuraScript() const override - { - return new spell_illidan_akama_door_channel_AuraScript(); - } + void Register() override + { + AfterEffectRemove += AuraEffectRemoveFn(spell_illidan_akama_door_channel::OnRemoveDummy, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } }; // 40904 - Draw Soul -class spell_illidan_draw_soul : public SpellScriptLoader +class spell_illidan_draw_soul : public SpellScript { - public: - spell_illidan_draw_soul() : SpellScriptLoader("spell_illidan_draw_soul") { } + PrepareSpellScript(spell_illidan_draw_soul); - class spell_illidan_draw_soul_SpellScript : public SpellScript - { - PrepareSpellScript(spell_illidan_draw_soul_SpellScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DRAW_SOUL_HEAL }); - } - - void HandleScriptEffect(SpellEffIndex effIndex) - { - PreventHitDefaultEffect(effIndex); - GetHitUnit()->CastSpell(GetCaster(), SPELL_DRAW_SOUL_HEAL, true); - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_DRAW_SOUL_HEAL }); + } - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_illidan_draw_soul_SpellScript::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); - } - }; + void HandleScriptEffect(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + GetHitUnit()->CastSpell(GetCaster(), SPELL_DRAW_SOUL_HEAL, true); + } - SpellScript* GetSpellScript() const override - { - return new spell_illidan_draw_soul_SpellScript(); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_illidan_draw_soul::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); + } }; /* 41917 - Parasitic Shadowfiend 41914 - Parasitic Shadowfiend */ -class spell_illidan_parasitic_shadowfiend : public SpellScriptLoader +class spell_illidan_parasitic_shadowfiend : public AuraScript { - public: - spell_illidan_parasitic_shadowfiend() : SpellScriptLoader("spell_illidan_parasitic_shadowfiend") { } + PrepareAuraScript(spell_illidan_parasitic_shadowfiend); - class spell_illidan_parasitic_shadowfiend_AuraScript : public AuraScript - { - PrepareAuraScript(spell_illidan_parasitic_shadowfiend_AuraScript); + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SUMMON_PARASITIC_SHADOWFIENDS }); + } - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_SUMMON_PARASITIC_SHADOWFIENDS }); - } + void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + AuraRemoveMode removeMode = GetTargetApplication()->GetRemoveMode(); + if (removeMode != AURA_REMOVE_BY_EXPIRE && removeMode != AURA_REMOVE_BY_DEATH) + return; - void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - Unit* target = GetTarget(); - target->CastSpell(target, SPELL_SUMMON_PARASITIC_SHADOWFIENDS, true); - } + Unit* target = GetTarget(); + target->CastSpell(target, SPELL_SUMMON_PARASITIC_SHADOWFIENDS, true); + } - void Register() override - { - AfterEffectRemove += AuraEffectRemoveFn(spell_illidan_parasitic_shadowfiend_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL); - } - }; + void Register() override + { + AfterEffectRemove += AuraEffectRemoveFn(spell_illidan_parasitic_shadowfiend::HandleEffectRemove, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL); + } +}; - AuraScript* GetAuraScript() const override - { - return new spell_illidan_parasitic_shadowfiend_AuraScript(); - } +// 41923 - Remove Parasitic Shadowfiends (SERVERSIDE) +class spell_illidan_remove_parasitic_shadowfiend : public AuraScript +{ + PrepareAuraScript(spell_illidan_remove_parasitic_shadowfiend); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_PARASITIC_SHADOWFIEND, SPELL_PARASITIC_SHADOWFIEND_2 }); + } + + void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->RemoveAurasDueToSpell(SPELL_PARASITIC_SHADOWFIEND); + GetTarget()->RemoveAurasDueToSpell(SPELL_PARASITIC_SHADOWFIEND_2); + } + + void Register() override + { + AfterEffectApply += AuraEffectApplyFn(spell_illidan_remove_parasitic_shadowfiend::HandleApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } }; /* 39635 - Throw Glaive 39849 - Throw Glaive */ -class spell_illidan_throw_warglaive : public SpellScriptLoader +class spell_illidan_throw_warglaive : public SpellScript { - public: - spell_illidan_throw_warglaive() : SpellScriptLoader("spell_illidan_throw_warglaive") { } + PrepareSpellScript(spell_illidan_throw_warglaive); - class spell_illidan_throw_warglaive_SpellScript : public SpellScript - { - PrepareSpellScript(spell_illidan_throw_warglaive_SpellScript); - - void HandleDummy(SpellEffIndex /*effIndex*/) - { - Unit* target = GetHitUnit(); - target->m_Events.AddEvent(new SummonWarglaiveEvent(target), target->m_Events.CalculateTime(1000)); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_illidan_throw_warglaive_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + void HandleDummy(SpellEffIndex /*effIndex*/) + { + Unit* target = GetHitUnit(); + target->m_Events.AddEvent(new SummonWarglaiveEvent(target), target->m_Events.CalculateTime(1000)); + } - SpellScript* GetSpellScript() const override - { - return new spell_illidan_throw_warglaive_SpellScript(); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_illidan_throw_warglaive::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; // 39857 - Tear of Azzinoth Summon Channel -class spell_illidan_tear_of_azzinoth_channel : public SpellScriptLoader +class spell_illidan_tear_of_azzinoth_channel : public AuraScript { - public: - spell_illidan_tear_of_azzinoth_channel() : SpellScriptLoader("spell_illidan_tear_of_azzinoth_channel") { } - - class spell_illidan_tear_of_azzinoth_channel_AuraScript : public AuraScript - { - PrepareAuraScript(spell_illidan_tear_of_azzinoth_channel_AuraScript); + PrepareAuraScript(spell_illidan_tear_of_azzinoth_channel); - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_UNCAGED_WRATH }); - } - - void OnPeriodic(AuraEffect const* /*aurEff*/) - { - PreventDefaultAction(); - if (Unit* caster = GetCaster()) - { - Unit* target = GetTarget(); - if (caster->GetDistance2d(target) > 25.0f) - { - target->CastSpell(target, SPELL_UNCAGED_WRATH, true); - Remove(); - } - } - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_UNCAGED_WRATH }); + } - void Register() override + void OnPeriodic(AuraEffect const* /*aurEff*/) + { + PreventDefaultAction(); + if (Unit* caster = GetCaster()) + { + Unit* target = GetTarget(); + if (caster->GetDistance2d(target) > 25.0f) { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_illidan_tear_of_azzinoth_channel_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + target->CastSpell(target, SPELL_UNCAGED_WRATH, true); + Remove(); } - }; - - AuraScript* GetAuraScript() const override - { - return new spell_illidan_tear_of_azzinoth_channel_AuraScript(); } + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_illidan_tear_of_azzinoth_channel::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } }; // 40631 - Flame Blast -class spell_illidan_flame_blast : public SpellScriptLoader +class spell_illidan_flame_blast : public SpellScript { - public: - spell_illidan_flame_blast() : SpellScriptLoader("spell_illidan_flame_blast") { } + PrepareSpellScript(spell_illidan_flame_blast); - class spell_illidan_flame_blast_SpellScript : public SpellScript - { - PrepareSpellScript(spell_illidan_flame_blast_SpellScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_BLAZE_SUMMON }); - } - - void HandleBlaze(SpellEffIndex /*effIndex*/) - { - Unit* target = GetHitUnit(); - if (target->GetTypeId() == TYPEID_PLAYER) - target->CastSpell(target, SPELL_BLAZE_SUMMON, true); - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_BLAZE_SUMMON }); + } - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_illidan_flame_blast_SpellScript::HandleBlaze, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); - } - }; + void HandleBlaze(SpellEffIndex /*effIndex*/) + { + Unit* target = GetHitUnit(); + if (target->GetTypeId() == TYPEID_PLAYER) + target->CastSpell(target, SPELL_BLAZE_SUMMON, true); + } - SpellScript* GetSpellScript() const override - { - return new spell_illidan_flame_blast_SpellScript(); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_illidan_flame_blast::HandleBlaze, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); + } }; // 39873 - Glaive Returns -class spell_illidan_return_glaives : public SpellScriptLoader +class spell_illidan_return_glaives : public SpellScript { - public: spell_illidan_return_glaives() : SpellScriptLoader("spell_illidan_return_glaives") { } - - class spell_illidan_return_glaives_SpellScript : public SpellScript - { - PrepareSpellScript(spell_illidan_return_glaives_SpellScript); - - void HandleScriptEffect(SpellEffIndex /*effIndex*/) - { - GetHitUnit()->SendPlaySpellVisual(SPELL_GLAIVE_VISUAL_KIT); - if (Creature* caster = GetCaster()->ToCreature()) - caster->DespawnOrUnsummon(); - } + PrepareSpellScript(spell_illidan_return_glaives); - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_illidan_return_glaives_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - } - }; + void HandleScriptEffect(SpellEffIndex /*effIndex*/) + { + GetHitUnit()->SendPlaySpellVisual(SPELL_GLAIVE_VISUAL_KIT); + if (Creature* caster = GetCaster()->ToCreature()) + caster->DespawnOrUnsummon(); + } - SpellScript* GetSpellScript() const override - { - return new spell_illidan_return_glaives_SpellScript(); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_illidan_return_glaives::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } }; // 40834 - Agonizing Flames -class spell_illidan_agonizing_flames : public SpellScriptLoader +class spell_illidan_agonizing_flames : public SpellScript { - public: - spell_illidan_agonizing_flames() : SpellScriptLoader("spell_illidan_agonizing_flames") { } - - class spell_illidan_agonizing_flames_SpellScript : public SpellScript - { - PrepareSpellScript(spell_illidan_agonizing_flames_SpellScript); + PrepareSpellScript(spell_illidan_agonizing_flames); - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_AGONIZING_FLAMES }); - } - - void FilterTargets(std::list<WorldObject*>& targets) - { - if (targets.empty()) - return; + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_AGONIZING_FLAMES }); + } - WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets); - targets.clear(); - targets.push_back(target); - } + void FilterTargets(std::list<WorldObject*>& targets) + { + if (targets.empty()) + return; - void HandleScript(SpellEffIndex /*effIndex*/) - { - GetCaster()->CastSpell(GetHitUnit(), SPELL_AGONIZING_FLAMES, true); - } + WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets); + targets.clear(); + targets.push_back(target); + } - void Register() override - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_illidan_agonizing_flames_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); - OnEffectHitTarget += SpellEffectFn(spell_illidan_agonizing_flames_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + void HandleScript(SpellEffIndex /*effIndex*/) + { + GetCaster()->CastSpell(GetHitUnit(), SPELL_AGONIZING_FLAMES, true); + } - SpellScript* GetSpellScript() const override - { - return new spell_illidan_agonizing_flames_SpellScript(); - } + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_illidan_agonizing_flames::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + OnEffectHitTarget += SpellEffectFn(spell_illidan_agonizing_flames::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; // 40511 - Demon Transform 1 -class spell_illidan_demon_transform1 : public SpellScriptLoader +class spell_illidan_demon_transform1 : public AuraScript { - public: - spell_illidan_demon_transform1() : SpellScriptLoader("spell_illidan_demon_transform1") { } - - class spell_illidan_demon_transform1_AuraScript : public AuraScript - { - PrepareAuraScript(spell_illidan_demon_transform1_AuraScript); + PrepareAuraScript(spell_illidan_demon_transform1); - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DEMON_TRANSFORM_2 }); - } - - void OnPeriodic(AuraEffect const* /*aurEff*/) - { - PreventDefaultAction(); - GetTarget()->CastSpell(GetTarget(), SPELL_DEMON_TRANSFORM_2, true); - Remove(); - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_DEMON_TRANSFORM_2 }); + } - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_illidan_demon_transform1_AuraScript::OnPeriodic, EFFECT_1, SPELL_AURA_PERIODIC_TRIGGER_SPELL); - } - }; + void OnPeriodic(AuraEffect const* /*aurEff*/) + { + PreventDefaultAction(); + GetTarget()->CastSpell(GetTarget(), SPELL_DEMON_TRANSFORM_2, true); + Remove(); + } - AuraScript* GetAuraScript() const override - { - return new spell_illidan_demon_transform1_AuraScript(); - } + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_illidan_demon_transform1::OnPeriodic, EFFECT_1, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } }; + // 40398 - Demon Transform 2 -class spell_illidan_demon_transform2 : public SpellScriptLoader +class spell_illidan_demon_transform2 : public AuraScript { - public: - spell_illidan_demon_transform2() : SpellScriptLoader("spell_illidan_demon_transform2") { } - - class spell_illidan_demon_transform2_AuraScript : public AuraScript - { - PrepareAuraScript(spell_illidan_demon_transform2_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DEMON_FORM, SPELL_DEMON_TRANSFORM_3 }); - } - - void OnPeriodic(AuraEffect const* aurEff) - { - PreventDefaultAction(); - Unit* target = GetTarget(); + PrepareAuraScript(spell_illidan_demon_transform2); - if (aurEff->GetTickNumber() == 1) - { - if (target->GetDisplayId() == target->GetNativeDisplayId()) - target->CastSpell(target, SPELL_DEMON_FORM, true); - else - target->RemoveAurasDueToSpell(SPELL_DEMON_FORM); - } - else if (aurEff->GetTickNumber() == 2) - { - target->CastSpell(target, SPELL_DEMON_TRANSFORM_3, true); - if (Aura* aura = GetUnitOwner()->GetAura(SPELL_DEMON_TRANSFORM_3)) - aura->SetDuration(4300); - Remove(); - } - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_DEMON_FORM, SPELL_DEMON_TRANSFORM_3 }); + } - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_illidan_demon_transform2_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); - } - }; + void OnPeriodic(AuraEffect const* aurEff) + { + PreventDefaultAction(); + Unit* target = GetTarget(); - AuraScript* GetAuraScript() const override + if (aurEff->GetTickNumber() == 1) + { + if (target->GetDisplayId() == target->GetNativeDisplayId()) + target->CastSpell(target, SPELL_DEMON_FORM, true); + else + target->RemoveAurasDueToSpell(SPELL_DEMON_FORM); + } + else if (aurEff->GetTickNumber() == 2) { - return new spell_illidan_demon_transform2_AuraScript(); + target->CastSpell(target, SPELL_DEMON_TRANSFORM_3, true); + if (Aura* aura = GetUnitOwner()->GetAura(SPELL_DEMON_TRANSFORM_3)) + aura->SetDuration(4300); + Remove(); } + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_illidan_demon_transform2::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } }; // 41126 - Flame Burst -class spell_illidan_flame_burst : public SpellScriptLoader +class spell_illidan_flame_burst : public SpellScript { - public: - spell_illidan_flame_burst() : SpellScriptLoader("spell_illidan_flame_burst") { } - - class spell_illidan_flame_burst_SpellScript : public SpellScript - { - PrepareSpellScript(spell_illidan_flame_burst_SpellScript); + PrepareSpellScript(spell_illidan_flame_burst); - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_FLAME_BURST_EFFECT }); - } - - void HandleScriptEffect(SpellEffIndex /*effIndex*/) - { - GetHitUnit()->CastSpell(GetHitUnit(), SPELL_FLAME_BURST_EFFECT, true); - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_FLAME_BURST_EFFECT }); + } - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_illidan_flame_burst_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - } - }; + void HandleScriptEffect(SpellEffIndex /*effIndex*/) + { + GetHitUnit()->CastSpell(GetHitUnit(), SPELL_FLAME_BURST_EFFECT, true); + } - SpellScript* GetSpellScript() const override - { - return new spell_illidan_flame_burst_SpellScript(); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_illidan_flame_burst::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } }; // 41081 - Find Target -class spell_illidan_find_target : public SpellScriptLoader +class spell_illidan_find_target : public SpellScript { - public: - spell_illidan_find_target() : SpellScriptLoader("spell_illidan_find_target") { } - - class spell_illidan_find_target_SpellScript : public SpellScript - { - PrepareSpellScript(spell_illidan_find_target_SpellScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_PARALYZE }); - } + PrepareSpellScript(spell_illidan_find_target); - void FilterTargets(std::list<WorldObject*>& targets) - { - targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_PARALYZE)); + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_PARALYZE }); + } - if (targets.empty()) - return; + void FilterTargets(std::list<WorldObject*>& targets) + { + targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_PARALYZE)); - WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets); - targets.clear(); - targets.push_back(target); - } + if (targets.empty()) + return; - void HandleScript(SpellEffIndex /*effIndex*/) - { - Unit* target = GetHitUnit(); - if (Creature* caster = GetCaster()->ToCreature()) - { - caster->CastSpell(target, SPELL_PARALYZE, true); - caster->AI()->SetGUID(target->GetGUID(), 0); - } - } - - void Register() override - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_illidan_find_target_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); - OnEffectHitTarget += SpellEffectFn(spell_illidan_find_target_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets); + targets.clear(); + targets.push_back(target); + } - SpellScript* GetSpellScript() const override + void HandleScript(SpellEffIndex /*effIndex*/) + { + Unit* target = GetHitUnit(); + if (Creature* caster = GetCaster()->ToCreature()) { - return new spell_illidan_find_target_SpellScript(); + caster->CastSpell(target, SPELL_PARALYZE, true); + caster->AI()->SetGUID(target->GetGUID(), 0); } + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_illidan_find_target::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + OnEffectHitTarget += SpellEffectFn(spell_illidan_find_target::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; // 39908 - Eye Blast -class spell_illidan_eye_blast : public SpellScriptLoader +class spell_illidan_eye_blast : public AuraScript { - public: - spell_illidan_eye_blast() : SpellScriptLoader("spell_illidan_eye_blast") { } - - class spell_illidan_eye_blast_AuraScript : public AuraScript - { - PrepareAuraScript(spell_illidan_eye_blast_AuraScript); - - void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - if (Creature* target = GetTarget()->ToCreature()) - target->DespawnOrUnsummon(); - } + PrepareAuraScript(spell_illidan_eye_blast); - void Register() override - { - AfterEffectRemove += AuraEffectRemoveFn(spell_illidan_eye_blast_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - } - }; + void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Creature* target = GetTarget()->ToCreature()) + target->DespawnOrUnsummon(); + } - AuraScript* GetAuraScript() const override - { - return new spell_illidan_eye_blast_AuraScript(); - } + void Register() override + { + AfterEffectRemove += AuraEffectRemoveFn(spell_illidan_eye_blast::HandleEffectRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } }; // 40761 - Cage Trap -class spell_illidan_cage_trap : public SpellScriptLoader +class spell_illidan_cage_trap : public SpellScript { - public: - spell_illidan_cage_trap() : SpellScriptLoader("spell_illidan_cage_trap") { } - - class spell_illidan_cage_trap_SpellScript : public SpellScript - { - PrepareSpellScript(spell_illidan_cage_trap_SpellScript); - - void HandleScriptEffect(SpellEffIndex /*effIndex*/) - { - Creature* target = GetHitCreature(); - Creature* caster = GetCaster()->ToCreature(); - - if (!target || !caster) - return; + PrepareSpellScript(spell_illidan_cage_trap); - if (caster->GetDistance2d(target) < 4.0f) - { - target->AI()->DoAction(ACTION_ILLIDAN_CAGED); - caster->DespawnOrUnsummon(); - if (GameObject* trap = target->FindNearestGameObject(GO_ILLIDAN_CAGE_TRAP, 10.0f)) - trap->UseDoorOrButton(); - } - } + void HandleScriptEffect(SpellEffIndex /*effIndex*/) + { + Creature* target = GetHitCreature(); + Creature* caster = GetCaster()->ToCreature(); - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_illidan_cage_trap_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - } - }; + if (!target || !caster) + return; - SpellScript* GetSpellScript() const override + if (caster->GetDistance2d(target) < 4.0f) { - return new spell_illidan_cage_trap_SpellScript(); + target->AI()->DoAction(ACTION_ILLIDAN_CAGED); + caster->DespawnOrUnsummon(); + if (GameObject* trap = target->FindNearestGameObject(GO_ILLIDAN_CAGE_TRAP, 10.0f)) + trap->UseDoorOrButton(); } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_illidan_cage_trap::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } }; // 40760 - Cage Trap -class spell_illidan_caged : public SpellScriptLoader +class spell_illidan_caged : public AuraScript { - public: - spell_illidan_caged() : SpellScriptLoader("spell_illidan_caged") { } - - class spell_illidan_caged_AuraScript : public AuraScript - { - PrepareAuraScript(spell_illidan_caged_AuraScript); + PrepareAuraScript(spell_illidan_caged); - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_CAGED_DEBUFF }); - } - - void OnPeriodic(AuraEffect const* /*aurEff*/) - { - PreventDefaultAction(); - Unit* target = GetTarget(); - target->CastSpell(target, SPELL_CAGED_DEBUFF, true); - Remove(); - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_CAGED_DEBUFF }); + } - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_illidan_caged_AuraScript::OnPeriodic, EFFECT_1, SPELL_AURA_PERIODIC_TRIGGER_SPELL); - } - }; + void OnPeriodic(AuraEffect const* /*aurEff*/) + { + PreventDefaultAction(); + Unit* target = GetTarget(); + target->CastSpell(target, SPELL_CAGED_DEBUFF, true); + Remove(); + } - AuraScript* GetAuraScript() const override - { - return new spell_illidan_caged_AuraScript(); - } + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_illidan_caged::OnPeriodic, EFFECT_1, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } }; // 40409 - Maiev Down -class spell_maiev_down : public SpellScriptLoader +class spell_maiev_down : public AuraScript { -public: - spell_maiev_down() : SpellScriptLoader("spell_maiev_down") { } + PrepareAuraScript(spell_maiev_down); - class spell_maiev_down_AuraScript : public AuraScript + bool Load() override { - PrepareAuraScript(spell_maiev_down_AuraScript); - - bool Load() override - { - return GetUnitOwner()->GetTypeId() == TYPEID_UNIT; - } - - void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - GetTarget()->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - } + return GetUnitOwner()->GetTypeId() == TYPEID_UNIT; + } - void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - GetTarget()->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - GetTarget()->GetAI()->DoAction(ACTION_MAIEV_DOWN_FADE); - } + void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + } - void Register() override - { - OnEffectApply += AuraEffectApplyFn(spell_maiev_down_AuraScript::HandleEffectApply, EFFECT_1, SPELL_AURA_MOD_STUN, AURA_EFFECT_HANDLE_REAL); - AfterEffectRemove += AuraEffectRemoveFn(spell_maiev_down_AuraScript::HandleEffectRemove, EFFECT_1, SPELL_AURA_MOD_STUN, AURA_EFFECT_HANDLE_REAL); - } - }; + void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + GetTarget()->GetAI()->DoAction(ACTION_MAIEV_DOWN_FADE); + } - AuraScript* GetAuraScript() const override + void Register() override { - return new spell_maiev_down_AuraScript(); + OnEffectApply += AuraEffectApplyFn(spell_maiev_down::HandleEffectApply, EFFECT_1, SPELL_AURA_MOD_STUN, AURA_EFFECT_HANDLE_REAL); + AfterEffectRemove += AuraEffectRemoveFn(spell_maiev_down::HandleEffectRemove, EFFECT_1, SPELL_AURA_MOD_STUN, AURA_EFFECT_HANDLE_REAL); } }; // 40693 - Cage Trap -class spell_illidan_cage_teleport : public SpellScriptLoader +class spell_illidan_cage_teleport : public SpellScript { - public: - spell_illidan_cage_teleport() : SpellScriptLoader("spell_illidan_cage_teleport") { } - - class spell_illidan_cage_teleport_SpellScript : public SpellScript - { - PrepareSpellScript(spell_illidan_cage_teleport_SpellScript); - - void SetDest(SpellDestination& dest) - { - Position offset = { 0.0f, 0.0f, GetCaster()->GetPositionZ(), 0.0f }; - dest.RelocateOffset(offset); - } + PrepareSpellScript(spell_illidan_cage_teleport); - void Register() override - { - OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_illidan_cage_teleport_SpellScript::SetDest, EFFECT_0, TARGET_DEST_CASTER_RADIUS); - } - }; + void SetDest(SpellDestination& dest) + { + Position offset = { 0.0f, 0.0f, GetCaster()->GetPositionZ(), 0.0f }; + dest.RelocateOffset(offset); + } - SpellScript* GetSpellScript() const override - { - return new spell_illidan_cage_teleport_SpellScript(); - } + void Register() override + { + OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_illidan_cage_teleport::SetDest, EFFECT_0, TARGET_DEST_CASTER_RADIUS); + } }; // 41242 - Akama Despawn -class spell_illidan_despawn_akama : public SpellScriptLoader +class spell_illidan_despawn_akama : public SpellScript { - public: - spell_illidan_despawn_akama() : SpellScriptLoader("spell_illidan_despawn_akama") { } - - class spell_illidan_despawn_akama_SpellScript : public SpellScript - { - PrepareSpellScript(spell_illidan_despawn_akama_SpellScript); + PrepareSpellScript(spell_illidan_despawn_akama); - void HandleDummy(SpellEffIndex /*effIndex*/) - { - if (Creature* target = GetHitCreature()) - target->DespawnOrUnsummon(Seconds(1)); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_illidan_despawn_akama_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + void HandleDummy(SpellEffIndex /*effIndex*/) + { + if (Creature* target = GetHitCreature()) + target->DespawnOrUnsummon(Seconds(1)); + } - SpellScript* GetSpellScript() const override - { - return new spell_illidan_despawn_akama_SpellScript(); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_illidan_despawn_akama::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; void AddSC_boss_illidan() { - new boss_illidan_stormrage(); - new npc_akama(); - new npc_parasitic_shadowfiend(); - new npc_blade_of_azzinoth(); - new npc_flame_of_azzinoth(); - new npc_illidan_db_target(); - new npc_maiev(); - new npc_illidan_shadow_demon(); - new npc_cage_trap_trigger(); - new spell_illidan_akama_teleport(); - new spell_illidan_akama_door_channel(); - new spell_illidan_draw_soul(); - new spell_illidan_parasitic_shadowfiend(); - new spell_illidan_throw_warglaive(); - new spell_illidan_tear_of_azzinoth_channel(); - new spell_illidan_flame_blast(); - new spell_illidan_return_glaives(); - new spell_illidan_agonizing_flames(); - new spell_illidan_demon_transform1(); - new spell_illidan_demon_transform2(); - new spell_illidan_flame_burst(); - new spell_illidan_find_target(); - new spell_illidan_eye_blast(); - new spell_illidan_cage_trap(); - new spell_illidan_caged(); - new spell_maiev_down(); - new spell_illidan_cage_teleport(); - new spell_illidan_despawn_akama(); + RegisterBlackTempleCreatureAI(boss_illidan_stormrage); + RegisterBlackTempleCreatureAI(npc_akama_illidan); + RegisterBlackTempleCreatureAI(npc_parasitic_shadowfiend); + RegisterBlackTempleCreatureAI(npc_blade_of_azzinoth); + RegisterBlackTempleCreatureAI(npc_flame_of_azzinoth); + RegisterBlackTempleCreatureAI(npc_illidan_db_target); + RegisterBlackTempleCreatureAI(npc_maiev); + RegisterBlackTempleCreatureAI(npc_shadow_demon); + RegisterBlackTempleCreatureAI(npc_cage_trap_trigger); + RegisterBlackTempleCreatureAI(npc_illidari_elite); + RegisterSpellScript(spell_illidan_akama_teleport); + RegisterAuraScript(spell_illidan_akama_door_channel); + RegisterSpellScript(spell_illidan_draw_soul); + RegisterAuraScript(spell_illidan_parasitic_shadowfiend); + RegisterAuraScript(spell_illidan_remove_parasitic_shadowfiend); + RegisterSpellScript(spell_illidan_throw_warglaive); + RegisterAuraScript(spell_illidan_tear_of_azzinoth_channel); + RegisterSpellScript(spell_illidan_flame_blast); + RegisterSpellScript(spell_illidan_return_glaives); + RegisterSpellScript(spell_illidan_agonizing_flames); + RegisterAuraScript(spell_illidan_demon_transform1); + RegisterAuraScript(spell_illidan_demon_transform2); + RegisterSpellScript(spell_illidan_flame_burst); + RegisterSpellScript(spell_illidan_find_target); + RegisterAuraScript(spell_illidan_eye_blast); + RegisterSpellScript(spell_illidan_cage_trap); + RegisterAuraScript(spell_illidan_caged); + RegisterAuraScript(spell_maiev_down); + RegisterSpellScript(spell_illidan_cage_teleport); + RegisterSpellScript(spell_illidan_despawn_akama); } diff --git a/src/server/scripts/Outland/BlackTemple/boss_illidari_council.cpp b/src/server/scripts/Outland/BlackTemple/boss_illidari_council.cpp index 245f7960628..72597d52d42 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_illidari_council.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_illidari_council.cpp @@ -27,63 +27,63 @@ enum Says { - SAY_COUNCIL_AGRO = 0, - SAY_COUNCIL_ENRAGE = 1, - SAY_COUNCIL_SPECIAL = 2, - SAY_COUNCIL_SLAY = 3, - SAY_COUNCIL_COMNT = 4, - SAY_COUNCIL_DEATH = 5 + SAY_COUNCIL_AGRO = 0, + SAY_COUNCIL_ENRAGE = 1, + SAY_COUNCIL_SPECIAL = 2, + SAY_COUNCIL_SLAY = 3, + SAY_COUNCIL_COMNT = 4, + SAY_COUNCIL_DEATH = 5 }; enum Spells { // Illidari Council (Trigger) - SPELL_EMPYREAL_BALANCE = 41499, - SPELL_EMPYREAL_EQUIVALENCY = 41333, + SPELL_EMPYREAL_BALANCE = 41499, + SPELL_EMPYREAL_EQUIVALENCY = 41333, // Generic - SPELL_SHARED_RULE = 41342, - SPELL_BERSERK = 45078, - SPELL_BALANCE_OF_POWER = 41341, - SPELL_QUIET_SUICIDE = 3617, // Serverside spell + SPELL_SHARED_RULE = 41342, + SPELL_BERSERK = 45078, + SPELL_BALANCE_OF_POWER = 41341, + SPELL_QUIET_SUICIDE = 3617, // High Nethermancer Zerevor's - SPELL_FLAMESTRIKE = 41481, - SPELL_BLIZZARD = 41482, - SPELL_ARCANE_BOLT = 41483, - SPELL_ARCANE_EXPLOSION = 41524, - SPELL_DAMPEN_MAGIC = 41478, + SPELL_FLAMESTRIKE = 41481, + SPELL_BLIZZARD = 41482, + SPELL_ARCANE_BOLT = 41483, + SPELL_ARCANE_EXPLOSION = 41524, + SPELL_DAMPEN_MAGIC = 41478, // Lady Malande's - SPELL_EMPOWERED_SMITE = 41471, - SPELL_CIRCLE_OF_HEALING = 41455, - SPELL_REFLECTIVE_SHIELD = 41475, - SPELL_REFLECTIVE_SHIELD_DAMAGE = 33619, - SPELL_DIVINE_WRATH = 41472, + SPELL_EMPOWERED_SMITE = 41471, + SPELL_CIRCLE_OF_HEALING = 41455, + SPELL_REFLECTIVE_SHIELD = 41475, + SPELL_REFLECTIVE_SHIELD_DAMAGE = 33619, + SPELL_DIVINE_WRATH = 41472, // Gathios the Shatterer's - SPELL_BLESS_PROTECTION = 41450, - SPELL_BLESS_SPELL_WARDING = 41451, - SPELL_CONSECRATION = 41541, - SPELL_HAMMER_OF_JUSTICE = 41468, - SPELL_SEAL_OF_COMMAND = 41469, - SPELL_SEAL_OF_BLOOD = 41459, - SPELL_CHROMATIC_AURA = 41453, - SPELL_DEVOTION_AURA = 41452, - SPELL_JUDGEMENT_PRIMER = 41473, - SPELL_JUDGEMENT = 41467, - SPELL_JUDGEMENT_OF_COMMAND = 41470, - SPELL_JUDGEMENT_OF_BLOOD = 41461, + SPELL_BLESS_PROTECTION = 41450, + SPELL_BLESS_SPELL_WARDING = 41451, + SPELL_CONSECRATION = 41541, + SPELL_HAMMER_OF_JUSTICE = 41468, + SPELL_SEAL_OF_COMMAND = 41469, + SPELL_SEAL_OF_BLOOD = 41459, + SPELL_CHROMATIC_AURA = 41453, + SPELL_DEVOTION_AURA = 41452, + SPELL_JUDGEMENT_PRIMER = 41473, + SPELL_JUDGEMENT = 41467, + SPELL_JUDGEMENT_OF_COMMAND = 41470, + SPELL_JUDGEMENT_OF_BLOOD = 41461, // Veras Darkshadow's - SPELL_DEADLY_STRIKE = 41480, - SPELL_DEADLY_POISON = 41485, - SPELL_ENVENOM = 41487, - SPELL_VANISH = 41476, + SPELL_DEADLY_STRIKE = 41480, + SPELL_DEADLY_POISON = 41485, + SPELL_ENVENOM = 41487, + SPELL_VANISH = 41476, // Veras Vanish Effect - SPELL_BIRTH = 40031, - SPELL_ENVENOM_DUMMY = 41510 + SPELL_BIRTH = 40031, + SPELL_ENVENOM_DUMMY = 41510 }; enum IllidariEvents @@ -131,123 +131,113 @@ static uint32 GetRandomBossExcept(uint32 exception) return bossData[urand(0, 3)]; } -class boss_illidari_council : public CreatureScript +struct boss_illidari_council : public BossAI { -public: - boss_illidari_council() : CreatureScript("boss_illidari_council") { } + boss_illidari_council(Creature* creature) : BossAI(creature, DATA_ILLIDARI_COUNCIL), _inCombat(false) { } - struct boss_illidari_councilAI : public BossAI + void Reset() override { - boss_illidari_councilAI(Creature* creature) : BossAI(creature, DATA_ILLIDARI_COUNCIL), _inCombat(false) { } - - void Reset() override - { - _Reset(); - _inCombat = false; - me->SummonCreatureGroup(SUMMON_COUNCIL_GROUP); - DoCastSelf(SPELL_EMPYREAL_BALANCE, true); - } + _Reset(); + _inCombat = false; + me->SummonCreatureGroup(SUMMON_COUNCIL_GROUP); + DoCastSelf(SPELL_EMPYREAL_BALANCE, true); + } - void EnterCombat(Unit* /*who*/) override + void EnterCombat(Unit* /*who*/) override + { + if (!_inCombat) { - if (!_inCombat) + _inCombat = true; + _EnterCombat(); + for (uint32 bossData : CouncilData) { - _inCombat = true; - _EnterCombat(); - for (uint32 bossData : CouncilData) + if (Creature* council = instance->GetCreature(bossData)) { - if (Creature* council = instance->GetCreature(bossData)) - { - instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, council); - DoZoneInCombat(council); - } + instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, council); + DoZoneInCombat(council); } - events.ScheduleEvent(EVENT_EMPYREAL_EQUIVALENCY, Seconds(2)); - events.ScheduleEvent(EVENT_BERSERK, Minutes(15)); - if (Creature* council = instance->GetCreature(CouncilData[urand(0, 3)])) - council->AI()->Talk(SAY_COUNCIL_AGRO); } + events.ScheduleEvent(EVENT_EMPYREAL_EQUIVALENCY, Seconds(2)); + events.ScheduleEvent(EVENT_BERSERK, Minutes(15)); + if (Creature* council = instance->GetCreature(CouncilData[urand(0, 3)])) + council->AI()->Talk(SAY_COUNCIL_AGRO); } + } - void EnterEvadeMode(EvadeReason /*why*/) override + void EnterEvadeMode(EvadeReason /*why*/) override + { + if (!me->IsInEvadeMode()) { - if (!me->IsInEvadeMode()) - { - _inCombat = false; - for (uint32 bossData : CouncilData) - if (Creature* council = instance->GetCreature(bossData)) - instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, council); + _inCombat = false; + for (uint32 bossData : CouncilData) + if (Creature* council = instance->GetCreature(bossData)) + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, council); - summons.DespawnAll(); - _DespawnAtEvade(); - } + summons.DespawnAll(); + _DespawnAtEvade(); } + } - void JustDied(Unit* /*killer*/) override - { - _inCombat = false; - events.Reset(); - instance->SetBossState(DATA_ILLIDARI_COUNCIL, DONE); + void JustDied(Unit* /*killer*/) override + { + _inCombat = false; + events.Reset(); + instance->SetBossState(DATA_ILLIDARI_COUNCIL, DONE); - for (uint32 bossData : CouncilData) + for (uint32 bossData : CouncilData) + { + if (Creature* council = instance->GetCreature(bossData)) { - if (Creature* council = instance->GetCreature(bossData)) - { - // Allow loot - instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, council); - council->LowerPlayerDamageReq(council->GetMaxHealth()); - council->CastSpell(council, SPELL_QUIET_SUICIDE, true); - } + // Allow loot + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, council); + council->LowerPlayerDamageReq(council->GetMaxHealth()); + council->CastSpell(council, SPELL_QUIET_SUICIDE, true); } } + } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - events.Update(diff); + events.Update(diff); - while (uint32 eventId = events.ExecuteEvent()) + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) { - switch (eventId) - { - case EVENT_EMPYREAL_EQUIVALENCY: - DoCastSelf(SPELL_EMPYREAL_EQUIVALENCY, true); - events.Repeat(Seconds(2)); - break; - case EVENT_BERSERK: - for (uint32 bossData : CouncilData) + case EVENT_EMPYREAL_EQUIVALENCY: + DoCastSelf(SPELL_EMPYREAL_EQUIVALENCY, true); + events.Repeat(Seconds(2)); + break; + case EVENT_BERSERK: + for (uint32 bossData : CouncilData) + { + if (Creature* council = instance->GetCreature(bossData)) { - if (Creature* council = instance->GetCreature(bossData)) - { - council->CastSpell(council, SPELL_BERSERK, true); - council->AI()->Talk(SAY_COUNCIL_ENRAGE); - } + council->CastSpell(council, SPELL_BERSERK, true); + council->AI()->Talk(SAY_COUNCIL_ENRAGE); } - break; - default: - break; - } - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + } + break; + default: + break; } - } - private: - bool _inCombat; - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetBlackTempleAI<boss_illidari_councilAI>(creature); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + } } + +private: + bool _inCombat; }; + struct IllidariCouncilBossAI : public BossAI { IllidariCouncilBossAI(Creature* creature, uint32 bossId) : BossAI(creature, bossId), _bossId(bossId) @@ -317,648 +307,492 @@ private: Unit const* _me; }; -class boss_gathios_the_shatterer : public CreatureScript +struct boss_gathios_the_shatterer : public IllidariCouncilBossAI { -public: - boss_gathios_the_shatterer() : CreatureScript("boss_gathios_the_shatterer") { } + boss_gathios_the_shatterer(Creature* creature) : IllidariCouncilBossAI(creature, DATA_GATHIOS_THE_SHATTERER) { } - struct boss_gathios_the_shattererAI : public IllidariCouncilBossAI + void ScheduleEvents() override { - boss_gathios_the_shattererAI(Creature* creature) : IllidariCouncilBossAI(creature, DATA_GATHIOS_THE_SHATTERER) { } - - void ScheduleEvents() override - { - DoCastSelf(SPELL_SEAL_OF_BLOOD); - events.ScheduleEvent(EVENT_BLESS, Seconds(20)); - events.ScheduleEvent(EVENT_CONSECRATION, Seconds(10)); - events.ScheduleEvent(EVENT_HAMMER_OF_JUSTICE, Seconds(10)); - events.ScheduleEvent(EVENT_JUDGEMENT, Seconds(15)); - events.ScheduleEvent(EVENT_AURA, Seconds(6)); - } + DoCastSelf(SPELL_SEAL_OF_BLOOD); + events.ScheduleEvent(EVENT_BLESS, Seconds(20)); + events.ScheduleEvent(EVENT_CONSECRATION, Seconds(10)); + events.ScheduleEvent(EVENT_HAMMER_OF_JUSTICE, Seconds(10)); + events.ScheduleEvent(EVENT_JUDGEMENT, Seconds(15)); + events.ScheduleEvent(EVENT_AURA, Seconds(6)); + } - void ExecuteEvent(uint32 eventId) override + void ExecuteEvent(uint32 eventId) override + { + switch (eventId) { - switch (eventId) + case EVENT_BLESS: { - case EVENT_BLESS: - { - std::list<Unit*> TargetList; - Trinity::AnyFriendlyUnitInObjectRangeCheck checker(me, me, 100.0f); - Trinity::UnitListSearcher<Trinity::AnyFriendlyUnitInObjectRangeCheck> searcher(me, TargetList, checker); - Cell::VisitAllObjects(me, searcher, 100.0f); + std::list<Unit*> TargetList; + Trinity::AnyFriendlyUnitInObjectRangeCheck checker(me, me, 100.0f); + Trinity::UnitListSearcher<Trinity::AnyFriendlyUnitInObjectRangeCheck> searcher(me, TargetList, checker); + Cell::VisitAllObjects(me, searcher, 100.0f); - if (!TargetList.empty()) - { - Unit* target = Trinity::Containers::SelectRandomContainerElement(TargetList); - DoCast(target, RAND(SPELL_BLESS_PROTECTION, SPELL_BLESS_SPELL_WARDING)); - } - events.Repeat(Seconds(30), Seconds(45)); - break; + if (!TargetList.empty()) + { + Unit* target = Trinity::Containers::SelectRandomContainerElement(TargetList); + DoCast(target, RAND(SPELL_BLESS_PROTECTION, SPELL_BLESS_SPELL_WARDING)); } - case EVENT_AURA: - DoCastSelf(RAND(SPELL_CHROMATIC_AURA, SPELL_DEVOTION_AURA)); - events.Repeat(Seconds(30)); - break; - case EVENT_HAMMER_OF_JUSTICE: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, HammerTargetSelector(me))) - DoCast(target, SPELL_HAMMER_OF_JUSTICE); - events.Repeat(Seconds(20)); - break; - case EVENT_JUDGEMENT: - DoCastVictim(SPELL_JUDGEMENT); - events.Repeat(Seconds(15)); - break; - case EVENT_CONSECRATION: - DoCastSelf(SPELL_CONSECRATION); - events.Repeat(Seconds(30), Seconds(35)); - break; - default: - break; - } + events.Repeat(Seconds(30), Seconds(45)); + break; + } + case EVENT_AURA: + DoCastSelf(RAND(SPELL_CHROMATIC_AURA, SPELL_DEVOTION_AURA)); + events.Repeat(Seconds(30)); + break; + case EVENT_HAMMER_OF_JUSTICE: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, HammerTargetSelector(me))) + DoCast(target, SPELL_HAMMER_OF_JUSTICE); + events.Repeat(Seconds(20)); + break; + case EVENT_JUDGEMENT: + DoCastVictim(SPELL_JUDGEMENT); + events.Repeat(Seconds(15)); + break; + case EVENT_CONSECRATION: + DoCastSelf(SPELL_CONSECRATION); + events.Repeat(Seconds(30), Seconds(35)); + break; + default: + break; } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetBlackTempleAI<boss_gathios_the_shattererAI>(creature); } }; -class boss_high_nethermancer_zerevor : public CreatureScript +struct boss_high_nethermancer_zerevor : public IllidariCouncilBossAI { -public: - boss_high_nethermancer_zerevor() : CreatureScript("boss_high_nethermancer_zerevor") { } + boss_high_nethermancer_zerevor(Creature* creature) : IllidariCouncilBossAI(creature, DATA_HIGH_NETHERMANCER_ZEREVOR), _canUseArcaneExplosion(true) { } - struct boss_high_nethermancer_zerevorAI : public IllidariCouncilBossAI + void Reset() override { - boss_high_nethermancer_zerevorAI(Creature* creature) : IllidariCouncilBossAI(creature, DATA_HIGH_NETHERMANCER_ZEREVOR), _canUseArcaneExplosion(true) { } + IllidariCouncilBossAI::Reset(); + _canUseArcaneExplosion = true; + DoCastSelf(SPELL_DAMPEN_MAGIC); + } - void Reset() override - { - IllidariCouncilBossAI::Reset(); - _canUseArcaneExplosion = true; - DoCastSelf(SPELL_DAMPEN_MAGIC); - } + void ScheduleEvents() override + { + events.ScheduleEvent(EVENT_FLAMESTRIKE, Seconds(8)); + events.ScheduleEvent(EVENT_BLIZZARD, Seconds(25)); + events.ScheduleEvent(EVENT_ARCANE_EXPLOSION, Seconds(5)); + DoCastSelf(SPELL_DAMPEN_MAGIC); + } - void ScheduleEvents() override - { - events.ScheduleEvent(EVENT_FLAMESTRIKE, Seconds(8)); - events.ScheduleEvent(EVENT_BLIZZARD, Seconds(25)); - events.ScheduleEvent(EVENT_ARCANE_EXPLOSION, Seconds(5)); - DoCastSelf(SPELL_DAMPEN_MAGIC); + void DoAction(int32 actionId) override + { + if (actionId == ACTION_REFRESH_DAMPEN) + events.ScheduleEvent(EVENT_DAMPEN_MAGIC, Seconds(50)); + } + void ExecuteEvent(uint32 eventId) override + { + switch (eventId) + { + case EVENT_FLAMESTRIKE: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) + DoCast(target, SPELL_FLAMESTRIKE); + Talk(SAY_COUNCIL_SPECIAL); + events.Repeat(Seconds(40)); + break; + case EVENT_BLIZZARD: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) + DoCast(target, SPELL_BLIZZARD); + events.Repeat(Seconds(15), Seconds(40)); + break; + case EVENT_ARCANE_EXPLOSION_CHECK: + _canUseArcaneExplosion = true; + break; + case EVENT_ARCANE_EXPLOSION: + if (_canUseArcaneExplosion && SelectTarget(SELECT_TARGET_RANDOM, 0, 10.0f)) + { + DoCastSelf(SPELL_ARCANE_EXPLOSION); + _canUseArcaneExplosion = false; + events.ScheduleEvent(EVENT_ARCANE_EXPLOSION_CHECK, Seconds(5)); + } + events.Repeat(Seconds(1)); + break; + case EVENT_DAMPEN_MAGIC: + DoCastSelf(SPELL_DAMPEN_MAGIC); + break; + default: + break; } + } - void DoAction(int32 actionId) override - { - if (actionId == ACTION_REFRESH_DAMPEN) - events.ScheduleEvent(EVENT_DAMPEN_MAGIC, Seconds(50)); - } - void ExecuteEvent(uint32 eventId) override - { - switch (eventId) - { - case EVENT_FLAMESTRIKE: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(target, SPELL_FLAMESTRIKE); - Talk(SAY_COUNCIL_SPECIAL); - events.Repeat(Seconds(40)); - break; - case EVENT_BLIZZARD: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(target, SPELL_BLIZZARD); - events.Repeat(Seconds(15), Seconds(40)); - break; - case EVENT_ARCANE_EXPLOSION_CHECK: - _canUseArcaneExplosion = true; - break; - case EVENT_ARCANE_EXPLOSION: - if (_canUseArcaneExplosion && SelectTarget(SELECT_TARGET_RANDOM, 0, 10.0f)) - { - DoCastSelf(SPELL_ARCANE_EXPLOSION); - _canUseArcaneExplosion = false; - events.ScheduleEvent(EVENT_ARCANE_EXPLOSION_CHECK, Seconds(5)); - } - events.Repeat(Seconds(1)); - break; - case EVENT_DAMPEN_MAGIC: - DoCastSelf(SPELL_DAMPEN_MAGIC); - break; - default: - break; - } - } + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; + events.Update(diff); - events.Update(diff); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + while (uint32 eventId = events.ExecuteEvent()) + { + ExecuteEvent(eventId); if (me->HasUnitState(UNIT_STATE_CASTING)) return; - - while (uint32 eventId = events.ExecuteEvent()) - { - ExecuteEvent(eventId); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - } - - DoSpellAttackIfReady(SPELL_ARCANE_BOLT); } - private: - bool _canUseArcaneExplosion; - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetBlackTempleAI<boss_high_nethermancer_zerevorAI>(creature); + DoSpellAttackIfReady(SPELL_ARCANE_BOLT); } +private: + bool _canUseArcaneExplosion; }; -class boss_lady_malande : public CreatureScript +struct boss_lady_malande : public IllidariCouncilBossAI { -public: - boss_lady_malande() : CreatureScript("boss_lady_malande") { } + boss_lady_malande(Creature* creature) : IllidariCouncilBossAI(creature, DATA_LADY_MALANDE) { } - struct boss_lady_malandeAI : public IllidariCouncilBossAI + void ScheduleEvents() override { - boss_lady_malandeAI(Creature* creature) : IllidariCouncilBossAI(creature, DATA_LADY_MALANDE) { } + events.ScheduleEvent(EVENT_CIRCLE_OF_HEALING, Seconds(20)); + events.ScheduleEvent(EVENT_REFLECTIVE_SHIELD, Seconds(25)); + events.ScheduleEvent(EVENT_DIVINE_WRATH, Seconds(32)); + } - void ScheduleEvents() override - { - events.ScheduleEvent(EVENT_CIRCLE_OF_HEALING, Seconds(20)); - events.ScheduleEvent(EVENT_REFLECTIVE_SHIELD, Seconds(25)); - events.ScheduleEvent(EVENT_DIVINE_WRATH, Seconds(32)); - } + void HealReceived(Unit* /*who*/, uint32& addhealth) override + { + // Need be negative to heal trigger + int32 bp = addhealth * (-1); + me->CastCustomSpell(SPELL_SHARED_RULE, SPELLVALUE_BASE_POINT0, bp, (Unit*) nullptr, true); + } - void HealReceived(Unit* /*who*/, uint32& addhealth) override - { - // Need be negative to heal trigger - int32 bp = addhealth * (-1); - me->CastCustomSpell(SPELL_SHARED_RULE, SPELLVALUE_BASE_POINT0, bp, (Unit*) nullptr, true); + void ExecuteEvent(uint32 eventId) override + { + switch (eventId) + { + case EVENT_CIRCLE_OF_HEALING: + DoCastSelf(SPELL_CIRCLE_OF_HEALING); + events.Repeat(Seconds(20), Seconds(35)); + break; + case EVENT_REFLECTIVE_SHIELD: + DoCastSelf(SPELL_REFLECTIVE_SHIELD); + Talk(SAY_COUNCIL_SPECIAL); + events.Repeat(Seconds(40)); + break; + case EVENT_DIVINE_WRATH: + DoCastVictim(SPELL_DIVINE_WRATH); + events.Repeat(Seconds(20)); + break; + default: + break; } + } - void ExecuteEvent(uint32 eventId) override - { - switch (eventId) - { - case EVENT_CIRCLE_OF_HEALING: - DoCastSelf(SPELL_CIRCLE_OF_HEALING); - events.Repeat(Seconds(20), Seconds(35)); - break; - case EVENT_REFLECTIVE_SHIELD: - DoCastSelf(SPELL_REFLECTIVE_SHIELD); - Talk(SAY_COUNCIL_SPECIAL); - events.Repeat(Seconds(40)); - break; - case EVENT_DIVINE_WRATH: - DoCastVictim(SPELL_DIVINE_WRATH); - events.Repeat(Seconds(20)); - break; - default: - break; - } - } + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; + events.Update(diff); - events.Update(diff); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + while (uint32 eventId = events.ExecuteEvent()) + { + ExecuteEvent(eventId); if (me->HasUnitState(UNIT_STATE_CASTING)) return; - - while (uint32 eventId = events.ExecuteEvent()) - { - ExecuteEvent(eventId); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - } - - DoSpellAttackIfReady(SPELL_EMPOWERED_SMITE); } - }; - CreatureAI* GetAI(Creature* creature) const override - { - return GetBlackTempleAI<boss_lady_malandeAI>(creature); + DoSpellAttackIfReady(SPELL_EMPOWERED_SMITE); } - }; -class boss_veras_darkshadow : public CreatureScript +struct boss_veras_darkshadow : public IllidariCouncilBossAI { -public: - boss_veras_darkshadow() : CreatureScript("boss_veras_darkshadow") { } - - struct boss_veras_darkshadowAI : public IllidariCouncilBossAI + boss_veras_darkshadow(Creature* creature) : IllidariCouncilBossAI(creature, DATA_VERAS_DARKSHADOW) { - boss_veras_darkshadowAI(Creature* creature) : IllidariCouncilBossAI(creature, DATA_VERAS_DARKSHADOW) - { - me->SetMaxHealth(1327900); - me->SetFullHealth(); - } - - void ScheduleEvents() override - { - events.ScheduleEvent(EVENT_DEADLY_STRIKE, Seconds(18)); - events.ScheduleEvent(EVENT_VANISH, Seconds(18)); - } + me->SetMaxHealth(1327900); + me->SetFullHealth(); + } - void ExecuteEvent(uint32 eventId) override - { - switch (eventId) - { - case EVENT_DEADLY_STRIKE: - DoCastSelf(SPELL_DEADLY_STRIKE); - events.Repeat(Seconds(60)); - break; - case EVENT_VANISH: - DoCastSelf(SPELL_VANISH); - Talk(SAY_COUNCIL_SPECIAL); - events.Repeat(Seconds(60)); - break; - default: - break; - } - } - }; + void ScheduleEvents() override + { + events.ScheduleEvent(EVENT_DEADLY_STRIKE, Seconds(18)); + events.ScheduleEvent(EVENT_VANISH, Seconds(18)); + } - CreatureAI* GetAI(Creature* creature) const override + void ExecuteEvent(uint32 eventId) override { - return GetBlackTempleAI<boss_veras_darkshadowAI>(creature); + switch (eventId) + { + case EVENT_DEADLY_STRIKE: + DoCastSelf(SPELL_DEADLY_STRIKE); + events.Repeat(Seconds(60)); + break; + case EVENT_VANISH: + DoCastSelf(SPELL_VANISH); + Talk(SAY_COUNCIL_SPECIAL); + events.Repeat(Seconds(60)); + break; + default: + break; + } } }; -class npc_veras_vanish_effect : public CreatureScript +struct npc_veras_vanish_effect : public PassiveAI { -public: - npc_veras_vanish_effect() : CreatureScript("npc_veras_vanish_effect") { } - - struct npc_veras_vanish_effectAI : public PassiveAI - { - npc_veras_vanish_effectAI(Creature* creature) : PassiveAI(creature) { } - - void Reset() override - { - DoCastSelf(SPELL_BIRTH, true); - DoCastSelf(SPELL_ENVENOM_DUMMY, true); - } - }; + npc_veras_vanish_effect(Creature* creature) : PassiveAI(creature) { } - CreatureAI* GetAI(Creature* creature) const override + void Reset() override { - return GetBlackTempleAI<npc_veras_vanish_effectAI>(creature); + DoCastSelf(SPELL_BIRTH, true); + DoCastSelf(SPELL_ENVENOM_DUMMY, true); } }; // 41499 - Empyreal Balance -class spell_illidari_council_empyreal_balance : public SpellScriptLoader +class spell_illidari_council_empyreal_balance : public SpellScript { - public: - spell_illidari_council_empyreal_balance() : SpellScriptLoader("spell_illidari_council_empyreal_balance") { } - - class spell_illidari_council_empyreal_balance_SpellScript : public SpellScript - { - PrepareSpellScript(spell_illidari_council_empyreal_balance_SpellScript); - - bool Validate(SpellInfo const* /*spell*/) override - { - return ValidateSpellInfo({ SPELL_BALANCE_OF_POWER }); - } + PrepareSpellScript(spell_illidari_council_empyreal_balance); - void HandleDummy(SpellEffIndex /*effIndex*/) - { - Unit* target = GetHitUnit(); - target->CastSpell(target, SPELL_BALANCE_OF_POWER, true); - } + bool Validate(SpellInfo const* /*spell*/) override + { + return ValidateSpellInfo({ SPELL_BALANCE_OF_POWER }); + } - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_illidari_council_empyreal_balance_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + void HandleDummy(SpellEffIndex /*effIndex*/) + { + Unit* target = GetHitUnit(); + target->CastSpell(target, SPELL_BALANCE_OF_POWER, true); + } - SpellScript* GetSpellScript() const override - { - return new spell_illidari_council_empyreal_balance_SpellScript(); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_illidari_council_empyreal_balance::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; // 41333 - Empyreal Equivalency -class spell_illidari_council_empyreal_equivalency : public SpellScriptLoader +class spell_illidari_council_empyreal_equivalency : public SpellScript { - public: - spell_illidari_council_empyreal_equivalency() : SpellScriptLoader("spell_illidari_council_empyreal_equivalency") { } + PrepareSpellScript(spell_illidari_council_empyreal_equivalency); - class spell_illidari_council_empyreal_equivalency_SpellScript : public SpellScript - { - PrepareSpellScript(spell_illidari_council_empyreal_equivalency_SpellScript); - - void HandleScript(SpellEffIndex /*effIndex*/) - { - Unit* target = GetHitUnit(); - int32 casterHpPct = (int32) GetCaster()->GetHealthPct(); - uint32 newHp = target->CountPctFromMaxHealth(casterHpPct); - if (newHp <= 0) - newHp = target->GetMaxHealth() - 1; - target->SetHealth(newHp); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_illidari_council_empyreal_equivalency_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + void HandleScript(SpellEffIndex /*effIndex*/) + { + Unit* target = GetHitUnit(); + int32 casterHpPct = (int32)GetCaster()->GetHealthPct(); + uint32 newHp = target->CountPctFromMaxHealth(casterHpPct); + if (newHp <= 0) + newHp = target->GetMaxHealth() - 1; + target->SetHealth(newHp); + } - SpellScript* GetSpellScript() const override - { - return new spell_illidari_council_empyreal_equivalency_SpellScript(); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_illidari_council_empyreal_equivalency::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; // 41341 - Balance of Power -class spell_illidari_council_balance_of_power : public SpellScriptLoader +class spell_illidari_council_balance_of_power : public AuraScript { - public: - spell_illidari_council_balance_of_power() : SpellScriptLoader("spell_illidari_council_balance_of_power") { } + PrepareAuraScript(spell_illidari_council_balance_of_power); - class spell_illidari_council_balance_of_power_AuraScript : public AuraScript - { - PrepareAuraScript(spell_illidari_council_balance_of_power_AuraScript); - - bool Validate(SpellInfo const* /*spell*/) override - { - return ValidateSpellInfo({ SPELL_SHARED_RULE }); - } - - void Absorb(AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& /*absorbAmount*/) - { - PreventDefaultAction(); - int32 bp = dmgInfo.GetDamage(); - GetTarget()->CastCustomSpell(SPELL_SHARED_RULE, SPELLVALUE_BASE_POINT0, bp, (Unit*) nullptr, true, nullptr, aurEff); - } + bool Validate(SpellInfo const* /*spell*/) override + { + return ValidateSpellInfo({ SPELL_SHARED_RULE }); + } - void Register() override - { - OnEffectAbsorb += AuraEffectAbsorbFn(spell_illidari_council_balance_of_power_AuraScript::Absorb, EFFECT_0); - } - }; + void Absorb(AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& /*absorbAmount*/) + { + PreventDefaultAction(); + int32 bp = dmgInfo.GetDamage(); + GetTarget()->CastCustomSpell(SPELL_SHARED_RULE, SPELLVALUE_BASE_POINT0, bp, (Unit*) nullptr, true, nullptr, aurEff); + } - AuraScript* GetAuraScript() const override - { - return new spell_illidari_council_balance_of_power_AuraScript(); - } + void Register() override + { + OnEffectAbsorb += AuraEffectAbsorbFn(spell_illidari_council_balance_of_power::Absorb, EFFECT_0); + } }; // 41480 - Deadly Strike -class spell_illidari_council_deadly_strike : public SpellScriptLoader +class spell_illidari_council_deadly_strike : public AuraScript { - public: - spell_illidari_council_deadly_strike() : SpellScriptLoader("spell_illidari_council_deadly_strike") { } - - class spell_illidari_council_deadly_strike_AuraScript : public AuraScript - { - PrepareAuraScript(spell_illidari_council_deadly_strike_AuraScript); + PrepareAuraScript(spell_illidari_council_deadly_strike); - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DEADLY_POISON }); - } - - void OnTrigger(AuraEffect const* aurEff) - { - PreventDefaultAction(); + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_DEADLY_POISON }); + } - if (Unit* victim = GetTarget()->GetAI()->SelectTarget(SELECT_TARGET_RANDOM, 0)) - GetTarget()->CastSpell(victim, SPELL_DEADLY_POISON, true, nullptr, aurEff); - } + void OnTrigger(AuraEffect const* aurEff) + { + PreventDefaultAction(); - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_illidari_council_deadly_strike_AuraScript::OnTrigger, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); - } - }; + if (Unit* victim = GetTarget()->GetAI()->SelectTarget(SELECT_TARGET_RANDOM, 0)) + GetTarget()->CastSpell(victim, SPELL_DEADLY_POISON, true, nullptr, aurEff); + } - AuraScript* GetAuraScript() const override - { - return new spell_illidari_council_deadly_strike_AuraScript(); - } + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_illidari_council_deadly_strike::OnTrigger, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } }; // 41485 - Deadly Poison -class spell_illidari_council_deadly_poison : public SpellScriptLoader +class spell_illidari_council_deadly_poison : public AuraScript { - public: - spell_illidari_council_deadly_poison() : SpellScriptLoader("spell_illidari_council_deadly_poison") { } - - class spell_illidari_council_deadly_poison_AuraScript : public AuraScript - { - PrepareAuraScript(spell_illidari_council_deadly_poison_AuraScript); + PrepareAuraScript(spell_illidari_council_deadly_poison); - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_ENVENOM }); - } - - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - if (Unit* caster = GetCaster()) - caster->CastSpell(GetTarget(), SPELL_ENVENOM, true); - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_ENVENOM }); + } - void Register() override - { - OnEffectRemove += AuraEffectRemoveFn(spell_illidari_council_deadly_poison_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL); - } - }; + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Unit* caster = GetCaster()) + caster->CastSpell(GetTarget(), SPELL_ENVENOM, true); + } - AuraScript* GetAuraScript() const override - { - return new spell_illidari_council_deadly_poison_AuraScript(); - } + void Register() override + { + OnEffectRemove += AuraEffectRemoveFn(spell_illidari_council_deadly_poison::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL); + } }; // 41475 - Reflective Shield -class spell_illidari_council_reflective_shield : public SpellScriptLoader +class spell_illidari_council_reflective_shield : public AuraScript { - public: - spell_illidari_council_reflective_shield() : SpellScriptLoader("spell_illidari_council_reflective_shield") { } + PrepareAuraScript(spell_illidari_council_reflective_shield); - class spell_illidari_council_reflective_shield_AuraScript : public AuraScript - { - PrepareAuraScript(spell_illidari_council_reflective_shield_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_REFLECTIVE_SHIELD_DAMAGE }); - } - - void OnAbsorb(AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount) - { - Unit* target = GetTarget(); - if (dmgInfo.GetAttacker() == target) - return; + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_REFLECTIVE_SHIELD_DAMAGE }); + } - int32 bp = absorbAmount / 2; - target->CastCustomSpell(dmgInfo.GetAttacker(), SPELL_REFLECTIVE_SHIELD_DAMAGE, &bp, nullptr, nullptr, true, nullptr, aurEff); - } + void OnAbsorb(AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount) + { + Unit* target = GetTarget(); + if (dmgInfo.GetAttacker() == target) + return; - void Register() override - { - AfterEffectAbsorb += AuraEffectAbsorbFn(spell_illidari_council_reflective_shield_AuraScript::OnAbsorb, EFFECT_0); - } - }; + int32 bp = absorbAmount / 2; + target->CastCustomSpell(dmgInfo.GetAttacker(), SPELL_REFLECTIVE_SHIELD_DAMAGE, &bp, nullptr, nullptr, true, nullptr, aurEff); + } - AuraScript* GetAuraScript() const override - { - return new spell_illidari_council_reflective_shield_AuraScript(); - } + void Register() override + { + AfterEffectAbsorb += AuraEffectAbsorbFn(spell_illidari_council_reflective_shield::OnAbsorb, EFFECT_0); + } }; // 41467 - Judgement -class spell_illidari_council_judgement : public SpellScriptLoader +class spell_illidari_council_judgement : public SpellScript { - public: - spell_illidari_council_judgement() : SpellScriptLoader("spell_illidari_council_judgement") { } + PrepareSpellScript(spell_illidari_council_judgement); - class spell_illidari_council_judgement_SpellScript : public SpellScript + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( { - PrepareSpellScript(spell_illidari_council_judgement_SpellScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_JUDGEMENT_OF_BLOOD, - SPELL_JUDGEMENT_OF_COMMAND, - SPELL_JUDGEMENT_PRIMER - }); - } - - void HandleScript(SpellEffIndex /*effIndex*/) - { - Unit* caster = GetCaster(); - Unit* target = GetHitUnit(); - uint32 judgementId = caster->HasAura(SPELL_SEAL_OF_BLOOD) ? SPELL_JUDGEMENT_OF_BLOOD : SPELL_JUDGEMENT_OF_COMMAND; - caster->CastSpell(target, SPELL_JUDGEMENT_PRIMER, true); - caster->CastSpell(target, judgementId, true); - } + SPELL_JUDGEMENT_OF_BLOOD, + SPELL_JUDGEMENT_OF_COMMAND, + SPELL_JUDGEMENT_PRIMER + }); + } - void OnFinishCast() - { - if (Creature* caster = GetCaster()->ToCreature()) - caster->AI()->Talk(SAY_COUNCIL_SPECIAL); - } + void HandleScript(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + Unit* target = GetHitUnit(); + uint32 judgementId = caster->HasAura(SPELL_SEAL_OF_BLOOD) ? SPELL_JUDGEMENT_OF_BLOOD : SPELL_JUDGEMENT_OF_COMMAND; + caster->CastSpell(target, SPELL_JUDGEMENT_PRIMER, true); + caster->CastSpell(target, judgementId, true); + } - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_illidari_council_judgement_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - AfterCast += SpellCastFn(spell_illidari_council_judgement_SpellScript::OnFinishCast); - } - }; + void OnFinishCast() + { + if (Creature* caster = GetCaster()->ToCreature()) + caster->AI()->Talk(SAY_COUNCIL_SPECIAL); + } - SpellScript* GetSpellScript() const override - { - return new spell_illidari_council_judgement_SpellScript(); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_illidari_council_judgement::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + AfterCast += SpellCastFn(spell_illidari_council_judgement::OnFinishCast); + } }; /* 41469 - Seal of Command 41459 - Seal of Blood */ -class spell_illidari_council_seal : public SpellScriptLoader +class spell_illidari_council_seal : public AuraScript { - public: - spell_illidari_council_seal() : SpellScriptLoader("spell_illidari_council_seal") { } + PrepareAuraScript(spell_illidari_council_seal); - class spell_illidari_council_seal_AuraScript : public AuraScript + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( { - PrepareAuraScript(spell_illidari_council_seal_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_SEAL_OF_COMMAND, - SPELL_SEAL_OF_BLOOD - }); - } - - void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) - { - Unit* target = GetTarget(); - if (target->IsInWorld() && target->IsAlive()) - { - uint32 spellId = aurEff->GetId() == SPELL_SEAL_OF_COMMAND ? SPELL_SEAL_OF_BLOOD : SPELL_SEAL_OF_COMMAND; - target->CastSpell(target, spellId, true); - } - } - - void Register() override - { - OnEffectRemove += AuraEffectRemoveFn(spell_illidari_council_seal_AuraScript::OnRemove, EFFECT_2, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - } - }; + SPELL_SEAL_OF_COMMAND, + SPELL_SEAL_OF_BLOOD + }); + } - AuraScript* GetAuraScript() const override + void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + if (target->IsInWorld() && target->IsAlive()) { - return new spell_illidari_council_seal_AuraScript(); + uint32 spellId = aurEff->GetId() == SPELL_SEAL_OF_COMMAND ? SPELL_SEAL_OF_BLOOD : SPELL_SEAL_OF_COMMAND; + target->CastSpell(target, spellId, true); } + } + + void Register() override + { + OnEffectRemove += AuraEffectRemoveFn(spell_illidari_council_seal::OnRemove, EFFECT_2, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } }; // 41478 - Dampen Magic -class spell_illidari_dampen_magic : public SpellScriptLoader +class spell_illidari_dampen_magic : public AuraScript { - public: - spell_illidari_dampen_magic() : SpellScriptLoader("spell_illidari_dampen_magic") { } - - class spell_illidari_dampen_magic_AuraScript : public AuraScript - { - PrepareAuraScript(spell_illidari_dampen_magic_AuraScript); - - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - if (Creature* target = GetTarget()->ToCreature()) - { - AuraRemoveMode mode = GetTargetApplication()->GetRemoveMode(); - if (mode == AURA_REMOVE_BY_ENEMY_SPELL || mode == AURA_REMOVE_BY_EXPIRE) - target->AI()->DoAction(ACTION_REFRESH_DAMPEN); - } - } - - void Register() override - { - OnEffectRemove += AuraEffectRemoveFn(spell_illidari_dampen_magic_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL); - } - }; + PrepareAuraScript(spell_illidari_dampen_magic); - AuraScript* GetAuraScript() const override + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Creature* target = GetTarget()->ToCreature()) { - return new spell_illidari_dampen_magic_AuraScript(); + AuraRemoveMode mode = GetTargetApplication()->GetRemoveMode(); + if (mode == AURA_REMOVE_BY_ENEMY_SPELL || mode == AURA_REMOVE_BY_EXPIRE) + target->AI()->DoAction(ACTION_REFRESH_DAMPEN); } + } + + void Register() override + { + OnEffectRemove += AuraEffectRemoveFn(spell_illidari_dampen_magic::OnRemove, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL); + } }; void AddSC_boss_illidari_council() { - new boss_illidari_council(); - new boss_gathios_the_shatterer(); - new boss_lady_malande(); - new boss_veras_darkshadow(); - new boss_high_nethermancer_zerevor(); - new npc_veras_vanish_effect(); - new spell_illidari_council_empyreal_balance(); - new spell_illidari_council_empyreal_equivalency(); - new spell_illidari_council_balance_of_power(); - new spell_illidari_council_deadly_strike(); - new spell_illidari_council_deadly_poison(); - new spell_illidari_council_reflective_shield(); - new spell_illidari_council_judgement(); - new spell_illidari_council_seal(); - new spell_illidari_dampen_magic(); + RegisterBlackTempleCreatureAI(boss_illidari_council); + RegisterBlackTempleCreatureAI(boss_gathios_the_shatterer); + RegisterBlackTempleCreatureAI(boss_lady_malande); + RegisterBlackTempleCreatureAI(boss_veras_darkshadow); + RegisterBlackTempleCreatureAI(boss_high_nethermancer_zerevor); + RegisterBlackTempleCreatureAI(npc_veras_vanish_effect); + RegisterSpellScript(spell_illidari_council_empyreal_balance); + RegisterSpellScript(spell_illidari_council_empyreal_equivalency); + RegisterAuraScript(spell_illidari_council_balance_of_power); + RegisterAuraScript(spell_illidari_council_deadly_strike); + RegisterAuraScript(spell_illidari_council_deadly_poison); + RegisterAuraScript(spell_illidari_council_reflective_shield); + RegisterSpellScript(spell_illidari_council_judgement); + RegisterAuraScript(spell_illidari_council_seal); + RegisterAuraScript(spell_illidari_dampen_magic); } diff --git a/src/server/scripts/Outland/BlackTemple/boss_mother_shahraz.cpp b/src/server/scripts/Outland/BlackTemple/boss_mother_shahraz.cpp index 38fa695c5db..fdd79cf92ea 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_mother_shahraz.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_mother_shahraz.cpp @@ -107,299 +107,233 @@ Position const TeleportPoint[7]= { 965.997f, 278.398f, 195.777f } }; -class boss_mother_shahraz : public CreatureScript +struct boss_mother_shahraz : public BossAI { -public: - boss_mother_shahraz() : CreatureScript("boss_mother_shahraz") { } + boss_mother_shahraz(Creature* creature) : BossAI(creature, DATA_MOTHER_SHAHRAZ), _enraged(false) { } - struct boss_shahrazAI : public BossAI + void Reset() override { - boss_shahrazAI(Creature* creature) : BossAI(creature, DATA_MOTHER_SHAHRAZ), _enraged(false) { } + _Reset(); + _enraged = false; + } - void Reset() override - { - _Reset(); - _enraged = false; - } + void EnterCombat(Unit* /*who*/) override + { + _EnterCombat(); + Talk(SAY_AGGRO); + events.ScheduleEvent(EVENT_SILENCING_SHRIEK, Seconds(22)); + events.ScheduleEvent(EVENT_PRISMATIC_SHIELD, Seconds(15)); + events.ScheduleEvent(EVENT_FATAL_ATTRACTION, Seconds(35)); + events.ScheduleEvent(EVENT_RANDOM_BEAM, Seconds(6)); + events.ScheduleEvent(EVENT_BERSERK, Minutes(10)); + events.ScheduleEvent(EVENT_TAUNT, Seconds(35)); + } - void EnterCombat(Unit* /*who*/) override - { - _EnterCombat(); - Talk(SAY_AGGRO); - events.ScheduleEvent(EVENT_SILENCING_SHRIEK, Seconds(22)); - events.ScheduleEvent(EVENT_PRISMATIC_SHIELD, Seconds(15)); - events.ScheduleEvent(EVENT_FATAL_ATTRACTION, Seconds(35)); - events.ScheduleEvent(EVENT_RANDOM_BEAM, Seconds(6)); - events.ScheduleEvent(EVENT_BERSERK, Minutes(10)); - events.ScheduleEvent(EVENT_TAUNT, Seconds(35)); - } + void KilledUnit(Unit* victim) override + { + if (victim->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_SLAY); + } - void KilledUnit(Unit* victim) override - { - if (victim->GetTypeId() == TYPEID_PLAYER) - Talk(SAY_SLAY); - } + void JustDied(Unit* /*killer*/) override + { + _JustDied(); + Talk(SAY_DEATH); + } - void JustDied(Unit* /*killer*/) override - { - _JustDied(); - Talk(SAY_DEATH); - } + void EnterEvadeMode(EvadeReason /*why*/) override + { + _DespawnAtEvade(); + } - void EnterEvadeMode(EvadeReason /*why*/) override + void DamageTaken(Unit* /*attacker*/, uint32 &damage) override + { + if (!_enraged && me->HealthBelowPctDamaged(10, damage)) { - _DespawnAtEvade(); + _enraged = true; + DoCastSelf(SPELL_RANDOM_PERIODIC, true); + Talk(EMOTE_ENRAGE, me); + Talk(SAY_ENRAGE); } + } - void DamageTaken(Unit* /*attacker*/, uint32 &damage) override + void ExecuteEvent(uint32 eventId) override + { + switch (eventId) { - if (!_enraged && me->HealthBelowPctDamaged(10, damage)) - { - _enraged = true; - DoCastSelf(SPELL_RANDOM_PERIODIC, true); - Talk(EMOTE_ENRAGE, me); - Talk(SAY_ENRAGE); - } + case EVENT_RANDOM_BEAM: + DoCastSelf(BeamTriggers[urand(0, 3)]); + events.Repeat(Seconds(30)); + break; + case EVENT_PRISMATIC_SHIELD: + DoCastSelf(PrismaticAuras[urand(0, 5)]); + events.Repeat(Seconds(15)); + break; + case EVENT_FATAL_ATTRACTION: + Talk(SAY_SPELL); + me->CastCustomSpell(SPELL_FATAL_ATTACTION_TELEPORT, SPELLVALUE_MAX_TARGETS, 3, me); + events.Repeat(Seconds(30)); + break; + case EVENT_SILENCING_SHRIEK: + DoCastVictim(SPELL_SILENCING_SHRIEK); + events.Repeat(Seconds(18), Seconds(30)); + break; + case EVENT_TAUNT: + Talk(SAY_TAUNT); + events.Repeat(Seconds(30), Seconds(40)); + break; + case EVENT_BERSERK: + Talk(EMOTE_BERSERK, me); + DoCastSelf(SPELL_BERSERK); + break; + default: + break; } + } - void ExecuteEvent(uint32 eventId) override +private: + bool _enraged; +}; + +// 40869 - Fatal Attraction +class spell_mother_shahraz_fatal_attraction : public SpellScript +{ + PrepareSpellScript(spell_mother_shahraz_fatal_attraction); + + bool Validate(SpellInfo const* /*spell*/) override + { + return ValidateSpellInfo( { - switch (eventId) - { - case EVENT_RANDOM_BEAM: - DoCastSelf(BeamTriggers[urand(0, 3)]); - events.Repeat(Seconds(30)); - break; - case EVENT_PRISMATIC_SHIELD: - DoCastSelf(PrismaticAuras[urand(0, 5)]); - events.Repeat(Seconds(15)); - break; - case EVENT_FATAL_ATTRACTION: - Talk(SAY_SPELL); - me->CastCustomSpell(SPELL_FATAL_ATTACTION_TELEPORT, SPELLVALUE_MAX_TARGETS, 3, me); - events.Repeat(Seconds(30)); - break; - case EVENT_SILENCING_SHRIEK: - DoCastVictim(SPELL_SILENCING_SHRIEK); - events.Repeat(Seconds(18), Seconds(30)); - break; - case EVENT_TAUNT: - Talk(SAY_TAUNT); - events.Repeat(Seconds(30), Seconds(40)); - break; - case EVENT_BERSERK: - Talk(EMOTE_BERSERK, me); - DoCastSelf(SPELL_BERSERK); - break; - default: - break; - } - } + SPELL_SABER_LASH_IMMUNITY, + SPELL_FATAL_ATTRACTION + }); + } - private: - bool _enraged; - }; + void FilterTargets(std::list<WorldObject*>& targets) + { + targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_SABER_LASH_IMMUNITY)); + } - CreatureAI* GetAI(Creature* creature) const override + void SetDest(SpellDestination& dest) { - return GetBlackTempleAI<boss_shahrazAI>(creature); + dest.Relocate(TeleportPoint[urand(0, 6)]); } -}; -// 40869 - Fatal Attraction -class spell_mother_shahraz_fatal_attraction : public SpellScriptLoader -{ - public: - spell_mother_shahraz_fatal_attraction() : SpellScriptLoader("spell_mother_shahraz_fatal_attraction") { } + void HandleTeleport(SpellEffIndex /*effIndex*/) + { + GetCaster()->CastSpell(GetHitUnit(), SPELL_FATAL_ATTRACTION, true); + } - class spell_mother_shahraz_fatal_attraction_SpellScript : public SpellScript - { - PrepareSpellScript(spell_mother_shahraz_fatal_attraction_SpellScript); - - bool Validate(SpellInfo const* /*spell*/) override - { - return ValidateSpellInfo( - { - SPELL_SABER_LASH_IMMUNITY, - SPELL_FATAL_ATTRACTION - }); - } - - void FilterTargets(std::list<WorldObject*>& targets) - { - targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_SABER_LASH_IMMUNITY)); - } - - void SetDest(SpellDestination& dest) - { - dest.Relocate(TeleportPoint[urand(0, 6)]); - } - - void HandleTeleport(SpellEffIndex /*effIndex*/) - { - GetCaster()->CastSpell(GetHitUnit(), SPELL_FATAL_ATTRACTION, true); - } - - void Register() override - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mother_shahraz_fatal_attraction_SpellScript::FilterTargets, EFFECT_ALL, TARGET_UNIT_SRC_AREA_ENEMY); - OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_mother_shahraz_fatal_attraction_SpellScript::SetDest, EFFECT_1, TARGET_DEST_CASTER_RANDOM); - OnEffectHitTarget += SpellEffectFn(spell_mother_shahraz_fatal_attraction_SpellScript::HandleTeleport, EFFECT_1, SPELL_EFFECT_TELEPORT_UNITS); - } - }; - - SpellScript* GetSpellScript() const override - { - return new spell_mother_shahraz_fatal_attraction_SpellScript(); - } + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mother_shahraz_fatal_attraction::FilterTargets, EFFECT_ALL, TARGET_UNIT_SRC_AREA_ENEMY); + OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_mother_shahraz_fatal_attraction::SetDest, EFFECT_1, TARGET_DEST_CASTER_RANDOM); + OnEffectHitTarget += SpellEffectFn(spell_mother_shahraz_fatal_attraction::HandleTeleport, EFFECT_1, SPELL_EFFECT_TELEPORT_UNITS); + } }; // 40870 - Fatal Attraction Dummy Visual -class spell_mother_shahraz_fatal_attraction_link : public SpellScriptLoader +class spell_mother_shahraz_fatal_attraction_link : public SpellScript { - public: - spell_mother_shahraz_fatal_attraction_link() : SpellScriptLoader("spell_mother_shahraz_fatal_attraction_link") { } - - class spell_mother_shahraz_fatal_attraction_link_SpellScript : public SpellScript - { - PrepareSpellScript(spell_mother_shahraz_fatal_attraction_link_SpellScript); + PrepareSpellScript(spell_mother_shahraz_fatal_attraction_link); - bool Validate(SpellInfo const* /*spell*/) override - { - return ValidateSpellInfo({ SPELL_FATAL_ATTRACTION_DAMAGE }); - } - - void HandleDummy(SpellEffIndex /*effIndex*/) - { - GetCaster()->CastSpell(GetCaster(), SPELL_FATAL_ATTRACTION_DAMAGE, true); - } + bool Validate(SpellInfo const* /*spell*/) override + { + return ValidateSpellInfo({ SPELL_FATAL_ATTRACTION_DAMAGE }); + } - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_mother_shahraz_fatal_attraction_link_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + void HandleDummy(SpellEffIndex /*effIndex*/) + { + GetCaster()->CastSpell(GetCaster(), SPELL_FATAL_ATTRACTION_DAMAGE, true); + } - SpellScript* GetSpellScript() const override - { - return new spell_mother_shahraz_fatal_attraction_link_SpellScript(); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_mother_shahraz_fatal_attraction_link::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; // 40816 - Saber Lash -class spell_mother_shahraz_saber_lash : public SpellScriptLoader +class spell_mother_shahraz_saber_lash : public AuraScript { - public: - spell_mother_shahraz_saber_lash() : SpellScriptLoader("spell_mother_shahraz_saber_lash") { } - - class spell_mother_shahraz_saber_lash_AuraScript : public AuraScript - { - PrepareAuraScript(spell_mother_shahraz_saber_lash_AuraScript); + PrepareAuraScript(spell_mother_shahraz_saber_lash); - bool Validate(SpellInfo const* spellInfo) override - { - return ValidateSpellInfo({ spellInfo->Effects[EFFECT_1].TriggerSpell }); - } - - void OnTrigger(AuraEffect const* aurEff) - { - PreventDefaultAction(); + bool Validate(SpellInfo const* spellInfo) override + { + return ValidateSpellInfo({ spellInfo->Effects[EFFECT_1].TriggerSpell }); + } - uint32 triggerSpell = GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell; - if (Unit* target = GetUnitOwner()->GetAI()->SelectTarget(SELECT_TARGET_RANDOM, 0)) - GetUnitOwner()->CastSpell(target, triggerSpell, true); - } + void OnTrigger(AuraEffect const* aurEff) + { + PreventDefaultAction(); - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_mother_shahraz_saber_lash_AuraScript::OnTrigger, EFFECT_1, SPELL_AURA_PERIODIC_TRIGGER_SPELL); - } - }; + uint32 triggerSpell = GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell; + if (Unit* target = GetUnitOwner()->GetAI()->SelectTarget(SELECT_TARGET_RANDOM, 0)) + GetUnitOwner()->CastSpell(target, triggerSpell, true); + } - AuraScript* GetAuraScript() const override - { - return new spell_mother_shahraz_saber_lash_AuraScript(); - } + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_mother_shahraz_saber_lash::OnTrigger, EFFECT_1, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } }; /* 40863 - Sinister Periodic 40865 - Vile Periodic 40866 - Wicked Periodic 40862 - Sinful Periodic */ -class spell_mother_shahraz_generic_periodic : public SpellScriptLoader +class spell_mother_shahraz_generic_periodic : public AuraScript { - public: - spell_mother_shahraz_generic_periodic() : SpellScriptLoader("spell_mother_shahraz_generic_periodic") { } - - class spell_mother_shahraz_generic_periodic_AuraScript : public AuraScript - { - PrepareAuraScript(spell_mother_shahraz_generic_periodic_AuraScript); - - bool Validate(SpellInfo const* spellInfo) override - { - return ValidateSpellInfo({ spellInfo->Effects[EFFECT_0].TriggerSpell }); - } + PrepareAuraScript(spell_mother_shahraz_generic_periodic); - void OnTrigger(AuraEffect const* aurEff) - { - PreventDefaultAction(); + bool Validate(SpellInfo const* spellInfo) override + { + return ValidateSpellInfo({ spellInfo->Effects[EFFECT_0].TriggerSpell }); + } - uint32 triggerSpell = GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell; - if (Unit* target = GetUnitOwner()->GetAI()->SelectTarget(SELECT_TARGET_RANDOM, 0)) - GetUnitOwner()->CastSpell(target, triggerSpell, true); - } + void OnTrigger(AuraEffect const* aurEff) + { + PreventDefaultAction(); - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_mother_shahraz_generic_periodic_AuraScript::OnTrigger, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); - } - }; + uint32 triggerSpell = GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell; + if (Unit* target = GetUnitOwner()->GetAI()->SelectTarget(SELECT_TARGET_RANDOM, 0)) + GetUnitOwner()->CastSpell(target, triggerSpell, true); + } - AuraScript* GetAuraScript() const override - { - return new spell_mother_shahraz_generic_periodic_AuraScript(); - } + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_mother_shahraz_generic_periodic::OnTrigger, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } }; // 40867 - Random Periodic -class spell_mother_shahraz_random_periodic : public SpellScriptLoader +class spell_mother_shahraz_random_periodic : public AuraScript { - public: - spell_mother_shahraz_random_periodic() : SpellScriptLoader("spell_mother_shahraz_random_periodic") { } + PrepareAuraScript(spell_mother_shahraz_random_periodic); - class spell_mother_shahraz_random_periodic_AuraScript : public AuraScript - { - PrepareAuraScript(spell_mother_shahraz_random_periodic_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo(RandomBeam); - } - - void OnPeriodic(AuraEffect const* /*aurEffect*/) - { - PreventDefaultAction(); - GetUnitOwner()->CastSpell(GetUnitOwner(), RandomBeam[urand(0, 3)], true); - } - - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_mother_shahraz_random_periodic_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); - } - }; - - AuraScript* GetAuraScript() const override - { - return new spell_mother_shahraz_random_periodic_AuraScript(); - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo(RandomBeam); + } + + void OnPeriodic(AuraEffect const* /*aurEffect*/) + { + PreventDefaultAction(); + GetUnitOwner()->CastSpell(GetUnitOwner(), RandomBeam[urand(0, 3)], true); + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_mother_shahraz_random_periodic::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } }; void AddSC_boss_mother_shahraz() { - new boss_mother_shahraz(); - new spell_mother_shahraz_fatal_attraction(); - new spell_mother_shahraz_fatal_attraction_link(); - new spell_mother_shahraz_saber_lash(); - new spell_mother_shahraz_generic_periodic(); - new spell_mother_shahraz_random_periodic(); + RegisterBlackTempleCreatureAI(boss_mother_shahraz); + RegisterSpellScript(spell_mother_shahraz_fatal_attraction); + RegisterSpellScript(spell_mother_shahraz_fatal_attraction_link); + RegisterAuraScript(spell_mother_shahraz_saber_lash); + RegisterAuraScript(spell_mother_shahraz_generic_periodic); + RegisterAuraScript(spell_mother_shahraz_random_periodic); } diff --git a/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp b/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp index ae3d961ca68..c069482f139 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp @@ -136,737 +136,638 @@ class EnslavedSoulEvent : public BasicEvent Creature* _owner; }; -class boss_reliquary_of_souls : public CreatureScript +struct boss_reliquary_of_souls : public BossAI { -public: - boss_reliquary_of_souls() : CreatureScript("boss_reliquary_of_souls") { } + boss_reliquary_of_souls(Creature* creature) : BossAI(creature, DATA_RELIQUARY_OF_SOULS), _inCombat(false) + { + creature->m_SightDistance = 70.0f; + } - struct boss_reliquary_of_soulsAI : public BossAI + void Reset() override { - boss_reliquary_of_soulsAI(Creature* creature) : BossAI(creature, DATA_RELIQUARY_OF_SOULS), _inCombat(false) - { - creature->m_SightDistance = 70.0f; - } + _Reset(); + me->SetReactState(REACT_PASSIVE); + _inCombat = false; + events.SetPhase(PHASE_ESSENCE_OF_SUFFERING); + } - void Reset() override + void MoveInLineOfSight(Unit* who) override + { + if (!_inCombat && who->GetTypeId() == TYPEID_PLAYER && !who->ToPlayer()->IsGameMaster() && CanAIAttack(who)) { - _Reset(); - me->SetReactState(REACT_PASSIVE); - _inCombat = false; - events.SetPhase(PHASE_ESSENCE_OF_SUFFERING); + _inCombat = true; + DoZoneInCombat(); + me->SetByteValue(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_STAND_STATE, UNIT_STAND_STATE_STAND); + events.ScheduleEvent(EVENT_SUBMERGE, Seconds(10)); } + } - void MoveInLineOfSight(Unit* who) override - { - if (!_inCombat && who->GetTypeId() == TYPEID_PLAYER && !who->ToPlayer()->IsGameMaster() && CanAIAttack(who)) - { - _inCombat = true; - DoZoneInCombat(); - me->SetByteValue(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_STAND_STATE, UNIT_STAND_STATE_STAND); - events.ScheduleEvent(EVENT_SUBMERGE, Seconds(10)); - } - } + uint32 GetSummonSpell() + { + if (events.IsInPhase(PHASE_ESSENCE_OF_SUFFERING)) + return SPELL_SUMMON_ESSENCE_OF_SUFFERING; + else if (events.IsInPhase(PHASE_ESSENCE_OF_DESIRE)) + return SPELL_SUMMON_ESSENCE_OF_DESIRE; + else if (events.IsInPhase(PHASE_ESSENCE_OF_ANGER)) + return SPELL_SUMMON_ESSENCE_OF_ANGER; + else //Should never happen + return 0; + } - uint32 GetSummonSpell() - { - if (events.IsInPhase(PHASE_ESSENCE_OF_SUFFERING)) - return SPELL_SUMMON_ESSENCE_OF_SUFFERING; - else if (events.IsInPhase(PHASE_ESSENCE_OF_DESIRE)) - return SPELL_SUMMON_ESSENCE_OF_DESIRE; - else if (events.IsInPhase(PHASE_ESSENCE_OF_ANGER)) - return SPELL_SUMMON_ESSENCE_OF_ANGER; - else //Should never happen - return 0; + void DoAction(int32 actionId) override + { + switch (actionId) + { + case ACTION_ESSENCE_OF_SUFFERING_DEAD: + me->RemoveAurasDueToSpell(SPELL_SUBMERGE_VISUAL); + events.SetPhase(PHASE_ESSENCE_OF_DESIRE); + HandleSpirits(); + events.ScheduleEvent(EVENT_SUBMERGE, Seconds(40)); + break; + case ACTION_ESSENCE_OF_DESIRE_DEAD: + me->RemoveAurasDueToSpell(SPELL_SUBMERGE_VISUAL); + events.SetPhase(PHASE_ESSENCE_OF_ANGER); + HandleSpirits(); + events.ScheduleEvent(EVENT_SUBMERGE, Seconds(40)); + break; + case ACTION_KILL_SELF: + me->KillSelf(); + break; } + } - void DoAction(int32 actionId) override - { - switch (actionId) - { - case ACTION_ESSENCE_OF_SUFFERING_DEAD: - me->RemoveAurasDueToSpell(SPELL_SUBMERGE_VISUAL); - events.SetPhase(PHASE_ESSENCE_OF_DESIRE); - HandleSpirits(); - events.ScheduleEvent(EVENT_SUBMERGE, Seconds(40)); - break; - case ACTION_ESSENCE_OF_DESIRE_DEAD: - me->RemoveAurasDueToSpell(SPELL_SUBMERGE_VISUAL); - events.SetPhase(PHASE_ESSENCE_OF_ANGER); - HandleSpirits(); - events.ScheduleEvent(EVENT_SUBMERGE, Seconds(40)); - break; - case ACTION_KILL_SELF: - me->KillSelf(); - break; - } + void HandleSpirits() + { + std::vector<Creature*> _worldTriggerList; + me->GetCreatureListWithEntryInGrid(_worldTriggerList, NPC_RELIQUARY_WORLD_TRIGGER, 70.0f); + + if (_worldTriggerList.empty()) + return; + + //Get random creatures + Trinity::Containers::RandomShuffle(_worldTriggerList); + _worldTriggerList.resize(21); + + for (uint8 i = 0; i < 21; i++) + { + Creature* wTrigger = _worldTriggerList[i]; + if (i < 3) + wTrigger->m_Events.AddEvent(new EnslavedSoulEvent(wTrigger), wTrigger->m_Events.CalculateTime(4000)); + else if (i < 6) + wTrigger->m_Events.AddEvent(new EnslavedSoulEvent(wTrigger), wTrigger->m_Events.CalculateTime(8000)); + else if (i < 9) + wTrigger->m_Events.AddEvent(new EnslavedSoulEvent(wTrigger), wTrigger->m_Events.CalculateTime(12000)); + else if (i < 12) + wTrigger->m_Events.AddEvent(new EnslavedSoulEvent(wTrigger), wTrigger->m_Events.CalculateTime(16000)); + else if (i < 15) + wTrigger->m_Events.AddEvent(new EnslavedSoulEvent(wTrigger), wTrigger->m_Events.CalculateTime(20000)); + else if (i < 18) + wTrigger->m_Events.AddEvent(new EnslavedSoulEvent(wTrigger), wTrigger->m_Events.CalculateTime(24000)); + else + wTrigger->m_Events.AddEvent(new EnslavedSoulEvent(wTrigger), wTrigger->m_Events.CalculateTime(28000)); } + } - void HandleSpirits() - { - std::vector<Creature*> _worldTriggerList; - me->GetCreatureListWithEntryInGrid(_worldTriggerList, NPC_RELIQUARY_WORLD_TRIGGER, 70.0f); - - if (_worldTriggerList.empty()) - return; + void KillAssyncEvents() + { + std::vector<Creature*> _worldTriggerList; + me->GetCreatureListWithEntryInGrid(_worldTriggerList, NPC_RELIQUARY_WORLD_TRIGGER, 70.0f); - //Get random creatures - Trinity::Containers::RandomShuffle(_worldTriggerList); - _worldTriggerList.resize(21); + if (_worldTriggerList.empty()) + return; - for (uint8 i = 0; i < 21; i++) - { - Creature* wTrigger = _worldTriggerList[i]; - if (i < 3) - wTrigger->m_Events.AddEvent(new EnslavedSoulEvent(wTrigger), wTrigger->m_Events.CalculateTime(4000)); - else if (i < 6) - wTrigger->m_Events.AddEvent(new EnslavedSoulEvent(wTrigger), wTrigger->m_Events.CalculateTime(8000)); - else if (i < 9) - wTrigger->m_Events.AddEvent(new EnslavedSoulEvent(wTrigger), wTrigger->m_Events.CalculateTime(12000)); - else if (i < 12) - wTrigger->m_Events.AddEvent(new EnslavedSoulEvent(wTrigger), wTrigger->m_Events.CalculateTime(16000)); - else if (i < 15) - wTrigger->m_Events.AddEvent(new EnslavedSoulEvent(wTrigger), wTrigger->m_Events.CalculateTime(20000)); - else if (i < 18) - wTrigger->m_Events.AddEvent(new EnslavedSoulEvent(wTrigger), wTrigger->m_Events.CalculateTime(24000)); - else - wTrigger->m_Events.AddEvent(new EnslavedSoulEvent(wTrigger), wTrigger->m_Events.CalculateTime(28000)); - } - } + for (Creature* trigger : _worldTriggerList) + trigger->m_Events.KillAllEvents(true); + } - void KillAssyncEvents() - { - std::vector<Creature*> _worldTriggerList; - me->GetCreatureListWithEntryInGrid(_worldTriggerList, NPC_RELIQUARY_WORLD_TRIGGER, 70.0f); + void EnterEvadeMode(EvadeReason /*why*/) override + { + events.Reset(); + summons.DespawnAll(); + KillAssyncEvents(); + _DespawnAtEvade(); + } - if (_worldTriggerList.empty()) - return; + void JustDied(Unit* /*killer*/) override + { + events.Reset(); + instance->SetBossState(DATA_RELIQUARY_OF_SOULS, DONE); + } - for (Creature* trigger : _worldTriggerList) - trigger->m_Events.KillAllEvents(true); - } + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - void EnterEvadeMode(EvadeReason /*why*/) override - { - events.Reset(); - summons.DespawnAll(); - KillAssyncEvents(); - _DespawnAtEvade(); - } + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - void JustDied(Unit* /*killer*/) override - { - events.Reset(); - instance->SetBossState(DATA_RELIQUARY_OF_SOULS, DONE); - } + events.Update(diff); - void UpdateAI(uint32 diff) override + while (uint32 eventId = events.ExecuteEvent()) { - if (!UpdateVictim()) - return; - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - events.Update(diff); - - while (uint32 eventId = events.ExecuteEvent()) + switch (eventId) { - switch (eventId) + case EVENT_SUBMERGE: + DoCastSelf(SPELL_SUBMERGE_VISUAL, true); + events.ScheduleEvent(EVENT_SUMMON_ESSENCE, Seconds(3)); + break; + case EVENT_SUMMON_ESSENCE: { - case EVENT_SUBMERGE: - DoCastSelf(SPELL_SUBMERGE_VISUAL, true); - events.ScheduleEvent(EVENT_SUMMON_ESSENCE, Seconds(3)); - break; - case EVENT_SUMMON_ESSENCE: - { - EntryCheckPredicate pred(NPC_ENSLAVED_SOUL); - summons.DoAction(ACTION_KILL_SELF, pred); - DoCastSelf(GetSummonSpell()); - break; - } - default: - break; + EntryCheckPredicate pred(NPC_ENSLAVED_SOUL); + summons.DoAction(ACTION_KILL_SELF, pred); + DoCastSelf(GetSummonSpell()); + break; } - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + default: + break; } - } - - private: - bool _inCombat; - }; - CreatureAI* GetAI(Creature* creature) const override - { - return GetBlackTempleAI<boss_reliquary_of_soulsAI>(creature); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + } } + +private: + bool _inCombat; }; -class boss_essence_of_suffering : public CreatureScript +struct boss_essence_of_suffering : public BossAI { -public: - boss_essence_of_suffering() : CreatureScript("boss_essence_of_suffering") { } + boss_essence_of_suffering(Creature* creature) : BossAI(creature, DATA_ESSENCE_OF_SUFFERING), _dead(false) + { + SetBoundary(instance->GetBossBoundary(DATA_RELIQUARY_OF_SOULS)); + } - struct boss_essence_of_sufferingAI : public BossAI + void Reset() override { - boss_essence_of_sufferingAI(Creature* creature) : BossAI(creature, DATA_ESSENCE_OF_SUFFERING), _dead(false) - { - SetBoundary(instance->GetBossBoundary(DATA_RELIQUARY_OF_SOULS)); - } + DoCastAOE(SPELL_AURA_OF_SUFFERING, true); + events.Reset(); + _dead = false; + } - void Reset() override - { - DoCastAOE(SPELL_AURA_OF_SUFFERING, true); - events.Reset(); - _dead = false; - } + void MovementInform(uint32 motionType, uint32 pointId) override + { + if (motionType != POINT_MOTION_TYPE) + return; - void MovementInform(uint32 motionType, uint32 pointId) override + if (pointId == RELIQUARY_DESPAWN_WAYPOINT) { - if (motionType != POINT_MOTION_TYPE) - return; - - if (pointId == RELIQUARY_DESPAWN_WAYPOINT) - { - if (Creature* reliquary = instance->GetCreature(DATA_RELIQUARY_OF_SOULS)) - reliquary->AI()->DoAction(ACTION_ESSENCE_OF_SUFFERING_DEAD); + if (Creature* reliquary = instance->GetCreature(DATA_RELIQUARY_OF_SOULS)) + reliquary->AI()->DoAction(ACTION_ESSENCE_OF_SUFFERING_DEAD); - DoCastSelf(SPELL_SUBMERGE_VISUAL, true); - me->DespawnOrUnsummon(Seconds(2)); - } + DoCastSelf(SPELL_SUBMERGE_VISUAL, true); + me->DespawnOrUnsummon(Seconds(2)); } + } - void DamageTaken(Unit* /*done_by*/, uint32 &damage) override + void DamageTaken(Unit* /*done_by*/, uint32 &damage) override + { + if (damage >= me->GetHealth()) { - if (damage >= me->GetHealth()) + damage = 0; + if (!_dead) { - damage = 0; - if (!_dead) - { - _dead = true; - Talk(SUFF_SAY_RECAP); - me->AttackStop(); - me->SetReactState(REACT_PASSIVE); - events.Reset(); - me->InterruptNonMeleeSpells(false); - me->GetMotionMaster()->MovePoint(RELIQUARY_DESPAWN_WAYPOINT, DespawnPoint); - } + _dead = true; + Talk(SUFF_SAY_RECAP); + me->AttackStop(); + me->SetReactState(REACT_PASSIVE); + events.Reset(); + me->InterruptNonMeleeSpells(false); + me->GetMotionMaster()->MovePoint(RELIQUARY_DESPAWN_WAYPOINT, DespawnPoint); } } + } - void EnterCombat(Unit* /*who*/) override - { - me->SetCombatPulseDelay(5); - me->setActive(true); - DoZoneInCombat(); + void EnterCombat(Unit* /*who*/) override + { + me->SetCombatPulseDelay(5); + me->setActive(true); + DoZoneInCombat(); - events.ScheduleEvent(EVENT_SOUL_DRAIN, Seconds(20)); - events.ScheduleEvent(EVENT_FRENZY, Seconds(45)); - Talk(SUFF_SAY_AGRO); - } + events.ScheduleEvent(EVENT_SOUL_DRAIN, Seconds(20)); + events.ScheduleEvent(EVENT_FRENZY, Seconds(45)); + Talk(SUFF_SAY_AGRO); + } - void KilledUnit(Unit* victim) override - { - if (victim->GetTypeId() == TYPEID_PLAYER) - Talk(SUFF_SAY_SLAY); - } + void KilledUnit(Unit* victim) override + { + if (victim->GetTypeId() == TYPEID_PLAYER) + Talk(SUFF_SAY_SLAY); + } - void EnterEvadeMode(EvadeReason /*why*/) override - { - if (Creature* reliquary = instance->GetCreature(DATA_RELIQUARY_OF_SOULS)) - reliquary->AI()->EnterEvadeMode(EVADE_REASON_OTHER); - } + void EnterEvadeMode(EvadeReason /*why*/) override + { + if (Creature* reliquary = instance->GetCreature(DATA_RELIQUARY_OF_SOULS)) + reliquary->AI()->EnterEvadeMode(EVADE_REASON_OTHER); + } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - events.Update(diff); + events.Update(diff); - while (uint32 eventId = events.ExecuteEvent()) + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) { - switch (eventId) - { - case EVENT_SOUL_DRAIN: - me->CastCustomSpell(SPELL_SOUL_DRAIN, SPELLVALUE_MAX_TARGETS, 5, me); - events.Repeat(Seconds(30), Seconds(35)); - break; - case EVENT_FRENZY: - Talk(SUFF_SAY_ENRAGE); - DoCastSelf(SPELL_FRENZY); - events.Repeat(Seconds(45), Seconds(50)); - break; - default: - break; - } - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + case EVENT_SOUL_DRAIN: + me->CastCustomSpell(SPELL_SOUL_DRAIN, SPELLVALUE_MAX_TARGETS, 5, me); + events.Repeat(Seconds(30), Seconds(35)); + break; + case EVENT_FRENZY: + Talk(SUFF_SAY_ENRAGE); + DoCastSelf(SPELL_FRENZY); + events.Repeat(Seconds(45), Seconds(50)); + break; + default: + break; } - DoMeleeAttackIfReady(); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; } - private: - bool _dead; - }; - CreatureAI* GetAI(Creature* creature) const override - { - return GetBlackTempleAI<boss_essence_of_sufferingAI>(creature); + DoMeleeAttackIfReady(); } +private: + bool _dead; }; -class boss_essence_of_desire : public CreatureScript +struct boss_essence_of_desire : public BossAI { -public: - boss_essence_of_desire() : CreatureScript("boss_essence_of_desire") { } - - struct boss_essence_of_desireAI : public BossAI + boss_essence_of_desire(Creature* creature) : BossAI(creature, DATA_ESSENCE_OF_DESIRE), _dead(false) { - boss_essence_of_desireAI(Creature* creature) : BossAI(creature, DATA_ESSENCE_OF_DESIRE), _dead(false) - { - SetBoundary(instance->GetBossBoundary(DATA_RELIQUARY_OF_SOULS)); - } + SetBoundary(instance->GetBossBoundary(DATA_RELIQUARY_OF_SOULS)); + } - void Reset() override - { - DoCastSelf(SPELL_AURA_OF_DESIRE, true); - events.Reset(); - _dead = false; - } + void Reset() override + { + DoCastSelf(SPELL_AURA_OF_DESIRE, true); + events.Reset(); + _dead = false; + } - void EnterCombat(Unit* /*who*/) override - { - events.ScheduleEvent(EVENT_SPIRIT_SHOCK, Seconds(11)); - events.ScheduleEvent(EVENT_RUNE_SHIELD, Seconds(16)); - events.ScheduleEvent(EVENT_DEADEN, Seconds(31)); + void EnterCombat(Unit* /*who*/) override + { + events.ScheduleEvent(EVENT_SPIRIT_SHOCK, Seconds(11)); + events.ScheduleEvent(EVENT_RUNE_SHIELD, Seconds(16)); + events.ScheduleEvent(EVENT_DEADEN, Seconds(31)); + + me->SetCombatPulseDelay(5); + me->setActive(true); + DoZoneInCombat(); + Talk(DESI_SAY_FREED); + } - me->SetCombatPulseDelay(5); - me->setActive(true); - DoZoneInCombat(); - Talk(DESI_SAY_FREED); - } + void MovementInform(uint32 motionType, uint32 pointId) override + { + if (motionType != POINT_MOTION_TYPE) + return; - void MovementInform(uint32 motionType, uint32 pointId) override + if (pointId == RELIQUARY_DESPAWN_WAYPOINT) { - if (motionType != POINT_MOTION_TYPE) - return; - - if (pointId == RELIQUARY_DESPAWN_WAYPOINT) - { - if (Creature* reliquary = instance->GetCreature(DATA_RELIQUARY_OF_SOULS)) - reliquary->AI()->DoAction(ACTION_ESSENCE_OF_DESIRE_DEAD); + if (Creature* reliquary = instance->GetCreature(DATA_RELIQUARY_OF_SOULS)) + reliquary->AI()->DoAction(ACTION_ESSENCE_OF_DESIRE_DEAD); - DoCastSelf(SPELL_SUBMERGE_VISUAL, true); - me->DespawnOrUnsummon(Seconds(2)); - } + DoCastSelf(SPELL_SUBMERGE_VISUAL, true); + me->DespawnOrUnsummon(Seconds(2)); } + } - void DamageTaken(Unit* /*done_by*/, uint32 &damage) override + void DamageTaken(Unit* /*done_by*/, uint32 &damage) override + { + if (damage >= me->GetHealth()) { - if (damage >= me->GetHealth()) + damage = 0; + if (!_dead) { - damage = 0; - if (!_dead) - { - _dead = true; - Talk(DESI_SAY_RECAP); - me->AttackStop(); - me->SetReactState(REACT_PASSIVE); - events.Reset(); - me->InterruptNonMeleeSpells(false); - me->GetMotionMaster()->MovePoint(RELIQUARY_DESPAWN_WAYPOINT, DespawnPoint); - } + _dead = true; + Talk(DESI_SAY_RECAP); + me->AttackStop(); + me->SetReactState(REACT_PASSIVE); + events.Reset(); + me->InterruptNonMeleeSpells(false); + me->GetMotionMaster()->MovePoint(RELIQUARY_DESPAWN_WAYPOINT, DespawnPoint); } } + } - void KilledUnit(Unit* victim) override - { - if (victim->GetTypeId() == TYPEID_PLAYER) - Talk(DESI_SAY_SLAY); - } + void KilledUnit(Unit* victim) override + { + if (victim->GetTypeId() == TYPEID_PLAYER) + Talk(DESI_SAY_SLAY); + } - void EnterEvadeMode(EvadeReason /*why*/) override - { - if (Creature* reliquary = instance->GetCreature(DATA_RELIQUARY_OF_SOULS)) - reliquary->AI()->EnterEvadeMode(EVADE_REASON_OTHER); - } + void EnterEvadeMode(EvadeReason /*why*/) override + { + if (Creature* reliquary = instance->GetCreature(DATA_RELIQUARY_OF_SOULS)) + reliquary->AI()->EnterEvadeMode(EVADE_REASON_OTHER); + } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - events.Update(diff); + events.Update(diff); - while (uint32 eventId = events.ExecuteEvent()) + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) { - switch (eventId) - { - case EVENT_SPIRIT_SHOCK: - DoCastVictim(SPELL_SPIRIT_SHOCK); - events.Repeat(Seconds(10), Seconds(15)); - break; - case EVENT_RUNE_SHIELD: - DoCastSelf(SPELL_RUNE_SHIELD); - events.Repeat(Seconds(16)); - break; - case EVENT_DEADEN: - Talk(DESI_SAY_SPEC); - DoCastVictim(SPELL_DEADEN); - events.Repeat(Seconds(31)); - break; - default: - break; - } - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + case EVENT_SPIRIT_SHOCK: + DoCastVictim(SPELL_SPIRIT_SHOCK); + events.Repeat(Seconds(10), Seconds(15)); + break; + case EVENT_RUNE_SHIELD: + DoCastSelf(SPELL_RUNE_SHIELD); + events.Repeat(Seconds(16)); + break; + case EVENT_DEADEN: + Talk(DESI_SAY_SPEC); + DoCastVictim(SPELL_DEADEN); + events.Repeat(Seconds(31)); + break; + default: + break; } - DoMeleeAttackIfReady(); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; } - private: - bool _dead; - }; - CreatureAI* GetAI(Creature* creature) const override - { - return GetBlackTempleAI<boss_essence_of_desireAI>(creature); + DoMeleeAttackIfReady(); } +private: + bool _dead; }; -class boss_essence_of_anger : public CreatureScript +struct boss_essence_of_anger : public BossAI { -public: - boss_essence_of_anger() : CreatureScript("boss_essence_of_anger") { } - - struct boss_essence_of_angerAI : public BossAI + boss_essence_of_anger(Creature* creature) :BossAI(creature, DATA_ESSENCE_OF_ANGER) { - boss_essence_of_angerAI(Creature* creature) :BossAI(creature, DATA_ESSENCE_OF_ANGER) - { - SetBoundary(instance->GetBossBoundary(DATA_RELIQUARY_OF_SOULS)); - } + SetBoundary(instance->GetBossBoundary(DATA_RELIQUARY_OF_SOULS)); + } - void Reset() override - { - events.Reset(); - _targetGUID.Clear(); - DoCastSelf(SPELL_AURA_OF_ANGER); - } + void Reset() override + { + events.Reset(); + _targetGUID.Clear(); + DoCastSelf(SPELL_AURA_OF_ANGER); + } - void EnterCombat(Unit* /*who*/) override - { - Talk(ANGER_SAY_FREED); + void EnterCombat(Unit* /*who*/) override + { + Talk(ANGER_SAY_FREED); - events.ScheduleEvent(EVENT_START_CHECK_TANKER, Seconds(5)); - events.ScheduleEvent(EVENT_SOUL_SCREAM, Seconds(11)); - events.ScheduleEvent(EVENT_SPITE, Seconds(20)); - events.ScheduleEvent(EVENT_FREED_2, Seconds(1), Minutes(3)); + events.ScheduleEvent(EVENT_START_CHECK_TANKER, Seconds(5)); + events.ScheduleEvent(EVENT_SOUL_SCREAM, Seconds(11)); + events.ScheduleEvent(EVENT_SPITE, Seconds(20)); + events.ScheduleEvent(EVENT_FREED_2, Seconds(1), Minutes(3)); - me->SetCombatPulseDelay(5); - me->setActive(true); - DoZoneInCombat(); - } + me->SetCombatPulseDelay(5); + me->setActive(true); + DoZoneInCombat(); + } - void JustDied(Unit* /*killer*/) override - { - DoPlaySoundToSet(me, ANGER_SOUND_ID_DEATH); - if (Creature* reliquary = instance->GetCreature(DATA_RELIQUARY_OF_SOULS)) - reliquary->AI()->DoAction(ACTION_KILL_SELF); - } + void JustDied(Unit* /*killer*/) override + { + DoPlaySoundToSet(me, ANGER_SOUND_ID_DEATH); + if (Creature* reliquary = instance->GetCreature(DATA_RELIQUARY_OF_SOULS)) + reliquary->AI()->DoAction(ACTION_KILL_SELF); + } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - events.Update(diff); + events.Update(diff); - while (uint32 eventId = events.ExecuteEvent()) + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) { - switch (eventId) + case EVENT_CHECK_TANKER: { - case EVENT_CHECK_TANKER: + Unit* target = me->GetVictim(); + if (!_targetGUID || !target) + return; + + if (target->GetGUID() != _targetGUID) { - Unit* target = me->GetVictim(); - if (!_targetGUID || !target) - return; - - if (target->GetGUID() != _targetGUID) - { - Talk(ANGER_SAY_SEETHE); - Talk(ANGER_EMOTE_SEETHE, me); - _targetGUID = target->GetGUID(); - DoCastSelf(SPELL_SEETHE, true); - } - break; + Talk(ANGER_SAY_SEETHE); + Talk(ANGER_EMOTE_SEETHE, me); + _targetGUID = target->GetGUID(); + DoCastSelf(SPELL_SEETHE, true); } - case EVENT_SOUL_SCREAM: - DoCastSelf(SPELL_SOUL_SCREAM); - events.Repeat(Seconds(11)); - break; - case EVENT_SPITE: - Talk(ANGER_SAY_SPITE); - me->CastCustomSpell(SPELL_SPITE, SPELLVALUE_MAX_TARGETS, 3, me); - events.Repeat(Seconds(20)); - break; - case EVENT_START_CHECK_TANKER: - if (Unit* target = me->GetVictim()) - { - _targetGUID = target->GetGUID(); - events.ScheduleEvent(EVENT_CHECK_TANKER, Seconds(1)); - } - else - events.Repeat(Seconds(1)); - break; - case EVENT_FREED_2: - Talk(ANGER_SAY_FREED_2); - break; - default: - break; + break; } - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + case EVENT_SOUL_SCREAM: + DoCastSelf(SPELL_SOUL_SCREAM); + events.Repeat(Seconds(11)); + break; + case EVENT_SPITE: + Talk(ANGER_SAY_SPITE); + me->CastCustomSpell(SPELL_SPITE, SPELLVALUE_MAX_TARGETS, 3, me); + events.Repeat(Seconds(20)); + break; + case EVENT_START_CHECK_TANKER: + if (Unit* target = me->GetVictim()) + { + _targetGUID = target->GetGUID(); + events.ScheduleEvent(EVENT_CHECK_TANKER, Seconds(1)); + } + else + events.Repeat(Seconds(1)); + break; + case EVENT_FREED_2: + Talk(ANGER_SAY_FREED_2); + break; + default: + break; } - DoMeleeAttackIfReady(); - } - - void EnterEvadeMode(EvadeReason /*why*/) override - { - if (Creature* reliquary = instance->GetCreature(DATA_RELIQUARY_OF_SOULS)) - reliquary->AI()->EnterEvadeMode(EVADE_REASON_OTHER); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; } - private: - ObjectGuid _targetGUID; - }; + DoMeleeAttackIfReady(); + } - CreatureAI* GetAI(Creature* creature) const override + void EnterEvadeMode(EvadeReason /*why*/) override { - return GetBlackTempleAI<boss_essence_of_angerAI>(creature); + if (Creature* reliquary = instance->GetCreature(DATA_RELIQUARY_OF_SOULS)) + reliquary->AI()->EnterEvadeMode(EVADE_REASON_OTHER); } + +private: + ObjectGuid _targetGUID; }; -class npc_enslaved_soul : public CreatureScript +struct npc_enslaved_soul : public ScriptedAI { -public: - npc_enslaved_soul() : CreatureScript("npc_enslaved_soul") { } + npc_enslaved_soul(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { } - struct npc_enslaved_soulAI : public ScriptedAI + void Reset() override { - npc_enslaved_soulAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { } - - void Reset() override - { - me->SetReactState(REACT_PASSIVE); - if (Creature* reliquary = _instance->GetCreature(DATA_RELIQUARY_OF_SOULS)) - reliquary->AI()->JustSummoned(me); + me->SetReactState(REACT_PASSIVE); + if (Creature* reliquary = _instance->GetCreature(DATA_RELIQUARY_OF_SOULS)) + reliquary->AI()->JustSummoned(me); - DoCastSelf(SPELL_ENSLAVED_SOUL_PASSIVE, true); + DoCastSelf(SPELL_ENSLAVED_SOUL_PASSIVE, true); - _scheduler.Schedule(Seconds(3), [this](TaskContext /*context*/) - { - me->SetReactState(REACT_AGGRESSIVE); - me->SetInCombatWithZone(); - }); - } - - void DoAction(int32 actionId) override + _scheduler.Schedule(Seconds(3), [this](TaskContext /*context*/) { - if (actionId == ACTION_KILL_SELF) - me->KillSelf(); - } + me->SetReactState(REACT_AGGRESSIVE); + me->SetInCombatWithZone(); + }); + } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; + void DoAction(int32 actionId) override + { + if (actionId == ACTION_KILL_SELF) + me->KillSelf(); + } - _scheduler.Update(diff); + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - DoMeleeAttackIfReady(); - } + _scheduler.Update(diff); - void JustDied(Unit* /*killer*/) override - { - DoCastSelf(SPELL_SOUL_RELEASE, true); - } - - private: - InstanceScript* _instance; - TaskScheduler _scheduler; - }; + DoMeleeAttackIfReady(); + } - CreatureAI* GetAI(Creature* creature) const override + void JustDied(Unit* /*killer*/) override { - return GetBlackTempleAI<npc_enslaved_soulAI>(creature); + DoCastSelf(SPELL_SOUL_RELEASE, true); } + +private: + InstanceScript* _instance; + TaskScheduler _scheduler; }; // 41350 - Aura of Desire -class spell_reliquary_of_souls_aura_of_desire : public SpellScriptLoader +class spell_reliquary_of_souls_aura_of_desire : public AuraScript { - public: - spell_reliquary_of_souls_aura_of_desire() : SpellScriptLoader("spell_reliquary_of_souls_aura_of_desire") { } - - class spell_reliquary_of_souls_aura_of_desire_AuraScript : public AuraScript - { - PrepareAuraScript(spell_reliquary_of_souls_aura_of_desire_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_AURA_OF_DESIRE_DAMAGE }); - } + PrepareAuraScript(spell_reliquary_of_souls_aura_of_desire); - void OnProcSpell(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - DamageInfo* damageInfo = eventInfo.GetDamageInfo(); - if (!damageInfo || !damageInfo->GetDamage()) - return; - - Unit* caster = eventInfo.GetActor(); - int32 bp = damageInfo->GetDamage() / 2; - caster->CastCustomSpell(SPELL_AURA_OF_DESIRE_DAMAGE, SPELLVALUE_BASE_POINT0, bp, caster, true, nullptr, aurEff); - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_AURA_OF_DESIRE_DAMAGE }); + } - void UpdateAmount(AuraEffect* /*aurEff*/) - { - if (AuraEffect* effect = GetAura()->GetEffect(EFFECT_1)) - effect->ChangeAmount(effect->GetAmount() - 5); - } + void OnProcSpell(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + DamageInfo* damageInfo = eventInfo.GetDamageInfo(); + if (!damageInfo || !damageInfo->GetDamage()) + return; + + Unit* caster = eventInfo.GetActor(); + int32 bp = damageInfo->GetDamage() / 2; + caster->CastCustomSpell(SPELL_AURA_OF_DESIRE_DAMAGE, SPELLVALUE_BASE_POINT0, bp, caster, true, nullptr, aurEff); + } - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_reliquary_of_souls_aura_of_desire_AuraScript::OnProcSpell, EFFECT_0, SPELL_AURA_MOD_HEALING_PCT); - OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_reliquary_of_souls_aura_of_desire_AuraScript::UpdateAmount, EFFECT_2, SPELL_AURA_PERIODIC_TRIGGER_SPELL); - } - }; + void UpdateAmount(AuraEffect* /*aurEff*/) + { + if (AuraEffect* effect = GetAura()->GetEffect(EFFECT_1)) + effect->ChangeAmount(effect->GetAmount() - 5); + } - AuraScript* GetAuraScript() const override - { - return new spell_reliquary_of_souls_aura_of_desire_AuraScript(); - } + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_reliquary_of_souls_aura_of_desire::OnProcSpell, EFFECT_0, SPELL_AURA_MOD_HEALING_PCT); + OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_reliquary_of_souls_aura_of_desire::UpdateAmount, EFFECT_2, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } }; // 28819 - Submerge Visual -class spell_reliquary_of_souls_submerge : public SpellScriptLoader +class spell_reliquary_of_souls_submerge : public AuraScript { - public: - spell_reliquary_of_souls_submerge() : SpellScriptLoader("spell_reliquary_of_souls_submerge") { } - - class spell_reliquary_of_souls_submerge_AuraScript : public AuraScript - { - PrepareAuraScript(spell_reliquary_of_souls_submerge_AuraScript); + PrepareAuraScript(spell_reliquary_of_souls_submerge); - void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - GetTarget()->SetByteValue(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_STAND_STATE, UNIT_STAND_STATE_SUBMERGED); - } + void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->SetByteValue(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_STAND_STATE, UNIT_STAND_STATE_SUBMERGED); + } - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - GetTarget()->SetByteValue(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_STAND_STATE, UNIT_STAND_STATE_STAND); - } + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->SetByteValue(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_STAND_STATE, UNIT_STAND_STATE_STAND); + } - void Register() override - { - AfterEffectApply += AuraEffectApplyFn(spell_reliquary_of_souls_submerge_AuraScript::OnApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - AfterEffectRemove += AuraEffectRemoveFn(spell_reliquary_of_souls_submerge_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - } - }; - - AuraScript* GetAuraScript() const override - { - return new spell_reliquary_of_souls_submerge_AuraScript(); - } + void Register() override + { + AfterEffectApply += AuraEffectApplyFn(spell_reliquary_of_souls_submerge::OnApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + AfterEffectRemove += AuraEffectRemoveFn(spell_reliquary_of_souls_submerge::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } }; // 41376 - Spite -class spell_reliquary_of_souls_spite : public SpellScriptLoader +class spell_reliquary_of_souls_spite : public AuraScript { - public: - spell_reliquary_of_souls_spite() : SpellScriptLoader("spell_reliquary_of_souls_spite") { } - - class spell_reliquary_of_souls_spite_AuraScript : public AuraScript - { - PrepareAuraScript(spell_reliquary_of_souls_spite_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_SPITE_DAMAGE }); - } + PrepareAuraScript(spell_reliquary_of_souls_spite); - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - if (Unit* caster = GetCaster()) - caster->CastSpell(GetTarget(), SPELL_SPITE_DAMAGE, true); - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SPITE_DAMAGE }); + } - void Register() override - { - AfterEffectRemove += AuraEffectRemoveFn(spell_reliquary_of_souls_spite_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DAMAGE_IMMUNITY, AURA_EFFECT_HANDLE_REAL); - } - }; + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Unit* caster = GetCaster()) + caster->CastSpell(GetTarget(), SPELL_SPITE_DAMAGE, true); + } - AuraScript* GetAuraScript() const - { - return new spell_reliquary_of_souls_spite_AuraScript(); - } + void Register() override + { + AfterEffectRemove += AuraEffectRemoveFn(spell_reliquary_of_souls_spite::OnRemove, EFFECT_0, SPELL_AURA_DAMAGE_IMMUNITY, AURA_EFFECT_HANDLE_REAL); + } }; // 41305 - Frenzy -class spell_reliquary_of_souls_frenzy : public SpellScriptLoader +class spell_reliquary_of_souls_frenzy : public SpellScript { - public: - spell_reliquary_of_souls_frenzy() : SpellScriptLoader("spell_reliquary_of_souls_frenzy") { } - - class spell_reliquary_of_souls_frenzy_SpellScript : public SpellScript - { - PrepareSpellScript(spell_reliquary_of_souls_frenzy_SpellScript); - - void HandleAfterCast() - { - if (Creature* caster = GetCaster()->ToCreature()) - caster->AI()->Talk(SUFF_EMOTE_ENRAGE, caster); - } + PrepareSpellScript(spell_reliquary_of_souls_frenzy); - void Register() override - { - AfterCast += SpellCastFn(spell_reliquary_of_souls_frenzy_SpellScript::HandleAfterCast); - } - }; + void HandleAfterCast() + { + if (Creature* caster = GetCaster()->ToCreature()) + caster->AI()->Talk(SUFF_EMOTE_ENRAGE, caster); + } - SpellScript* GetSpellScript() const override - { - return new spell_reliquary_of_souls_frenzy_SpellScript(); - } + void Register() override + { + AfterCast += SpellCastFn(spell_reliquary_of_souls_frenzy::HandleAfterCast); + } }; void AddSC_boss_reliquary_of_souls() { - new boss_reliquary_of_souls(); - new boss_essence_of_suffering(); - new boss_essence_of_desire(); - new boss_essence_of_anger(); - new npc_enslaved_soul(); - new spell_reliquary_of_souls_aura_of_desire(); - new spell_reliquary_of_souls_submerge(); - new spell_reliquary_of_souls_spite(); - new spell_reliquary_of_souls_frenzy(); + RegisterBlackTempleCreatureAI(boss_reliquary_of_souls); + RegisterBlackTempleCreatureAI(boss_essence_of_suffering); + RegisterBlackTempleCreatureAI(boss_essence_of_desire); + RegisterBlackTempleCreatureAI(boss_essence_of_anger); + RegisterBlackTempleCreatureAI(npc_enslaved_soul); + RegisterAuraScript(spell_reliquary_of_souls_aura_of_desire); + RegisterAuraScript(spell_reliquary_of_souls_submerge); + RegisterAuraScript(spell_reliquary_of_souls_spite); + RegisterSpellScript(spell_reliquary_of_souls_frenzy); } diff --git a/src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp b/src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp index 41090701682..17fd7d91c21 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp @@ -32,14 +32,14 @@ enum Says { // Akama - SAY_BROKEN_FREE_0 = 0, - SAY_BROKEN_FREE_1 = 1, - SAY_BROKEN_FREE_2 = 2, - SAY_LOW_HEALTH = 3, - SAY_DEAD = 4, + SAY_BROKEN_FREE_0 = 0, + SAY_BROKEN_FREE_1 = 1, + SAY_BROKEN_FREE_2 = 2, + SAY_LOW_HEALTH = 3, + SAY_DEAD = 4, // Ashtongue Broken - SAY_BROKEN_SPECIAL = 0, - SAY_BROKEN_HAIL = 1 + SAY_BROKEN_SPECIAL = 0, + SAY_BROKEN_HAIL = 1 }; enum Spells @@ -81,20 +81,20 @@ enum Spells enum Creatures { - NPC_ASHTONGUE_CHANNELER = 23421, - NPC_ASHTONGUE_BROKEN = 23319, - NPC_CREATURE_SPAWNER_AKAMA = 23210 + NPC_ASHTONGUE_CHANNELER = 23421, + NPC_ASHTONGUE_BROKEN = 23319, + NPC_CREATURE_SPAWNER_AKAMA = 23210 }; enum Actions { - ACTION_START_SPAWNING = 0, - ACTION_STOP_SPAWNING = 1, - ACTION_DESPAWN_ALL_SPAWNS = 2, - ACTION_SHADE_OF_AKAMA_DEAD = 3, - ACTION_BROKEN_SPECIAL = 4, - ACTION_BROKEN_EMOTE = 5, - ACTION_BROKEN_HAIL = 6 + ACTION_START_SPAWNING = 0, + ACTION_STOP_SPAWNING = 1, + ACTION_DESPAWN_ALL_SPAWNS = 2, + ACTION_SHADE_OF_AKAMA_DEAD = 3, + ACTION_BROKEN_SPECIAL = 4, + ACTION_BROKEN_EMOTE = 5, + ACTION_BROKEN_HAIL = 6 }; enum Events @@ -139,10 +139,9 @@ enum Events enum Misc { - AKAMA_CHANNEL_WAYPOINT = 0, - AKAMA_INTRO_WAYPOINT = 1, - - SUMMON_GROUP_RESET = 1 + AKAMA_CHANNEL_WAYPOINT = 0, + AKAMA_INTRO_WAYPOINT = 1, + SUMMON_GROUP_RESET = 1 }; Position const AkamaWP[2] = @@ -199,1073 +198,941 @@ static float const MIDDLE_OF_ROOM = 400.0f; static float const FACE_THE_DOOR = 0.08726646f; static float const FACE_THE_PLATFORM = 3.118662f; -class boss_shade_of_akama : public CreatureScript + +struct boss_shade_of_akama : public BossAI { -public: - boss_shade_of_akama() : CreatureScript("boss_shade_of_akama") { } + boss_shade_of_akama(Creature* creature) : BossAI(creature, DATA_SHADE_OF_AKAMA) + { + Initialize(); + } - struct boss_shade_of_akamaAI : public BossAI + void Initialize() { - boss_shade_of_akamaAI(Creature* creature) : BossAI(creature, DATA_SHADE_OF_AKAMA) - { - Initialize(); - } + _spawners.clear(); + _isInPhaseOne = true; + } - void Initialize() - { - _spawners.clear(); - _isInPhaseOne = true; - } + void Reset() override + { + _Reset(); + Initialize(); + me->SetImmuneToPC(true); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_STUN); + me->SetWalk(true); + events.ScheduleEvent(EVENT_INITIALIZE_SPAWNERS, Seconds(1)); + me->SummonCreatureGroup(SUMMON_GROUP_RESET); + } + + void EnterEvadeMode(EvadeReason /*why*/) override + { + events.Reset(); + summons.DespawnAll(); + + for (ObjectGuid const spawnerGuid : _spawners) + if (Creature* spawner = ObjectAccessor::GetCreature(*me, spawnerGuid)) + spawner->AI()->DoAction(ACTION_DESPAWN_ALL_SPAWNS); - void Reset() override + _DespawnAtEvade(); + } + + void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override + { + if (spell->Id == SPELL_AKAMA_SOUL_CHANNEL) { - _Reset(); - Initialize(); - me->SetImmuneToPC(true); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_STUN); - me->SetWalk(true); - events.ScheduleEvent(EVENT_INITIALIZE_SPAWNERS, Seconds(1)); - me->SummonCreatureGroup(SUMMON_GROUP_RESET); + events.ScheduleEvent(EVENT_START_CHANNELERS_AND_SPAWNERS, Seconds(1)); + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE); + events.ScheduleEvent(EVENT_EVADE_CHECK, Seconds(10)); + if (Creature* akama = instance->GetCreature(DATA_AKAMA_SHADE)) + AttackStart(akama); } - void EnterEvadeMode(EvadeReason /*why*/) override + if (spell->Id == SPELL_AKAMA_SOUL_RETRIEVE) + DoCastSelf(SPELL_AKAMA_SOUL_EXPEL_CHANNEL); + } + + void MovementInform(uint32 motionType, uint32 /*pointId*/) override + { + if (_isInPhaseOne && motionType == CHASE_MOTION_TYPE) { - events.Reset(); - summons.DespawnAll(); + _isInPhaseOne = false; + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + me->SetImmuneToPC(false); + me->SetWalk(false); + events.ScheduleEvent(EVENT_ADD_THREAT, Milliseconds(100)); for (ObjectGuid const spawnerGuid : _spawners) if (Creature* spawner = ObjectAccessor::GetCreature(*me, spawnerGuid)) - spawner->AI()->DoAction(ACTION_DESPAWN_ALL_SPAWNS); - - _DespawnAtEvade(); + spawner->AI()->DoAction(ACTION_STOP_SPAWNING); } + } - void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override - { - if (spell->Id == SPELL_AKAMA_SOUL_CHANNEL) - { - events.ScheduleEvent(EVENT_START_CHANNELERS_AND_SPAWNERS, Seconds(1)); - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE); - events.ScheduleEvent(EVENT_EVADE_CHECK, Seconds(10)); - if (Creature* akama = instance->GetCreature(DATA_AKAMA_SHADE)) - AttackStart(akama); - } - - if (spell->Id == SPELL_AKAMA_SOUL_RETRIEVE) - DoCastSelf(SPELL_AKAMA_SOUL_EXPEL_CHANNEL); - } + void JustDied(Unit* /*killer*/) override + { + DoCastSelf(SPELL_SHADE_OF_AKAMA_TRIGGER); - void MovementInform(uint32 motionType, uint32 /*pointId*/) override - { - if (_isInPhaseOne && motionType == CHASE_MOTION_TYPE) - { - _isInPhaseOne = false; - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->SetImmuneToPC(false); - me->SetWalk(false); - events.ScheduleEvent(EVENT_ADD_THREAT, Milliseconds(100)); - - for (ObjectGuid const spawnerGuid : _spawners) - if (Creature* spawner = ObjectAccessor::GetCreature(*me, spawnerGuid)) - spawner->AI()->DoAction(ACTION_STOP_SPAWNING); - } - } + if (Creature* akama = instance->GetCreature(DATA_AKAMA_SHADE)) + akama->AI()->DoAction(ACTION_SHADE_OF_AKAMA_DEAD); - void JustDied(Unit* /*killer*/) override - { - DoCastSelf(SPELL_SHADE_OF_AKAMA_TRIGGER); + for (ObjectGuid const spawnerGuid : _spawners) + if (Creature* spawner = ObjectAccessor::GetCreature(*me, spawnerGuid)) + spawner->AI()->DoAction(ACTION_DESPAWN_ALL_SPAWNS); - if (Creature* akama = instance->GetCreature(DATA_AKAMA_SHADE)) - akama->AI()->DoAction(ACTION_SHADE_OF_AKAMA_DEAD); + events.Reset(); + summons.DespawnEntry(NPC_ASHTONGUE_CHANNELER); + instance->SetBossState(DATA_SHADE_OF_AKAMA, DONE); + } - for (ObjectGuid const spawnerGuid : _spawners) - if (Creature* spawner = ObjectAccessor::GetCreature(*me, spawnerGuid)) - spawner->AI()->DoAction(ACTION_DESPAWN_ALL_SPAWNS); + void EnterEvadeModeIfNeeded() + { + Map::PlayerList const& players = me->GetMap()->GetPlayers(); + for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i) + if (Player* player = i->GetSource()) + if (player->IsAlive() && !player->IsGameMaster() && CheckBoundary(player)) + return; - events.Reset(); - summons.DespawnEntry(NPC_ASHTONGUE_CHANNELER); - instance->SetBossState(DATA_SHADE_OF_AKAMA, DONE); - } + EnterEvadeMode(EVADE_REASON_NO_HOSTILES); + } - void EnterEvadeModeIfNeeded() - { - Map::PlayerList const& players = me->GetMap()->GetPlayers(); - for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i) - if (Player* player = i->GetSource()) - if (player->IsAlive() && !player->IsGameMaster() && CheckBoundary(player)) - return; + void UpdateAI(uint32 diff) override + { + events.Update(diff); - EnterEvadeMode(EVADE_REASON_NO_HOSTILES); - } + if (!UpdateVictim()) + return; - void UpdateAI(uint32 diff) override + while (uint32 eventId = events.ExecuteEvent()) { - events.Update(diff); - - if (!UpdateVictim()) - return; - - while (uint32 eventId = events.ExecuteEvent()) + switch (eventId) { - switch (eventId) + case EVENT_INITIALIZE_SPAWNERS: { - case EVENT_INITIALIZE_SPAWNERS: - { - std::list<Creature*> SpawnerList; - me->GetCreatureListWithEntryInGrid(SpawnerList, NPC_CREATURE_SPAWNER_AKAMA); - for (Creature* spawner : SpawnerList) - _spawners.push_back(spawner->GetGUID()); + std::list<Creature*> SpawnerList; + me->GetCreatureListWithEntryInGrid(SpawnerList, NPC_CREATURE_SPAWNER_AKAMA); + for (Creature* spawner : SpawnerList) + _spawners.push_back(spawner->GetGUID()); - break; - } - case EVENT_START_CHANNELERS_AND_SPAWNERS: - { - for (ObjectGuid const summonGuid : summons) - if (Creature* channeler = ObjectAccessor::GetCreature(*me, summonGuid)) - channeler->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + break; + } + case EVENT_START_CHANNELERS_AND_SPAWNERS: + { + for (ObjectGuid const summonGuid : summons) + if (Creature* channeler = ObjectAccessor::GetCreature(*me, summonGuid)) + channeler->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - for (ObjectGuid const spawnerGuid : _spawners) - if (Creature* spawner = ObjectAccessor::GetCreature(*me, spawnerGuid)) - spawner->AI()->DoAction(ACTION_START_SPAWNING); + for (ObjectGuid const spawnerGuid : _spawners) + if (Creature* spawner = ObjectAccessor::GetCreature(*me, spawnerGuid)) + spawner->AI()->DoAction(ACTION_START_SPAWNING); - break; - } - case EVENT_ADD_THREAT: - DoCast(SPELL_THREAT); - events.Repeat(Seconds(3) + Milliseconds(500)); - break; - case EVENT_EVADE_CHECK: - EnterEvadeModeIfNeeded(); - events.Repeat(Seconds(10)); - break; - default: - break; + break; } + case EVENT_ADD_THREAT: + DoCast(SPELL_THREAT); + events.Repeat(Seconds(3) + Milliseconds(500)); + break; + case EVENT_EVADE_CHECK: + EnterEvadeModeIfNeeded(); + events.Repeat(Seconds(10)); + break; + default: + break; } - - DoMeleeAttackIfReady(); } - private: - GuidVector _spawners; - bool _isInPhaseOne; - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetBlackTempleAI<boss_shade_of_akamaAI>(creature); + DoMeleeAttackIfReady(); } + +private: + GuidVector _spawners; + bool _isInPhaseOne; }; -class npc_akama_shade : public CreatureScript +struct npc_akama_shade : public ScriptedAI { -public: - npc_akama_shade() : CreatureScript("npc_akama_shade") { } - - struct npc_akamaAI : public ScriptedAI + npc_akama_shade(Creature* creature) : ScriptedAI(creature), _summons(me) { - npc_akamaAI(Creature* creature) : ScriptedAI(creature), _summons(me) - { - Initialize(); - _instance = creature->GetInstanceScript(); - } + Initialize(); + _instance = creature->GetInstanceScript(); + } - void Initialize() - { - _isInCombat = false; - _hasYelledOnce = false; - _chosen.Clear(); - _summons.DespawnAll(); - _events.Reset(); - } + void Initialize() + { + _isInCombat = false; + _hasYelledOnce = false; + _chosen.Clear(); + _summons.DespawnAll(); + _events.Reset(); + } - void Reset() override - { - Initialize(); - me->SetFaction(FACTION_ASHTONGUE_DEATHSWORN); - DoCastSelf(SPELL_STEALTH); + void Reset() override + { + Initialize(); + me->SetFaction(FACTION_ASHTONGUE_DEATHSWORN); + DoCastSelf(SPELL_STEALTH); - if (_instance->GetBossState(DATA_SHADE_OF_AKAMA) != DONE) - me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - } + if (_instance->GetBossState(DATA_SHADE_OF_AKAMA) != DONE) + me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + } - void JustSummoned(Creature* summon) override - { - _summons.Summon(summon); - } + void JustSummoned(Creature* summon) override + { + _summons.Summon(summon); + } - void EnterEvadeMode(EvadeReason /*why*/) override { } + void EnterEvadeMode(EvadeReason /*why*/) override { } - void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override + void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override + { + if (spell->Id == SPELL_THREAT && !_isInCombat) { - if (spell->Id == SPELL_THREAT && !_isInCombat) + _isInCombat = true; + me->SetWalk(false); + me->RemoveAurasDueToSpell(SPELL_AKAMA_SOUL_CHANNEL); + if (Creature* shade = _instance->GetCreature(DATA_SHADE_OF_AKAMA)) { - _isInCombat = true; - me->SetWalk(false); - me->RemoveAurasDueToSpell(SPELL_AKAMA_SOUL_CHANNEL); - if (Creature* shade = _instance->GetCreature(DATA_SHADE_OF_AKAMA)) - { - shade->RemoveAurasDueToSpell(SPELL_AKAMA_SOUL_CHANNEL); - AttackStart(shade); - _events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, Seconds(2)); - _events.ScheduleEvent(EVENT_DESTRUCTIVE_POISON, Seconds(5)); - } + shade->RemoveAurasDueToSpell(SPELL_AKAMA_SOUL_CHANNEL); + AttackStart(shade); + _events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, Seconds(2)); + _events.ScheduleEvent(EVENT_DESTRUCTIVE_POISON, Seconds(5)); } } + } - void DamageTaken(Unit* /*who*/, uint32& /*damage*/) override + void DamageTaken(Unit* /*who*/, uint32& /*damage*/) override + { + if (me->HealthBelowPct(20) && !_hasYelledOnce) { - if (me->HealthBelowPct(20) && !_hasYelledOnce) - { - _hasYelledOnce = true; - Talk(SAY_LOW_HEALTH); - } + _hasYelledOnce = true; + Talk(SAY_LOW_HEALTH); } + } - void DoAction(int32 actionId) override + void DoAction(int32 actionId) override + { + if (actionId == ACTION_SHADE_OF_AKAMA_DEAD) { - if (actionId == ACTION_SHADE_OF_AKAMA_DEAD) - { - _isInCombat = false; - me->CombatStop(true); - me->SetFaction(FACTION_ASHTONGUE_DEATHSWORN); - me->SetWalk(true); - _events.Reset(); - me->GetMotionMaster()->MovePoint(AKAMA_INTRO_WAYPOINT, AkamaWP[1]); - } + _isInCombat = false; + me->CombatStop(true); + me->SetFaction(FACTION_ASHTONGUE_DEATHSWORN); + me->SetWalk(true); + _events.Reset(); + me->GetMotionMaster()->MovePoint(AKAMA_INTRO_WAYPOINT, AkamaWP[1]); } + } - void MovementInform(uint32 motionType, uint32 pointId) override - { - if (motionType != POINT_MOTION_TYPE) - return; + void MovementInform(uint32 motionType, uint32 pointId) override + { + if (motionType != POINT_MOTION_TYPE) + return; - if (pointId == AKAMA_CHANNEL_WAYPOINT) - _events.ScheduleEvent(EVENT_SHADE_CHANNEL, Seconds(1)); + if (pointId == AKAMA_CHANNEL_WAYPOINT) + _events.ScheduleEvent(EVENT_SHADE_CHANNEL, Seconds(1)); - else if (pointId == AKAMA_INTRO_WAYPOINT) - { - me->SetWalk(false); - _events.ScheduleEvent(EVENT_START_SOUL_RETRIEVE, Seconds(1)); - } + else if (pointId == AKAMA_INTRO_WAYPOINT) + { + me->SetWalk(false); + _events.ScheduleEvent(EVENT_START_SOUL_RETRIEVE, Seconds(1)); } + } - void SummonBrokens() + void SummonBrokens() + { + for (uint8 i = 0; i < 18; i++) { - for (uint8 i = 0; i < 18; i++) + if (TempSummon* summoned = me->SummonCreature(NPC_ASHTONGUE_BROKEN, BrokenPos[i])) { - if (TempSummon* summoned = me->SummonCreature(NPC_ASHTONGUE_BROKEN, BrokenPos[i])) - { - summoned->SetWalk(true); - summoned->GetMotionMaster()->MovePoint(0, BrokenWP[i]); - if (i == 9) //On Sniffs, npc that Yell "Special" is the tenth to be created - _chosen = summoned->GetGUID(); - } + summoned->SetWalk(true); + summoned->GetMotionMaster()->MovePoint(0, BrokenWP[i]); + if (i == 9) //On Sniffs, npc that Yell "Special" is the tenth to be created + _chosen = summoned->GetGUID(); } } + } - void UpdateAI(uint32 diff) override - { - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_SHADE_START: - _instance->SetBossState(DATA_SHADE_OF_AKAMA, IN_PROGRESS); - me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - me->RemoveAurasDueToSpell(SPELL_STEALTH); - me->SetWalk(true); - me->GetMotionMaster()->MovePoint(AKAMA_CHANNEL_WAYPOINT, AkamaWP[0], false); - break; - case EVENT_SHADE_CHANNEL: - me->SetFacingTo(FACE_THE_PLATFORM); - DoCastSelf(SPELL_AKAMA_SOUL_CHANNEL); - me->SetFaction(FACTION_MONSTER_SPAR_BUDDY); - _events.ScheduleEvent(EVENT_FIXATE, Seconds(5)); - break; - case EVENT_FIXATE: - DoCast(SPELL_FIXATE); - break; - case EVENT_CHAIN_LIGHTNING: - DoCastVictim(SPELL_CHAIN_LIGHTNING); - _events.Repeat(Seconds(8), Seconds(15)); - break; - case EVENT_DESTRUCTIVE_POISON: - DoCastSelf(SPELL_DESTRUCTIVE_POISON); - _events.Repeat(Seconds(3), Seconds(7)); - break; - case EVENT_START_SOUL_RETRIEVE: - me->SetFacingTo(FACE_THE_DOOR); - DoCast(SPELL_AKAMA_SOUL_RETRIEVE); - _events.ScheduleEvent(EVENT_START_BROKEN_FREE, Seconds(15)); - break; - case EVENT_START_BROKEN_FREE: - me->HandleEmoteCommand(EMOTE_ONESHOT_ROAR); - Talk(SAY_BROKEN_FREE_0); - SummonBrokens(); - _events.ScheduleEvent(EVENT_BROKEN_FREE_1, Seconds(10)); - break; - case EVENT_BROKEN_FREE_1: - Talk(SAY_BROKEN_FREE_1); - _events.ScheduleEvent(EVENT_BROKEN_FREE_2, Seconds(12)); - break; - case EVENT_BROKEN_FREE_2: - Talk(SAY_BROKEN_FREE_2); - _events.ScheduleEvent(EVENT_BROKEN_FREE_3, Seconds(15)); - break; - case EVENT_BROKEN_FREE_3: - if (Creature* special = ObjectAccessor::GetCreature(*me, _chosen)) - special->AI()->Talk(SAY_BROKEN_SPECIAL); - - _summons.DoAction(ACTION_BROKEN_EMOTE, _pred); - _events.ScheduleEvent(EVENT_BROKEN_FREE_4, Seconds(5)); - break; - case EVENT_BROKEN_FREE_4: - _summons.DoAction(ACTION_BROKEN_HAIL, _pred); - break; - default: - break; - } - } + void UpdateAI(uint32 diff) override + { + _events.Update(diff); - if (me->GetFaction() == FACTION_MONSTER_SPAR_BUDDY) + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) { - if (!UpdateVictim()) - return; + case EVENT_SHADE_START: + _instance->SetBossState(DATA_SHADE_OF_AKAMA, IN_PROGRESS); + me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + me->RemoveAurasDueToSpell(SPELL_STEALTH); + me->SetWalk(true); + me->GetMotionMaster()->MovePoint(AKAMA_CHANNEL_WAYPOINT, AkamaWP[0], false); + break; + case EVENT_SHADE_CHANNEL: + me->SetFacingTo(FACE_THE_PLATFORM); + DoCastSelf(SPELL_AKAMA_SOUL_CHANNEL); + me->SetFaction(FACTION_MONSTER_SPAR_BUDDY); + _events.ScheduleEvent(EVENT_FIXATE, Seconds(5)); + break; + case EVENT_FIXATE: + DoCast(SPELL_FIXATE); + break; + case EVENT_CHAIN_LIGHTNING: + DoCastVictim(SPELL_CHAIN_LIGHTNING); + _events.Repeat(Seconds(8), Seconds(15)); + break; + case EVENT_DESTRUCTIVE_POISON: + DoCastSelf(SPELL_DESTRUCTIVE_POISON); + _events.Repeat(Seconds(3), Seconds(7)); + break; + case EVENT_START_SOUL_RETRIEVE: + me->SetFacingTo(FACE_THE_DOOR); + DoCast(SPELL_AKAMA_SOUL_RETRIEVE); + _events.ScheduleEvent(EVENT_START_BROKEN_FREE, Seconds(15)); + break; + case EVENT_START_BROKEN_FREE: + me->HandleEmoteCommand(EMOTE_ONESHOT_ROAR); + Talk(SAY_BROKEN_FREE_0); + SummonBrokens(); + _events.ScheduleEvent(EVENT_BROKEN_FREE_1, Seconds(10)); + break; + case EVENT_BROKEN_FREE_1: + Talk(SAY_BROKEN_FREE_1); + _events.ScheduleEvent(EVENT_BROKEN_FREE_2, Seconds(12)); + break; + case EVENT_BROKEN_FREE_2: + Talk(SAY_BROKEN_FREE_2); + _events.ScheduleEvent(EVENT_BROKEN_FREE_3, Seconds(15)); + break; + case EVENT_BROKEN_FREE_3: + if (Creature* special = ObjectAccessor::GetCreature(*me, _chosen)) + special->AI()->Talk(SAY_BROKEN_SPECIAL); - DoMeleeAttackIfReady(); + _summons.DoAction(ACTION_BROKEN_EMOTE, _pred); + _events.ScheduleEvent(EVENT_BROKEN_FREE_4, Seconds(5)); + break; + case EVENT_BROKEN_FREE_4: + _summons.DoAction(ACTION_BROKEN_HAIL, _pred); + break; + default: + break; } } - void JustDied(Unit* /*killer*/) override + if (me->GetFaction() == FACTION_MONSTER_SPAR_BUDDY) { - _summons.DespawnAll(); - Talk(SAY_DEAD); - if (Creature* shade = _instance->GetCreature(DATA_SHADE_OF_AKAMA)) - if (shade->IsAlive()) - shade->AI()->EnterEvadeMode(EVADE_REASON_OTHER); - } + if (!UpdateVictim()) + return; - bool GossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override - { - if (gossipListId == 0) - { - CloseGossipMenuFor(player); - _events.ScheduleEvent(EVENT_SHADE_START, Milliseconds(500)); - } - return false; + DoMeleeAttackIfReady(); } + } - private: - InstanceScript* _instance; - EventMap _events; - SummonList _summons; - DummyEntryCheckPredicate _pred; - ObjectGuid _chosen; //Creature that should yell the speech special. - bool _isInCombat; - bool _hasYelledOnce; - }; + void JustDied(Unit* /*killer*/) override + { + _summons.DespawnAll(); + Talk(SAY_DEAD); + if (Creature* shade = _instance->GetCreature(DATA_SHADE_OF_AKAMA)) + if (shade->IsAlive()) + shade->AI()->EnterEvadeMode(EVADE_REASON_OTHER); + } - CreatureAI* GetAI(Creature* creature) const override + bool GossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override { - return GetBlackTempleAI<npc_akamaAI>(creature); + if (gossipListId == 0) + { + CloseGossipMenuFor(player); + _events.ScheduleEvent(EVENT_SHADE_START, Milliseconds(500)); + } + return false; } + +private: + InstanceScript* _instance; + EventMap _events; + SummonList _summons; + DummyEntryCheckPredicate _pred; + ObjectGuid _chosen; //Creature that should yell the speech special. + bool _isInCombat; + bool _hasYelledOnce; }; -class npc_ashtongue_channeler : public CreatureScript +struct npc_ashtongue_channeler : public PassiveAI { -public: - npc_ashtongue_channeler() : CreatureScript("npc_ashtongue_channeler") { } - - struct npc_ashtongue_channelerAI : public PassiveAI + npc_ashtongue_channeler(Creature* creature) : PassiveAI(creature) { - npc_ashtongue_channelerAI(Creature* creature) : PassiveAI(creature) - { - _instance = creature->GetInstanceScript(); - } + _instance = creature->GetInstanceScript(); + } - void Reset() override + void Reset() override + { + _scheduler.Schedule(Seconds(2), [this](TaskContext channel) { - _scheduler.Schedule(Seconds(2), [this](TaskContext channel) + if (Creature* shade = _instance->GetCreature(DATA_SHADE_OF_AKAMA)) { - if (Creature* shade = _instance->GetCreature(DATA_SHADE_OF_AKAMA)) - { - if (shade->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE)) - DoCastSelf(SPELL_SHADE_SOUL_CHANNEL); - - else - me->DespawnOrUnsummon(Seconds(3)); - } - - channel.Repeat(Seconds(2)); - }); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - } + if (shade->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE)) + DoCastSelf(SPELL_SHADE_SOUL_CHANNEL); - void UpdateAI(uint32 diff) override - { - _scheduler.Update(diff); - } + else + me->DespawnOrUnsummon(Seconds(3)); + } - private: - InstanceScript* _instance; - TaskScheduler _scheduler; - }; + channel.Repeat(Seconds(2)); + }); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + } - CreatureAI* GetAI(Creature* creature) const override + void UpdateAI(uint32 diff) override { - return GetBlackTempleAI<npc_ashtongue_channelerAI>(creature); + _scheduler.Update(diff); } + +private: + InstanceScript* _instance; + TaskScheduler _scheduler; }; -class npc_creature_generator_akama : public CreatureScript +struct npc_creature_generator_akama : public ScriptedAI { -public: - npc_creature_generator_akama() : CreatureScript("npc_creature_generator_akama") { } + npc_creature_generator_akama(Creature* creature) : ScriptedAI(creature), _summons(me) + { + Initialize(); + } - struct npc_creature_generator_akamaAI : public ScriptedAI + void Initialize() { - npc_creature_generator_akamaAI(Creature* creature) : ScriptedAI(creature), _summons(me) - { - Initialize(); - } + _leftSide = false; + _events.Reset(); + _summons.DespawnAll(); + } - void Initialize() - { - _leftSide = false; - _events.Reset(); - _summons.DespawnAll(); - } + void Reset() override + { + Initialize(); - void Reset() override - { - Initialize(); + if (me->GetPositionY() < MIDDLE_OF_ROOM) + _leftSide = true; + } - if (me->GetPositionY() < MIDDLE_OF_ROOM) - _leftSide = true; - } + void JustSummoned(Creature* summon) override + { + _summons.Summon(summon); + } - void JustSummoned(Creature* summon) override + void DoAction(int32 actionId) override + { + switch (actionId) { - _summons.Summon(summon); + case ACTION_START_SPAWNING: + if (_leftSide) + { + _events.ScheduleEvent(EVENT_SPAWN_WAVE_B, Milliseconds(100)); + _events.ScheduleEvent(EVENT_SUMMON_ASHTONGUE_SORCERER, Seconds(2), Seconds(5)); + } + else + { + _events.ScheduleEvent(EVENT_SPAWN_WAVE_B, Seconds(10)); + _events.ScheduleEvent(EVENT_SUMMON_ASHTONGUE_DEFENDER, Seconds(2), Seconds(5)); + } + break; + case ACTION_STOP_SPAWNING: + _events.Reset(); + break; + case ACTION_DESPAWN_ALL_SPAWNS: + _events.Reset(); + _summons.DespawnAll(); + break; + default: + break; } + } + + void UpdateAI(uint32 diff) override + { + _events.Update(diff); - void DoAction(int32 actionId) override + while (uint32 eventId = _events.ExecuteEvent()) { - switch (actionId) + switch (eventId) { - case ACTION_START_SPAWNING: - if (_leftSide) - { - _events.ScheduleEvent(EVENT_SPAWN_WAVE_B, Milliseconds(100)); - _events.ScheduleEvent(EVENT_SUMMON_ASHTONGUE_SORCERER, Seconds(2), Seconds(5)); - } - else - { - _events.ScheduleEvent(EVENT_SPAWN_WAVE_B, Seconds(10)); - _events.ScheduleEvent(EVENT_SUMMON_ASHTONGUE_DEFENDER, Seconds(2), Seconds(5)); - } + case EVENT_SPAWN_WAVE_B: + DoCastSelf(SPELL_ASHTONGUE_WAVE_B); + _events.Repeat(Seconds(50), Seconds(60)); break; - case ACTION_STOP_SPAWNING: - _events.Reset(); + case EVENT_SUMMON_ASHTONGUE_SORCERER: // left + DoCastSelf(SPELL_SUMMON_ASHTONGUE_SORCERER); + _events.Repeat(Seconds(30), Seconds(35)); break; - case ACTION_DESPAWN_ALL_SPAWNS: - _events.Reset(); - _summons.DespawnAll(); + case EVENT_SUMMON_ASHTONGUE_DEFENDER: // right + DoCastSelf(SPELL_SUMMON_ASHTONGUE_DEFENDER); + _events.Repeat(Seconds(30), Seconds(40)); break; default: break; } } + } - void UpdateAI(uint32 diff) override - { - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_SPAWN_WAVE_B: - DoCastSelf(SPELL_ASHTONGUE_WAVE_B); - _events.Repeat(Seconds(50), Seconds(60)); - break; - case EVENT_SUMMON_ASHTONGUE_SORCERER: // left - DoCastSelf(SPELL_SUMMON_ASHTONGUE_SORCERER); - _events.Repeat(Seconds(30), Seconds(35)); - break; - case EVENT_SUMMON_ASHTONGUE_DEFENDER: // right - DoCastSelf(SPELL_SUMMON_ASHTONGUE_DEFENDER); - _events.Repeat(Seconds(30), Seconds(40)); - break; - default: - break; - } - } - } - - private: - EventMap _events; - SummonList _summons; - bool _leftSide; - }; +private: + EventMap _events; + SummonList _summons; + bool _leftSide; +}; - CreatureAI* GetAI(Creature* creature) const override +struct npc_ashtongue_sorcerer : public ScriptedAI +{ + npc_ashtongue_sorcerer(Creature* creature) : ScriptedAI(creature) { - return GetBlackTempleAI<npc_creature_generator_akamaAI>(creature); + Initialize(); + _instance = creature->GetInstanceScript(); } -}; -class npc_ashtongue_sorcerer : public CreatureScript -{ -public: - npc_ashtongue_sorcerer() : CreatureScript("npc_ashtongue_sorcerer") { } + void Initialize() + { + _switchToCombat = false; + _inBanish = false; + } - struct npc_ashtongue_sorcererAI : public ScriptedAI + void Reset() override { - npc_ashtongue_sorcererAI(Creature* creature) : ScriptedAI(creature) + if (Creature* shade = _instance->GetCreature(DATA_SHADE_OF_AKAMA)) { - Initialize(); - _instance = creature->GetInstanceScript(); - } + if (shade->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE)) + me->GetMotionMaster()->MovePoint(0, shade->GetPosition()); - void Initialize() - { - _switchToCombat = false; - _inBanish = false; + else if (Creature* akama = _instance->GetCreature(DATA_AKAMA_SHADE)) + AttackStart(akama); } + Initialize(); + } - void Reset() override - { - if (Creature* shade = _instance->GetCreature(DATA_SHADE_OF_AKAMA)) - { - if (shade->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE)) - me->GetMotionMaster()->MovePoint(0, shade->GetPosition()); + void JustDied(Unit* /*killer*/) override + { + me->DespawnOrUnsummon(Seconds(5)); + } - else if (Creature* akama = _instance->GetCreature(DATA_AKAMA_SHADE)) - AttackStart(akama); - } - Initialize(); - } + void EnterEvadeMode(EvadeReason /*why*/) override { } + void EnterCombat(Unit* /*who*/) override { } - void JustDied(Unit* /*killer*/) override - { - me->DespawnOrUnsummon(Seconds(5)); - } + void AttackStart(Unit* who) override + { + if (!_switchToCombat) + return; - void EnterEvadeMode(EvadeReason /*why*/) override { } - void EnterCombat(Unit* /*who*/) override { } + ScriptedAI::AttackStart(who); + } - void AttackStart(Unit* who) override + void MoveInLineOfSight(Unit* who) override + { + if (!_inBanish && who->GetGUID() == _instance->GetGuidData(DATA_SHADE_OF_AKAMA) && me->IsWithinDist(who, 20.0f, false)) { - if (!_switchToCombat) - return; + _inBanish = true; + me->StopMoving(); + me->GetMotionMaster()->Clear(false); + me->GetMotionMaster()->MovePoint(1, me->GetPositionX() + frand(-8.0f, 8.0f), me->GetPositionY() + frand(-8.0f, 8.0f), me->GetPositionZ()); - ScriptedAI::AttackStart(who); - } - - void MoveInLineOfSight(Unit* who) override - { - if (!_inBanish && who->GetGUID() == _instance->GetGuidData(DATA_SHADE_OF_AKAMA) && me->IsWithinDist(who, 20.0f, false)) + _scheduler.Schedule(Seconds(1) + Milliseconds(500), [this](TaskContext sorcer_channel) { - _inBanish = true; - me->StopMoving(); - me->GetMotionMaster()->Clear(false); - me->GetMotionMaster()->MovePoint(1, me->GetPositionX() + frand(-8.0f, 8.0f), me->GetPositionY() + frand(-8.0f, 8.0f), me->GetPositionZ()); - - _scheduler.Schedule(Seconds(1) + Milliseconds(500), [this](TaskContext sorcer_channel) + if (Creature* shade = _instance->GetCreature(DATA_SHADE_OF_AKAMA)) { - if (Creature* shade = _instance->GetCreature(DATA_SHADE_OF_AKAMA)) + if (shade->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE)) + { + me->SetFacingToObject(shade); + DoCastSelf(SPELL_SHADE_SOUL_CHANNEL); + sorcer_channel.Repeat(Seconds(2)); + } + else { - if (shade->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE)) - { - me->SetFacingToObject(shade); - DoCastSelf(SPELL_SHADE_SOUL_CHANNEL); - sorcer_channel.Repeat(Seconds(2)); - } - else - { - me->InterruptSpell(CURRENT_CHANNELED_SPELL); - _switchToCombat = true; - if (Creature* akama = _instance->GetCreature(DATA_AKAMA_SHADE)) - AttackStart(akama); - } + me->InterruptSpell(CURRENT_CHANNELED_SPELL); + _switchToCombat = true; + if (Creature* akama = _instance->GetCreature(DATA_AKAMA_SHADE)) + AttackStart(akama); } - }); - } + } + }); } + } - void UpdateAI(uint32 diff) override - { - _scheduler.Update(diff); + void UpdateAI(uint32 diff) override + { + _scheduler.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - if (!UpdateVictim()) - return; + if (!UpdateVictim()) + return; - DoMeleeAttackIfReady(); - } + DoMeleeAttackIfReady(); + } - private: - InstanceScript* _instance; - TaskScheduler _scheduler; - bool _switchToCombat; - bool _inBanish; - }; +private: + InstanceScript* _instance; + TaskScheduler _scheduler; + bool _switchToCombat; + bool _inBanish; +}; - CreatureAI* GetAI(Creature* creature) const override +struct npc_ashtongue_defender : public ScriptedAI +{ + npc_ashtongue_defender(Creature* creature) : ScriptedAI(creature) { - return GetBlackTempleAI<npc_ashtongue_sorcererAI>(creature); + _instance = creature->GetInstanceScript(); } -}; -class npc_ashtongue_defender : public CreatureScript -{ -public: - npc_ashtongue_defender() : CreatureScript("npc_ashtongue_defender") { } + void Reset() override + { + if (Creature* akama = _instance->GetCreature(DATA_AKAMA_SHADE)) + AttackStart(akama); + } - struct npc_ashtongue_defenderAI : public ScriptedAI + void JustDied(Unit* /*killer*/) override { - npc_ashtongue_defenderAI(Creature* creature) : ScriptedAI(creature) - { - _instance = creature->GetInstanceScript(); - } + me->DespawnOrUnsummon(Seconds(5)); + } - void Reset() override - { - if (Creature* akama = _instance->GetCreature(DATA_AKAMA_SHADE)) - AttackStart(akama); - } + void EnterCombat(Unit* /*who*/) override + { + _events.ScheduleEvent(EVENT_HEROIC_STRIKE, Seconds(5)); + _events.ScheduleEvent(EVENT_SHIELD_BASH, Seconds(10), Seconds(16)); + _events.ScheduleEvent(EVENT_DEBILITATING_STRIKE, Seconds(10), Seconds(16)); + _events.ScheduleEvent(EVENT_WINDFURY, Seconds(8), Seconds(12)); + } - void JustDied(Unit* /*killer*/) override - { - me->DespawnOrUnsummon(Seconds(5)); - } - void EnterCombat(Unit* /*who*/) override - { - _events.ScheduleEvent(EVENT_HEROIC_STRIKE, Seconds(5)); - _events.ScheduleEvent(EVENT_SHIELD_BASH, Seconds(10), Seconds(16)); - _events.ScheduleEvent(EVENT_DEBILITATING_STRIKE, Seconds(10), Seconds(16)); - _events.ScheduleEvent(EVENT_WINDFURY, Seconds(8), Seconds(12)); - } + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + _events.Update(diff); - void UpdateAI(uint32 diff) override + while (uint32 eventId = _events.ExecuteEvent()) { - if (!UpdateVictim()) - return; - - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) + switch (eventId) { - switch (eventId) - { - case EVENT_DEBILITATING_STRIKE: - DoCastVictim(SPELL_DEBILITATING_STRIKE); - _events.Repeat(Seconds(20), Seconds(25)); - break; - case EVENT_HEROIC_STRIKE: - DoCastSelf(SPELL_HEROIC_STRIKE); - _events.Repeat(Seconds(5), Seconds(15)); - break; - case EVENT_SHIELD_BASH: - DoCastVictim(SPELL_SHIELD_BASH); - _events.Repeat(Seconds(10), Seconds(20)); - break; - case EVENT_WINDFURY: - DoCastVictim(SPELL_WINDFURY); - _events.Repeat(Seconds(6), Seconds(8)); - break; - default: - break; - } + case EVENT_DEBILITATING_STRIKE: + DoCastVictim(SPELL_DEBILITATING_STRIKE); + _events.Repeat(Seconds(20), Seconds(25)); + break; + case EVENT_HEROIC_STRIKE: + DoCastSelf(SPELL_HEROIC_STRIKE); + _events.Repeat(Seconds(5), Seconds(15)); + break; + case EVENT_SHIELD_BASH: + DoCastVictim(SPELL_SHIELD_BASH); + _events.Repeat(Seconds(10), Seconds(20)); + break; + case EVENT_WINDFURY: + DoCastVictim(SPELL_WINDFURY); + _events.Repeat(Seconds(6), Seconds(8)); + break; + default: + break; } - - DoMeleeAttackIfReady(); } - private: - InstanceScript* _instance; - EventMap _events; - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetBlackTempleAI<npc_ashtongue_defenderAI>(creature); + DoMeleeAttackIfReady(); } + +private: + InstanceScript* _instance; + EventMap _events; }; -class npc_ashtongue_rogue : public CreatureScript +struct npc_ashtongue_rogue : public ScriptedAI { -public: - npc_ashtongue_rogue() : CreatureScript("npc_ashtongue_rogue") { } - - struct npc_ashtongue_rogueAI : public ScriptedAI + npc_ashtongue_rogue(Creature* creature) : ScriptedAI(creature) { - npc_ashtongue_rogueAI(Creature* creature) : ScriptedAI(creature) - { - _instance = creature->GetInstanceScript(); - } + _instance = creature->GetInstanceScript(); + } - void Reset() override - { - if (Creature* akama = _instance->GetCreature(DATA_AKAMA_SHADE)) - AttackStart(akama); - } + void Reset() override + { + if (Creature* akama = _instance->GetCreature(DATA_AKAMA_SHADE)) + AttackStart(akama); + } - void JustDied(Unit* /*killer*/) override - { - me->DespawnOrUnsummon(Seconds(5)); - } + void JustDied(Unit* /*killer*/) override + { + me->DespawnOrUnsummon(Seconds(5)); + } - void EnterCombat(Unit* /*who*/) override - { - _events.ScheduleEvent(EVENT_DEBILITATING_POISON, Milliseconds(500), Seconds(2)); - _events.ScheduleEvent(EVENT_EVISCERATE, Seconds(2), Seconds(5)); - } + void EnterCombat(Unit* /*who*/) override + { + _events.ScheduleEvent(EVENT_DEBILITATING_POISON, Milliseconds(500), Seconds(2)); + _events.ScheduleEvent(EVENT_EVISCERATE, Seconds(2), Seconds(5)); + } - void EnterEvadeMode(EvadeReason /*why*/) override { } + void EnterEvadeMode(EvadeReason /*why*/) override { } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - _events.Update(diff); + _events.Update(diff); - while (uint32 eventId = _events.ExecuteEvent()) + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) { - switch (eventId) - { - case EVENT_DEBILITATING_POISON: - DoCastVictim(SPELL_DEBILITATING_POISON); - _events.Repeat(Seconds(15), Seconds(20)); - break; - case EVENT_EVISCERATE: - DoCastVictim(SPELL_EVISCERATE); - _events.Repeat(Seconds(12), Seconds(20)); - break; - default: - break; - } + case EVENT_DEBILITATING_POISON: + DoCastVictim(SPELL_DEBILITATING_POISON); + _events.Repeat(Seconds(15), Seconds(20)); + break; + case EVENT_EVISCERATE: + DoCastVictim(SPELL_EVISCERATE); + _events.Repeat(Seconds(12), Seconds(20)); + break; + default: + break; } - - DoMeleeAttackIfReady(); } - private: - InstanceScript* _instance; - EventMap _events; - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetBlackTempleAI<npc_ashtongue_rogueAI>(creature); + DoMeleeAttackIfReady(); } + +private: + InstanceScript* _instance; + EventMap _events; }; -class npc_ashtongue_elementalist : public CreatureScript +struct npc_ashtongue_elementalist : public ScriptedAI { -public: - npc_ashtongue_elementalist() : CreatureScript("npc_ashtongue_elementalist") { } - - struct npc_ashtongue_elementalistAI : public ScriptedAI + npc_ashtongue_elementalist(Creature* creature) : ScriptedAI(creature) { - npc_ashtongue_elementalistAI(Creature* creature) : ScriptedAI(creature) - { - _instance = creature->GetInstanceScript(); - } + _instance = creature->GetInstanceScript(); + } - void Reset() override - { - if (Creature* akama = _instance->GetCreature(DATA_AKAMA_SHADE)) - AttackStart(akama); - } + void Reset() override + { + if (Creature* akama = _instance->GetCreature(DATA_AKAMA_SHADE)) + AttackStart(akama); + } - void JustDied(Unit* /*killer*/) override - { - me->DespawnOrUnsummon(Seconds(5)); - } + void JustDied(Unit* /*killer*/) override + { + me->DespawnOrUnsummon(Seconds(5)); + } - void EnterCombat(Unit* /*who*/) override - { - _events.ScheduleEvent(EVENT_RAIN_OF_FIRE, Seconds(18)); - _events.ScheduleEvent(EVENT_LIGHTNING_BOLT, Seconds(6)); - } + void EnterCombat(Unit* /*who*/) override + { + _events.ScheduleEvent(EVENT_RAIN_OF_FIRE, Seconds(18)); + _events.ScheduleEvent(EVENT_LIGHTNING_BOLT, Seconds(6)); + } - void EnterEvadeMode(EvadeReason /*why*/) override { } + void EnterEvadeMode(EvadeReason /*why*/) override { } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - _events.Update(diff); + _events.Update(diff); - while (uint32 eventId = _events.ExecuteEvent()) + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) { - switch (eventId) - { - case EVENT_RAIN_OF_FIRE: - DoCastVictim(SPELL_RAIN_OF_FIRE); - _events.Repeat(Seconds(15), Seconds(20)); - break; - case EVENT_LIGHTNING_BOLT: - DoCastVictim(SPELL_LIGHTNING_BOLT); - _events.Repeat(Seconds(8), Seconds(15)); - break; - default: - break; - } + case EVENT_RAIN_OF_FIRE: + DoCastVictim(SPELL_RAIN_OF_FIRE); + _events.Repeat(Seconds(15), Seconds(20)); + break; + case EVENT_LIGHTNING_BOLT: + DoCastVictim(SPELL_LIGHTNING_BOLT); + _events.Repeat(Seconds(8), Seconds(15)); + break; + default: + break; } - - DoMeleeAttackIfReady(); } - private: - InstanceScript* _instance; - EventMap _events; - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetBlackTempleAI<npc_ashtongue_elementalistAI>(creature); + DoMeleeAttackIfReady(); } + +private: + InstanceScript* _instance; + EventMap _events; }; -class npc_ashtongue_spiritbinder : public CreatureScript +struct npc_ashtongue_spiritbinder : public ScriptedAI { -public: - npc_ashtongue_spiritbinder() : CreatureScript("npc_ashtongue_spiritbinder") { } - - struct npc_ashtongue_spiritbinderAI : public ScriptedAI + npc_ashtongue_spiritbinder(Creature* creature) : ScriptedAI(creature) { - npc_ashtongue_spiritbinderAI(Creature* creature) : ScriptedAI(creature) - { - Initialize(); - _instance = creature->GetInstanceScript(); - } - - void Initialize() - { - _spiritMend = false; - _chainHeal = false; - } - - void Reset() override - { - Initialize(); - - if (Creature* akama = _instance->GetCreature(DATA_AKAMA_SHADE)) - AttackStart(akama); - } - - void JustDied(Unit* /*killer*/) override - { - me->DespawnOrUnsummon(Seconds(5)); - } - - void EnterCombat(Unit* /*who*/) override - { - _events.ScheduleEvent(EVENT_SPIRIT_HEAL, Seconds(5), Seconds(6)); - } + Initialize(); + _instance = creature->GetInstanceScript(); + } - void DamageTaken(Unit* /*who*/, uint32& /*damage*/) override - { - if (!_spiritMend) - if (HealthBelowPct(30)) - { - DoCastSelf(SPELL_SPIRIT_MEND); - _spiritMend = true; - _events.ScheduleEvent(EVENT_SPIRIT_MEND_RESET, Seconds(10),Seconds(15)); - } + void Initialize() + { + _spiritMend = false; + _chainHeal = false; + } - if (!_chainHeal) - if (HealthBelowPct(50)) - { - DoCastSelf(SPELL_CHAIN_HEAL); - _chainHeal = true; - _events.ScheduleEvent(EVENT_CHAIN_HEAL_RESET, Seconds(10), Seconds(15)); - } + void Reset() override + { + Initialize(); - } + if (Creature* akama = _instance->GetCreature(DATA_AKAMA_SHADE)) + AttackStart(akama); + } - void EnterEvadeMode(EvadeReason /*why*/) override { } + void JustDied(Unit* /*killer*/) override + { + me->DespawnOrUnsummon(Seconds(5)); + } - void UpdateAI(uint32 diff) override - { - _events.Update(diff); + void EnterCombat(Unit* /*who*/) override + { + _events.ScheduleEvent(EVENT_SPIRIT_HEAL, Seconds(5), Seconds(6)); + } - while (uint32 eventId = _events.ExecuteEvent()) + void DamageTaken(Unit* /*who*/, uint32& /*damage*/) override + { + if (!_spiritMend) + if (HealthBelowPct(30)) { - switch (eventId) - { - case EVENT_SPIRIT_HEAL: - DoCastSelf(SPELL_SPIRITBINDER_SPIRIT_HEAL); - _events.Repeat(Seconds(13), Seconds(16)); - break; - case EVENT_SPIRIT_MEND_RESET: - _spiritMend = false; - break; - case EVENT_CHAIN_HEAL_RESET: - _chainHeal = false; - break; - default: - break; - } + DoCastSelf(SPELL_SPIRIT_MEND); + _spiritMend = true; + _events.ScheduleEvent(EVENT_SPIRIT_MEND_RESET, Seconds(10), Seconds(15)); } - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - } - - private: - InstanceScript* _instance; - EventMap _events; - bool _spiritMend; - bool _chainHeal; - }; + if (!_chainHeal) + if (HealthBelowPct(50)) + { + DoCastSelf(SPELL_CHAIN_HEAL); + _chainHeal = true; + _events.ScheduleEvent(EVENT_CHAIN_HEAL_RESET, Seconds(10), Seconds(15)); + } - CreatureAI* GetAI(Creature* creature) const override - { - return GetBlackTempleAI<npc_ashtongue_spiritbinderAI>(creature); } -}; -class npc_ashtongue_broken : public CreatureScript -{ -public: - npc_ashtongue_broken() : CreatureScript("npc_ashtongue_broken") { } + void EnterEvadeMode(EvadeReason /*why*/) override { } - struct npc_ashtongue_brokenAI : public ScriptedAI + void UpdateAI(uint32 diff) override { - npc_ashtongue_brokenAI(Creature* creature) : ScriptedAI(creature) - { - _instance = me->GetInstanceScript(); - } - - void MovementInform(uint32 motionType, uint32 /*pointId*/) override - { - if (motionType != POINT_MOTION_TYPE) - return; - - if (Creature* akama = _instance->GetCreature(DATA_AKAMA_SHADE)) - me->SetFacingToObject(akama); - } + _events.Update(diff); - void DoAction(int32 actionId) override + while (uint32 eventId = _events.ExecuteEvent()) { - switch (actionId) + switch (eventId) { - case ACTION_BROKEN_SPECIAL: - Talk(SAY_BROKEN_SPECIAL); + case EVENT_SPIRIT_HEAL: + DoCastSelf(SPELL_SPIRITBINDER_SPIRIT_HEAL); + _events.Repeat(Seconds(13), Seconds(16)); break; - case ACTION_BROKEN_HAIL: - me->SetFaction(FACTION_ASHTONGUE_DEATHSWORN); - Talk(SAY_BROKEN_HAIL); + case EVENT_SPIRIT_MEND_RESET: + _spiritMend = false; break; - case ACTION_BROKEN_EMOTE: - me->SetByteValue(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_STAND_STATE, UNIT_STAND_STATE_KNEEL); + case EVENT_CHAIN_HEAL_RESET: + _chainHeal = false; break; default: break; } } - private: - InstanceScript* _instance; - }; - + if (!UpdateVictim()) + return; - CreatureAI* GetAI(Creature* creature) const override - { - return GetBlackTempleAI<npc_ashtongue_brokenAI>(creature); + DoMeleeAttackIfReady(); } + +private: + InstanceScript* _instance; + EventMap _events; + bool _spiritMend; + bool _chainHeal; }; -// 40401 - Shade Soul Channel (serverside spell) -class spell_shade_soul_channel_serverside : public SpellScriptLoader +struct npc_ashtongue_broken : public ScriptedAI { -public: - spell_shade_soul_channel_serverside() : SpellScriptLoader("spell_shade_soul_channel_serverside") { } + npc_ashtongue_broken(Creature* creature) : ScriptedAI(creature) + { + _instance = me->GetInstanceScript(); + } - class spell_shade_soul_channel_serverside_AuraScript : public AuraScript + void MovementInform(uint32 motionType, uint32 /*pointId*/) override { - PrepareAuraScript(spell_shade_soul_channel_serverside_AuraScript); + if (motionType != POINT_MOTION_TYPE) + return; - bool Validate(SpellInfo const* /*spell*/) override - { - return ValidateSpellInfo({ SPELL_SHADE_SOUL_CHANNEL_2 }); - } + if (Creature* akama = _instance->GetCreature(DATA_AKAMA_SHADE)) + me->SetFacingToObject(akama); + } - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + void DoAction(int32 actionId) override + { + switch (actionId) { - GetTarget()->RemoveAuraFromStack(SPELL_SHADE_SOUL_CHANNEL_2); + case ACTION_BROKEN_SPECIAL: + Talk(SAY_BROKEN_SPECIAL); + break; + case ACTION_BROKEN_HAIL: + me->SetFaction(FACTION_ASHTONGUE_DEATHSWORN); + Talk(SAY_BROKEN_HAIL); + break; + case ACTION_BROKEN_EMOTE: + me->SetByteValue(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_STAND_STATE, UNIT_STAND_STATE_KNEEL); + break; + default: + break; } + } - void Register() override - { - AfterEffectRemove += AuraEffectRemoveFn(spell_shade_soul_channel_serverside_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - } - }; +private: + InstanceScript* _instance; +}; + +// 40401 - Shade Soul Channel (serverside spell) +class spell_shade_soul_channel_serverside : public AuraScript +{ + PrepareAuraScript(spell_shade_soul_channel_serverside); - AuraScript* GetAuraScript() const override + bool Validate(SpellInfo const* /*spell*/) override { - return new spell_shade_soul_channel_serverside_AuraScript(); + return ValidateSpellInfo({ SPELL_SHADE_SOUL_CHANNEL_2 }); + } + + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->RemoveAuraFromStack(SPELL_SHADE_SOUL_CHANNEL_2); + } + + void Register() override + { + AfterEffectRemove += AuraEffectRemoveFn(spell_shade_soul_channel_serverside::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); } }; // 40520 - Shade Soul Channel -class spell_shade_soul_channel : public SpellScriptLoader +class spell_shade_soul_channel : public AuraScript { -public: - spell_shade_soul_channel() : SpellScriptLoader("spell_shade_soul_channel") { } + PrepareAuraScript(spell_shade_soul_channel); - class spell_shade_soul_channel_AuraScript : public AuraScript + void OnApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) { - PrepareAuraScript(spell_shade_soul_channel_AuraScript); - - void OnApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) - { - int32 const maxSlowEff = -99; - if (aurEff->GetAmount() < maxSlowEff) - if (AuraEffect* slowEff = GetEffect(EFFECT_0)) - slowEff->ChangeAmount(maxSlowEff); - } - - void Register() override - { - AfterEffectApply += AuraEffectApplyFn(spell_shade_soul_channel_AuraScript::OnApply, EFFECT_0, SPELL_AURA_MOD_DECREASE_SPEED, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); - } - }; + int32 const maxSlowEff = -99; + if (aurEff->GetAmount() < maxSlowEff) + if (AuraEffect* slowEff = GetEffect(EFFECT_0)) + slowEff->ChangeAmount(maxSlowEff); + } - AuraScript* GetAuraScript() const override + void Register() override { - return new spell_shade_soul_channel_AuraScript(); + AfterEffectApply += AuraEffectApplyFn(spell_shade_soul_channel::OnApply, EFFECT_0, SPELL_AURA_MOD_DECREASE_SPEED, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); } }; void AddSC_boss_shade_of_akama() { - new boss_shade_of_akama(); - new npc_akama_shade(); - new npc_ashtongue_channeler(); - new npc_creature_generator_akama(); - new npc_ashtongue_sorcerer(); - new npc_ashtongue_defender(); - new npc_ashtongue_rogue(); - new npc_ashtongue_elementalist(); - new npc_ashtongue_spiritbinder(); - new npc_ashtongue_broken(); - new spell_shade_soul_channel_serverside(); - new spell_shade_soul_channel(); + RegisterBlackTempleCreatureAI(boss_shade_of_akama); + RegisterBlackTempleCreatureAI(npc_akama_shade); + RegisterBlackTempleCreatureAI(npc_ashtongue_channeler); + RegisterBlackTempleCreatureAI(npc_creature_generator_akama); + RegisterBlackTempleCreatureAI(npc_ashtongue_sorcerer); + RegisterBlackTempleCreatureAI(npc_ashtongue_defender); + RegisterBlackTempleCreatureAI(npc_ashtongue_rogue); + RegisterBlackTempleCreatureAI(npc_ashtongue_elementalist); + RegisterBlackTempleCreatureAI(npc_ashtongue_spiritbinder); + RegisterBlackTempleCreatureAI(npc_ashtongue_broken); + RegisterAuraScript(spell_shade_soul_channel_serverside); + RegisterAuraScript(spell_shade_soul_channel); } diff --git a/src/server/scripts/Outland/BlackTemple/boss_supremus.cpp b/src/server/scripts/Outland/BlackTemple/boss_supremus.cpp index c84a3504f61..ca7bc790aa1 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_supremus.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_supremus.cpp @@ -63,200 +63,165 @@ enum Actions { ACTION_DISABLE_VULCANO = 1 }; - -class boss_supremus : public CreatureScript +struct boss_supremus : public BossAI { -public: - boss_supremus() : CreatureScript("boss_supremus") { } + boss_supremus(Creature* creature) : BossAI(creature, DATA_SUPREMUS) { } - struct boss_supremusAI : public BossAI + void Reset() override { - boss_supremusAI(Creature* creature) : BossAI(creature, DATA_SUPREMUS) { } + _Reset(); + events.SetPhase(PHASE_INITIAL); + me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, false); + me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, false); + } - void Reset() override + void EnterEvadeMode(EvadeReason /*why*/) override + { + summons.DespawnAll(); + _DespawnAtEvade(); + } + + void EnterCombat(Unit* /*who*/) override + { + _EnterCombat(); + ChangePhase(); + events.ScheduleEvent(EVENT_BERSERK, Minutes(15)); + events.ScheduleEvent(EVENT_FLAME, Seconds(20)); + } + + void ChangePhase() + { + if (events.IsInPhase(PHASE_INITIAL) || events.IsInPhase(PHASE_CHASE)) { - _Reset(); - events.SetPhase(PHASE_INITIAL); + events.SetPhase(PHASE_STRIKE); + DummyEntryCheckPredicate pred; + summons.DoAction(ACTION_DISABLE_VULCANO, pred); + events.ScheduleEvent(EVENT_HATEFUL_STRIKE, Seconds(2), 0, PHASE_STRIKE); + me->RemoveAurasDueToSpell(SPELL_SNARE_SELF); me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, false); me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, false); } - - void EnterEvadeMode(EvadeReason /*why*/) override - { - summons.DespawnAll(); - _DespawnAtEvade(); - } - - void EnterCombat(Unit* /*who*/) override + else { - _EnterCombat(); - ChangePhase(); - events.ScheduleEvent(EVENT_BERSERK, Minutes(15)); - events.ScheduleEvent(EVENT_FLAME, Seconds(20)); + events.SetPhase(PHASE_CHASE); + events.ScheduleEvent(EVENT_VOLCANO, Seconds(5), 0, PHASE_CHASE); + events.ScheduleEvent(EVENT_SWITCH_TARGET, Seconds(10), 0, PHASE_CHASE); + me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true); + me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, true); + DoCast(SPELL_SNARE_SELF); } + ResetThreatList(); + DoZoneInCombat(); + events.ScheduleEvent(EVENT_SWITCH_PHASE, Seconds(60)); + } - void ChangePhase() - { - if (events.IsInPhase(PHASE_INITIAL) || events.IsInPhase(PHASE_CHASE)) - { - events.SetPhase(PHASE_STRIKE); - DummyEntryCheckPredicate pred; - summons.DoAction(ACTION_DISABLE_VULCANO, pred); - events.ScheduleEvent(EVENT_HATEFUL_STRIKE, Seconds(2), 0, PHASE_STRIKE); - me->RemoveAurasDueToSpell(SPELL_SNARE_SELF); - me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, false); - me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, false); - } - else - { - events.SetPhase(PHASE_CHASE); - events.ScheduleEvent(EVENT_VOLCANO, Seconds(5), 0, PHASE_CHASE); - events.ScheduleEvent(EVENT_SWITCH_TARGET, Seconds(10), 0, PHASE_CHASE); - me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true); - me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, true); - DoCast(SPELL_SNARE_SELF); - } - ResetThreatList(); - DoZoneInCombat(); - events.ScheduleEvent(EVENT_SWITCH_PHASE, Seconds(60)); - } + Unit* CalculateHatefulStrikeTarget() + { + uint32 health = 0; + Unit* target = nullptr; - Unit* CalculateHatefulStrikeTarget() + for (auto* ref : me->GetThreatManager().GetUnsortedThreatList()) { - uint32 health = 0; - Unit* target = nullptr; - - for (auto* ref : me->GetThreatManager().GetUnsortedThreatList()) + Unit* unit = ref->GetVictim(); + if (me->IsWithinMeleeRange(unit)) { - Unit* unit = ref->GetVictim(); - if (me->IsWithinMeleeRange(unit)) + if (unit->GetHealth() > health) { - if (unit->GetHealth() > health) - { - health = unit->GetHealth(); - target = unit; - } + health = unit->GetHealth(); + target = unit; } } - - return target; } - void ExecuteEvent(uint32 eventId) override - { - switch (eventId) - { - case EVENT_BERSERK: - DoCastSelf(SPELL_BERSERK, true); - break; - case EVENT_FLAME: - DoCast(SPELL_MOLTEN_PUNCH); - events.Repeat(Seconds(15), Seconds(20)); - break; - case EVENT_HATEFUL_STRIKE: - if (Unit* target = CalculateHatefulStrikeTarget()) - DoCast(target, SPELL_HATEFUL_STRIKE); - events.Repeat(Seconds(5)); - break; - case EVENT_SWITCH_TARGET: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100.0f, true)) - { - ResetThreatList(); - AddThreat(target, 1000000.0f); - DoCast(target, SPELL_CHARGE); - Talk(EMOTE_NEW_TARGET); - } - events.Repeat(Seconds(10)); - break; - case EVENT_VOLCANO: - DoCastAOE(SPELL_VOLCANIC_SUMMON, true); - Talk(EMOTE_GROUND_CRACK); - events.Repeat(Seconds(10)); - break; - case EVENT_SWITCH_PHASE: - ChangePhase(); - break; - default: - break; - } - } - - }; + return target; + } - CreatureAI* GetAI(Creature* creature) const override + void ExecuteEvent(uint32 eventId) override { - return GetBlackTempleAI<boss_supremusAI>(creature); + switch (eventId) + { + case EVENT_BERSERK: + DoCastSelf(SPELL_BERSERK, true); + break; + case EVENT_FLAME: + DoCast(SPELL_MOLTEN_PUNCH); + events.Repeat(Seconds(15), Seconds(20)); + break; + case EVENT_HATEFUL_STRIKE: + if (Unit* target = CalculateHatefulStrikeTarget()) + DoCast(target, SPELL_HATEFUL_STRIKE); + events.Repeat(Seconds(5)); + break; + case EVENT_SWITCH_TARGET: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100.0f, true)) + { + ResetThreatList(); + AddThreat(target, 1000000.0f); + DoCast(target, SPELL_CHARGE); + Talk(EMOTE_NEW_TARGET); + } + events.Repeat(Seconds(10)); + break; + case EVENT_VOLCANO: + DoCastAOE(SPELL_VOLCANIC_SUMMON, true); + Talk(EMOTE_GROUND_CRACK); + events.Repeat(Seconds(10)); + break; + case EVENT_SWITCH_PHASE: + ChangePhase(); + break; + default: + break; + } } }; -class npc_molten_flame : public CreatureScript +struct npc_molten_flame : public NullCreatureAI { -public: - npc_molten_flame() : CreatureScript("npc_molten_flame") { } + npc_molten_flame(Creature* creature) : NullCreatureAI(creature) { } - struct npc_molten_flameAI : public NullCreatureAI + void InitializeAI() override { - npc_molten_flameAI(Creature* creature) : NullCreatureAI(creature) { } - - void InitializeAI() override - { - float x, y, z; - me->GetNearPoint(me, x, y, z, 1, 100.0f, frand(0.f, 2.f * float(M_PI))); - me->GetMotionMaster()->MovePoint(0, x, y, z); - DoCastSelf(SPELL_MOLTEN_FLAME, true); - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetBlackTempleAI<npc_molten_flameAI>(creature); + float x, y, z; + me->GetNearPoint(me, x, y, z, 1, 100.0f, frand(0.f, 2.f * float(M_PI))); + me->GetMotionMaster()->MovePoint(0, x, y, z); + DoCastSelf(SPELL_MOLTEN_FLAME, true); } }; -class npc_volcano : public CreatureScript +struct npc_volcano : public NullCreatureAI { -public: - npc_volcano() : CreatureScript("npc_volcano") { } + npc_volcano(Creature* creature) : NullCreatureAI(creature) { } - struct npc_volcanoAI : public NullCreatureAI + void Reset() override { - npc_volcanoAI(Creature* creature) : NullCreatureAI(creature) { } - - void Reset() override + _scheduler.Schedule(Seconds(3), [this](TaskContext /*context*/) { - _scheduler.Schedule(Seconds(3), [this](TaskContext /*context*/) - { - DoCastSelf(SPELL_VOLCANIC_ERUPTION); - }); - } - - void DoAction(int32 action) override - { - if (action == ACTION_DISABLE_VULCANO) - { - me->RemoveAurasDueToSpell(SPELL_VOLCANIC_ERUPTION); - me->RemoveAurasDueToSpell(SPELL_VOLCANIC_GEYSER); - } - } + DoCastSelf(SPELL_VOLCANIC_ERUPTION); + }); + } - void UpdateAI(uint32 diff) override + void DoAction(int32 action) override + { + if (action == ACTION_DISABLE_VULCANO) { - _scheduler.Update(diff); + me->RemoveAurasDueToSpell(SPELL_VOLCANIC_ERUPTION); + me->RemoveAurasDueToSpell(SPELL_VOLCANIC_GEYSER); } + } - private: - TaskScheduler _scheduler; - }; - - CreatureAI* GetAI(Creature* creature) const override + void UpdateAI(uint32 diff) override { - return GetBlackTempleAI<npc_volcanoAI>(creature); + _scheduler.Update(diff); } + +private: + TaskScheduler _scheduler; }; void AddSC_boss_supremus() { - new boss_supremus(); - new npc_molten_flame(); - new npc_volcano(); + RegisterBlackTempleCreatureAI(boss_supremus); + RegisterBlackTempleCreatureAI(npc_molten_flame); + RegisterBlackTempleCreatureAI(npc_volcano); } diff --git a/src/server/scripts/Outland/BlackTemple/boss_teron_gorefiend.cpp b/src/server/scripts/Outland/BlackTemple/boss_teron_gorefiend.cpp index 67ed253f247..496212ed692 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_teron_gorefiend.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_teron_gorefiend.cpp @@ -69,14 +69,13 @@ enum Spells SPELL_SPIRIT_VOLLEY = 40314, SPELL_SPIRIT_SHIELD = 40322, SPELL_SPIRIT_LANCE = 40157 - }; enum Npcs { - NPC_DOOM_BLOSSOM = 23123, - NPC_SHADOWY_CONSTRUCT = 23111, - NPC_VENGEFUL_SPIRIT = 23109 //Npc controlled by player + NPC_DOOM_BLOSSOM = 23123, + NPC_SHADOWY_CONSTRUCT = 23111, + NPC_VENGEFUL_SPIRIT = 23109 //Npc controlled by player }; enum Events @@ -108,411 +107,348 @@ uint32 const SkeletronSpells[4] = SPELL_SUMMON_SKELETRON_4 }; -class boss_teron_gorefiend : public CreatureScript +struct boss_teron_gorefiend : public BossAI { -public: - boss_teron_gorefiend() : CreatureScript("boss_teron_gorefiend") { } + boss_teron_gorefiend(Creature* creature) : BossAI(creature, DATA_TERON_GOREFIEND) { } - struct boss_teron_gorefiendAI : public BossAI + void Reset() override { - boss_teron_gorefiendAI(Creature* creature) : BossAI(creature, DATA_TERON_GOREFIEND), _intro(false) + _Reset(); + if (instance->GetData(DATA_TERON_GOREFIEND_INTRO)) { - creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); - creature->SetReactState(REACT_PASSIVE); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); + me->SetReactState(REACT_PASSIVE); } + } - void EnterCombat(Unit* /*who*/) override - { - _EnterCombat(); - Talk(SAY_AGGRO); - events.SetPhase(PHASE_COMBAT); - events.ScheduleEvent(EVENT_ENRAGE, Minutes(10)); - events.ScheduleEvent(EVENT_INCINERATE, Seconds(12)); - events.ScheduleEvent(EVENT_SUMMON_DOOM_BLOSSOM, Seconds(8)); - events.ScheduleEvent(EVENT_SHADOW_DEATH, Seconds(8)); - events.ScheduleEvent(EVENT_CRUSHING_SHADOWS, Seconds(18)); - } + void EnterCombat(Unit* /*who*/) override + { + _EnterCombat(); + Talk(SAY_AGGRO); + events.SetPhase(PHASE_COMBAT); + events.ScheduleEvent(EVENT_ENRAGE, Minutes(10)); + events.ScheduleEvent(EVENT_INCINERATE, Seconds(12)); + events.ScheduleEvent(EVENT_SUMMON_DOOM_BLOSSOM, Seconds(8)); + events.ScheduleEvent(EVENT_SHADOW_DEATH, Seconds(8)); + events.ScheduleEvent(EVENT_CRUSHING_SHADOWS, Seconds(18)); + } - void EnterEvadeMode(EvadeReason /*why*/) override - { - DoCast(SPELL_SHADOW_OF_DEATH_REMOVE); - summons.DespawnAll(); - _DespawnAtEvade(); - } + void EnterEvadeMode(EvadeReason /*why*/) override + { + DoCast(SPELL_SHADOW_OF_DEATH_REMOVE); + summons.DespawnAll(); + _DespawnAtEvade(); + } - void DoAction(int32 action) override + void DoAction(int32 action) override + { + if (action == ACTION_START_INTRO && me->IsAlive()) { - if (action == ACTION_START_INTRO && !_intro && me->IsAlive()) - { - _intro = true; - Talk(SAY_INTRO); - events.SetPhase(PHASE_INTRO); - events.ScheduleEvent(EVENT_FINISH_INTRO, Seconds(20)); - } + instance->SetData(DATA_TERON_GOREFIEND_INTRO, 0); + Talk(SAY_INTRO); + events.SetPhase(PHASE_INTRO); + events.ScheduleEvent(EVENT_FINISH_INTRO, Seconds(20)); } + } - void KilledUnit(Unit* victim) override - { - if (victim->GetTypeId() == TYPEID_PLAYER) - Talk(SAY_SLAY); - } + void KilledUnit(Unit* victim) override + { + if (victim->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_SLAY); + } - void JustDied(Unit* /*killer*/) override - { - Talk(SAY_DEATH); - DoCast(SPELL_SHADOW_OF_DEATH_REMOVE); - _JustDied(); - } + void JustDied(Unit* /*killer*/) override + { + Talk(SAY_DEATH); + DoCast(SPELL_SHADOW_OF_DEATH_REMOVE); + _JustDied(); + } - void UpdateAI(uint32 diff) override - { - if (!events.IsInPhase(PHASE_INTRO) && !UpdateVictim()) - return; + void UpdateAI(uint32 diff) override + { + if (!events.IsInPhase(PHASE_INTRO) && !UpdateVictim()) + return; - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - events.Update(diff); + events.Update(diff); - while (uint32 eventId = events.ExecuteEvent()) + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) { - switch (eventId) - { - case EVENT_ENRAGE: - DoCast(SPELL_BERSERK); - break; - case EVENT_INCINERATE: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(target, SPELL_INCINERATE); - Talk(SAY_INCINERATE); - events.Repeat(Seconds(12), Seconds(20)); - break; - case EVENT_SUMMON_DOOM_BLOSSOM: - DoCastSelf(SPELL_SUMMON_DOOM_BLOSSOM, true); - Talk(SAY_BLOSSOM); - events.Repeat(Seconds(30), Seconds(40)); - break; - case EVENT_SHADOW_DEATH: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100.0f, true, true, -SPELL_SPIRITUAL_VENGEANCE)) - DoCast(target, SPELL_SHADOW_OF_DEATH); - events.Repeat(Seconds(30), Seconds(35)); - break; - case EVENT_CRUSHING_SHADOWS: - me->CastCustomSpell(SPELL_CRUSHING_SHADOWS, SPELLVALUE_MAX_TARGETS, 5, me); - Talk(SAY_CRUSHING); - events.Repeat(Seconds(18), Seconds(30)); - break; - case EVENT_FINISH_INTRO: - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE); - me->SetReactState(REACT_AGGRESSIVE); - break; - default: - break; - } - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + case EVENT_ENRAGE: + DoCast(SPELL_BERSERK); + break; + case EVENT_INCINERATE: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) + DoCast(target, SPELL_INCINERATE); + Talk(SAY_INCINERATE); + events.Repeat(Seconds(12), Seconds(20)); + break; + case EVENT_SUMMON_DOOM_BLOSSOM: + DoCastSelf(SPELL_SUMMON_DOOM_BLOSSOM, true); + Talk(SAY_BLOSSOM); + events.Repeat(Seconds(30), Seconds(40)); + break; + case EVENT_SHADOW_DEATH: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100.0f, true, true, -SPELL_SPIRITUAL_VENGEANCE)) + DoCast(target, SPELL_SHADOW_OF_DEATH); + events.Repeat(Seconds(30), Seconds(35)); + break; + case EVENT_CRUSHING_SHADOWS: + me->CastCustomSpell(SPELL_CRUSHING_SHADOWS, SPELLVALUE_MAX_TARGETS, 5, me); + Talk(SAY_CRUSHING); + events.Repeat(Seconds(18), Seconds(30)); + break; + case EVENT_FINISH_INTRO: + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE); + me->SetReactState(REACT_AGGRESSIVE); + break; + default: + break; } - DoMeleeAttackIfReady(); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; } - private: - bool _intro; - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetBlackTempleAI<boss_teron_gorefiendAI>(creature); + DoMeleeAttackIfReady(); } }; -class npc_doom_blossom : public CreatureScript +struct npc_doom_blossom : public NullCreatureAI { -public: - npc_doom_blossom() : CreatureScript("npc_doom_blossom") { } - struct npc_doom_blossomAI : public NullCreatureAI - { - npc_doom_blossomAI(Creature* creature) : NullCreatureAI(creature), _instance(me->GetInstanceScript()) { } + npc_doom_blossom(Creature* creature) : NullCreatureAI(creature), _instance(me->GetInstanceScript()) { } - void Reset() override - { - /* Workaround - Until SMSG_SET_PLAY_HOVER_ANIM be implemented */ - Position pos; - pos.Relocate(me); - pos.m_positionZ += 8.0f; - me->GetMotionMaster()->MoveTakeoff(0, pos); - - DoCast(SPELL_SUMMON_BLOSSOM_MOVE_TARGET); - _scheduler.CancelAll(); - me->SetInCombatWithZone(); - _scheduler.Schedule(Seconds(12), [this](TaskContext shadowBolt) - { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(target, SPELL_SHADOWBOLT); - - shadowBolt.Repeat(Seconds(2)); - }); - } - - void UpdateAI(uint32 diff) override + void Reset() override + { + /* Workaround - Until SMSG_SET_PLAY_HOVER_ANIM be implemented */ + Position pos; + pos.Relocate(me); + pos.m_positionZ += 8.0f; + me->GetMotionMaster()->MoveTakeoff(0, pos); + + DoCast(SPELL_SUMMON_BLOSSOM_MOVE_TARGET); + _scheduler.CancelAll(); + me->SetInCombatWithZone(); + _scheduler.Schedule(Seconds(12), [this](TaskContext shadowBolt) { - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - _scheduler.Update(diff); - } + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) + DoCast(target, SPELL_SHADOWBOLT); - private: - TaskScheduler _scheduler; - InstanceScript* _instance; - }; + shadowBolt.Repeat(Seconds(2)); + }); + } - CreatureAI* GetAI(Creature* creature) const override + void UpdateAI(uint32 diff) override { - return GetBlackTempleAI<npc_doom_blossomAI>(creature); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + _scheduler.Update(diff); } + +private: + TaskScheduler _scheduler; + InstanceScript* _instance; }; -class npc_shadowy_construct : public CreatureScript +struct npc_shadowy_construct : public ScriptedAI { -public: - npc_shadowy_construct() : CreatureScript("npc_shadowy_construct") { } + npc_shadowy_construct(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) + { + //This creature must be immune everything, except spells of Vengeful Spirit. + creature->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, true); + creature->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_MAGIC, true); + } - struct npc_shadowy_constructAI : public ScriptedAI + void Reset() override { - npc_shadowy_constructAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) + if (_instance->GetBossState(DATA_TERON_GOREFIEND) != IN_PROGRESS) { - //This creature must be immune everything, except spells of Vengeful Spirit. - creature->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, true); - creature->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_MAGIC, true); + me->DespawnOrUnsummon(); + return; } - void Reset() override + targetGUID.Clear(); + _scheduler.CancelAll(); + _scheduler.Schedule(Seconds(12), [this](TaskContext atrophy) { - if (_instance->GetBossState(DATA_TERON_GOREFIEND) != IN_PROGRESS) + DoCastVictim(SPELL_ATROPHY); + atrophy.Repeat(Seconds(10), Seconds(12)); + }); + _scheduler.Schedule(Milliseconds(200), [this](TaskContext checkPlayer) + { + if (Unit* target = ObjectAccessor::GetUnit(*me, targetGUID)) { - me->DespawnOrUnsummon(); - return; + if (!target->IsAlive() || !me->CanCreatureAttack(target)) + SelectNewTarget(); } + else + SelectNewTarget(); - targetGUID.Clear(); - _scheduler.CancelAll(); - _scheduler.Schedule(Seconds(12), [this](TaskContext atrophy) - { - DoCastVictim(SPELL_ATROPHY); - atrophy.Repeat(Seconds(10), Seconds(12)); - }); - _scheduler.Schedule(Milliseconds(200), [this](TaskContext checkPlayer) - { - if (Unit* target = ObjectAccessor::GetUnit(*me, targetGUID)) - { - if (!target->IsAlive() || !me->CanCreatureAttack(target)) - SelectNewTarget(); - } - else - SelectNewTarget(); + checkPlayer.Repeat(Seconds(1)); + }); - checkPlayer.Repeat(Seconds(1)); - }); + if (Creature* teron = _instance->GetCreature(DATA_TERON_GOREFIEND)) + teron->AI()->JustSummoned(me); - if (Creature* teron = _instance->GetCreature(DATA_TERON_GOREFIEND)) - teron->AI()->JustSummoned(me); + SelectNewTarget(); + } - SelectNewTarget(); - } + void UpdateAI(uint32 diff) override + { + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - void UpdateAI(uint32 diff) override + _scheduler.Update(diff, [this] { - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - _scheduler.Update(diff, [this] - { - DoMeleeAttackIfReady(); - }); - } + DoMeleeAttackIfReady(); + }); + } - void SelectNewTarget() + void SelectNewTarget() + { + if (Creature* teron = _instance->GetCreature(DATA_TERON_GOREFIEND)) { - if (Creature* teron = _instance->GetCreature(DATA_TERON_GOREFIEND)) + Unit* target = teron->AI()->SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true, true, -SPELL_SPIRITUAL_VENGEANCE); + // He should target Vengeful Spirits only if has no other player available + if (!target) + target = teron->AI()->SelectTarget(SELECT_TARGET_RANDOM, 0); + + if (target) { - Unit* target = teron->AI()->SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true, true, -SPELL_SPIRITUAL_VENGEANCE); - // He should target Vengeful Spirits only if has no other player available - if (!target) - target = teron->AI()->SelectTarget(SELECT_TARGET_RANDOM, 0); - - if (target) - { - ResetThreatList(); - AttackStart(target); - AddThreat(target, 1000000.0f); - targetGUID = target->GetGUID(); - } + ResetThreatList(); + AttackStart(target); + AddThreat(target, 1000000.0f); + targetGUID = target->GetGUID(); } } - - private: - TaskScheduler _scheduler; - InstanceScript* _instance; - ObjectGuid targetGUID; - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetBlackTempleAI<npc_shadowy_constructAI>(creature); } -}; - -class at_teron_gorefiend_entrance : public AreaTriggerScript -{ -public: - at_teron_gorefiend_entrance() : AreaTriggerScript("at_teron_gorefiend_entrance") { } - - bool OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/) override - { - if (InstanceScript* instance = player->GetInstanceScript()) - if (Creature* teron = instance->GetCreature(DATA_TERON_GOREFIEND)) - teron->AI()->DoAction(ACTION_START_INTRO); - return true; - } +private: + TaskScheduler _scheduler; + InstanceScript* _instance; + ObjectGuid targetGUID; }; // 40251 - Shadow of Death -class spell_teron_gorefiend_shadow_of_death : public SpellScriptLoader +class spell_teron_gorefiend_shadow_of_death : public AuraScript { - public: - spell_teron_gorefiend_shadow_of_death() : SpellScriptLoader("spell_teron_gorefiend_shadow_of_death") { } + PrepareAuraScript(spell_teron_gorefiend_shadow_of_death); - class spell_teron_gorefiend_shadow_of_death_AuraScript : public AuraScript + bool Validate(SpellInfo const* /*spell*/) override + { + return ValidateSpellInfo( { - PrepareAuraScript(spell_teron_gorefiend_shadow_of_death_AuraScript); - - bool Validate(SpellInfo const* /*spell*/) override - { - return ValidateSpellInfo( - { - SPELL_SUMMON_SPIRIT, - SPELL_POSSESS_SPIRIT_IMMUNE, - SPELL_SPIRITUAL_VENGEANCE, - SPELL_SUMMON_SKELETRON_1, - SPELL_SUMMON_SKELETRON_2, - SPELL_SUMMON_SKELETRON_3, - SPELL_SUMMON_SKELETRON_4 - }); - } - - void Absorb(AuraEffect* /*aurEff*/, DamageInfo& /*dmgInfo*/, uint32& /*absorbAmount*/) - { - PreventDefaultAction(); - } - - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE) - { - Unit* target = GetTarget(); - target->CastSpell(target, SPELL_SUMMON_SPIRIT, true); + SPELL_SUMMON_SPIRIT, + SPELL_POSSESS_SPIRIT_IMMUNE, + SPELL_SPIRITUAL_VENGEANCE, + SPELL_SUMMON_SKELETRON_1, + SPELL_SUMMON_SKELETRON_2, + SPELL_SUMMON_SKELETRON_3, + SPELL_SUMMON_SKELETRON_4 + }); + } - for (uint8 i = 0; i < 4; ++i) - target->CastSpell(target, SkeletronSpells[i], true); + void Absorb(AuraEffect* /*aurEff*/, DamageInfo& /*dmgInfo*/, uint32& /*absorbAmount*/) + { + PreventDefaultAction(); + } - target->CastSpell(target, SPELL_POSSESS_SPIRIT_IMMUNE, true); - target->CastSpell(target, SPELL_SPIRITUAL_VENGEANCE, true); - } - } + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE) + { + Unit* target = GetTarget(); + target->CastSpell(target, SPELL_SUMMON_SPIRIT, true); - void Register() override - { - OnEffectAbsorb += AuraEffectAbsorbFn(spell_teron_gorefiend_shadow_of_death_AuraScript::Absorb, EFFECT_0); - AfterEffectRemove += AuraEffectRemoveFn(spell_teron_gorefiend_shadow_of_death_AuraScript::OnRemove, EFFECT_1, SPELL_AURA_OVERRIDE_CLASS_SCRIPTS, AURA_EFFECT_HANDLE_REAL); - } - }; + for (uint8 i = 0; i < 4; ++i) + target->CastSpell(target, SkeletronSpells[i], true); - AuraScript* GetAuraScript() const override - { - return new spell_teron_gorefiend_shadow_of_death_AuraScript(); + target->CastSpell(target, SPELL_POSSESS_SPIRIT_IMMUNE, true); + target->CastSpell(target, SPELL_SPIRITUAL_VENGEANCE, true); } + } + + void Register() override + { + OnEffectAbsorb += AuraEffectAbsorbFn(spell_teron_gorefiend_shadow_of_death::Absorb, EFFECT_0); + AfterEffectRemove += AuraEffectRemoveFn(spell_teron_gorefiend_shadow_of_death::OnRemove, EFFECT_1, SPELL_AURA_OVERRIDE_CLASS_SCRIPTS, AURA_EFFECT_HANDLE_REAL); + } }; // 40268 - Spiritual Vengeance -class spell_teron_gorefiend_spiritual_vengeance : public SpellScriptLoader +class spell_teron_gorefiend_spiritual_vengeance : public AuraScript { - public: - spell_teron_gorefiend_spiritual_vengeance() : SpellScriptLoader("spell_teron_gorefiend_spiritual_vengeance") { } + PrepareAuraScript(spell_teron_gorefiend_spiritual_vengeance); - class spell_teron_gorefiend_spiritual_vengeance_AuraScript : public AuraScript - { - PrepareAuraScript(spell_teron_gorefiend_spiritual_vengeance_AuraScript); - - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - GetTarget()->KillSelf(); - } - - void Register() override - { - AfterEffectRemove += AuraEffectRemoveFn(spell_teron_gorefiend_spiritual_vengeance_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_MOD_POSSESS, AURA_EFFECT_HANDLE_REAL); - AfterEffectRemove += AuraEffectRemoveFn(spell_teron_gorefiend_spiritual_vengeance_AuraScript::OnRemove, EFFECT_2, SPELL_AURA_MOD_PACIFY_SILENCE, AURA_EFFECT_HANDLE_REAL); - } - }; + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->KillSelf(); + } - AuraScript* GetAuraScript() const override - { - return new spell_teron_gorefiend_spiritual_vengeance_AuraScript(); - } + void Register() override + { + AfterEffectRemove += AuraEffectRemoveFn(spell_teron_gorefiend_spiritual_vengeance::OnRemove, EFFECT_0, SPELL_AURA_MOD_POSSESS, AURA_EFFECT_HANDLE_REAL); + AfterEffectRemove += AuraEffectRemoveFn(spell_teron_gorefiend_spiritual_vengeance::OnRemove, EFFECT_2, SPELL_AURA_MOD_PACIFY_SILENCE, AURA_EFFECT_HANDLE_REAL); + } }; // 41999 - Shadow of Death Remove -class spell_teron_gorefiend_shadow_of_death_remove : public SpellScriptLoader +class spell_teron_gorefiend_shadow_of_death_remove : public SpellScript { - public: - spell_teron_gorefiend_shadow_of_death_remove() : SpellScriptLoader("spell_teron_gorefiend_shadow_of_death_remove") { } + PrepareSpellScript(spell_teron_gorefiend_shadow_of_death_remove); - class spell_teron_gorefiend_shadow_of_death_remove_SpellScript : public SpellScript + bool Validate(SpellInfo const* /*spell*/) override + { + return ValidateSpellInfo( { - PrepareSpellScript(spell_teron_gorefiend_shadow_of_death_remove_SpellScript); + SPELL_SHADOW_OF_DEATH, + SPELL_POSSESS_SPIRIT_IMMUNE, + SPELL_SPIRITUAL_VENGEANCE + }); + } - bool Validate(SpellInfo const* /*spell*/) override - { - return ValidateSpellInfo( - { - SPELL_SHADOW_OF_DEATH, - SPELL_POSSESS_SPIRIT_IMMUNE, - SPELL_SPIRITUAL_VENGEANCE - }); - } + void RemoveAuras() + { + Unit* target = GetHitUnit(); - void RemoveAuras() - { - Unit* target = GetHitUnit(); + target->RemoveAurasDueToSpell(SPELL_POSSESS_SPIRIT_IMMUNE); + target->RemoveAurasDueToSpell(SPELL_SPIRITUAL_VENGEANCE); + target->RemoveAurasDueToSpell(SPELL_SHADOW_OF_DEATH); + } - target->RemoveAurasDueToSpell(SPELL_POSSESS_SPIRIT_IMMUNE); - target->RemoveAurasDueToSpell(SPELL_SPIRITUAL_VENGEANCE); - target->RemoveAurasDueToSpell(SPELL_SHADOW_OF_DEATH); - } + void Register() override + { + OnHit += SpellHitFn(spell_teron_gorefiend_shadow_of_death_remove::RemoveAuras); + } +}; - void Register() override - { - OnHit += SpellHitFn(spell_teron_gorefiend_shadow_of_death_remove_SpellScript::RemoveAuras); - } +class at_teron_gorefiend_entrance : public OnlyOnceAreaTriggerScript +{ +public: + at_teron_gorefiend_entrance() : OnlyOnceAreaTriggerScript("at_teron_gorefiend_entrance") { } - }; + bool _OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/) override + { + if (InstanceScript* instance = player->GetInstanceScript()) + if (Creature* teron = instance->GetCreature(DATA_TERON_GOREFIEND)) + teron->AI()->DoAction(ACTION_START_INTRO); - SpellScript* GetSpellScript() const override - { - return new spell_teron_gorefiend_shadow_of_death_remove_SpellScript(); - } + return true; + } }; void AddSC_boss_teron_gorefiend() { - new boss_teron_gorefiend(); - new npc_doom_blossom(); - new npc_shadowy_construct(); + RegisterBlackTempleCreatureAI(boss_teron_gorefiend); + RegisterBlackTempleCreatureAI(npc_doom_blossom); + RegisterBlackTempleCreatureAI(npc_shadowy_construct); + RegisterAuraScript(spell_teron_gorefiend_shadow_of_death); + RegisterAuraScript(spell_teron_gorefiend_spiritual_vengeance); + RegisterSpellScript(spell_teron_gorefiend_shadow_of_death_remove); new at_teron_gorefiend_entrance(); - new spell_teron_gorefiend_shadow_of_death(); - new spell_teron_gorefiend_spiritual_vengeance(); - new spell_teron_gorefiend_shadow_of_death_remove(); } diff --git a/src/server/scripts/Outland/BlackTemple/boss_warlord_najentus.cpp b/src/server/scripts/Outland/BlackTemple/boss_warlord_najentus.cpp index b49ad6e3f20..4a35acc20db 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_warlord_najentus.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_warlord_najentus.cpp @@ -28,220 +28,207 @@ enum Texts { - SAY_AGGRO = 0, - SAY_NEEDLE = 1, - SAY_SLAY = 2, - SAY_SPECIAL = 3, - SAY_ENRAGE = 4, - SAY_DEATH = 5 + SAY_AGGRO = 0, + SAY_NEEDLE = 1, + SAY_SLAY = 2, + SAY_SPECIAL = 3, + SAY_ENRAGE = 4, + SAY_DEATH = 5 }; enum Spells { - SPELL_NEEDLE_SPINE_TARGETING = 39992, - SPELL_NEEDLE_SPINE = 39835, - SPELL_TIDAL_BURST = 39878, - SPELL_TIDAL_SHIELD = 39872, - SPELL_IMPALING_SPINE = 39837, - SPELL_CREATE_NAJENTUS_SPINE = 39956, - SPELL_HURL_SPINE = 39948, - SPELL_BERSERK = 26662 - + SPELL_NEEDLE_SPINE_TARGETING = 39992, + SPELL_NEEDLE_SPINE = 39835, + SPELL_TIDAL_BURST = 39878, + SPELL_TIDAL_SHIELD = 39872, + SPELL_IMPALING_SPINE = 39837, + SPELL_CREATE_NAJENTUS_SPINE = 39956, + SPELL_HURL_SPINE = 39948, + SPELL_BERSERK = 26662 }; enum Events { - EVENT_BERSERK = 1, - EVENT_YELL = 2, - EVENT_NEEDLE = 3, - EVENT_SPINE = 4, - EVENT_SHIELD = 5 + EVENT_BERSERK = 1, + EVENT_YELL = 2, + EVENT_NEEDLE = 3, + EVENT_SPINE = 4, + EVENT_SHIELD = 5 }; -class boss_najentus : public CreatureScript +enum Misc { -public: - boss_najentus() : CreatureScript("boss_najentus") { } - - struct boss_najentusAI : public BossAI - { - boss_najentusAI(Creature* creature) : BossAI(creature, DATA_HIGH_WARLORD_NAJENTUS) { } - - void Reset() override - { - _Reset(); - SpineTargetGUID.Clear(); - } - - void EnterEvadeMode(EvadeReason /*why*/) override - { - _DespawnAtEvade(); - } + DATA_REMOVE_IMPALING_SPINE = 1, + ACTION_RESET_IMPALING_TARGET = 2 +}; - void KilledUnit(Unit* victim) override - { - if (victim->GetTypeId() == TYPEID_PLAYER) - Talk(SAY_SLAY); - } +struct boss_najentus : public BossAI +{ + boss_najentus(Creature* creature) : BossAI(creature, DATA_HIGH_WARLORD_NAJENTUS) { } - void JustDied(Unit* /*killer*/) override - { - _JustDied(); - Talk(SAY_DEATH); - } + void Reset() override + { + _Reset(); + _spineTargetGUID.Clear(); + } - void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override - { - if (spell->Id == SPELL_HURL_SPINE && me->HasAura(SPELL_TIDAL_SHIELD)) - { - me->RemoveAurasDueToSpell(SPELL_TIDAL_SHIELD); - DoCastSelf(SPELL_TIDAL_BURST, true); - events.RescheduleEvent(EVENT_SPINE, Seconds(2)); - } - } + void EnterEvadeMode(EvadeReason /*why*/) override + { + _EnterEvadeMode(); + _DespawnAtEvade(); + } - void EnterCombat(Unit* /*who*/) override - { - _EnterCombat(); - Talk(SAY_AGGRO); - events.ScheduleEvent(EVENT_NEEDLE, Seconds(2)); - events.ScheduleEvent(EVENT_SHIELD, Seconds(60)); - events.ScheduleEvent(EVENT_SPINE, Seconds(30)); - events.ScheduleEvent(EVENT_BERSERK, Seconds(480)); - events.ScheduleEvent(EVENT_YELL, Seconds(45), Seconds(100)); - } + void KilledUnit(Unit* victim) override + { + if (victim->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_SLAY); + } - bool RemoveImpalingSpine() - { - if (!SpineTargetGUID) - return false; - - Unit* target = ObjectAccessor::GetUnit(*me, SpineTargetGUID); - if (target && target->HasAura(SPELL_IMPALING_SPINE)) - target->RemoveAurasDueToSpell(SPELL_IMPALING_SPINE); - SpineTargetGUID.Clear(); - return true; - } + void JustDied(Unit* /*killer*/) override + { + _JustDied(); + Talk(SAY_DEATH); + } - void ExecuteEvent(uint32 eventId) override + void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override + { + if (spell->Id == SPELL_HURL_SPINE && me->HasAura(SPELL_TIDAL_SHIELD)) { - switch (eventId) - { - case EVENT_SHIELD: - DoCastSelf(SPELL_TIDAL_SHIELD, true); - events.RescheduleEvent(EVENT_SPINE, Seconds(50)); - events.Repeat(Seconds(55), Seconds(60)); - break; - case EVENT_BERSERK: - Talk(SAY_ENRAGE); - DoCastSelf(SPELL_BERSERK, true); - break; - case EVENT_SPINE: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 200.0f, true)) - { - DoCast(target, SPELL_IMPALING_SPINE, true); - SpineTargetGUID = target->GetGUID(); - //must let target summon, otherwise you cannot click the spine - target->SummonGameObject(GO_NAJENTUS_SPINE, *target, QuaternionData(), 30); - Talk(SAY_NEEDLE); - } - events.Repeat(Seconds(20), Seconds(25)); - break; - case EVENT_NEEDLE: - DoCastSelf(SPELL_NEEDLE_SPINE_TARGETING, true); - events.Repeat(Seconds(2)); - break; - case EVENT_YELL: - Talk(SAY_SPECIAL); - events.Repeat(Seconds(25), Seconds(100)); - break; - default: - break; - } + me->RemoveAurasDueToSpell(SPELL_TIDAL_SHIELD); + DoCastSelf(SPELL_TIDAL_BURST, true); + events.RescheduleEvent(EVENT_SPINE, Seconds(2)); } + } - private: - ObjectGuid SpineTargetGUID; - }; + void EnterCombat(Unit* /*who*/) override + { + _EnterCombat(); + Talk(SAY_AGGRO); + events.ScheduleEvent(EVENT_NEEDLE, Seconds(2)); + events.ScheduleEvent(EVENT_SHIELD, Seconds(60)); + events.ScheduleEvent(EVENT_SPINE, Seconds(30)); + events.ScheduleEvent(EVENT_BERSERK, Seconds(480)); + events.ScheduleEvent(EVENT_YELL, Seconds(45), Seconds(100)); + } - CreatureAI* GetAI(Creature* creature) const override + uint32 GetData(uint32 data) const override { - return GetBlackTempleAI<boss_najentusAI>(creature); + if (data == DATA_REMOVE_IMPALING_SPINE) + return RemoveImpalingSpine() ? 1 : 0; + return 0; } -}; -class go_najentus_spine : public GameObjectScript -{ -public: - go_najentus_spine() : GameObjectScript("go_najentus_spine") { } + void DoAction(int32 actionId) override + { + if (actionId == ACTION_RESET_IMPALING_TARGET) + _spineTargetGUID.Clear(); + } - struct go_najentus_spineAI : public GameObjectAI + bool RemoveImpalingSpine() const { - go_najentus_spineAI(GameObject* go) : GameObjectAI(go), instance(go->GetInstanceScript()) { } + if (!_spineTargetGUID) + return false; - InstanceScript* instance; + Unit* target = ObjectAccessor::GetUnit(*me, _spineTargetGUID); + if (target && target->HasAura(SPELL_IMPALING_SPINE)) + target->RemoveAurasDueToSpell(SPELL_IMPALING_SPINE); + return true; + } - bool GossipHello(Player* player) override + void ExecuteEvent(uint32 eventId) override + { + switch (eventId) { - if (Creature* najentus = instance->GetCreature(DATA_HIGH_WARLORD_NAJENTUS)) - { - if (ENSURE_AI(boss_najentus::boss_najentusAI, najentus->AI())->RemoveImpalingSpine()) + case EVENT_SHIELD: + DoCastSelf(SPELL_TIDAL_SHIELD, true); + events.RescheduleEvent(EVENT_SPINE, Seconds(50)); + events.Repeat(Seconds(55), Seconds(60)); + break; + case EVENT_BERSERK: + Talk(SAY_ENRAGE); + DoCastSelf(SPELL_BERSERK, true); + break; + case EVENT_SPINE: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 200.0f, true)) { - me->CastSpell(player, SPELL_CREATE_NAJENTUS_SPINE, true); - me->Delete(); + DoCast(target, SPELL_IMPALING_SPINE, true); + _spineTargetGUID = target->GetGUID(); + //must let target summon, otherwise you cannot click the spine + target->SummonGameObject(GO_NAJENTUS_SPINE, *target, QuaternionData(), 30); + Talk(SAY_NEEDLE); } - } - return true; + events.Repeat(Seconds(20), Seconds(25)); + break; + case EVENT_NEEDLE: + DoCastSelf(SPELL_NEEDLE_SPINE_TARGETING, true); + events.Repeat(Seconds(2)); + break; + case EVENT_YELL: + Talk(SAY_SPECIAL); + events.Repeat(Seconds(25), Seconds(100)); + break; + default: + break; } - }; - - GameObjectAI* GetAI(GameObject* go) const override - { - return GetBlackTempleAI<go_najentus_spineAI>(go); } + +private: + ObjectGuid _spineTargetGUID; }; -// 39992 - Needle Spine Targeting -class spell_najentus_needle_spine : public SpellScriptLoader +struct go_najentus_spine : public GameObjectAI { - public: - spell_najentus_needle_spine() : SpellScriptLoader("spell_najentus_needle_spine") { } + go_najentus_spine(GameObject* go) : GameObjectAI(go), _instance(go->GetInstanceScript()) { } - class spell_najentus_needle_spine_SpellScript : public SpellScript - { - PrepareSpellScript(spell_najentus_needle_spine_SpellScript); + bool GossipHello(Player* player) override + { + if (!_instance) + return false; - bool Validate(SpellInfo const* /*spellInfo*/) override + if (Creature* najentus = _instance->GetCreature(DATA_HIGH_WARLORD_NAJENTUS)) + if (najentus->AI()->GetData(DATA_REMOVE_IMPALING_SPINE)) { - return ValidateSpellInfo({ SPELL_NEEDLE_SPINE }); + najentus->AI()->DoAction(ACTION_RESET_IMPALING_TARGET); + me->CastSpell(player, SPELL_CREATE_NAJENTUS_SPINE, true); + me->Delete(); } + return true; + } +private: + InstanceScript* _instance; +}; - void FilterTargets(std::list<WorldObject*>& targets) - { - targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_IMPALING_SPINE)); - } +// 39992 - Needle Spine Targeting +class spell_najentus_needle_spine : public SpellScript +{ + PrepareSpellScript(spell_najentus_needle_spine); - void HandleScript(SpellEffIndex /*effIndex*/) - { - GetCaster()->CastSpell(GetHitUnit(), SPELL_NEEDLE_SPINE, true); - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_NEEDLE_SPINE }); + } - void Register() override - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_najentus_needle_spine_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); - OnEffectHitTarget += SpellEffectFn(spell_najentus_needle_spine_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + void FilterTargets(std::list<WorldObject*>& targets) + { + targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_IMPALING_SPINE)); + } - SpellScript* GetSpellScript() const override - { - return new spell_najentus_needle_spine_SpellScript(); - } + void HandleScript(SpellEffIndex /*effIndex*/) + { + GetCaster()->CastSpell(GetHitUnit(), SPELL_NEEDLE_SPINE, true); + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_najentus_needle_spine::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + OnEffectHitTarget += SpellEffectFn(spell_najentus_needle_spine::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; void AddSC_boss_najentus() { - new boss_najentus(); - new go_najentus_spine(); - new spell_najentus_needle_spine(); + RegisterBlackTempleCreatureAI(boss_najentus); + RegisterGameObjectAI(go_najentus_spine); + RegisterSpellScript(spell_najentus_needle_spine); } diff --git a/src/server/scripts/Outland/BlackTemple/instance_black_temple.cpp b/src/server/scripts/Outland/BlackTemple/instance_black_temple.cpp index f679428e44e..3a4132ac8c7 100644 --- a/src/server/scripts/Outland/BlackTemple/instance_black_temple.cpp +++ b/src/server/scripts/Outland/BlackTemple/instance_black_temple.cpp @@ -101,7 +101,9 @@ class instance_black_temple : public InstanceMapScript LoadDoorData(doorData); LoadObjectData(creatureData, gameObjectData); LoadBossBoundaries(boundaries); - akamaState = AKAMA_INTRO; + AkamaState = AKAMA_INTRO; + TeronGorefiendIntro = 1; + AkamaIllidanIntro = 1; } void OnGameObjectCreate(GameObject* go) override @@ -126,7 +128,7 @@ class instance_black_temple : public InstanceMapScript case NPC_ASHTONGUE_STORMCALLER: case NPC_ASHTONGUE_FERAL_SPIRIT: case NPC_STORM_FURY: - AshtongueGUIDs.emplace_back(creature->GetGUID()); + AshtongueGUIDs.push_back(creature->GetGUID()); if (GetBossState(DATA_SHADE_OF_AKAMA) == DONE) creature->SetFaction(FACTION_ASHTONGUE_DEATHSWORN); break; @@ -135,25 +137,37 @@ class instance_black_temple : public InstanceMapScript } } - uint32 GetData(uint32 data) const override + uint32 GetData(uint32 type) const override { - if (data == DATA_AKAMA) - return akamaState; - - return 0; + switch (type) + { + case DATA_AKAMA: + return AkamaState; + case DATA_TERON_GOREFIEND_INTRO: + return TeronGorefiendIntro; + case DATA_AKAMA_ILLIDAN_INTRO: + return AkamaIllidanIntro; + default: + return 0; + } } - void SetData(uint32 data, uint32 value) override + void SetData(uint32 type, uint32 data) override { - switch (data) + switch (type) { case DATA_AKAMA: - akamaState = value; + AkamaState = data; break; case ACTION_OPEN_DOOR: if (GameObject* illidanGate = GetGameObject(DATA_GO_ILLIDAN_GATE)) HandleGameObject(ObjectGuid::Empty, true, illidanGate); break; + case DATA_TERON_GOREFIEND_INTRO: + TeronGorefiendIntro = data; + break; + case DATA_AKAMA_ILLIDAN_INTRO: + AkamaIllidanIntro = data; default: break; } @@ -211,7 +225,9 @@ class instance_black_temple : public InstanceMapScript protected: GuidVector AshtongueGUIDs; - uint8 akamaState; + uint8 AkamaState; + uint8 TeronGorefiendIntro; + uint8 AkamaIllidanIntro; }; InstanceScript* GetInstanceScript(InstanceMap* map) const override diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp index 29185f77185..2b0305f374a 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp @@ -332,9 +332,7 @@ public: if (instance->GetGuidData(DATA_LEOTHERAS_EVENT_STARTER)) { - Unit* victim = nullptr; - victim = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_LEOTHERAS_EVENT_STARTER)); - if (victim) + if (Unit* victim = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_LEOTHERAS_EVENT_STARTER))) AddThreat(victim, 1); StartEvent(); } @@ -586,9 +584,7 @@ public: //at this point he divides himself in two parts CastConsumingMadness(); DespawnDemon(); - Creature* Copy = nullptr; - Copy = DoSpawnCreature(DEMON_FORM, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 6000); - if (Copy) + if (Creature* Copy = DoSpawnCreature(DEMON_FORM, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 6000)) { Demon = Copy->GetGUID(); if (me->GetVictim()) @@ -738,7 +734,7 @@ public: instance->SetGuidData(DATA_LEOTHERAS_EVENT_STARTER, who->GetGUID()); } - void JustRespawned() override + void JustAppeared() override { AddedBanish = false; Reset(); @@ -764,9 +760,7 @@ public: if (!me->IsInCombat() && instance->GetGuidData(DATA_LEOTHERAS_EVENT_STARTER)) { - Unit* victim = nullptr; - victim = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_LEOTHERAS_EVENT_STARTER)); - if (victim) + if (Unit* victim = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_LEOTHERAS_EVENT_STARTER))) AttackStart(victim); } @@ -784,10 +778,8 @@ public: if (Mindblast_Timer <= diff) { - Unit* target = nullptr; - target = SelectTarget(SELECT_TARGET_RANDOM, 0); - - if (target)DoCast(target, SPELL_MINDBLAST); + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) + DoCast(target, SPELL_MINDBLAST); Mindblast_Timer = urand(10000, 15000); } else Mindblast_Timer -= diff; diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/instance_serpent_shrine.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/instance_serpent_shrine.cpp index 4b694ab5861..0a26f129bf7 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/instance_serpent_shrine.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/instance_serpent_shrine.cpp @@ -148,7 +148,7 @@ class instance_serpent_shrine : public InstanceMapScript player->CastSpell(player, SPELL_SCALDINGWATER, true); } - else if (Water == WATERSTATE_FRENZY) + else { //spawn frenzy if (DoSpawnFrenzy) diff --git a/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/boss_ahune.cpp b/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/boss_ahune.cpp index c5bb049d443..b7d7c10f6c7 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/boss_ahune.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/boss_ahune.cpp @@ -308,7 +308,7 @@ public: void Initialize() { me->SetReactState(REACT_PASSIVE); - me->setRegeneratingHealth(false); + me->SetRegenerateHealth(false); DoCast(me, SPELL_FROZEN_CORE_GETS_HIT); DoCast(me, SPELL_ICE_SPEAR_AURA); } diff --git a/src/server/scripts/Outland/GruulsLair/boss_gruul.cpp b/src/server/scripts/Outland/GruulsLair/boss_gruul.cpp index f6ad97f6328..ac6c9e62072 100644 --- a/src/server/scripts/Outland/GruulsLair/boss_gruul.cpp +++ b/src/server/scripts/Outland/GruulsLair/boss_gruul.cpp @@ -285,7 +285,7 @@ class spell_gruul_shatter : public SpellScriptLoader if (Unit* target = GetHitUnit()) { target->RemoveAurasDueToSpell(SPELL_STONED); - target->CastSpell((Unit*)nullptr, SPELL_SHATTER_EFFECT, true); + target->CastSpell(nullptr, SPELL_SHATTER_EFFECT, true); } } diff --git a/src/server/scripts/Outland/GruulsLair/boss_high_king_maulgar.cpp b/src/server/scripts/Outland/GruulsLair/boss_high_king_maulgar.cpp index 57423f63ab0..2b43de82bb5 100644 --- a/src/server/scripts/Outland/GruulsLair/boss_high_king_maulgar.cpp +++ b/src/server/scripts/Outland/GruulsLair/boss_high_king_maulgar.cpp @@ -181,9 +181,7 @@ public: //Charging_Timer if (Charging_Timer <= diff) { - Unit* target = nullptr; - target = SelectTarget(SELECT_TARGET_RANDOM, 0); - if (target) + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) { AttackStart(target); DoCast(target, SPELL_BERSERKER_C); @@ -293,9 +291,7 @@ public: //DeathCoil Timer /need correct timer if (DeathCoil_Timer <= diff) { - Unit* target = nullptr; - target = SelectTarget(SELECT_TARGET_RANDOM, 0); - if (target) + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) DoCast(target, SPELL_DEATH_COIL); DeathCoil_Timer = 20000; } else DeathCoil_Timer -= diff; diff --git a/src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/boss_magtheridon.cpp b/src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/boss_magtheridon.cpp index 354e4b0fce3..f0cf459acfe 100644 --- a/src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/boss_magtheridon.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/boss_magtheridon.cpp @@ -477,9 +477,9 @@ public: return true; if (Creature* trigger = player->FindNearestCreature(NPC_HELFIRE_RAID_TRIGGER, 10.0f)) - trigger->CastSpell((Unit*)nullptr, SPELL_SHADOW_GRASP_VISUAL); + trigger->CastSpell(nullptr, SPELL_SHADOW_GRASP_VISUAL); - player->CastSpell((Unit*)nullptr, SPELL_SHADOW_GRASP, true); + player->CastSpell(nullptr, SPELL_SHADOW_GRASP, true); return true; } }; diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp index 9b683770be0..6d65ceae758 100644 --- a/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp +++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp @@ -436,9 +436,7 @@ class boss_alar : public CreatureScript } else { - Unit* target = nullptr; - target = me->SelectNearestTargetInAttackDistance(5); - if (target) + if (Unit* target = me->SelectNearestTargetInAttackDistance(5)) AttackStart(target); else { diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp index d3aa6b7e1fa..3323c53d546 100644 --- a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp +++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp @@ -1124,8 +1124,7 @@ class boss_grand_astromancer_capernian : public CreatureScript //Conflagration_Timer if (Conflagration_Timer <= diff) { - Unit* target = nullptr; - target = SelectTarget(SELECT_TARGET_RANDOM, 0); + Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0); if (target && me->IsWithinDistInMap(target, 30)) DoCast(target, SPELL_CONFLAGRATION); diff --git a/src/server/scripts/Outland/boss_doomlord_kazzak.cpp b/src/server/scripts/Outland/boss_doomlord_kazzak.cpp index 93ea132a545..240ec55c215 100644 --- a/src/server/scripts/Outland/boss_doomlord_kazzak.cpp +++ b/src/server/scripts/Outland/boss_doomlord_kazzak.cpp @@ -83,7 +83,7 @@ class boss_doomlord_kazzak : public CreatureScript _events.ScheduleEvent(EVENT_BERSERK, 180000); } - void JustRespawned() override + void JustAppeared() override { Talk(SAY_INTRO); } diff --git a/src/server/scripts/Outland/zone_hellfire_peninsula.cpp b/src/server/scripts/Outland/zone_hellfire_peninsula.cpp index 0660d781e57..c56208d77af 100644 --- a/src/server/scripts/Outland/zone_hellfire_peninsula.cpp +++ b/src/server/scripts/Outland/zone_hellfire_peninsula.cpp @@ -150,9 +150,9 @@ class npc_ancestral_wolf : public CreatureScript public: npc_ancestral_wolf() : CreatureScript("npc_ancestral_wolf") { } - struct npc_ancestral_wolfAI : public npc_escortAI + struct npc_ancestral_wolfAI : public EscortAI { - npc_ancestral_wolfAI(Creature* creature) : npc_escortAI(creature) + npc_ancestral_wolfAI(Creature* creature) : EscortAI(creature) { if (creature->GetOwner() && creature->GetOwner()->GetTypeId() == TYPEID_PLAYER) Start(false, false, creature->GetOwner()->GetGUID()); @@ -170,11 +170,11 @@ public: // Override Evade Mode event, recast buff that was removed by standard handler void EnterEvadeMode(EvadeReason why) override { - npc_escortAI::EnterEvadeMode(why); + EscortAI::EnterEvadeMode(why); DoCast(me, SPELL_ANCESTRAL_WOLF_BUFF, true); } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { switch (waypointId) { @@ -258,9 +258,9 @@ class npc_wounded_blood_elf : public CreatureScript public: npc_wounded_blood_elf() : CreatureScript("npc_wounded_blood_elf") { } - struct npc_wounded_blood_elfAI : public npc_escortAI + struct npc_wounded_blood_elfAI : public EscortAI { - npc_wounded_blood_elfAI(Creature* creature) : npc_escortAI(creature) { } + npc_wounded_blood_elfAI(Creature* creature) : EscortAI(creature) { } void Reset() override { } @@ -280,11 +280,11 @@ public: if (quest->GetQuestId() == QUEST_ROAD_TO_FALCON_WATCH) { me->SetFaction(FACTION_ESCORTEE_H_PASSIVE); - npc_escortAI::Start(true, false, player->GetGUID()); + EscortAI::Start(true, false, player->GetGUID()); } } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { Player* player = GetPlayerForEscort(); if (!player) diff --git a/src/server/scripts/Outland/zone_nagrand.cpp b/src/server/scripts/Outland/zone_nagrand.cpp index ce71c80e5f0..d19e77a6d0f 100644 --- a/src/server/scripts/Outland/zone_nagrand.cpp +++ b/src/server/scripts/Outland/zone_nagrand.cpp @@ -73,9 +73,9 @@ class npc_maghar_captive : public CreatureScript public: npc_maghar_captive() : CreatureScript("npc_maghar_captive") { } - struct npc_maghar_captiveAI : public npc_escortAI + struct npc_maghar_captiveAI : public EscortAI { - npc_maghar_captiveAI(Creature* creature) : npc_escortAI(creature) { Reset(); } + npc_maghar_captiveAI(Creature* creature) : EscortAI(creature) { Reset(); } uint32 ChainLightningTimer; uint32 HealTimer; @@ -105,7 +105,7 @@ public: } } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { switch (waypointId) { @@ -157,7 +157,7 @@ public: void UpdateAI(uint32 diff) override { - npc_escortAI::UpdateAI(diff); + EscortAI::UpdateAI(diff); if (!UpdateVictim()) return; @@ -434,9 +434,9 @@ class npc_kurenai_captive : public CreatureScript public: npc_kurenai_captive() : CreatureScript("npc_kurenai_captive") { } - struct npc_kurenai_captiveAI : public npc_escortAI + struct npc_kurenai_captiveAI : public EscortAI { - npc_kurenai_captiveAI(Creature* creature) : npc_escortAI(creature) + npc_kurenai_captiveAI(Creature* creature) : EscortAI(creature) { Initialize(); } @@ -474,7 +474,7 @@ public: } } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { switch (waypointId) { @@ -538,7 +538,7 @@ public: void UpdateAI(uint32 diff) override { - npc_escortAI::UpdateAI(diff); + EscortAI::UpdateAI(diff); if (!UpdateVictim()) return; diff --git a/src/server/scripts/Outland/zone_netherstorm.cpp b/src/server/scripts/Outland/zone_netherstorm.cpp index 6fcf5c37004..8104282117c 100644 --- a/src/server/scripts/Outland/zone_netherstorm.cpp +++ b/src/server/scripts/Outland/zone_netherstorm.cpp @@ -488,9 +488,9 @@ class npc_bessy : public CreatureScript public: npc_bessy() : CreatureScript("npc_bessy") { } - struct npc_bessyAI : public npc_escortAI + struct npc_bessyAI : public EscortAI { - npc_bessyAI(Creature* creature) : npc_escortAI(creature) { } + npc_bessyAI(Creature* creature) : EscortAI(creature) { } void JustDied(Unit* /*killer*/) override { @@ -498,7 +498,7 @@ public: player->FailQuest(Q_ALMABTRIEB); } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { Player* player = GetPlayerForEscort(); if (!player) @@ -569,9 +569,9 @@ class npc_maxx_a_million_escort : public CreatureScript public: npc_maxx_a_million_escort() : CreatureScript("npc_maxx_a_million_escort") { } - struct npc_maxx_a_million_escortAI : public npc_escortAI + struct npc_maxx_a_million_escortAI : public EscortAI { - npc_maxx_a_million_escortAI(Creature* creature) : npc_escortAI(creature) + npc_maxx_a_million_escortAI(Creature* creature) : EscortAI(creature) { Initialize(); } @@ -590,7 +590,7 @@ public: Initialize(); } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { Player* player = GetPlayerForEscort(); if (!player) @@ -624,7 +624,7 @@ public: void UpdateAI(uint32 uiDiff) override { - npc_escortAI::UpdateAI(uiDiff); + EscortAI::UpdateAI(uiDiff); if (bTake) { @@ -668,7 +668,11 @@ public: enum CaptainTyralius { NPC_CAPTAIN_TYRALIUS = 20787, + NPC_ETHEREUM_PRISONER = 20825, + SPELL_TELEPORT_VISUAL = 51347, SAY_FREE = 0, + ACTION_FREED = 0, + EVENT_TELEPORT = 1 }; class go_captain_tyralius_prison : public GameObjectScript @@ -680,15 +684,26 @@ class go_captain_tyralius_prison : public GameObjectScript { go_captain_tyralius_prisonAI(GameObject* go) : GameObjectAI(go) { } + void Reset() override + { + me->SummonCreature(NPC_CAPTAIN_TYRALIUS, me->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN); + me->SummonCreature(NPC_ETHEREUM_PRISONER, me->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN); + } + bool GossipHello(Player* player) override { - me->UseDoorOrButton(); + me->SetRespawnTime(60); + me->SetLootState(GO_JUST_DEACTIVATED); + if (Creature* tyralius = me->FindNearestCreature(NPC_CAPTAIN_TYRALIUS, 1.0f)) { player->KilledMonsterCredit(NPC_CAPTAIN_TYRALIUS); - tyralius->AI()->Talk(SAY_FREE); - tyralius->DespawnOrUnsummon(8000); + tyralius->AI()->DoAction(ACTION_FREED); } + + if (Creature* prisoner = me->FindNearestCreature(NPC_ETHEREUM_PRISONER, 1.0f)) + prisoner->DespawnOrUnsummon(0); + return true; } }; @@ -699,6 +714,47 @@ class go_captain_tyralius_prison : public GameObjectScript } }; +class npc_captain_tyralius : public CreatureScript +{ +public: + npc_captain_tyralius() : CreatureScript("npc_captain_tyralius") { } + + CreatureAI* GetAI(Creature* creature) const override + { + return new npc_captain_tyraliusAI(creature); + } + + struct npc_captain_tyraliusAI : public ScriptedAI + { + npc_captain_tyraliusAI(Creature* creature) : ScriptedAI(creature) { } + + void DoAction(int32 /*action*/) override + { + Talk(SAY_FREE); + _events.ScheduleEvent(EVENT_TELEPORT, Seconds(5)); + } + + void UpdateAI(uint32 diff) override + { + _events.Update(diff); + + if (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_TELEPORT: + DoCastSelf(SPELL_TELEPORT_VISUAL); + me->DespawnOrUnsummon(Seconds(2)); + break; + } + } + } + + private: + EventMap _events; + }; +}; + void AddSC_netherstorm() { new npc_commander_dawnforge(); @@ -707,4 +763,5 @@ void AddSC_netherstorm() new npc_bessy(); new npc_maxx_a_million_escort(); new go_captain_tyralius_prison(); + new npc_captain_tyralius(); } diff --git a/src/server/scripts/Outland/zone_shadowmoon_valley.cpp b/src/server/scripts/Outland/zone_shadowmoon_valley.cpp index 65eaefa2d7b..9ee82504a49 100644 --- a/src/server/scripts/Outland/zone_shadowmoon_valley.cpp +++ b/src/server/scripts/Outland/zone_shadowmoon_valley.cpp @@ -592,9 +592,9 @@ class npc_earthmender_wilda : public CreatureScript public: npc_earthmender_wilda() : CreatureScript("npc_earthmender_wilda") { } - struct npc_earthmender_wildaAI : public npc_escortAI + struct npc_earthmender_wildaAI : public EscortAI { - npc_earthmender_wildaAI(Creature* creature) : npc_escortAI(creature) + npc_earthmender_wildaAI(Creature* creature) : EscortAI(creature) { Initialize(); } @@ -611,7 +611,7 @@ public: Initialize(); } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { Player* player = GetPlayerForEscort(); if (!player) @@ -704,7 +704,7 @@ public: void UpdateAI(uint32 uiDiff) override { - npc_escortAI::UpdateAI(uiDiff); + EscortAI::UpdateAI(uiDiff); if (!UpdateVictim()) return; @@ -1376,7 +1376,7 @@ public: enum Enraged_Dpirits { -// QUESTS + // QUESTS QUEST_ENRAGED_SPIRITS_FIRE_EARTH = 10458, QUEST_ENRAGED_SPIRITS_AIR = 10481, QUEST_ENRAGED_SPIRITS_WATER = 10480, @@ -1391,6 +1391,22 @@ enum Enraged_Dpirits NPC_ENRAGED_AIR_SPIRIT = 21060, NPC_ENRAGED_WATER_SPIRIT = 21059, + // ENRAGED WATER SPIRIT SPELLS + SPELL_STORMBOLT = 38032, + + // ENRAGED AIR SPIRIT SPELLS + SPELL_AIR_SPIRIT_CHAIN_LIGHTNING = 12058, + SPELL_HURRICANE = 32717, + SPELL_ENRAGE = 8599, + + // ENRAGED FIRE SPIRIT SPELLS - Will be using the enrage spell from Air Spirit + SPELL_FEL_FIREBALL = 36247, + SPELL_FEL_FIRE_AURA = 36006, // Earth spirit uses this one + + // ENRAGED EARTH SPIRIT SPELLS + SPELL_FIERY_BOULDER = 38498, + SPELL_SUMMON_ENRAGED_EARTH_SHARD = 38365, + // SOULS NPC_EARTHEN_SOUL = 21073, NPC_FIERY_SOUL = 21097, @@ -1413,6 +1429,15 @@ enum Enraged_Dpirits SPELL_SOUL_CAPTURED = 36115 }; +enum Enraged_Spirits_Events +{ + EVENT_ENRAGED_WATER_SPIRIT = 1, + EVENT_ENRAGED_FIRE_SPIRIT = 2, + EVENT_ENRAGED_EARTH_SPIRIT = 3, + EVENT_ENRAGED_AIR_SPIRIT_CHAIN_LIGHTNING = 4, + EVENT_ENRAGED_AIR_SPIRIT_HURRICANE = 5 +}; + class npc_enraged_spirit : public CreatureScript { public: @@ -1420,7 +1445,7 @@ public: CreatureAI* GetAI(Creature* creature) const override { - return new npc_enraged_spiritAI(creature); + return new npc_enraged_spiritAI(creature); } struct npc_enraged_spiritAI : public ScriptedAI @@ -1429,7 +1454,77 @@ public: void Reset() override { } - void EnterCombat(Unit* /*who*/) override { } + void EnterCombat(Unit* /*who*/) override + { + switch (me->GetEntry()) + { + case NPC_ENRAGED_WATER_SPIRIT: + _events.ScheduleEvent(EVENT_ENRAGED_WATER_SPIRIT, Seconds(0), Seconds(1)); + break; + case NPC_ENRAGED_FIRE_SPIRIT: + if (!me->GetAura(SPELL_FEL_FIRE_AURA)) + DoCastSelf(SPELL_FEL_FIRE_AURA); + _events.ScheduleEvent(EVENT_ENRAGED_FIRE_SPIRIT, Seconds(2), Seconds(10)); + break; + case NPC_ENRAGED_EARTH_SPIRIT: + if (!me->GetAura(SPELL_FEL_FIRE_AURA)) + DoCastSelf(SPELL_FEL_FIRE_AURA); + _events.ScheduleEvent(EVENT_ENRAGED_EARTH_SPIRIT, Seconds(3), Seconds(4)); + break; + case NPC_ENRAGED_AIR_SPIRIT: + _events.ScheduleEvent(EVENT_ENRAGED_AIR_SPIRIT_CHAIN_LIGHTNING, Seconds(10)); + break; + default: + break; + } + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_ENRAGED_WATER_SPIRIT: + if (UpdateVictim()) + DoCastVictim(SPELL_STORMBOLT); + _events.Repeat(Seconds(17), Seconds(23)); + break; + case EVENT_ENRAGED_FIRE_SPIRIT: + if (UpdateVictim()) + DoCastVictim(SPELL_FEL_FIREBALL); + _events.Repeat(Seconds(6), Seconds(12)); + break; + case EVENT_ENRAGED_EARTH_SPIRIT: + if (UpdateVictim()) + DoCastVictim(SPELL_FIERY_BOULDER); + _events.Repeat(Seconds(6), Seconds(9)); + break; + case EVENT_ENRAGED_AIR_SPIRIT_CHAIN_LIGHTNING: + if (UpdateVictim()) + DoCastVictim(SPELL_CHAIN_LIGHTNING); + _events.ScheduleEvent(EVENT_ENRAGED_AIR_SPIRIT_HURRICANE, Seconds(3), Seconds(5)); + break; + case EVENT_ENRAGED_AIR_SPIRIT_HURRICANE: + if (UpdateVictim()) + DoCastVictim(SPELL_HURRICANE); + _events.ScheduleEvent(EVENT_ENRAGED_AIR_SPIRIT_CHAIN_LIGHTNING, Seconds(15), Seconds(20)); + break; + default: + break; + } + } + + if (me->GetEntry() == NPC_ENRAGED_FIRE_SPIRIT || me->GetEntry() == NPC_ENRAGED_AIR_SPIRIT) + if (HealthBelowPct(35) && !me->GetAura(SPELL_ENRAGE)) + DoCastSelf(SPELL_ENRAGE); + + DoMeleeAttackIfReady(); + } void JustDied(Unit* /*killer*/) override { @@ -1450,6 +1545,7 @@ public: entry = NPC_EARTHEN_SOUL; //credit = SPELL_EARTHEN_SOUL_CAPTURED_CREDIT; credit = NPC_CREDIT_EARTH; + DoCastSelf(SPELL_SUMMON_ENRAGED_EARTH_SHARD); break; case NPC_ENRAGED_AIR_SPIRIT: entry = NPC_ENRAGED_AIRY_SOUL; @@ -1488,6 +1584,9 @@ public: } } } + + private: + EventMap _events; }; }; diff --git a/src/server/scripts/Outland/zone_shattrath_city.cpp b/src/server/scripts/Outland/zone_shattrath_city.cpp index 87143a32e7b..073897b5689 100644 --- a/src/server/scripts/Outland/zone_shattrath_city.cpp +++ b/src/server/scripts/Outland/zone_shattrath_city.cpp @@ -19,346 +19,21 @@ /* ScriptData SDName: Shattrath_City SD%Complete: 100 -SDComment: Quest support: 10004, 10009, 10211. Flask vendors, Teleport to Caverns of Time +SDComment: Quest support: 10211. SDCategory: Shattrath City EndScriptData */ /* ContentData -npc_raliq_the_drunk -npc_salsalabim -npc_shattrathflaskvendors -npc_zephyr npc_kservant EndContentData */ #include "ScriptMgr.h" #include "ScriptedCreature.h" -#include "ScriptedGossip.h" #include "ScriptedEscortAI.h" #include "Player.h" #include "WorldSession.h" /*###### -## npc_raliq_the_drunk -######*/ - -enum RaliqTheDrunk -{ - SAY_RALIQ_ATTACK = 0, - OPTION_ID_COLLECT_A_DEBT = 0, - MENU_ID_COLLECT_A_DEBT = 7729, - NPC_TEXT_WUT_YOU_WANT = 9440, - CRACKIN_SOME_SKULLS = 10009, - SPELL_UPPERCUT = 10966 -}; - -class npc_raliq_the_drunk : public CreatureScript -{ -public: - npc_raliq_the_drunk() : CreatureScript("npc_raliq_the_drunk") { } - - struct npc_raliq_the_drunkAI : public ScriptedAI - { - npc_raliq_the_drunkAI(Creature* creature) : ScriptedAI(creature) - { - Initialize(); - } - - void Initialize() - { - Uppercut_Timer = 5000; - } - - uint32 Uppercut_Timer; - - void Reset() override - { - Initialize(); - me->RestoreFaction(); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - if (Uppercut_Timer <= diff) - { - DoCastVictim(SPELL_UPPERCUT); - Uppercut_Timer = 15000; - } else Uppercut_Timer -= diff; - - DoMeleeAttackIfReady(); - } - - bool GossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override - { - uint32 const action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId); - ClearGossipMenuFor(player); - if (action == GOSSIP_ACTION_INFO_DEF + 1) - { - CloseGossipMenuFor(player); - me->SetFaction(FACTION_OGRE); - Talk(SAY_RALIQ_ATTACK, player); - AttackStart(player); - } - return true; - } - - bool GossipHello(Player* player) override - { - if (player->GetQuestStatus(CRACKIN_SOME_SKULLS) == QUEST_STATUS_INCOMPLETE) - { - AddGossipItemFor(player, MENU_ID_COLLECT_A_DEBT, OPTION_ID_COLLECT_A_DEBT, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - SendGossipMenuFor(player, NPC_TEXT_WUT_YOU_WANT, me->GetGUID()); - } - else - { - ClearGossipMenuFor(player); - SendGossipMenuFor(player, player->GetGossipTextId(me), me->GetGUID()); - } - return true; - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_raliq_the_drunkAI(creature); - } -}; - -/*###### -# npc_salsalabim -######*/ - -enum Salsalabim -{ - SAY_DEMONIC_AGGRO = 0, - OPTION_ID_ALTRUIS_SENT_ME = 0, - MENU_ID_ALTRUIS_SENT_ME = 7725, - NPC_TEXT_SAL_GROWLS_AT_YOU = 9435, - PATIENCE_AND_UNDERSTANDING = 10004, - SPELL_MAGNETIC_PULL = 31705 -}; - -class npc_salsalabim : public CreatureScript -{ -public: - npc_salsalabim() : CreatureScript("npc_salsalabim") { } - - struct npc_salsalabimAI : public ScriptedAI - { - npc_salsalabimAI(Creature* creature) : ScriptedAI(creature) - { - Initialize(); - } - - void Initialize() - { - MagneticPull_Timer = 15000; - } - - uint32 MagneticPull_Timer; - - void Reset() override - { - Initialize(); - me->RestoreFaction(); - } - - void DamageTaken(Unit* done_by, uint32 &damage) override - { - if (done_by->GetTypeId() == TYPEID_PLAYER && me->HealthBelowPctDamaged(20, damage)) - { - done_by->ToPlayer()->GroupEventHappens(PATIENCE_AND_UNDERSTANDING, me); - damage = 0; - EnterEvadeMode(); - } - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - if (MagneticPull_Timer <= diff) - { - DoCastVictim(SPELL_MAGNETIC_PULL); - MagneticPull_Timer = 15000; - } else MagneticPull_Timer -= diff; - - DoMeleeAttackIfReady(); - } - - bool GossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override - { - uint32 const action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId); - ClearGossipMenuFor(player); - if (action == GOSSIP_ACTION_INFO_DEF + 1) - { - CloseGossipMenuFor(player); - me->SetFaction(FACTION_DEMON); - Talk(SAY_DEMONIC_AGGRO, player); - AttackStart(player); - } - return true; - } - - bool GossipHello(Player* player) override - { - if (player->GetQuestStatus(PATIENCE_AND_UNDERSTANDING) == QUEST_STATUS_INCOMPLETE) - { - AddGossipItemFor(player, MENU_ID_ALTRUIS_SENT_ME, OPTION_ID_ALTRUIS_SENT_ME, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - SendGossipMenuFor(player, NPC_TEXT_SAL_GROWLS_AT_YOU, me->GetGUID()); - } - else - { - if (me->IsQuestGiver()) - player->PrepareQuestMenu(me->GetGUID()); - SendGossipMenuFor(player, player->GetGossipTextId(me), me->GetGUID()); - } - return true; - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_salsalabimAI(creature); - } -}; - -/* -################################################## -Shattrath City Flask Vendors provides flasks to people exalted with 3 fActions: -Haldor the Compulsive -Arcanist Xorith -Both sell special flasks for use in Outlands 25man raids only, -purchasable for one Mark of Illidari each -Purchase requires exalted reputation with Scryers/Aldor, Cenarion Expedition and The Sha'tar -################################################## -*/ - -enum FlaskVendors -{ - ALDOR_REPUTATION = 932, - SCRYERS_REPUTATION = 934, - THE_SHA_TAR_REPUTATION = 935, - CENARION_EXPEDITION_REP = 942, - NPC_TEXT_EXALTED_ALDOR = 11083, // (need to be exalted with Sha'tar, Cenarion Expedition and the Aldor) - NPC_TEXT_EXALTED_SCRYERS = 11084, // (need to be exalted with Sha'tar, Cenarion Expedition and the Scryers) - NPC_TEXT_WELCOME_NAME = 11085, // Access granted - ARCANIST_XORITH = 23483, // Scryer Apothecary - HALDOR_THE_COMPULSIVE = 23484 // Aldor Apothecary -}; - -class npc_shattrathflaskvendors : public CreatureScript -{ -public: - npc_shattrathflaskvendors() : CreatureScript("npc_shattrathflaskvendors") { } - - struct npc_shattrathflaskvendorsAI : public ScriptedAI - { - npc_shattrathflaskvendorsAI(Creature* creature) : ScriptedAI(creature) { } - - bool GossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override - { - uint32 const action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId); - ClearGossipMenuFor(player); - if (action == GOSSIP_ACTION_TRADE) - player->GetSession()->SendListInventory(me->GetGUID()); - - return true; - } - - bool GossipHello(Player* player) override - { - if (me->GetEntry() == HALDOR_THE_COMPULSIVE) - { - // Aldor vendor - if (me->IsVendor() && (player->GetReputationRank(ALDOR_REPUTATION) == REP_EXALTED) && (player->GetReputationRank(THE_SHA_TAR_REPUTATION) == REP_EXALTED) && (player->GetReputationRank(CENARION_EXPEDITION_REP) == REP_EXALTED)) - { - AddGossipItemFor(player, GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); - SendGossipMenuFor(player, NPC_TEXT_WELCOME_NAME, me->GetGUID()); - } - else - { - SendGossipMenuFor(player, NPC_TEXT_EXALTED_ALDOR, me->GetGUID()); - } - } - - if (me->GetEntry() == ARCANIST_XORITH) - { - // Scryers vendor - if (me->IsVendor() && (player->GetReputationRank(SCRYERS_REPUTATION) == REP_EXALTED) && (player->GetReputationRank(THE_SHA_TAR_REPUTATION) == REP_EXALTED) && (player->GetReputationRank(CENARION_EXPEDITION_REP) == REP_EXALTED)) - { - AddGossipItemFor(player, GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); - SendGossipMenuFor(player, NPC_TEXT_WELCOME_NAME, me->GetGUID()); - } - else - { - SendGossipMenuFor(player, NPC_TEXT_EXALTED_SCRYERS, me->GetGUID()); - } - } - - return true; - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_shattrathflaskvendorsAI(creature); - } -}; - -/*###### -# npc_zephyr -######*/ - -enum Zephyr -{ - OPTION_ID_TAKE_ME_TO_C_O_T = 0, - KEEPERS_OF_TIME_REPUTATION = 989, - MENU_ID_TAKE_ME_TO_C_O_T = 9205, - TELEPORT_CAVERNS_OF_TIME = 37778 -}; - -class npc_zephyr : public CreatureScript -{ -public: - npc_zephyr() : CreatureScript("npc_zephyr") { } - - struct npc_zephyrAI : public ScriptedAI - { - npc_zephyrAI(Creature* creature) : ScriptedAI(creature) { } - - bool GossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override - { - uint32 const action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId); - ClearGossipMenuFor(player); - if (action == GOSSIP_ACTION_INFO_DEF + 1) - player->CastSpell(player, TELEPORT_CAVERNS_OF_TIME, false); - - return true; - } - - bool GossipHello(Player* player) override - { - if (player->GetReputationRank(KEEPERS_OF_TIME_REPUTATION) >= REP_REVERED) - AddGossipItemFor(player, MENU_ID_TAKE_ME_TO_C_O_T, OPTION_ID_TAKE_ME_TO_C_O_T, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - - SendGossipMenuFor(player, player->GetGossipTextId(me), me->GetGUID()); - - return true; - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_zephyrAI(creature); - } -}; - -/*###### # npc_kservant ######*/ @@ -399,12 +74,12 @@ public: return new npc_kservantAI(creature); } - struct npc_kservantAI : public npc_escortAI + struct npc_kservantAI : public EscortAI { public: - npc_kservantAI(Creature* creature) : npc_escortAI(creature) { } + npc_kservantAI(Creature* creature) : EscortAI(creature) { } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { Player* player = GetPlayerForEscort(); if (!player) @@ -505,9 +180,5 @@ public: void AddSC_shattrath_city() { - new npc_raliq_the_drunk(); - new npc_salsalabim(); - new npc_shattrathflaskvendors(); - new npc_zephyr(); new npc_kservant(); } diff --git a/src/server/scripts/Outland/zone_terokkar_forest.cpp b/src/server/scripts/Outland/zone_terokkar_forest.cpp index 758db799ea4..a8b91b913e5 100644 --- a/src/server/scripts/Outland/zone_terokkar_forest.cpp +++ b/src/server/scripts/Outland/zone_terokkar_forest.cpp @@ -19,26 +19,22 @@ /* ScriptData SDName: Terokkar_Forest SD%Complete: 85 -SDComment: Quest support: 9889, 10009, 10873, 10896, 10898, 11096, 10052, 10051. Skettis->Ogri'la Flight +SDComment: Quest support: 9889, 10898, 10052, 10051. SDCategory: Terokkar Forest EndScriptData */ /* ContentData npc_unkor_the_ruthless -npc_infested_root_walker -npc_rotting_forest_rager -npc_floon npc_isla_starmane -npc_slim +npc_skywing +npc_akuno EndContentData */ #include "ScriptMgr.h" #include "GameObject.h" -#include "GameObjectAI.h" #include "Group.h" #include "Player.h" #include "ScriptedEscortAI.h" -#include "ScriptedGossip.h" #include "WorldSession.h" /*###### @@ -166,43 +162,6 @@ public: }; /*###### -## npc_infested_root_walker -######*/ - -enum InfestedRootWalker -{ - SPELL_SUMMON_WOOD_MITES = 39130 -}; - -class npc_infested_root_walker : public CreatureScript -{ -public: - npc_infested_root_walker() : CreatureScript("npc_infested_root_walker") { } - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_infested_root_walkerAI(creature); - } - - struct npc_infested_root_walkerAI : public ScriptedAI - { - npc_infested_root_walkerAI(Creature* creature) : ScriptedAI(creature) { } - - void Reset() override { } - void EnterCombat(Unit* /*who*/) override { } - - void DamageTaken(Unit* done_by, uint32 &damage) override - { - if (done_by && done_by->GetTypeId() == TYPEID_PLAYER) - if (me->GetHealth() <= damage) - if (rand32() % 100 < 75) - //Summon Wood Mites - DoCast(me, SPELL_SUMMON_WOOD_MITES, true); - } - }; -}; - -/*###### ## npc_skywing ######*/ @@ -221,12 +180,12 @@ public: return new npc_skywingAI(creature); } - struct npc_skywingAI : public npc_escortAI + struct npc_skywingAI : public EscortAI { public: - npc_skywingAI(Creature* creature) : npc_escortAI(creature) { } + npc_skywingAI(Creature* creature) : EscortAI(creature) { } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { Player* player = GetPlayerForEscort(); if (!player) @@ -258,162 +217,9 @@ public: void UpdateAI(uint32 diff) override { - npc_escortAI::UpdateAI(diff); - } - }; -}; - -/*###### -## npc_rotting_forest_rager -######*/ - -enum RottingForestRager -{ - SPELL_SUMMON_LOTS_OF_WOOD_MITES = 39134 -}; - -class npc_rotting_forest_rager : public CreatureScript -{ -public: - npc_rotting_forest_rager() : CreatureScript("npc_rotting_forest_rager") { } - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_rotting_forest_ragerAI(creature); - } - - struct npc_rotting_forest_ragerAI : public ScriptedAI - { - npc_rotting_forest_ragerAI(Creature* creature) : ScriptedAI(creature) { } - - void Reset() override { } - void EnterCombat(Unit* /*who*/) override { } - - void DamageTaken(Unit* done_by, uint32 &damage) override - { - if (done_by->GetTypeId() == TYPEID_PLAYER) - if (me->GetHealth() <= damage) - if (rand32() % 100 < 75) - //Summon Lots of Wood Mites - DoCast(me, SPELL_SUMMON_LOTS_OF_WOOD_MITES, true); - } - }; -}; - -/*###### -## npc_floon -######*/ - -enum Floon -{ - SAY_FLOON_ATTACK = 0, - OPTION_ID_PAY_UP_OR_DIE = 0, - OPTION_ID_COLLECT_A_DEBT = 0, - MENU_ID_PAY_UP_OR_DIE = 7731, - MENU_ID_COLLECT_A_DEBT = 7732, - GOSSIP_FLOON_STRANGE_SOUNDS = 9442, - GOSSIP_HE_ALREADY_KILLED_ME = 9443, - - SPELL_SILENCE = 6726, - SPELL_FROSTBOLT = 9672, - SPELL_FROST_NOVA = 11831, - - QUEST_CRACKIN_SOME_SKULLS = 10009 -}; - -class npc_floon : public CreatureScript -{ -public: - npc_floon() : CreatureScript("npc_floon") { } - - struct npc_floonAI : public ScriptedAI - { - npc_floonAI(Creature* creature) : ScriptedAI(creature) - { - Initialize(); - m_uiNormFaction = creature->GetFaction(); - } - - void Initialize() - { - Silence_Timer = 2000; - Frostbolt_Timer = 4000; - FrostNova_Timer = 9000; - } - - uint32 m_uiNormFaction; - uint32 Silence_Timer; - uint32 Frostbolt_Timer; - uint32 FrostNova_Timer; - - void Reset() override - { - Initialize(); - if (me->GetFaction() != m_uiNormFaction) - me->SetFaction(m_uiNormFaction); - } - - void EnterCombat(Unit* /*who*/) override { } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - if (Silence_Timer <= diff) - { - DoCastVictim(SPELL_SILENCE); - Silence_Timer = 30000; - } else Silence_Timer -= diff; - - if (FrostNova_Timer <= diff) - { - DoCast(me, SPELL_FROST_NOVA); - FrostNova_Timer = 20000; - } else FrostNova_Timer -= diff; - - if (Frostbolt_Timer <= diff) - { - DoCastVictim(SPELL_FROSTBOLT); - Frostbolt_Timer = 5000; - } else Frostbolt_Timer -= diff; - - DoMeleeAttackIfReady(); - } - - bool GossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override - { - uint32 const action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId); - ClearGossipMenuFor(player); - if (action == GOSSIP_ACTION_INFO_DEF) - { - AddGossipItemFor(player, MENU_ID_PAY_UP_OR_DIE, OPTION_ID_PAY_UP_OR_DIE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - SendGossipMenuFor(player, GOSSIP_HE_ALREADY_KILLED_ME, me->GetGUID()); - } - if (action == GOSSIP_ACTION_INFO_DEF + 1) - { - CloseGossipMenuFor(player); - me->SetFaction(FACTION_ARAKKOA); - Talk(SAY_FLOON_ATTACK, player); - AttackStart(player); - } - return true; - } - - bool GossipHello(Player* player) override - { - if (player->GetQuestStatus(QUEST_CRACKIN_SOME_SKULLS) == QUEST_STATUS_INCOMPLETE) - AddGossipItemFor(player, MENU_ID_COLLECT_A_DEBT, OPTION_ID_COLLECT_A_DEBT, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - - SendGossipMenuFor(player, GOSSIP_FLOON_STRANGE_SOUNDS, me->GetGUID()); - return true; + EscortAI::UpdateAI(diff); } }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_floonAI(creature); - } }; /*###### @@ -437,11 +243,11 @@ class npc_isla_starmane : public CreatureScript public: npc_isla_starmane() : CreatureScript("npc_isla_starmane") { } - struct npc_isla_starmaneAI : public npc_escortAI + struct npc_isla_starmaneAI : public EscortAI { - npc_isla_starmaneAI(Creature* creature) : npc_escortAI(creature) { } + npc_isla_starmaneAI(Creature* creature) : EscortAI(creature) { } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { Player* player = GetPlayerForEscort(); if (!player) @@ -512,135 +318,6 @@ public: } }; -/*###### -## go_skull_pile -######*/ - -enum SkullPile -{ - OPTION_ID_GEZZARAK_THE_HUNTRESS = 0, - OPTION_ID_DARKSCREECHER_AKKARAI = 1, - OPTION_ID_KARROG = 2, - OPTION_ID_VAKKIZ_THE_WINDRAGER = 3, - GOSSIP_MENU_ID_SKULL_PILE = 8660, - ADVERSARIAL_BLOOD = 11885, - SUMMON_GEZZARAK_THE_HUNTRESS = 40632, - SUMMON_KARROG = 40640, - SUMMON_DARKSCREECHER_AKKARAI = 40642, - SUMMON_VAKKIZ_THE_WINDRAGER = 40644 -}; - -class go_skull_pile : public GameObjectScript -{ -public: - go_skull_pile() : GameObjectScript("go_skull_pile") { } - - struct go_skull_pileAI : public GameObjectAI - { - go_skull_pileAI(GameObject* go) : GameObjectAI(go) { } - - bool GossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override - { - uint32 const sender = player->PlayerTalkClass->GetGossipOptionSender(gossipListId); - uint32 const action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId); - ClearGossipMenuFor(player); - switch (sender) - { - case GOSSIP_SENDER_MAIN: SendActionMenu(player, action); break; - } - return true; - } - - bool GossipHello(Player* player) override - { - if ((player->GetQuestStatus(ADVERSARIAL_BLOOD) == QUEST_STATUS_INCOMPLETE) || player->GetQuestRewardStatus(ADVERSARIAL_BLOOD)) - { - AddGossipItemFor(player, GOSSIP_MENU_ID_SKULL_PILE, OPTION_ID_GEZZARAK_THE_HUNTRESS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - AddGossipItemFor(player, GOSSIP_MENU_ID_SKULL_PILE, OPTION_ID_DARKSCREECHER_AKKARAI, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - AddGossipItemFor(player, GOSSIP_MENU_ID_SKULL_PILE, OPTION_ID_KARROG, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); - AddGossipItemFor(player, GOSSIP_MENU_ID_SKULL_PILE, OPTION_ID_VAKKIZ_THE_WINDRAGER, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4); - } - - SendGossipMenuFor(player, me->GetGOInfo()->questgiver.gossipID, me->GetGUID()); - return true; - } - - void SendActionMenu(Player* player, uint32 action) - { - switch (action) - { - case GOSSIP_ACTION_INFO_DEF + 1: - player->CastSpell(player, SUMMON_GEZZARAK_THE_HUNTRESS, false); - break; - case GOSSIP_ACTION_INFO_DEF + 2: - player->CastSpell(player, SUMMON_DARKSCREECHER_AKKARAI, false); - break; - case GOSSIP_ACTION_INFO_DEF + 3: - player->CastSpell(player, SUMMON_KARROG, false); - break; - case GOSSIP_ACTION_INFO_DEF + 4: - player->CastSpell(player, SUMMON_VAKKIZ_THE_WINDRAGER, false); - break; - } - } - }; - - GameObjectAI* GetAI(GameObject* go) const override - { - return new go_skull_pileAI(go); - } -}; - -/*###### -## npc_slim -######*/ - -enum Slim -{ - FACTION_CONSORTIUM = 933, - NPC_TEXT_NEITHER_SLIM_NOR_SHADY = 9895, - NPC_TEXT_I_SEE_YOU_ARE_A_FRIEND = 9896 -}; - -class npc_slim : public CreatureScript -{ -public: - npc_slim() : CreatureScript("npc_slim") { } - - struct npc_slimAI : public ScriptedAI - { - npc_slimAI(Creature* creature) : ScriptedAI(creature) { } - - bool GossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override - { - uint32 const action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId); - ClearGossipMenuFor(player); - if (action == GOSSIP_ACTION_TRADE) - player->GetSession()->SendListInventory(me->GetGUID()); - - return true; - } - - bool GossipHello(Player* player) override - { - if (me->IsVendor() && player->GetReputationRank(FACTION_CONSORTIUM) >= REP_FRIENDLY) - { - AddGossipItemFor(player, GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); - SendGossipMenuFor(player, NPC_TEXT_I_SEE_YOU_ARE_A_FRIEND, me->GetGUID()); - } - else - SendGossipMenuFor(player, NPC_TEXT_NEITHER_SLIM_NOR_SHADY, me->GetGUID()); - - return true; - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_slimAI(creature); - } -}; - /*######## ####npc_akuno #####*/ @@ -656,11 +333,11 @@ class npc_akuno : public CreatureScript public: npc_akuno() : CreatureScript("npc_akuno") { } - struct npc_akunoAI : public npc_escortAI + struct npc_akunoAI : public EscortAI { - npc_akunoAI(Creature* creature) : npc_escortAI(creature) { } + npc_akunoAI(Creature* creature) : EscortAI(creature) { } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { Player* player = GetPlayerForEscort(); if (!player) @@ -707,12 +384,7 @@ public: void AddSC_terokkar_forest() { new npc_unkor_the_ruthless(); - new npc_infested_root_walker(); - new npc_rotting_forest_rager(); - new npc_floon(); new npc_isla_starmane(); - new go_skull_pile(); new npc_skywing(); - new npc_slim(); new npc_akuno(); } diff --git a/src/server/scripts/Outland/zone_zangarmarsh.cpp b/src/server/scripts/Outland/zone_zangarmarsh.cpp index fabf7290129..9eff40f296c 100644 --- a/src/server/scripts/Outland/zone_zangarmarsh.cpp +++ b/src/server/scripts/Outland/zone_zangarmarsh.cpp @@ -19,14 +19,12 @@ /* ScriptData SDName: Zangarmarsh SD%Complete: 100 -SDComment: Quest support: 9752, 9785, 9803, 10009. Mark Of ... buffs. +SDComment: Quest support: 9752, 9785, Mark Of ... buffs. SDCategory: Zangarmarsh EndScriptData */ /* ContentData npcs_ashyen_and_keleth -npc_cooshcoosh -npc_elder_kuruti npc_kayra_longmane EndContentData */ @@ -157,159 +155,6 @@ public: }; /*###### -## npc_cooshcoosh -######*/ - -#define GOSSIP_COOSH "You owe Sim'salabim money. Hand them over or die!" - -enum Cooshhooosh -{ - SPELL_LIGHTNING_BOLT = 9532, - QUEST_CRACK_SKULLS = 10009 -}; - -class npc_cooshcoosh : public CreatureScript -{ -public: - npc_cooshcoosh() : CreatureScript("npc_cooshcoosh") { } - - struct npc_cooshcooshAI : public ScriptedAI - { - npc_cooshcooshAI(Creature* creature) : ScriptedAI(creature) - { - m_uiNormFaction = creature->GetFaction(); - Initialize(); - } - - void Initialize() - { - LightningBolt_Timer = 2000; - } - - uint32 m_uiNormFaction; - uint32 LightningBolt_Timer; - - void Reset() override - { - Initialize(); - if (me->GetFaction() != m_uiNormFaction) - me->SetFaction(m_uiNormFaction); - } - - void EnterCombat(Unit* /*who*/) override { } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - if (LightningBolt_Timer <= diff) - { - DoCastVictim(SPELL_LIGHTNING_BOLT); - LightningBolt_Timer = 5000; - } else LightningBolt_Timer -= diff; - - DoMeleeAttackIfReady(); - } - - bool GossipHello(Player* player) override - { - if (player->GetQuestStatus(QUEST_CRACK_SKULLS) == QUEST_STATUS_INCOMPLETE) - AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_COOSH, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - - SendGossipMenuFor(player, 9441, me->GetGUID()); - return true; - } - - bool GossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override - { - uint32 const action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId); - ClearGossipMenuFor(player); - if (action == GOSSIP_ACTION_INFO_DEF) - { - CloseGossipMenuFor(player); - me->SetFaction(FACTION_OGRE); - AttackStart(player); - } - return true; - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_cooshcooshAI(creature); - } -}; - -/*###### -## npc_elder_kuruti -######*/ - -#define GOSSIP_ITEM_KUR1 "Greetings, elder. It is time for your people to end their hostility towards the draenei and their allies." -#define GOSSIP_ITEM_KUR2 "I did not mean to deceive you, elder. The draenei of Telredor thought to approach you in a way that would seem familiar to you." -#define GOSSIP_ITEM_KUR3 "I will tell them. Farewell, elder." - -class npc_elder_kuruti : public CreatureScript -{ -public: - npc_elder_kuruti() : CreatureScript("npc_elder_kuruti") { } - - struct npc_elder_kurutiAI : public ScriptedAI - { - npc_elder_kurutiAI(Creature* creature) : ScriptedAI(creature) { } - - bool GossipHello(Player* player) override - { - if (player->GetQuestStatus(9803) == QUEST_STATUS_INCOMPLETE) - AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_ITEM_KUR1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - - SendGossipMenuFor(player, 9226, me->GetGUID()); - return true; - } - - bool GossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override - { - uint32 const action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId); - ClearGossipMenuFor(player); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF: - AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_ITEM_KUR2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - SendGossipMenuFor(player, 9227, me->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 1: - AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_ITEM_KUR3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - SendGossipMenuFor(player, 9229, me->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 2: - { - if (!player->HasItemCount(24573)) - { - ItemPosCountVec dest; - uint32 itemId = 24573; - InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemId, 1, nullptr); - if (msg == EQUIP_ERR_OK) - { - player->StoreNewItem(dest, itemId, true); - } - else - player->SendEquipError(msg, nullptr, nullptr, itemId); - } - SendGossipMenuFor(player, 9231, me->GetGUID()); - break; - } - } - return true; - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_elder_kurutiAI(creature); - } -}; - -/*###### ## npc_kayra_longmane ######*/ @@ -330,13 +175,13 @@ class npc_kayra_longmane : public CreatureScript public: npc_kayra_longmane() : CreatureScript("npc_kayra_longmane") { } - struct npc_kayra_longmaneAI : public npc_escortAI + struct npc_kayra_longmaneAI : public EscortAI { - npc_kayra_longmaneAI(Creature* creature) : npc_escortAI(creature) { } + npc_kayra_longmaneAI(Creature* creature) : EscortAI(creature) { } void Reset() override { } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override { Player* player = GetPlayerForEscort(); if (!player) @@ -391,7 +236,5 @@ public: void AddSC_zangarmarsh() { new npcs_ashyen_and_keleth(); - new npc_cooshcoosh(); - new npc_elder_kuruti(); new npc_kayra_longmane(); } diff --git a/src/server/scripts/Pet/pet_hunter.cpp b/src/server/scripts/Pet/pet_hunter.cpp index 20dcf5fb5d7..ed5f9ea48ed 100644 --- a/src/server/scripts/Pet/pet_hunter.cpp +++ b/src/server/scripts/Pet/pet_hunter.cpp @@ -236,7 +236,7 @@ class spell_pet_guard_dog : public SpellScriptLoader PreventDefaultAction(); Unit* caster = eventInfo.GetActor(); - caster->CastSpell((Unit*)nullptr, SPELL_PET_GUARD_DOG_HAPPINESS, true, nullptr, aurEff); + caster->CastSpell(nullptr, SPELL_PET_GUARD_DOG_HAPPINESS, true, nullptr, aurEff); float addThreat = CalculatePct(ASSERT_NOTNULL(eventInfo.GetSpellInfo())->Effects[EFFECT_0].CalcValue(caster), aurEff->GetAmount()); eventInfo.GetProcTarget()->GetThreatManager().AddThreat(caster, addThreat, GetSpellInfo(), false, true); @@ -288,7 +288,7 @@ class spell_pet_silverback : public SpellScriptLoader PreventDefaultAction(); uint32 spellId = triggerSpell[GetSpellInfo()->GetRank() - 1]; - eventInfo.GetActor()->CastSpell((Unit*)nullptr, spellId, true, nullptr, aurEff); + eventInfo.GetActor()->CastSpell(nullptr, spellId, true, nullptr, aurEff); } void Register() override diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp index bd2e36bc30f..1cbe0537563 100644 --- a/src/server/scripts/Spells/spell_dk.cpp +++ b/src/server/scripts/Spells/spell_dk.cpp @@ -1546,7 +1546,7 @@ class spell_dk_pvp_4p_bonus : public SpellScriptLoader void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) { PreventDefaultAction(); - eventInfo.GetActionTarget()->CastSpell((Unit*)nullptr, SPELL_DK_RUNIC_RETURN, true, nullptr, aurEff); + eventInfo.GetActionTarget()->CastSpell(nullptr, SPELL_DK_RUNIC_RETURN, true, nullptr, aurEff); } void Register() override diff --git a/src/server/scripts/Spells/spell_druid.cpp b/src/server/scripts/Spells/spell_druid.cpp index d57bd1e3008..0a4b7ae303e 100644 --- a/src/server/scripts/Spells/spell_druid.cpp +++ b/src/server/scripts/Spells/spell_druid.cpp @@ -495,7 +495,7 @@ class spell_dru_glyph_of_barkskin : public SpellScriptLoader void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) { PreventDefaultAction(); - eventInfo.GetActor()->CastSpell((Unit*)nullptr, SPELL_DRUID_BARKSKIN_01, true, nullptr, aurEff); + eventInfo.GetActor()->CastSpell(nullptr, SPELL_DRUID_BARKSKIN_01, true, nullptr, aurEff); } void Register() override @@ -1160,7 +1160,7 @@ class spell_dru_omen_of_clarity : public SpellScriptLoader { Unit* target = GetTarget(); if (target->HasAura(SPELL_DRUID_BALANCE_T10_BONUS)) - target->CastSpell((Unit*)nullptr, SPELL_DRUID_BALANCE_T10_BONUS_PROC, true, nullptr, aurEff); + target->CastSpell(nullptr, SPELL_DRUID_BALANCE_T10_BONUS_PROC, true, nullptr, aurEff); } void Register() override @@ -1874,7 +1874,7 @@ class spell_dru_t4_2p_bonus : public SpellScriptLoader void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) { PreventDefaultAction(); - eventInfo.GetActor()->CastSpell((Unit*)nullptr, SPELL_DRUID_INFUSION, true, nullptr, aurEff); + eventInfo.GetActor()->CastSpell(nullptr, SPELL_DRUID_INFUSION, true, nullptr, aurEff); } void Register() override @@ -1940,7 +1940,7 @@ class spell_dru_item_t6_trinket : public SpellScriptLoader return; if (roll_chance_i(chance)) - eventInfo.GetActor()->CastSpell((Unit*)nullptr, spellId, true, nullptr, aurEff); + eventInfo.GetActor()->CastSpell(nullptr, spellId, true, nullptr, aurEff); } void Register() override diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index cbec8270e18..1b06b8c3a4a 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -42,39 +42,28 @@ #include "SpellScript.h" #include "Vehicle.h" -class spell_gen_absorb0_hitlimit1 : public SpellScriptLoader +class spell_gen_absorb0_hitlimit1 : public AuraScript { - public: - spell_gen_absorb0_hitlimit1() : SpellScriptLoader("spell_gen_absorb0_hitlimit1") { } - - class spell_gen_absorb0_hitlimit1_AuraScript : public AuraScript - { - PrepareAuraScript(spell_gen_absorb0_hitlimit1_AuraScript); - - uint32 limit = 0; + PrepareAuraScript(spell_gen_absorb0_hitlimit1); - bool Load() override - { - // Max absorb stored in 1 dummy effect - limit = GetSpellInfo()->Effects[EFFECT_1].CalcValue(); - return true; - } + uint32 limit = 0; - void Absorb(AuraEffect* /*aurEff*/, DamageInfo& /*dmgInfo*/, uint32& absorbAmount) - { - absorbAmount = std::min(limit, absorbAmount); - } + bool Load() override + { + // Max absorb stored in 1 dummy effect + limit = GetSpellInfo()->Effects[EFFECT_1].CalcValue(); + return true; + } - void Register() override - { - OnEffectAbsorb += AuraEffectAbsorbFn(spell_gen_absorb0_hitlimit1_AuraScript::Absorb, EFFECT_0); - } - }; + void Absorb(AuraEffect* /*aurEff*/, DamageInfo& /*dmgInfo*/, uint32& absorbAmount) + { + absorbAmount = std::min(limit, absorbAmount); + } - AuraScript* GetAuraScript() const override - { - return new spell_gen_absorb0_hitlimit1_AuraScript(); - } + void Register() override + { + OnEffectAbsorb += AuraEffectAbsorbFn(spell_gen_absorb0_hitlimit1::Absorb, EFFECT_0); + } }; // 28764 - Adaptive Warding (Frostfire Regalia Set) @@ -87,115 +76,93 @@ enum AdaptiveWarding SPELL_GEN_ADAPTIVE_WARDING_ARCANE = 28770 }; -class spell_gen_adaptive_warding : public SpellScriptLoader +class spell_gen_adaptive_warding : public AuraScript { - public: - spell_gen_adaptive_warding() : SpellScriptLoader("spell_gen_adaptive_warding") { } - - class spell_gen_adaptive_warding_AuraScript : public AuraScript - { - PrepareAuraScript(spell_gen_adaptive_warding_AuraScript); + PrepareAuraScript(spell_gen_adaptive_warding); - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_GEN_ADAPTIVE_WARDING_FIRE, - SPELL_GEN_ADAPTIVE_WARDING_NATURE, - SPELL_GEN_ADAPTIVE_WARDING_FROST, - SPELL_GEN_ADAPTIVE_WARDING_SHADOW, - SPELL_GEN_ADAPTIVE_WARDING_ARCANE - }); - } - - bool CheckProc(ProcEventInfo& eventInfo) - { - DamageInfo* damageInfo = eventInfo.GetDamageInfo(); - if (!damageInfo || !damageInfo->GetSpellInfo()) - return false; - - // find Mage Armor - if (!GetTarget()->GetAuraEffect(SPELL_AURA_MOD_MANA_REGEN_INTERRUPT, SPELLFAMILY_MAGE, 0x10000000, 0x0, 0x0)) - return false; - - switch (GetFirstSchoolInMask(eventInfo.GetSchoolMask())) - { - case SPELL_SCHOOL_NORMAL: - case SPELL_SCHOOL_HOLY: - return false; - default: - break; - } - return true; - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( + { + SPELL_GEN_ADAPTIVE_WARDING_FIRE, + SPELL_GEN_ADAPTIVE_WARDING_NATURE, + SPELL_GEN_ADAPTIVE_WARDING_FROST, + SPELL_GEN_ADAPTIVE_WARDING_SHADOW, + SPELL_GEN_ADAPTIVE_WARDING_ARCANE + }); + } - uint32 spellId = 0; - switch (GetFirstSchoolInMask(eventInfo.GetSchoolMask())) - { - case SPELL_SCHOOL_FIRE: - spellId = SPELL_GEN_ADAPTIVE_WARDING_FIRE; - break; - case SPELL_SCHOOL_NATURE: - spellId = SPELL_GEN_ADAPTIVE_WARDING_NATURE; - break; - case SPELL_SCHOOL_FROST: - spellId = SPELL_GEN_ADAPTIVE_WARDING_FROST; - break; - case SPELL_SCHOOL_SHADOW: - spellId = SPELL_GEN_ADAPTIVE_WARDING_SHADOW; - break; - case SPELL_SCHOOL_ARCANE: - spellId = SPELL_GEN_ADAPTIVE_WARDING_ARCANE; - break; - default: - return; - } - GetTarget()->CastSpell(GetTarget(), spellId, true, nullptr, aurEff); - } + bool CheckProc(ProcEventInfo& eventInfo) + { + DamageInfo* damageInfo = eventInfo.GetDamageInfo(); + if (!damageInfo || !damageInfo->GetSpellInfo()) + return false; - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_gen_adaptive_warding_AuraScript::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_gen_adaptive_warding_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } - }; + // find Mage Armor + if (!GetTarget()->GetAuraEffect(SPELL_AURA_MOD_MANA_REGEN_INTERRUPT, SPELLFAMILY_MAGE, 0x10000000, 0x0, 0x0)) + return false; - AuraScript* GetAuraScript() const override + switch (GetFirstSchoolInMask(eventInfo.GetSchoolMask())) { - return new spell_gen_adaptive_warding_AuraScript(); + case SPELL_SCHOOL_NORMAL: + case SPELL_SCHOOL_HOLY: + return false; + default: + break; } -}; + return true; + } -class spell_gen_allow_cast_from_item_only : public SpellScriptLoader -{ - public: - spell_gen_allow_cast_from_item_only() : SpellScriptLoader("spell_gen_allow_cast_from_item_only") { } + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + uint32 spellId = 0; + switch (GetFirstSchoolInMask(eventInfo.GetSchoolMask())) + { + case SPELL_SCHOOL_FIRE: + spellId = SPELL_GEN_ADAPTIVE_WARDING_FIRE; + break; + case SPELL_SCHOOL_NATURE: + spellId = SPELL_GEN_ADAPTIVE_WARDING_NATURE; + break; + case SPELL_SCHOOL_FROST: + spellId = SPELL_GEN_ADAPTIVE_WARDING_FROST; + break; + case SPELL_SCHOOL_SHADOW: + spellId = SPELL_GEN_ADAPTIVE_WARDING_SHADOW; + break; + case SPELL_SCHOOL_ARCANE: + spellId = SPELL_GEN_ADAPTIVE_WARDING_ARCANE; + break; + default: + return; + } + GetTarget()->CastSpell(GetTarget(), spellId, true, nullptr, aurEff); + } - class spell_gen_allow_cast_from_item_only_SpellScript : public SpellScript - { - PrepareSpellScript(spell_gen_allow_cast_from_item_only_SpellScript); + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_gen_adaptive_warding::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_gen_adaptive_warding::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; - SpellCastResult CheckRequirement() - { - if (!GetCastItem()) - return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW; - return SPELL_CAST_OK; - } +class spell_gen_allow_cast_from_item_only : public SpellScript +{ + PrepareSpellScript(spell_gen_allow_cast_from_item_only); - void Register() override - { - OnCheckCast += SpellCheckCastFn(spell_gen_allow_cast_from_item_only_SpellScript::CheckRequirement); - } - }; + SpellCastResult CheckRequirement() + { + if (!GetCastItem()) + return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW; + return SPELL_CAST_OK; + } - SpellScript* GetSpellScript() const override - { - return new spell_gen_allow_cast_from_item_only_SpellScript(); - } + void Register() override + { + OnCheckCast += SpellCheckCastFn(spell_gen_allow_cast_from_item_only::CheckRequirement); + } }; enum AnimalBloodPoolSpell @@ -204,74 +171,52 @@ enum AnimalBloodPoolSpell SPELL_SPAWN_BLOOD_POOL = 63471 }; -class spell_gen_animal_blood : public SpellScriptLoader +class spell_gen_animal_blood : public AuraScript { - public: - spell_gen_animal_blood() : SpellScriptLoader("spell_gen_animal_blood") { } - - class spell_gen_animal_blood_AuraScript : public AuraScript - { - PrepareAuraScript(spell_gen_animal_blood_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_SPAWN_BLOOD_POOL }); - } + PrepareAuraScript(spell_gen_animal_blood); - void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - // Remove all auras with spell id 46221, except the one currently being applied - while (Aura* aur = GetUnitOwner()->GetOwnedAura(SPELL_ANIMAL_BLOOD, ObjectGuid::Empty, ObjectGuid::Empty, 0, GetAura())) - GetUnitOwner()->RemoveOwnedAura(aur); - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SPAWN_BLOOD_POOL }); + } - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - if (Unit* owner = GetUnitOwner()) - if (owner->IsInWater()) - owner->CastSpell(owner, SPELL_SPAWN_BLOOD_POOL, true); - } + void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + // Remove all auras with spell id 46221, except the one currently being applied + while (Aura* aur = GetUnitOwner()->GetOwnedAura(SPELL_ANIMAL_BLOOD, ObjectGuid::Empty, ObjectGuid::Empty, 0, GetAura())) + GetUnitOwner()->RemoveOwnedAura(aur); + } - void Register() override - { - AfterEffectApply += AuraEffectRemoveFn(spell_gen_animal_blood_AuraScript::OnApply, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL); - AfterEffectRemove += AuraEffectRemoveFn(spell_gen_animal_blood_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL); - } - }; + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Unit* owner = GetUnitOwner()) + if (owner->IsInWater()) + owner->CastSpell(owner, SPELL_SPAWN_BLOOD_POOL, true); + } - AuraScript* GetAuraScript() const override - { - return new spell_gen_animal_blood_AuraScript(); - } + void Register() override + { + AfterEffectApply += AuraEffectRemoveFn(spell_gen_animal_blood::OnApply, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL); + AfterEffectRemove += AuraEffectRemoveFn(spell_gen_animal_blood::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL); + } }; // 41337 Aura of Anger -class spell_gen_aura_of_anger : public SpellScriptLoader +class spell_gen_aura_of_anger : public AuraScript { - public: - spell_gen_aura_of_anger() : SpellScriptLoader("spell_gen_aura_of_anger") { } - - class spell_gen_aura_of_anger_AuraScript : public AuraScript - { - PrepareAuraScript(spell_gen_aura_of_anger_AuraScript); - - void HandleEffectPeriodicUpdate(AuraEffect* aurEff) - { - if (AuraEffect* aurEff1 = aurEff->GetBase()->GetEffect(EFFECT_1)) - aurEff1->ChangeAmount(aurEff1->GetAmount() + 5); - aurEff->SetAmount(100 * aurEff->GetTickNumber()); - } + PrepareAuraScript(spell_gen_aura_of_anger); - void Register() override - { - OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_gen_aura_of_anger_AuraScript::HandleEffectPeriodicUpdate, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE); - } - }; + void HandleEffectPeriodicUpdate(AuraEffect* aurEff) + { + if (AuraEffect* aurEff1 = aurEff->GetBase()->GetEffect(EFFECT_1)) + aurEff1->ChangeAmount(aurEff1->GetAmount() + 5); + aurEff->SetAmount(100 * aurEff->GetTickNumber()); + } - AuraScript* GetAuraScript() const override - { - return new spell_gen_aura_of_anger_AuraScript(); - } + void Register() override + { + OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_gen_aura_of_anger::HandleEffectPeriodicUpdate, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE); + } }; enum ServiceUniform @@ -284,94 +229,72 @@ enum ServiceUniform MODEL_GOBLIN_FEMALE = 31003 }; -class spell_gen_aura_service_uniform : public SpellScriptLoader +class spell_gen_aura_service_uniform : public AuraScript { - public: - spell_gen_aura_service_uniform() : SpellScriptLoader("spell_gen_aura_service_uniform") { } - - class spell_gen_aura_service_uniform_AuraScript : public AuraScript - { - PrepareAuraScript(spell_gen_aura_service_uniform_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_SERVICE_UNIFORM }); - } - - void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - // Apply model goblin - Unit* target = GetTarget(); - if (target->GetTypeId() == TYPEID_PLAYER) - { - if (target->getGender() == GENDER_MALE) - target->SetDisplayId(MODEL_GOBLIN_MALE); - else - target->SetDisplayId(MODEL_GOBLIN_FEMALE); - } - } + PrepareAuraScript(spell_gen_aura_service_uniform); - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - Unit* target = GetTarget(); - if (target->GetTypeId() == TYPEID_PLAYER) - target->RestoreDisplayId(); - } - - void Register() override - { - AfterEffectApply += AuraEffectRemoveFn(spell_gen_aura_service_uniform_AuraScript::OnApply, EFFECT_0, SPELL_AURA_TRANSFORM, AURA_EFFECT_HANDLE_REAL); - AfterEffectRemove += AuraEffectRemoveFn(spell_gen_aura_service_uniform_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_TRANSFORM, AURA_EFFECT_HANDLE_REAL); - } - }; + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SERVICE_UNIFORM }); + } - AuraScript* GetAuraScript() const override + void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + // Apply model goblin + Unit* target = GetTarget(); + if (target->GetTypeId() == TYPEID_PLAYER) { - return new spell_gen_aura_service_uniform_AuraScript(); + if (target->getGender() == GENDER_MALE) + target->SetDisplayId(MODEL_GOBLIN_MALE); + else + target->SetDisplayId(MODEL_GOBLIN_FEMALE); } -}; - -class spell_gen_av_drekthar_presence : public SpellScriptLoader -{ - public: - spell_gen_av_drekthar_presence() : SpellScriptLoader("spell_gen_av_drekthar_presence") { } + } - class spell_gen_av_drekthar_presence_AuraScript : public AuraScript - { - PrepareAuraScript(spell_gen_av_drekthar_presence_AuraScript); + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + if (target->GetTypeId() == TYPEID_PLAYER) + target->RestoreDisplayId(); + } - bool CheckAreaTarget(Unit* target) - { - switch (target->GetEntry()) - { - // alliance - case 14762: // Dun Baldar North Marshal - case 14763: // Dun Baldar South Marshal - case 14764: // Icewing Marshal - case 14765: // Stonehearth Marshal - case 11948: // Vandar Stormspike - // horde - case 14772: // East Frostwolf Warmaster - case 14776: // Tower Point Warmaster - case 14773: // Iceblood Warmaster - case 14777: // West Frostwolf Warmaster - case 11946: // Drek'thar - return true; - default: - return false; - } - } + void Register() override + { + AfterEffectApply += AuraEffectRemoveFn(spell_gen_aura_service_uniform::OnApply, EFFECT_0, SPELL_AURA_TRANSFORM, AURA_EFFECT_HANDLE_REAL); + AfterEffectRemove += AuraEffectRemoveFn(spell_gen_aura_service_uniform::OnRemove, EFFECT_0, SPELL_AURA_TRANSFORM, AURA_EFFECT_HANDLE_REAL); + } +}; - void Register() override - { - DoCheckAreaTarget += AuraCheckAreaTargetFn(spell_gen_av_drekthar_presence_AuraScript::CheckAreaTarget); - } - }; +class spell_gen_av_drekthar_presence : public AuraScript +{ + PrepareAuraScript(spell_gen_av_drekthar_presence); - AuraScript* GetAuraScript() const override - { - return new spell_gen_av_drekthar_presence_AuraScript(); + bool CheckAreaTarget(Unit* target) + { + switch (target->GetEntry()) + { + // alliance + case 14762: // Dun Baldar North Marshal + case 14763: // Dun Baldar South Marshal + case 14764: // Icewing Marshal + case 14765: // Stonehearth Marshal + case 11948: // Vandar Stormspike + // horde + case 14772: // East Frostwolf Warmaster + case 14776: // Tower Point Warmaster + case 14773: // Iceblood Warmaster + case 14777: // West Frostwolf Warmaster + case 11946: // Drek'thar + return true; + default: + return false; } + } + + void Register() override + { + DoCheckAreaTarget += AuraCheckAreaTargetFn(spell_gen_av_drekthar_presence::CheckAreaTarget); + } }; enum GenericBandage @@ -379,47 +302,36 @@ enum GenericBandage SPELL_RECENTLY_BANDAGED = 11196 }; -class spell_gen_bandage : public SpellScriptLoader +class spell_gen_bandage : public SpellScript { - public: - spell_gen_bandage() : SpellScriptLoader("spell_gen_bandage") { } - - class spell_gen_bandage_SpellScript : public SpellScript - { - PrepareSpellScript(spell_gen_bandage_SpellScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_RECENTLY_BANDAGED }); - } - - SpellCastResult CheckCast() - { - if (Unit* target = GetExplTargetUnit()) - { - if (target->HasAura(SPELL_RECENTLY_BANDAGED)) - return SPELL_FAILED_TARGET_AURASTATE; - } - return SPELL_CAST_OK; - } - - void HandleScript() - { - if (Unit* target = GetHitUnit()) - GetCaster()->CastSpell(target, SPELL_RECENTLY_BANDAGED, true); - } + PrepareSpellScript(spell_gen_bandage); - void Register() override - { - OnCheckCast += SpellCheckCastFn(spell_gen_bandage_SpellScript::CheckCast); - AfterHit += SpellHitFn(spell_gen_bandage_SpellScript::HandleScript); - } - }; + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_RECENTLY_BANDAGED }); + } - SpellScript* GetSpellScript() const override + SpellCastResult CheckCast() + { + if (Unit* target = GetExplTargetUnit()) { - return new spell_gen_bandage_SpellScript(); + if (target->HasAura(SPELL_RECENTLY_BANDAGED)) + return SPELL_FAILED_TARGET_AURASTATE; } + return SPELL_CAST_OK; + } + + void HandleScript() + { + if (Unit* target = GetHitUnit()) + GetCaster()->CastSpell(target, SPELL_RECENTLY_BANDAGED, true); + } + + void Register() override + { + OnCheckCast += SpellCheckCastFn(spell_gen_bandage::CheckCast); + AfterHit += SpellHitFn(spell_gen_bandage::HandleScript); + } }; // Blood Reserve - 64568 @@ -429,50 +341,39 @@ enum BloodReserve SPELL_GEN_BLOOD_RESERVE_HEAL = 64569 }; -class spell_gen_blood_reserve : public SpellScriptLoader +class spell_gen_blood_reserve : public AuraScript { - public: - spell_gen_blood_reserve() : SpellScriptLoader("spell_gen_blood_reserve") { } - - class spell_gen_blood_reserve_AuraScript : public AuraScript - { - PrepareAuraScript(spell_gen_blood_reserve_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_GEN_BLOOD_RESERVE_HEAL }); - } + PrepareAuraScript(spell_gen_blood_reserve); - bool CheckProc(ProcEventInfo& eventInfo) - { - if (DamageInfo* dmgInfo = eventInfo.GetDamageInfo()) - if (Unit* caster = eventInfo.GetActionTarget()) - if (caster->HealthBelowPctDamaged(35, dmgInfo->GetDamage())) - return true; + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_GEN_BLOOD_RESERVE_HEAL }); + } - return false; - } + bool CheckProc(ProcEventInfo& eventInfo) + { + if (DamageInfo* dmgInfo = eventInfo.GetDamageInfo()) + if (Unit* caster = eventInfo.GetActionTarget()) + if (caster->HealthBelowPctDamaged(35, dmgInfo->GetDamage())) + return true; - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); + return false; + } - Unit* caster = eventInfo.GetActionTarget(); - caster->CastCustomSpell(SPELL_GEN_BLOOD_RESERVE_HEAL, SPELLVALUE_BASE_POINT0, aurEff->GetAmount(), caster, TRIGGERED_FULL_MASK, nullptr, aurEff); - caster->RemoveAura(SPELL_GEN_BLOOD_RESERVE_AURA); - } + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_gen_blood_reserve_AuraScript::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_gen_blood_reserve_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } - }; + Unit* caster = eventInfo.GetActionTarget(); + caster->CastCustomSpell(SPELL_GEN_BLOOD_RESERVE_HEAL, SPELLVALUE_BASE_POINT0, aurEff->GetAmount(), caster, TRIGGERED_FULL_MASK, nullptr, aurEff); + caster->RemoveAura(SPELL_GEN_BLOOD_RESERVE_AURA); + } - AuraScript* GetAuraScript() const override - { - return new spell_gen_blood_reserve_AuraScript(); - } + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_gen_blood_reserve::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_gen_blood_reserve::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } }; // Blade Warding - 64440 @@ -481,46 +382,35 @@ enum BladeWarding SPELL_GEN_BLADE_WARDING_TRIGGERED = 64442 }; -class spell_gen_blade_warding : public SpellScriptLoader +class spell_gen_blade_warding : public AuraScript { - public: - spell_gen_blade_warding() : SpellScriptLoader("spell_gen_blade_warding") { } + PrepareAuraScript(spell_gen_blade_warding); - class spell_gen_blade_warding_AuraScript : public AuraScript - { - PrepareAuraScript(spell_gen_blade_warding_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_GEN_BLADE_WARDING_TRIGGERED }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_GEN_BLADE_WARDING_TRIGGERED }); + } - Unit* caster = eventInfo.GetActionTarget(); - SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(SPELL_GEN_BLADE_WARDING_TRIGGERED); + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); - uint8 stacks = GetStackAmount(); - int32 bp = 0; + Unit* caster = eventInfo.GetActionTarget(); + SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(SPELL_GEN_BLADE_WARDING_TRIGGERED); - for (uint8 i = 0; i < stacks; ++i) - bp += spellInfo->Effects[EFFECT_0].CalcValue(caster); + uint8 stacks = GetStackAmount(); + int32 bp = 0; - caster->CastCustomSpell(SPELL_GEN_BLADE_WARDING_TRIGGERED, SPELLVALUE_BASE_POINT0, bp, eventInfo.GetActor(), TRIGGERED_FULL_MASK, nullptr, aurEff); - } + for (uint8 i = 0; i < stacks; ++i) + bp += spellInfo->Effects[EFFECT_0].CalcValue(caster); - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_gen_blade_warding_AuraScript::HandleProc, EFFECT_1, SPELL_AURA_PROC_TRIGGER_SPELL); - } - }; + caster->CastCustomSpell(SPELL_GEN_BLADE_WARDING_TRIGGERED, SPELLVALUE_BASE_POINT0, bp, eventInfo.GetActor(), TRIGGERED_FULL_MASK, nullptr, aurEff); + } - AuraScript* GetAuraScript() const override - { - return new spell_gen_blade_warding_AuraScript(); - } + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_gen_blade_warding::HandleProc, EFFECT_1, SPELL_AURA_PROC_TRIGGER_SPELL); + } }; enum Bonked @@ -530,42 +420,31 @@ enum Bonked SPELL_ON_GUARD = 62972 }; -class spell_gen_bonked : public SpellScriptLoader +class spell_gen_bonked : public SpellScript { - public: - spell_gen_bonked() : SpellScriptLoader("spell_gen_bonked") { } + PrepareSpellScript(spell_gen_bonked); - class spell_gen_bonked_SpellScript : public SpellScript + void HandleScript(SpellEffIndex /*effIndex*/) + { + if (Player* target = GetHitPlayer()) { - PrepareSpellScript(spell_gen_bonked_SpellScript); - - void HandleScript(SpellEffIndex /*effIndex*/) - { - if (Player* target = GetHitPlayer()) - { - Aura const* aura = GetHitAura(); - if (!(aura && aura->GetStackAmount() == 3)) - return; - - target->CastSpell(target, SPELL_FOAM_SWORD_DEFEAT, true); - target->RemoveAurasDueToSpell(SPELL_BONKED); - - if (Aura const* auraOnGuard = target->GetAura(SPELL_ON_GUARD)) - if (Item* item = target->GetItemByGuid(auraOnGuard->GetCastItemGUID())) - target->DestroyItemCount(item->GetEntry(), 1, true); - } - } + Aura const* aura = GetHitAura(); + if (!(aura && aura->GetStackAmount() == 3)) + return; - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_gen_bonked_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); - } - }; + target->CastSpell(target, SPELL_FOAM_SWORD_DEFEAT, true); + target->RemoveAurasDueToSpell(SPELL_BONKED); - SpellScript* GetSpellScript() const override - { - return new spell_gen_bonked_SpellScript(); + if (Aura const* auraOnGuard = target->GetAura(SPELL_ON_GUARD)) + if (Item* item = target->GetItemByGuid(auraOnGuard->GetCastItemGUID())) + target->DestroyItemCount(item->GetEntry(), 1, true); } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_gen_bonked::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); + } }; /* DOCUMENTATION: Break-Shield spells @@ -678,70 +557,48 @@ class spell_gen_break_shield: public SpellScriptLoader }; // 46394 Brutallus Burn -class spell_gen_burn_brutallus : public SpellScriptLoader +class spell_gen_burn_brutallus : public AuraScript { - public: - spell_gen_burn_brutallus() : SpellScriptLoader("spell_gen_burn_brutallus") { } - - class spell_gen_burn_brutallus_AuraScript : public AuraScript - { - PrepareAuraScript(spell_gen_burn_brutallus_AuraScript); - - void HandleEffectPeriodicUpdate(AuraEffect* aurEff) - { - if (aurEff->GetTickNumber() % 11 == 0) - aurEff->SetAmount(aurEff->GetAmount() * 2); - } + PrepareAuraScript(spell_gen_burn_brutallus); - void Register() override - { - OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_gen_burn_brutallus_AuraScript::HandleEffectPeriodicUpdate, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE); - } - }; + void HandleEffectPeriodicUpdate(AuraEffect* aurEff) + { + if (aurEff->GetTickNumber() % 11 == 0) + aurEff->SetAmount(aurEff->GetAmount() * 2); + } - AuraScript* GetAuraScript() const override - { - return new spell_gen_burn_brutallus_AuraScript(); - } + void Register() override + { + OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_gen_burn_brutallus::HandleEffectPeriodicUpdate, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE); + } }; // 48750 - Burning Depths Necrolyte Image -class spell_gen_burning_depths_necrolyte_image : public SpellScriptLoader +class spell_gen_burning_depths_necrolyte_image : public AuraScript { - public: - spell_gen_burning_depths_necrolyte_image() : SpellScriptLoader("spell_gen_burning_depths_necrolyte_image") { } - - class spell_gen_burning_depths_necrolyte_image_AuraScript : public AuraScript - { - PrepareAuraScript(spell_gen_burning_depths_necrolyte_image_AuraScript); - - bool Validate(SpellInfo const* spellInfo) override - { - return ValidateSpellInfo({ static_cast<uint32>(spellInfo->Effects[EFFECT_2].CalcValue()) }); - } + PrepareAuraScript(spell_gen_burning_depths_necrolyte_image); - void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - if (Unit* caster = GetCaster()) - caster->CastSpell(GetTarget(), uint32(GetSpellInfo()->Effects[EFFECT_2].CalcValue())); - } + bool Validate(SpellInfo const* spellInfo) override + { + return ValidateSpellInfo({ static_cast<uint32>(spellInfo->Effects[EFFECT_2].CalcValue()) }); + } - void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - GetTarget()->RemoveAurasDueToSpell(uint32(GetSpellInfo()->Effects[EFFECT_2].CalcValue()), GetCasterGUID()); - } + void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Unit* caster = GetCaster()) + caster->CastSpell(GetTarget(), uint32(GetSpellInfo()->Effects[EFFECT_2].CalcValue())); + } - void Register() override - { - AfterEffectApply += AuraEffectApplyFn(spell_gen_burning_depths_necrolyte_image_AuraScript::HandleApply, EFFECT_0, SPELL_AURA_TRANSFORM, AURA_EFFECT_HANDLE_REAL); - AfterEffectRemove += AuraEffectRemoveFn(spell_gen_burning_depths_necrolyte_image_AuraScript::HandleRemove, EFFECT_0, SPELL_AURA_TRANSFORM, AURA_EFFECT_HANDLE_REAL); - } - }; + void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->RemoveAurasDueToSpell(uint32(GetSpellInfo()->Effects[EFFECT_2].CalcValue()), GetCasterGUID()); + } - AuraScript* GetAuraScript() const override - { - return new spell_gen_burning_depths_necrolyte_image_AuraScript(); - } + void Register() override + { + AfterEffectApply += AuraEffectApplyFn(spell_gen_burning_depths_necrolyte_image::HandleApply, EFFECT_0, SPELL_AURA_TRANSFORM, AURA_EFFECT_HANDLE_REAL); + AfterEffectRemove += AuraEffectRemoveFn(spell_gen_burning_depths_necrolyte_image::HandleRemove, EFFECT_0, SPELL_AURA_TRANSFORM, AURA_EFFECT_HANDLE_REAL); + } }; enum CannibalizeSpells @@ -749,52 +606,41 @@ enum CannibalizeSpells SPELL_CANNIBALIZE_TRIGGERED = 20578 }; -class spell_gen_cannibalize : public SpellScriptLoader +class spell_gen_cannibalize : public SpellScript { - public: - spell_gen_cannibalize() : SpellScriptLoader("spell_gen_cannibalize") { } + PrepareSpellScript(spell_gen_cannibalize); - class spell_gen_cannibalize_SpellScript : public SpellScript - { - PrepareSpellScript(spell_gen_cannibalize_SpellScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_CANNIBALIZE_TRIGGERED }); - } - - SpellCastResult CheckIfCorpseNear() - { - Unit* caster = GetCaster(); - float max_range = GetSpellInfo()->GetMaxRange(false); - WorldObject* result = nullptr; - // search for nearby enemy corpse in range - Trinity::AnyDeadUnitSpellTargetInRangeCheck check(caster, max_range, GetSpellInfo(), TARGET_CHECK_ENEMY); - Trinity::WorldObjectSearcher<Trinity::AnyDeadUnitSpellTargetInRangeCheck> searcher(caster, result, check); - Cell::VisitWorldObjects(caster, searcher, max_range); - if (!result) - Cell::VisitGridObjects(caster, searcher, max_range); - if (!result) - return SPELL_FAILED_NO_EDIBLE_CORPSES; - return SPELL_CAST_OK; - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_CANNIBALIZE_TRIGGERED }); + } - void HandleDummy(SpellEffIndex /*effIndex*/) - { - GetCaster()->CastSpell(GetCaster(), SPELL_CANNIBALIZE_TRIGGERED, false); - } + SpellCastResult CheckIfCorpseNear() + { + Unit* caster = GetCaster(); + float max_range = GetSpellInfo()->GetMaxRange(false); + WorldObject* result = nullptr; + // search for nearby enemy corpse in range + Trinity::AnyDeadUnitSpellTargetInRangeCheck check(caster, max_range, GetSpellInfo(), TARGET_CHECK_ENEMY); + Trinity::WorldObjectSearcher<Trinity::AnyDeadUnitSpellTargetInRangeCheck> searcher(caster, result, check); + Cell::VisitWorldObjects(caster, searcher, max_range); + if (!result) + Cell::VisitGridObjects(caster, searcher, max_range); + if (!result) + return SPELL_FAILED_NO_EDIBLE_CORPSES; + return SPELL_CAST_OK; + } - void Register() override - { - OnEffectHit += SpellEffectFn(spell_gen_cannibalize_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - OnCheckCast += SpellCheckCastFn(spell_gen_cannibalize_SpellScript::CheckIfCorpseNear); - } - }; + void HandleDummy(SpellEffIndex /*effIndex*/) + { + GetCaster()->CastSpell(GetCaster(), SPELL_CANNIBALIZE_TRIGGERED, false); + } - SpellScript* GetSpellScript() const override - { - return new spell_gen_cannibalize_SpellScript(); - } + void Register() override + { + OnEffectHit += SpellEffectFn(spell_gen_cannibalize::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnCheckCast += SpellCheckCastFn(spell_gen_cannibalize::CheckIfCorpseNear); + } }; enum ChaosBlast @@ -802,65 +648,43 @@ enum ChaosBlast SPELL_CHAOS_BLAST = 37675 }; -class spell_gen_chaos_blast : public SpellScriptLoader +class spell_gen_chaos_blast : public SpellScript { - public: - spell_gen_chaos_blast() : SpellScriptLoader("spell_gen_chaos_blast") { } - - class spell_gen_chaos_blast_SpellScript : public SpellScript - { - PrepareSpellScript(spell_gen_chaos_blast_SpellScript); + PrepareSpellScript(spell_gen_chaos_blast); - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_CHAOS_BLAST }); - } - void HandleDummy(SpellEffIndex /* effIndex */) - { - int32 basepoints0 = 100; - Unit* caster = GetCaster(); - if (Unit* target = GetHitUnit()) - caster->CastCustomSpell(target, SPELL_CHAOS_BLAST, &basepoints0, nullptr, nullptr, true); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_gen_chaos_blast_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_CHAOS_BLAST }); + } + void HandleDummy(SpellEffIndex /* effIndex */) + { + int32 basepoints0 = 100; + Unit* caster = GetCaster(); + if (Unit* target = GetHitUnit()) + caster->CastCustomSpell(target, SPELL_CHAOS_BLAST, &basepoints0, nullptr, nullptr, true); + } - SpellScript* GetSpellScript() const override - { - return new spell_gen_chaos_blast_SpellScript(); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_gen_chaos_blast::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; -class spell_gen_clone : public SpellScriptLoader +class spell_gen_clone : public SpellScript { - public: - spell_gen_clone() : SpellScriptLoader("spell_gen_clone") { } - - class spell_gen_clone_SpellScript : public SpellScript - { - PrepareSpellScript(spell_gen_clone_SpellScript); + PrepareSpellScript(spell_gen_clone); - void HandleScriptEffect(SpellEffIndex effIndex) - { - PreventHitDefaultEffect(effIndex); - GetHitUnit()->CastSpell(GetCaster(), uint32(GetEffectValue()), true); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_gen_clone_SpellScript::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); - OnEffectHitTarget += SpellEffectFn(spell_gen_clone_SpellScript::HandleScriptEffect, EFFECT_2, SPELL_EFFECT_SCRIPT_EFFECT); - } - }; + void HandleScriptEffect(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + GetHitUnit()->CastSpell(GetCaster(), uint32(GetEffectValue()), true); + } - SpellScript* GetSpellScript() const override - { - return new spell_gen_clone_SpellScript(); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_gen_clone::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_gen_clone::HandleScriptEffect, EFFECT_2, SPELL_EFFECT_SCRIPT_EFFECT); + } }; enum CloneWeaponSpells @@ -875,147 +699,125 @@ enum CloneWeaponSpells SPELL_COPY_RANGED_AURA = 57594 }; -class spell_gen_clone_weapon : public SpellScriptLoader +class spell_gen_clone_weapon : public SpellScript { - public: - spell_gen_clone_weapon() : SpellScriptLoader("spell_gen_clone_weapon") { } - - class spell_gen_clone_weapon_SpellScript : public SpellScript - { - PrepareSpellScript(spell_gen_clone_weapon_SpellScript); - - void HandleScriptEffect(SpellEffIndex effIndex) - { - PreventHitDefaultEffect(effIndex); - GetHitUnit()->CastSpell(GetCaster(), uint32(GetEffectValue()), true); - } + PrepareSpellScript(spell_gen_clone_weapon); - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_gen_clone_weapon_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - } - }; + void HandleScriptEffect(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + GetHitUnit()->CastSpell(GetCaster(), uint32(GetEffectValue()), true); + } - SpellScript* GetSpellScript() const override - { - return new spell_gen_clone_weapon_SpellScript(); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_gen_clone_weapon::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } }; -class spell_gen_clone_weapon_aura : public SpellScriptLoader +class spell_gen_clone_weapon_aura : public AuraScript { - public: - spell_gen_clone_weapon_aura() : SpellScriptLoader("spell_gen_clone_weapon_aura") { } + PrepareAuraScript(spell_gen_clone_weapon_aura); - class spell_gen_clone_weapon_auraScript : public AuraScript - { - PrepareAuraScript(spell_gen_clone_weapon_auraScript); + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( + { + SPELL_COPY_WEAPON_AURA, + SPELL_COPY_WEAPON_2_AURA, + SPELL_COPY_WEAPON_3_AURA, + SPELL_COPY_OFFHAND_AURA, + SPELL_COPY_OFFHAND_2_AURA, + SPELL_COPY_RANGED_AURA + }); + } - bool Validate(SpellInfo const* /*spellInfo*/) override + void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* caster = GetCaster(); + Unit* target = GetTarget(); + if (!caster) + return; + + switch (GetSpellInfo()->Id) + { + case SPELL_COPY_WEAPON_AURA: + case SPELL_COPY_WEAPON_2_AURA: + case SPELL_COPY_WEAPON_3_AURA: { - return ValidateSpellInfo( + prevItem = target->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID); + + if (Player* player = caster->ToPlayer()) { - SPELL_COPY_WEAPON_AURA, - SPELL_COPY_WEAPON_2_AURA, - SPELL_COPY_WEAPON_3_AURA, - SPELL_COPY_OFFHAND_AURA, - SPELL_COPY_OFFHAND_2_AURA, - SPELL_COPY_RANGED_AURA - }); + if (Item* mainItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND)) + target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, mainItem->GetEntry()); + } + else + target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, caster->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID)); + break; } - - void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + case SPELL_COPY_OFFHAND_AURA: + case SPELL_COPY_OFFHAND_2_AURA: { - Unit* caster = GetCaster(); - Unit* target = GetTarget(); - if (!caster) - return; + prevItem = target->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID) + 1; - switch (GetSpellInfo()->Id) + if (Player* player = caster->ToPlayer()) { - case SPELL_COPY_WEAPON_AURA: - case SPELL_COPY_WEAPON_2_AURA: - case SPELL_COPY_WEAPON_3_AURA: - { - prevItem = target->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID); - - if (Player* player = caster->ToPlayer()) - { - if (Item* mainItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND)) - target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, mainItem->GetEntry()); - } - else - target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, caster->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID)); - break; - } - case SPELL_COPY_OFFHAND_AURA: - case SPELL_COPY_OFFHAND_2_AURA: - { - prevItem = target->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID) + 1; - - if (Player* player = caster->ToPlayer()) - { - if (Item* offItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND)) - target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, offItem->GetEntry()); - } - else - target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, caster->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1)); - break; - } - case SPELL_COPY_RANGED_AURA: - { - prevItem = target->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID) + 2; - - if (Player* player = caster->ToPlayer()) - { - if (Item* rangedItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED)) - target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 2, rangedItem->GetEntry()); - } - else - target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 2, caster->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 2)); - break; - } - default: - break; + if (Item* offItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND)) + target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, offItem->GetEntry()); } + else + target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, caster->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1)); + break; } - - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + case SPELL_COPY_RANGED_AURA: { - Unit* target = GetTarget(); + prevItem = target->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID) + 2; - switch (GetSpellInfo()->Id) + if (Player* player = caster->ToPlayer()) { - case SPELL_COPY_WEAPON_AURA: - case SPELL_COPY_WEAPON_2_AURA: - case SPELL_COPY_WEAPON_3_AURA: - target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, prevItem); - break; - case SPELL_COPY_OFFHAND_AURA: - case SPELL_COPY_OFFHAND_2_AURA: - target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, prevItem); - break; - case SPELL_COPY_RANGED_AURA: - target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 2, prevItem); - break; - default: - break; + if (Item* rangedItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED)) + target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 2, rangedItem->GetEntry()); } + else + target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 2, caster->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 2)); + break; } + default: + break; + } + } - void Register() override - { - OnEffectApply += AuraEffectApplyFn(spell_gen_clone_weapon_auraScript::OnApply, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); - OnEffectRemove += AuraEffectRemoveFn(spell_gen_clone_weapon_auraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); - } + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + + switch (GetSpellInfo()->Id) + { + case SPELL_COPY_WEAPON_AURA: + case SPELL_COPY_WEAPON_2_AURA: + case SPELL_COPY_WEAPON_3_AURA: + target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, prevItem); + break; + case SPELL_COPY_OFFHAND_AURA: + case SPELL_COPY_OFFHAND_2_AURA: + target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, prevItem); + break; + case SPELL_COPY_RANGED_AURA: + target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 2, prevItem); + break; + default: + break; + } + } - uint32 prevItem = 0; - }; + void Register() override + { + OnEffectApply += AuraEffectApplyFn(spell_gen_clone_weapon_aura::OnApply, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); + OnEffectRemove += AuraEffectRemoveFn(spell_gen_clone_weapon_aura::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); + } - AuraScript* GetAuraScript() const override - { - return new spell_gen_clone_weapon_auraScript(); - } + uint32 prevItem = 0; }; class spell_gen_count_pct_from_max_hp : public SpellScriptLoader @@ -1063,86 +865,64 @@ enum CreateLanceSpells SPELL_CREATE_LANCE_HORDE = 63919 }; -class spell_gen_create_lance : public SpellScriptLoader +class spell_gen_create_lance : public SpellScript { - public: - spell_gen_create_lance() : SpellScriptLoader("spell_gen_create_lance") { } + PrepareSpellScript(spell_gen_create_lance); - class spell_gen_create_lance_SpellScript : public SpellScript + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( { - PrepareSpellScript(spell_gen_create_lance_SpellScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_CREATE_LANCE_ALLIANCE, - SPELL_CREATE_LANCE_HORDE - }); - } - - void HandleScript(SpellEffIndex effIndex) - { - PreventHitDefaultEffect(effIndex); - - if (Player* target = GetHitPlayer()) - { - if (target->GetTeam() == ALLIANCE) - GetCaster()->CastSpell(target, SPELL_CREATE_LANCE_ALLIANCE, true); - else - GetCaster()->CastSpell(target, SPELL_CREATE_LANCE_HORDE, true); - } - } + SPELL_CREATE_LANCE_ALLIANCE, + SPELL_CREATE_LANCE_HORDE + }); + } - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_gen_create_lance_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - } - }; + void HandleScript(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); - SpellScript* GetSpellScript() const override + if (Player* target = GetHitPlayer()) { - return new spell_gen_create_lance_SpellScript(); + if (target->GetTeam() == ALLIANCE) + GetCaster()->CastSpell(target, SPELL_CREATE_LANCE_ALLIANCE, true); + else + GetCaster()->CastSpell(target, SPELL_CREATE_LANCE_HORDE, true); } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_gen_create_lance::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } }; -class spell_gen_creature_permanent_feign_death : public SpellScriptLoader +class spell_gen_creature_permanent_feign_death : public AuraScript { - public: - spell_gen_creature_permanent_feign_death() : SpellScriptLoader("spell_gen_creature_permanent_feign_death") { } - - class spell_gen_creature_permanent_feign_death_AuraScript : public AuraScript - { - PrepareAuraScript(spell_gen_creature_permanent_feign_death_AuraScript); - - void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - Unit* target = GetTarget(); - target->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD); - target->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH); + PrepareAuraScript(spell_gen_creature_permanent_feign_death); - if (target->GetTypeId() == TYPEID_UNIT) - target->ToCreature()->SetReactState(REACT_PASSIVE); - } + void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + target->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD); + target->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH); - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - Unit* target = GetTarget(); - target->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD); - target->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH); - } + if (target->GetTypeId() == TYPEID_UNIT) + target->ToCreature()->SetReactState(REACT_PASSIVE); + } - void Register() override - { - OnEffectApply += AuraEffectApplyFn(spell_gen_creature_permanent_feign_death_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - OnEffectRemove += AuraEffectRemoveFn(spell_gen_creature_permanent_feign_death_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - } - }; + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + target->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD); + target->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH); + } - AuraScript* GetAuraScript() const override - { - return new spell_gen_creature_permanent_feign_death_AuraScript(); - } + void Register() override + { + OnEffectApply += AuraEffectApplyFn(spell_gen_creature_permanent_feign_death::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + OnEffectRemove += AuraEffectRemoveFn(spell_gen_creature_permanent_feign_death::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } }; enum DalaranDisguiseSpells @@ -1233,50 +1013,38 @@ enum DamageReductionAura SPELL_DAMAGE_REDUCTION_AURA = 68066 }; -class spell_gen_damage_reduction_aura : public SpellScriptLoader +class spell_gen_damage_reduction_aura : public AuraScript { - public: - spell_gen_damage_reduction_aura() : SpellScriptLoader("spell_gen_damage_reduction_aura") { } - - class spell_gen_damage_reduction_AuraScript : public AuraScript - { - PrepareAuraScript(spell_gen_damage_reduction_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DAMAGE_REDUCTION_AURA }); - } - - void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - Unit* target = GetTarget(); - target->CastSpell(target, SPELL_DAMAGE_REDUCTION_AURA, true); - } - - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - Unit* target = GetTarget(); - if (target->HasAura(SPELL_DAMAGE_REDUCTION_AURA) && !(target->HasAura(SPELL_BLESSING_OF_SANCTUARY) || - target->HasAura(SPELL_GREATER_BLESSING_OF_SANCTUARY) || - target->HasAura(SPELL_RENEWED_HOPE) || - target->HasAura(SPELL_VIGILANCE))) - { - target->RemoveAurasDueToSpell(SPELL_DAMAGE_REDUCTION_AURA); - } - } + PrepareAuraScript(spell_gen_damage_reduction_aura); - void Register() override - { - OnEffectApply += AuraEffectApplyFn(spell_gen_damage_reduction_AuraScript::OnApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); - OnEffectRemove += AuraEffectRemoveFn(spell_gen_damage_reduction_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_DAMAGE_REDUCTION_AURA }); + } - }; + void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + target->CastSpell(target, SPELL_DAMAGE_REDUCTION_AURA, true); + } - AuraScript* GetAuraScript() const override + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + if (target->HasAura(SPELL_DAMAGE_REDUCTION_AURA) && !(target->HasAura(SPELL_BLESSING_OF_SANCTUARY) || + target->HasAura(SPELL_GREATER_BLESSING_OF_SANCTUARY) || + target->HasAura(SPELL_RENEWED_HOPE) || + target->HasAura(SPELL_VIGILANCE))) { - return new spell_gen_damage_reduction_AuraScript(); + target->RemoveAurasDueToSpell(SPELL_DAMAGE_REDUCTION_AURA); } + } + + void Register() override + { + OnEffectApply += AuraEffectApplyFn(spell_gen_damage_reduction_aura::OnApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); + OnEffectRemove += AuraEffectRemoveFn(spell_gen_damage_reduction_aura::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); + } }; enum DefendVisuals @@ -1286,114 +1054,92 @@ enum DefendVisuals SPELL_VISUAL_SHIELD_3 = 63132 }; -class spell_gen_defend : public SpellScriptLoader +class spell_gen_defend : public AuraScript { - public: - spell_gen_defend() : SpellScriptLoader("spell_gen_defend") { } + PrepareAuraScript(spell_gen_defend); - class spell_gen_defend_AuraScript : public AuraScript + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( { - PrepareAuraScript(spell_gen_defend_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_VISUAL_SHIELD_1, - SPELL_VISUAL_SHIELD_2, - SPELL_VISUAL_SHIELD_3 - }); - } - - void RefreshVisualShields(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) - { - if (GetCaster()) - { - Unit* target = GetTarget(); + SPELL_VISUAL_SHIELD_1, + SPELL_VISUAL_SHIELD_2, + SPELL_VISUAL_SHIELD_3 + }); + } - for (uint8 i = 0; i < GetSpellInfo()->StackAmount; ++i) - target->RemoveAurasDueToSpell(SPELL_VISUAL_SHIELD_1 + i); + void RefreshVisualShields(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) + { + if (GetCaster()) + { + Unit* target = GetTarget(); - target->CastSpell(target, SPELL_VISUAL_SHIELD_1 + GetAura()->GetStackAmount() - 1, true, nullptr, aurEff); - } - else - GetTarget()->RemoveAurasDueToSpell(GetId()); - } + for (uint8 i = 0; i < GetSpellInfo()->StackAmount; ++i) + target->RemoveAurasDueToSpell(SPELL_VISUAL_SHIELD_1 + i); - void RemoveVisualShields(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - for (uint8 i = 0; i < GetSpellInfo()->StackAmount; ++i) - GetTarget()->RemoveAurasDueToSpell(SPELL_VISUAL_SHIELD_1 + i); - } + target->CastSpell(target, SPELL_VISUAL_SHIELD_1 + GetAura()->GetStackAmount() - 1, true, nullptr, aurEff); + } + else + GetTarget()->RemoveAurasDueToSpell(GetId()); + } - void RemoveDummyFromDriver(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - if (Unit* caster = GetCaster()) - if (TempSummon* vehicle = caster->ToTempSummon()) - if (Unit* rider = vehicle->GetSummoner()) - rider->RemoveAurasDueToSpell(GetId()); - } + void RemoveVisualShields(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + for (uint8 i = 0; i < GetSpellInfo()->StackAmount; ++i) + GetTarget()->RemoveAurasDueToSpell(SPELL_VISUAL_SHIELD_1 + i); + } - void Register() override - { - SpellInfo const* spell = sSpellMgr->AssertSpellInfo(m_scriptSpellId); + void RemoveDummyFromDriver(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Unit* caster = GetCaster()) + if (TempSummon* vehicle = caster->ToTempSummon()) + if (Unit* rider = vehicle->GetSummoner()) + rider->RemoveAurasDueToSpell(GetId()); + } - // Defend spells cast by NPCs (add visuals) - if (spell->Effects[EFFECT_0].ApplyAuraName == SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN) - { - AfterEffectApply += AuraEffectApplyFn(spell_gen_defend_AuraScript::RefreshVisualShields, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); - OnEffectRemove += AuraEffectRemoveFn(spell_gen_defend_AuraScript::RemoveVisualShields, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK); - } + void Register() override + { + SpellInfo const* spell = sSpellMgr->AssertSpellInfo(m_scriptSpellId); - // Remove Defend spell from player when he dismounts - if (spell->Effects[EFFECT_2].ApplyAuraName == SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN) - OnEffectRemove += AuraEffectRemoveFn(spell_gen_defend_AuraScript::RemoveDummyFromDriver, EFFECT_2, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL); + // Defend spells cast by NPCs (add visuals) + if (spell->Effects[EFFECT_0].ApplyAuraName == SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN) + { + AfterEffectApply += AuraEffectApplyFn(spell_gen_defend::RefreshVisualShields, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); + OnEffectRemove += AuraEffectRemoveFn(spell_gen_defend::RemoveVisualShields, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK); + } - // Defend spells cast by players (add/remove visuals) - if (spell->Effects[EFFECT_1].ApplyAuraName == SPELL_AURA_DUMMY) - { - AfterEffectApply += AuraEffectApplyFn(spell_gen_defend_AuraScript::RefreshVisualShields, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); - OnEffectRemove += AuraEffectRemoveFn(spell_gen_defend_AuraScript::RemoveVisualShields, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK); - } - } - }; + // Remove Defend spell from player when he dismounts + if (spell->Effects[EFFECT_2].ApplyAuraName == SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN) + OnEffectRemove += AuraEffectRemoveFn(spell_gen_defend::RemoveDummyFromDriver, EFFECT_2, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL); - AuraScript* GetAuraScript() const override + // Defend spells cast by players (add/remove visuals) + if (spell->Effects[EFFECT_1].ApplyAuraName == SPELL_AURA_DUMMY) { - return new spell_gen_defend_AuraScript(); + AfterEffectApply += AuraEffectApplyFn(spell_gen_defend::RefreshVisualShields, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); + OnEffectRemove += AuraEffectRemoveFn(spell_gen_defend::RemoveVisualShields, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK); } + } }; -class spell_gen_despawn_self : public SpellScriptLoader +class spell_gen_despawn_self : public SpellScript { - public: - spell_gen_despawn_self() : SpellScriptLoader("spell_gen_despawn_self") { } - - class spell_gen_despawn_self_SpellScript : public SpellScript - { - PrepareSpellScript(spell_gen_despawn_self_SpellScript); - - bool Load() override - { - return GetCaster()->GetTypeId() == TYPEID_UNIT; - } + PrepareSpellScript(spell_gen_despawn_self); - void HandleDummy(SpellEffIndex effIndex) - { - if (GetSpellInfo()->Effects[effIndex].Effect == SPELL_EFFECT_DUMMY || GetSpellInfo()->Effects[effIndex].Effect == SPELL_EFFECT_SCRIPT_EFFECT) - GetCaster()->ToCreature()->DespawnOrUnsummon(); - } + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_UNIT; + } - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_gen_despawn_self_SpellScript::HandleDummy, EFFECT_ALL, SPELL_EFFECT_ANY); - } - }; + void HandleDummy(SpellEffIndex effIndex) + { + if (GetSpellInfo()->Effects[effIndex].Effect == SPELL_EFFECT_DUMMY || GetSpellInfo()->Effects[effIndex].Effect == SPELL_EFFECT_SCRIPT_EFFECT) + GetCaster()->ToCreature()->DespawnOrUnsummon(); + } - SpellScript* GetSpellScript() const override - { - return new spell_gen_despawn_self_SpellScript(); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_gen_despawn_self::HandleDummy, EFFECT_ALL, SPELL_EFFECT_ANY); + } }; enum DivineStormSpell @@ -1402,119 +1148,86 @@ enum DivineStormSpell }; // 70769 Divine Storm! -class spell_gen_divine_storm_cd_reset : public SpellScriptLoader +class spell_gen_divine_storm_cd_reset : public SpellScript { - public: - spell_gen_divine_storm_cd_reset() : SpellScriptLoader("spell_gen_divine_storm_cd_reset") { } - - class spell_gen_divine_storm_cd_reset_SpellScript : public SpellScript - { - PrepareSpellScript(spell_gen_divine_storm_cd_reset_SpellScript); - - bool Load() override - { - return GetCaster()->GetTypeId() == TYPEID_PLAYER; - } + PrepareSpellScript(spell_gen_divine_storm_cd_reset); - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DIVINE_STORM }); - } + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } - void HandleScript(SpellEffIndex /*effIndex*/) - { - Player* caster = GetCaster()->ToPlayer(); - if (caster->GetSpellHistory()->HasCooldown(SPELL_DIVINE_STORM)) - caster->GetSpellHistory()->ResetCooldown(SPELL_DIVINE_STORM, true); - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_DIVINE_STORM }); + } - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_gen_divine_storm_cd_reset_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + void HandleScript(SpellEffIndex /*effIndex*/) + { + Player* caster = GetCaster()->ToPlayer(); + if (caster->GetSpellHistory()->HasCooldown(SPELL_DIVINE_STORM)) + caster->GetSpellHistory()->ResetCooldown(SPELL_DIVINE_STORM, true); + } - SpellScript* GetSpellScript() const override - { - return new spell_gen_divine_storm_cd_reset_SpellScript(); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_gen_divine_storm_cd_reset::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; -class spell_gen_ds_flush_knockback : public SpellScriptLoader +class spell_gen_ds_flush_knockback : public SpellScript { - public: - spell_gen_ds_flush_knockback() : SpellScriptLoader("spell_gen_ds_flush_knockback") { } + PrepareSpellScript(spell_gen_ds_flush_knockback); - class spell_gen_ds_flush_knockback_SpellScript : public SpellScript + void HandleScript(SpellEffIndex /*effIndex*/) + { + // Here the target is the water spout and determines the position where the player is knocked from + if (Unit* target = GetHitUnit()) { - PrepareSpellScript(spell_gen_ds_flush_knockback_SpellScript); - - void HandleScript(SpellEffIndex /*effIndex*/) - { - // Here the target is the water spout and determines the position where the player is knocked from - if (Unit* target = GetHitUnit()) - { - if (Player* player = GetCaster()->ToPlayer()) - { - float horizontalSpeed = 20.0f + (40.0f - GetCaster()->GetDistance(target)); - float verticalSpeed = 8.0f; - // This method relies on the Dalaran Sewer map disposition and Water Spout position - // What we do is knock the player from a position exactly behind him and at the end of the pipe - player->KnockbackFrom(target->GetPositionX(), player->GetPositionY(), horizontalSpeed, verticalSpeed); - } - } - } - - void Register() override + if (Player* player = GetCaster()->ToPlayer()) { - OnEffectHitTarget += SpellEffectFn(spell_gen_ds_flush_knockback_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); + float horizontalSpeed = 20.0f + (40.0f - GetCaster()->GetDistance(target)); + float verticalSpeed = 8.0f; + // This method relies on the Dalaran Sewer map disposition and Water Spout position + // What we do is knock the player from a position exactly behind him and at the end of the pipe + player->KnockbackFrom(target->GetPositionX(), player->GetPositionY(), horizontalSpeed, verticalSpeed); } - }; - - SpellScript* GetSpellScript() const override - { - return new spell_gen_ds_flush_knockback_SpellScript(); } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_gen_ds_flush_knockback::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; -class spell_gen_dungeon_credit : public SpellScriptLoader +class spell_gen_dungeon_credit : public SpellScript { - public: - spell_gen_dungeon_credit() : SpellScriptLoader("spell_gen_dungeon_credit") { } + PrepareSpellScript(spell_gen_dungeon_credit); - class spell_gen_dungeon_credit_SpellScript : public SpellScript - { - PrepareSpellScript(spell_gen_dungeon_credit_SpellScript); - - bool Load() override - { - return GetCaster()->GetTypeId() == TYPEID_UNIT; - } - - void CreditEncounter() - { - // This hook is executed for every target, make sure we only credit instance once - if (_handled) - return; - - _handled = true; - Unit* caster = GetCaster(); - if (InstanceScript* instance = caster->GetInstanceScript()) - instance->UpdateEncounterStateForSpellCast(GetSpellInfo()->Id, caster); - } + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_UNIT; + } - void Register() override - { - AfterHit += SpellHitFn(spell_gen_dungeon_credit_SpellScript::CreditEncounter); - } + void CreditEncounter() + { + // This hook is executed for every target, make sure we only credit instance once + if (_handled) + return; + + _handled = true; + Unit* caster = GetCaster(); + if (InstanceScript* instance = caster->GetInstanceScript()) + instance->UpdateEncounterStateForSpellCast(GetSpellInfo()->Id, caster); + } - bool _handled = false; - }; + void Register() override + { + AfterHit += SpellHitFn(spell_gen_dungeon_credit::CreditEncounter); + } - SpellScript* GetSpellScript() const override - { - return new spell_gen_dungeon_credit_SpellScript(); - } + bool _handled = false; }; enum EluneCandle @@ -1530,65 +1243,54 @@ enum EluneCandle SPELL_ELUNE_CANDLE_NORMAL = 26636 }; -class spell_gen_elune_candle : public SpellScriptLoader +class spell_gen_elune_candle : public SpellScript { - public: - spell_gen_elune_candle() : SpellScriptLoader("spell_gen_elune_candle") { } + PrepareSpellScript(spell_gen_elune_candle); - class spell_gen_elune_candle_SpellScript : public SpellScript - { - PrepareSpellScript(spell_gen_elune_candle_SpellScript); + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( + { + SPELL_ELUNE_CANDLE_OMEN_HEAD, + SPELL_ELUNE_CANDLE_OMEN_CHEST, + SPELL_ELUNE_CANDLE_OMEN_HAND_R, + SPELL_ELUNE_CANDLE_OMEN_HAND_L, + SPELL_ELUNE_CANDLE_NORMAL + }); + } - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_ELUNE_CANDLE_OMEN_HEAD, - SPELL_ELUNE_CANDLE_OMEN_CHEST, - SPELL_ELUNE_CANDLE_OMEN_HAND_R, - SPELL_ELUNE_CANDLE_OMEN_HAND_L, - SPELL_ELUNE_CANDLE_NORMAL - }); - } + void HandleScript(SpellEffIndex /*effIndex*/) + { + uint32 spellId = 0; - void HandleScript(SpellEffIndex /*effIndex*/) + if (GetHitUnit()->GetEntry() == NPC_OMEN) + { + switch (urand(0, 3)) { - uint32 spellId = 0; - - if (GetHitUnit()->GetEntry() == NPC_OMEN) - { - switch (urand(0, 3)) - { - case 0: - spellId = SPELL_ELUNE_CANDLE_OMEN_HEAD; - break; - case 1: - spellId = SPELL_ELUNE_CANDLE_OMEN_CHEST; - break; - case 2: - spellId = SPELL_ELUNE_CANDLE_OMEN_HAND_R; - break; - case 3: - spellId = SPELL_ELUNE_CANDLE_OMEN_HAND_L; - break; - } - } - else - spellId = SPELL_ELUNE_CANDLE_NORMAL; - - GetCaster()->CastSpell(GetHitUnit(), spellId, true, nullptr); + case 0: + spellId = SPELL_ELUNE_CANDLE_OMEN_HEAD; + break; + case 1: + spellId = SPELL_ELUNE_CANDLE_OMEN_CHEST; + break; + case 2: + spellId = SPELL_ELUNE_CANDLE_OMEN_HAND_R; + break; + case 3: + spellId = SPELL_ELUNE_CANDLE_OMEN_HAND_L; + break; } + } + else + spellId = SPELL_ELUNE_CANDLE_NORMAL; - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_gen_elune_candle_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + GetCaster()->CastSpell(GetHitUnit(), spellId, true, nullptr); + } - SpellScript* GetSpellScript() const override - { - return new spell_gen_elune_candle_SpellScript(); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_gen_elune_candle::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; enum TransporterBackfires @@ -1598,100 +1300,78 @@ enum TransporterBackfires SPELL_TRANSPORTER_MALFUNCTION_MISS = 36902 }; -class spell_gen_gadgetzan_transporter_backfire : public SpellScriptLoader +class spell_gen_gadgetzan_transporter_backfire : public SpellScript { - public: - spell_gen_gadgetzan_transporter_backfire() : SpellScriptLoader("spell_gen_gadgetzan_transporter_backfire") { } + PrepareSpellScript(spell_gen_gadgetzan_transporter_backfire); - class spell_gen_gadgetzan_transporter_backfire_SpellScript : public SpellScript + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( { - PrepareSpellScript(spell_gen_gadgetzan_transporter_backfire_SpellScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_TRANSPORTER_MALFUNCTION_POLYMORPH, - SPELL_TRANSPORTER_EVIL_TWIN, - SPELL_TRANSPORTER_MALFUNCTION_MISS - }); - } - - void HandleDummy(SpellEffIndex /* effIndex */) - { - Unit* caster = GetCaster(); - int32 r = irand(0, 119); - if (r < 20) // Transporter Malfunction - 1/6 polymorph - caster->CastSpell(caster, SPELL_TRANSPORTER_MALFUNCTION_POLYMORPH, true); - else if (r < 100) // Evil Twin - 4/6 evil twin - caster->CastSpell(caster, SPELL_TRANSPORTER_EVIL_TWIN, true); - else // Transporter Malfunction - 1/6 miss the target - caster->CastSpell(caster, SPELL_TRANSPORTER_MALFUNCTION_MISS, true); - } + SPELL_TRANSPORTER_MALFUNCTION_POLYMORPH, + SPELL_TRANSPORTER_EVIL_TWIN, + SPELL_TRANSPORTER_MALFUNCTION_MISS + }); + } - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_gen_gadgetzan_transporter_backfire_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + void HandleDummy(SpellEffIndex /* effIndex */) + { + Unit* caster = GetCaster(); + int32 r = irand(0, 119); + if (r < 20) // Transporter Malfunction - 1/6 polymorph + caster->CastSpell(caster, SPELL_TRANSPORTER_MALFUNCTION_POLYMORPH, true); + else if (r < 100) // Evil Twin - 4/6 evil twin + caster->CastSpell(caster, SPELL_TRANSPORTER_EVIL_TWIN, true); + else // Transporter Malfunction - 1/6 miss the target + caster->CastSpell(caster, SPELL_TRANSPORTER_MALFUNCTION_MISS, true); + } - SpellScript* GetSpellScript() const override - { - return new spell_gen_gadgetzan_transporter_backfire_SpellScript(); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_gen_gadgetzan_transporter_backfire::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; -class spell_gen_gift_of_naaru : public SpellScriptLoader +class spell_gen_gift_of_naaru : public AuraScript { - public: - spell_gen_gift_of_naaru() : SpellScriptLoader("spell_gen_gift_of_naaru") { } - - class spell_gen_gift_of_naaru_AuraScript : public AuraScript - { - PrepareAuraScript(spell_gen_gift_of_naaru_AuraScript); - - void CalculateAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/) - { - if (!GetCaster()) - return; - - float heal = 0.0f; - switch (GetSpellInfo()->SpellFamilyName) - { - case SPELLFAMILY_MAGE: - case SPELLFAMILY_WARLOCK: - case SPELLFAMILY_PRIEST: - heal = 1.885f * float(GetCaster()->SpellBaseDamageBonusDone(GetSpellInfo()->GetSchoolMask())); - break; - case SPELLFAMILY_PALADIN: - case SPELLFAMILY_SHAMAN: - heal = std::max(1.885f * float(GetCaster()->SpellBaseDamageBonusDone(GetSpellInfo()->GetSchoolMask())), 1.1f * float(GetCaster()->GetTotalAttackPowerValue(BASE_ATTACK))); - break; - case SPELLFAMILY_WARRIOR: - case SPELLFAMILY_HUNTER: - case SPELLFAMILY_DEATHKNIGHT: - heal = 1.1f * float(std::max(GetCaster()->GetTotalAttackPowerValue(BASE_ATTACK), GetCaster()->GetTotalAttackPowerValue(RANGED_ATTACK))); - break; - case SPELLFAMILY_GENERIC: - default: - break; - } - - int32 healTick = std::floor(heal / aurEff->GetTotalTicks()); - amount += int32(std::max(healTick, 0)); - } + PrepareAuraScript(spell_gen_gift_of_naaru); - void Register() override - { - DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_gift_of_naaru_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_PERIODIC_HEAL); - } - }; + void CalculateAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/) + { + if (!GetCaster()) + return; + + float heal = 0.0f; + switch (GetSpellInfo()->SpellFamilyName) + { + case SPELLFAMILY_MAGE: + case SPELLFAMILY_WARLOCK: + case SPELLFAMILY_PRIEST: + heal = 1.885f * float(GetCaster()->SpellBaseDamageBonusDone(GetSpellInfo()->GetSchoolMask())); + break; + case SPELLFAMILY_PALADIN: + case SPELLFAMILY_SHAMAN: + heal = std::max(1.885f * float(GetCaster()->SpellBaseDamageBonusDone(GetSpellInfo()->GetSchoolMask())), 1.1f * float(GetCaster()->GetTotalAttackPowerValue(BASE_ATTACK))); + break; + case SPELLFAMILY_WARRIOR: + case SPELLFAMILY_HUNTER: + case SPELLFAMILY_DEATHKNIGHT: + heal = 1.1f * float(std::max(GetCaster()->GetTotalAttackPowerValue(BASE_ATTACK), GetCaster()->GetTotalAttackPowerValue(RANGED_ATTACK))); + break; + case SPELLFAMILY_GENERIC: + default: + break; + } + + int32 healTick = std::floor(heal / aurEff->GetTotalTicks()); + amount += int32(std::max(healTick, 0)); + } - AuraScript* GetAuraScript() const override - { - return new spell_gen_gift_of_naaru_AuraScript(); - } + void Register() override + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_gift_of_naaru::CalculateAmount, EFFECT_0, SPELL_AURA_PERIODIC_HEAL); + } }; enum GnomishTransporter @@ -1700,66 +1380,44 @@ enum GnomishTransporter SPELL_TRANSPORTER_FAILURE = 23446 }; -class spell_gen_gnomish_transporter : public SpellScriptLoader +class spell_gen_gnomish_transporter : public SpellScript { - public: - spell_gen_gnomish_transporter() : SpellScriptLoader("spell_gen_gnomish_transporter") { } + PrepareSpellScript(spell_gen_gnomish_transporter); - class spell_gen_gnomish_transporter_SpellScript : public SpellScript + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( { - PrepareSpellScript(spell_gen_gnomish_transporter_SpellScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_TRANSPORTER_SUCCESS, - SPELL_TRANSPORTER_FAILURE - }); - } - - void HandleDummy(SpellEffIndex /* effIndex */) - { - GetCaster()->CastSpell(GetCaster(), roll_chance_i(50) ? SPELL_TRANSPORTER_SUCCESS : SPELL_TRANSPORTER_FAILURE, true); - } + SPELL_TRANSPORTER_SUCCESS, + SPELL_TRANSPORTER_FAILURE + }); + } - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_gen_gnomish_transporter_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + void HandleDummy(SpellEffIndex /* effIndex */) + { + GetCaster()->CastSpell(GetCaster(), roll_chance_i(50) ? SPELL_TRANSPORTER_SUCCESS : SPELL_TRANSPORTER_FAILURE, true); + } - SpellScript* GetSpellScript() const override - { - return new spell_gen_gnomish_transporter_SpellScript(); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_gen_gnomish_transporter::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; -class spell_gen_lifeblood : public SpellScriptLoader +class spell_gen_lifeblood : public AuraScript { - public: - spell_gen_lifeblood() : SpellScriptLoader("spell_gen_lifeblood") { } - - class spell_gen_lifeblood_AuraScript : public AuraScript - { - PrepareAuraScript(spell_gen_lifeblood_AuraScript); - - void CalculateAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/) - { - if (Unit* owner = GetUnitOwner()) - amount += int32(CalculatePct(owner->GetMaxHealth(), 1.5f / aurEff->GetTotalTicks())); - } + PrepareAuraScript(spell_gen_lifeblood); - void Register() override - { - DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_lifeblood_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_PERIODIC_HEAL); - } - }; + void CalculateAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/) + { + if (Unit* owner = GetUnitOwner()) + amount += int32(CalculatePct(owner->GetMaxHealth(), 1.5f / aurEff->GetTotalTicks())); + } - AuraScript* GetAuraScript() const override - { - return new spell_gen_lifeblood_AuraScript(); - } + void Register() override + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_lifeblood::CalculateAmount, EFFECT_0, SPELL_AURA_PERIODIC_HEAL); + } }; enum GenericLifebloom @@ -1791,7 +1449,7 @@ class spell_gen_lifebloom : public SpellScriptLoader void AfterRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) { - // Final heal only on duration end + // final heal only on duration end or dispel if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE && GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_ENEMY_SPELL) return; @@ -1823,52 +1481,41 @@ enum MagicRoosterSpells SPELL_MAGIC_ROOSTER_TAUREN_MALE = 66124 }; -class spell_gen_magic_rooster : public SpellScriptLoader +class spell_gen_magic_rooster : public SpellScript { - public: - spell_gen_magic_rooster() : SpellScriptLoader("spell_gen_magic_rooster") { } + PrepareSpellScript(spell_gen_magic_rooster); - class spell_gen_magic_rooster_SpellScript : public SpellScript + void HandleScript(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + if (Player* target = GetHitPlayer()) { - PrepareSpellScript(spell_gen_magic_rooster_SpellScript); - - void HandleScript(SpellEffIndex effIndex) - { - PreventHitDefaultEffect(effIndex); - if (Player* target = GetHitPlayer()) - { - // prevent client crashes from stacking mounts - target->RemoveAurasByType(SPELL_AURA_MOUNTED); - - uint32 spellId = SPELL_MAGIC_ROOSTER_NORMAL; - switch (target->getRace()) - { - case RACE_DRAENEI: - if (target->getGender() == GENDER_MALE) - spellId = SPELL_MAGIC_ROOSTER_DRAENEI_MALE; - break; - case RACE_TAUREN: - if (target->getGender() == GENDER_MALE) - spellId = SPELL_MAGIC_ROOSTER_TAUREN_MALE; - break; - default: - break; - } - - target->CastSpell(target, spellId, true); - } - } + // prevent client crashes from stacking mounts + target->RemoveAurasByType(SPELL_AURA_MOUNTED); - void Register() override + uint32 spellId = SPELL_MAGIC_ROOSTER_NORMAL; + switch (target->getRace()) { - OnEffectHitTarget += SpellEffectFn(spell_gen_magic_rooster_SpellScript::HandleScript, EFFECT_2, SPELL_EFFECT_SCRIPT_EFFECT); + case RACE_DRAENEI: + if (target->getGender() == GENDER_MALE) + spellId = SPELL_MAGIC_ROOSTER_DRAENEI_MALE; + break; + case RACE_TAUREN: + if (target->getGender() == GENDER_MALE) + spellId = SPELL_MAGIC_ROOSTER_TAUREN_MALE; + break; + default: + break; } - }; - SpellScript* GetSpellScript() const override - { - return new spell_gen_magic_rooster_SpellScript(); + target->CastSpell(target, spellId, true); } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_gen_magic_rooster::HandleScript, EFFECT_2, SPELL_EFFECT_SCRIPT_EFFECT); + } }; enum Mounts @@ -2089,115 +1736,104 @@ enum ChargeSpells SPELL_CHARGE_MISS_EFFECT = 62977, }; -class spell_gen_mounted_charge: public SpellScriptLoader +class spell_gen_mounted_charge : public SpellScript { - public: - spell_gen_mounted_charge() : SpellScriptLoader("spell_gen_mounted_charge") { } - - class spell_gen_mounted_charge_SpellScript : public SpellScript - { - PrepareSpellScript(spell_gen_mounted_charge_SpellScript); - - void HandleScriptEffect(SpellEffIndex effIndex) - { - Unit* target = GetHitUnit(); - - switch (effIndex) - { - case EFFECT_0: // On spells wich trigger the damaging spell (and also the visual) - { - uint32 spellId; - - switch (GetSpellInfo()->Id) - { - case SPELL_CHARGE_TRIGGER_TRIAL_CHAMPION: - spellId = SPELL_CHARGE_CHARGING_EFFECT_20K_1; - break; - case SPELL_CHARGE_TRIGGER_FACTION_MOUNTS: - spellId = SPELL_CHARGE_CHARGING_EFFECT_8K5; - break; - default: - return; - } - - // If target isn't a training dummy there's a chance of failing the charge - if (!target->IsCharmedOwnedByPlayerOrPlayer() && roll_chance_f(12.5f)) - spellId = SPELL_CHARGE_MISS_EFFECT; + PrepareSpellScript(spell_gen_mounted_charge); - if (Unit* vehicle = GetCaster()->GetVehicleBase()) - vehicle->CastSpell(target, spellId, false); - else - GetCaster()->CastSpell(target, spellId, false); - break; - } - case EFFECT_1: // On damaging spells, for removing a defend layer - case EFFECT_2: - { - Unit::AuraApplicationMap const& auras = target->GetAppliedAuras(); - for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) - { - if (Aura* aura = itr->second->GetBase()) - { - SpellInfo const* auraInfo = aura->GetSpellInfo(); - if (auraInfo && auraInfo->SpellIconID == 2007 && aura->HasEffectType(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN)) - { - aura->ModStackAmount(-1, AURA_REMOVE_BY_ENEMY_SPELL); - // Remove dummys from rider (Necessary for updating visual shields) - if (Unit* rider = target->GetCharmer()) - if (Aura* defend = rider->GetAura(aura->GetId())) - defend->ModStackAmount(-1, AURA_REMOVE_BY_ENEMY_SPELL); - break; - } - } - } - break; - } - } - } + void HandleScriptEffect(SpellEffIndex effIndex) + { + Unit* target = GetHitUnit(); - void HandleChargeEffect(SpellEffIndex /*effIndex*/) + switch (effIndex) + { + case EFFECT_0: // On spells wich trigger the damaging spell (and also the visual) { uint32 spellId; switch (GetSpellInfo()->Id) { - case SPELL_CHARGE_CHARGING_EFFECT_8K5: - spellId = SPELL_CHARGE_DAMAGE_8K5; - break; - case SPELL_CHARGE_CHARGING_EFFECT_20K_1: - case SPELL_CHARGE_CHARGING_EFFECT_20K_2: - spellId = SPELL_CHARGE_DAMAGE_20K; + case SPELL_CHARGE_TRIGGER_TRIAL_CHAMPION: + spellId = SPELL_CHARGE_CHARGING_EFFECT_20K_1; break; - case SPELL_CHARGE_CHARGING_EFFECT_45K_1: - case SPELL_CHARGE_CHARGING_EFFECT_45K_2: - spellId = SPELL_CHARGE_DAMAGE_45K; + case SPELL_CHARGE_TRIGGER_FACTION_MOUNTS: + spellId = SPELL_CHARGE_CHARGING_EFFECT_8K5; break; default: return; } - if (Unit* rider = GetCaster()->GetCharmer()) - rider->CastSpell(GetHitUnit(), spellId, false); + // If target isn't a training dummy there's a chance of failing the charge + if (!target->IsCharmedOwnedByPlayerOrPlayer() && roll_chance_f(12.5f)) + spellId = SPELL_CHARGE_MISS_EFFECT; + + if (Unit* vehicle = GetCaster()->GetVehicleBase()) + vehicle->CastSpell(target, spellId, false); else - GetCaster()->CastSpell(GetHitUnit(), spellId, false); + GetCaster()->CastSpell(target, spellId, false); + break; } - - void Register() override + case EFFECT_1: // On damaging spells, for removing a defend layer + case EFFECT_2: { - SpellInfo const* spell = sSpellMgr->AssertSpellInfo(m_scriptSpellId); - - if (spell->HasEffect(SPELL_EFFECT_SCRIPT_EFFECT)) - OnEffectHitTarget += SpellEffectFn(spell_gen_mounted_charge_SpellScript::HandleScriptEffect, EFFECT_FIRST_FOUND, SPELL_EFFECT_SCRIPT_EFFECT); - - if (spell->Effects[EFFECT_0].Effect == SPELL_EFFECT_CHARGE) - OnEffectHitTarget += SpellEffectFn(spell_gen_mounted_charge_SpellScript::HandleChargeEffect, EFFECT_0, SPELL_EFFECT_CHARGE); + Unit::AuraApplicationMap const& auras = target->GetAppliedAuras(); + for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) + { + if (Aura* aura = itr->second->GetBase()) + { + SpellInfo const* auraInfo = aura->GetSpellInfo(); + if (auraInfo && auraInfo->SpellIconID == 2007 && aura->HasEffectType(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN)) + { + aura->ModStackAmount(-1, AURA_REMOVE_BY_ENEMY_SPELL); + // Remove dummys from rider (Necessary for updating visual shields) + if (Unit* rider = target->GetCharmer()) + if (Aura* defend = rider->GetAura(aura->GetId())) + defend->ModStackAmount(-1, AURA_REMOVE_BY_ENEMY_SPELL); + break; + } + } + } + break; } - }; + } + } - SpellScript* GetSpellScript() const override - { - return new spell_gen_mounted_charge_SpellScript(); + void HandleChargeEffect(SpellEffIndex /*effIndex*/) + { + uint32 spellId; + + switch (GetSpellInfo()->Id) + { + case SPELL_CHARGE_CHARGING_EFFECT_8K5: + spellId = SPELL_CHARGE_DAMAGE_8K5; + break; + case SPELL_CHARGE_CHARGING_EFFECT_20K_1: + case SPELL_CHARGE_CHARGING_EFFECT_20K_2: + spellId = SPELL_CHARGE_DAMAGE_20K; + break; + case SPELL_CHARGE_CHARGING_EFFECT_45K_1: + case SPELL_CHARGE_CHARGING_EFFECT_45K_2: + spellId = SPELL_CHARGE_DAMAGE_45K; + break; + default: + return; } + + if (Unit* rider = GetCaster()->GetCharmer()) + rider->CastSpell(GetHitUnit(), spellId, false); + else + GetCaster()->CastSpell(GetHitUnit(), spellId, false); + } + + void Register() override + { + SpellInfo const* spell = sSpellMgr->AssertSpellInfo(m_scriptSpellId); + + if (spell->HasEffect(SPELL_EFFECT_SCRIPT_EFFECT)) + OnEffectHitTarget += SpellEffectFn(spell_gen_mounted_charge::HandleScriptEffect, EFFECT_FIRST_FOUND, SPELL_EFFECT_SCRIPT_EFFECT); + + if (spell->Effects[EFFECT_0].Effect == SPELL_EFFECT_CHARGE) + OnEffectHitTarget += SpellEffectFn(spell_gen_mounted_charge::HandleChargeEffect, EFFECT_0, SPELL_EFFECT_CHARGE); + } }; enum MossCoveredFeet @@ -2207,36 +1843,25 @@ enum MossCoveredFeet // 6870 Moss Covered Feet // 31399 Moss Covered Feet -class spell_gen_moss_covered_feet : public SpellScriptLoader +class spell_gen_moss_covered_feet : public AuraScript { - public: - spell_gen_moss_covered_feet() : SpellScriptLoader("spell_gen_moss_covered_feet") { } - - class spell_gen_moss_covered_feet_AuraScript : public AuraScript - { - PrepareAuraScript(spell_gen_moss_covered_feet_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_FALL_DOWN }); - } + PrepareAuraScript(spell_gen_moss_covered_feet); - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - eventInfo.GetActionTarget()->CastSpell((Unit*)nullptr, SPELL_FALL_DOWN, true, nullptr, aurEff); - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_FALL_DOWN }); + } - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_gen_moss_covered_feet_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } - }; + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + eventInfo.GetActionTarget()->CastSpell(nullptr, SPELL_FALL_DOWN, true, nullptr, aurEff); + } - AuraScript* GetAuraScript() const override - { - return new spell_gen_moss_covered_feet_AuraScript(); - } + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_gen_moss_covered_feet::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } }; enum Netherbloom : uint32 @@ -2245,57 +1870,46 @@ enum Netherbloom : uint32 }; // 28702 - Netherbloom -class spell_gen_netherbloom : public SpellScriptLoader +class spell_gen_netherbloom : public SpellScript { - public: - spell_gen_netherbloom() : SpellScriptLoader("spell_gen_netherbloom") { } - - class spell_gen_netherbloom_SpellScript : public SpellScript - { - PrepareSpellScript(spell_gen_netherbloom_SpellScript); + PrepareSpellScript(spell_gen_netherbloom); - bool Validate(SpellInfo const* /*spellInfo*/) override - { - for (uint8 i = 0; i < 5; ++i) - if (!ValidateSpellInfo({ SPELL_NETHERBLOOM_POLLEN_1 + i })) - return false; - - return true; - } - - void HandleScript(SpellEffIndex effIndex) - { - PreventHitDefaultEffect(effIndex); + bool Validate(SpellInfo const* /*spellInfo*/) override + { + for (uint8 i = 0; i < 5; ++i) + if (!ValidateSpellInfo({ SPELL_NETHERBLOOM_POLLEN_1 + i })) + return false; - if (Unit* target = GetHitUnit()) - { - // 25% chance of casting a random buff - if (roll_chance_i(75)) - return; + return true; + } - // triggered spells are 28703 to 28707 - // Note: some sources say, that there was the possibility of - // receiving a debuff. However, this seems to be removed by a patch. + void HandleScript(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); - // don't overwrite an existing aura - for (uint8 i = 0; i < 5; ++i) - if (target->HasAura(SPELL_NETHERBLOOM_POLLEN_1 + i)) - return; + if (Unit* target = GetHitUnit()) + { + // 25% chance of casting a random buff + if (roll_chance_i(75)) + return; - target->CastSpell(target, SPELL_NETHERBLOOM_POLLEN_1 + urand(0, 4), true); - } - } + // triggered spells are 28703 to 28707 + // Note: some sources say, that there was the possibility of + // receiving a debuff. However, this seems to be removed by a patch. - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_gen_netherbloom_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - } - }; + // don't overwrite an existing aura + for (uint8 i = 0; i < 5; ++i) + if (target->HasAura(SPELL_NETHERBLOOM_POLLEN_1 + i)) + return; - SpellScript* GetSpellScript() const override - { - return new spell_gen_netherbloom_SpellScript(); + target->CastSpell(target, SPELL_NETHERBLOOM_POLLEN_1 + urand(0, 4), true); } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_gen_netherbloom::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } }; enum NightmareVine @@ -2304,42 +1918,31 @@ enum NightmareVine }; // 28720 - Nightmare Vine -class spell_gen_nightmare_vine : public SpellScriptLoader +class spell_gen_nightmare_vine : public SpellScript { - public: - spell_gen_nightmare_vine() : SpellScriptLoader("spell_gen_nightmare_vine") { } - - class spell_gen_nightmare_vine_SpellScript : public SpellScript - { - PrepareSpellScript(spell_gen_nightmare_vine_SpellScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_NIGHTMARE_POLLEN }); - } + PrepareSpellScript(spell_gen_nightmare_vine); - void HandleScript(SpellEffIndex effIndex) - { - PreventHitDefaultEffect(effIndex); - - if (Unit* target = GetHitUnit()) - { - // 25% chance of casting Nightmare Pollen - if (roll_chance_i(25)) - target->CastSpell(target, SPELL_NIGHTMARE_POLLEN, true); - } - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_NIGHTMARE_POLLEN }); + } - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_gen_nightmare_vine_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - } - }; + void HandleScript(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); - SpellScript* GetSpellScript() const override + if (Unit* target = GetHitUnit()) { - return new spell_gen_nightmare_vine_SpellScript(); + // 25% chance of casting Nightmare Pollen + if (roll_chance_i(25)) + target->CastSpell(target, SPELL_NIGHTMARE_POLLEN, true); } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_gen_nightmare_vine::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } }; enum ObsidianArmor @@ -2353,126 +1956,104 @@ enum ObsidianArmor }; // 27539 - Obsidian Armor -class spell_gen_obsidian_armor : public SpellScriptLoader +class spell_gen_obsidian_armor : public AuraScript { - public: - spell_gen_obsidian_armor() : SpellScriptLoader("spell_gen_obsidian_armor") { } - - class spell_gen_obsidian_armor_AuraScript : public AuraScript - { - PrepareAuraScript(spell_gen_obsidian_armor_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_GEN_OBSIDIAN_ARMOR_HOLY, - SPELL_GEN_OBSIDIAN_ARMOR_FIRE, - SPELL_GEN_OBSIDIAN_ARMOR_NATURE, - SPELL_GEN_OBSIDIAN_ARMOR_FROST, - SPELL_GEN_OBSIDIAN_ARMOR_SHADOW, - SPELL_GEN_OBSIDIAN_ARMOR_ARCANE - }); - } - - bool CheckProc(ProcEventInfo& eventInfo) - { - DamageInfo* damageInfo = eventInfo.GetDamageInfo(); - if (!damageInfo || !damageInfo->GetSpellInfo()) - return false; - - if (GetFirstSchoolInMask(eventInfo.GetSchoolMask()) == SPELL_SCHOOL_NORMAL) - return false; + PrepareAuraScript(spell_gen_obsidian_armor); - return true; - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( + { + SPELL_GEN_OBSIDIAN_ARMOR_HOLY, + SPELL_GEN_OBSIDIAN_ARMOR_FIRE, + SPELL_GEN_OBSIDIAN_ARMOR_NATURE, + SPELL_GEN_OBSIDIAN_ARMOR_FROST, + SPELL_GEN_OBSIDIAN_ARMOR_SHADOW, + SPELL_GEN_OBSIDIAN_ARMOR_ARCANE + }); + } - void OnProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); + bool CheckProc(ProcEventInfo& eventInfo) + { + DamageInfo* damageInfo = eventInfo.GetDamageInfo(); + if (!damageInfo || !damageInfo->GetSpellInfo()) + return false; - uint32 spellId = 0; - switch (GetFirstSchoolInMask(eventInfo.GetSchoolMask())) - { - case SPELL_SCHOOL_HOLY: - spellId = SPELL_GEN_OBSIDIAN_ARMOR_HOLY; - break; - case SPELL_SCHOOL_FIRE: - spellId = SPELL_GEN_OBSIDIAN_ARMOR_FIRE; - break; - case SPELL_SCHOOL_NATURE: - spellId = SPELL_GEN_OBSIDIAN_ARMOR_NATURE; - break; - case SPELL_SCHOOL_FROST: - spellId = SPELL_GEN_OBSIDIAN_ARMOR_FROST; - break; - case SPELL_SCHOOL_SHADOW: - spellId = SPELL_GEN_OBSIDIAN_ARMOR_SHADOW; - break; - case SPELL_SCHOOL_ARCANE: - spellId = SPELL_GEN_OBSIDIAN_ARMOR_ARCANE; - break; - default: - return; - } - GetTarget()->CastSpell(GetTarget(), spellId, true, nullptr, aurEff); - } + if (GetFirstSchoolInMask(eventInfo.GetSchoolMask()) == SPELL_SCHOOL_NORMAL) + return false; - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_gen_obsidian_armor_AuraScript::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_gen_obsidian_armor_AuraScript::OnProc, EFFECT_0, SPELL_AURA_DUMMY); - } - }; + return true; + } - AuraScript* GetAuraScript() const override - { - return new spell_gen_obsidian_armor_AuraScript(); + void OnProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + uint32 spellId = 0; + switch (GetFirstSchoolInMask(eventInfo.GetSchoolMask())) + { + case SPELL_SCHOOL_HOLY: + spellId = SPELL_GEN_OBSIDIAN_ARMOR_HOLY; + break; + case SPELL_SCHOOL_FIRE: + spellId = SPELL_GEN_OBSIDIAN_ARMOR_FIRE; + break; + case SPELL_SCHOOL_NATURE: + spellId = SPELL_GEN_OBSIDIAN_ARMOR_NATURE; + break; + case SPELL_SCHOOL_FROST: + spellId = SPELL_GEN_OBSIDIAN_ARMOR_FROST; + break; + case SPELL_SCHOOL_SHADOW: + spellId = SPELL_GEN_OBSIDIAN_ARMOR_SHADOW; + break; + case SPELL_SCHOOL_ARCANE: + spellId = SPELL_GEN_OBSIDIAN_ARMOR_ARCANE; + break; + default: + return; } + GetTarget()->CastSpell(GetTarget(), spellId, true, nullptr, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_gen_obsidian_armor::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_gen_obsidian_armor::OnProc, EFFECT_0, SPELL_AURA_DUMMY); + } }; -class spell_gen_oracle_wolvar_reputation : public SpellScriptLoader +class spell_gen_oracle_wolvar_reputation : public SpellScript { - public: - spell_gen_oracle_wolvar_reputation() : SpellScriptLoader("spell_gen_oracle_wolvar_reputation") { } - - class spell_gen_oracle_wolvar_reputation_SpellScript : public SpellScript - { - PrepareSpellScript(spell_gen_oracle_wolvar_reputation_SpellScript); - - bool Load() override - { - return GetCaster()->GetTypeId() == TYPEID_PLAYER; - } + PrepareSpellScript(spell_gen_oracle_wolvar_reputation); - void HandleDummy(SpellEffIndex effIndex) - { - Player* player = GetCaster()->ToPlayer(); - uint32 factionId = GetSpellInfo()->Effects[effIndex].CalcValue(); - int32 repChange = GetSpellInfo()->Effects[EFFECT_1].CalcValue(); + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } - FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionId); - if (!factionEntry) - return; + void HandleDummy(SpellEffIndex effIndex) + { + Player* player = GetCaster()->ToPlayer(); + uint32 factionId = GetSpellInfo()->Effects[effIndex].CalcValue(); + int32 repChange = GetSpellInfo()->Effects[EFFECT_1].CalcValue(); - // Set rep to baserep + basepoints (expecting spillover for oposite faction -> become hated) - // Not when player already has equal or higher rep with this faction - if (player->GetReputationMgr().GetReputation(factionEntry) < repChange) - player->GetReputationMgr().SetReputation(factionEntry, repChange); + FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionId); + if (!factionEntry) + return; - // EFFECT_INDEX_2 most likely update at war state, we already handle this in SetReputation - } + // Set rep to baserep + basepoints (expecting spillover for oposite faction -> become hated) + // Not when player already has equal or higher rep with this faction + if (player->GetReputationMgr().GetReputation(factionEntry) < repChange) + player->GetReputationMgr().SetReputation(factionEntry, repChange); - void Register() override - { - OnEffectHit += SpellEffectFn(spell_gen_oracle_wolvar_reputation_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + // EFFECT_INDEX_2 most likely update at war state, we already handle this in SetReputation + } - SpellScript* GetSpellScript() const override - { - return new spell_gen_oracle_wolvar_reputation_SpellScript(); - } + void Register() override + { + OnEffectHit += SpellEffectFn(spell_gen_oracle_wolvar_reputation::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; enum OrcDisguiseSpells @@ -2482,48 +2063,37 @@ enum OrcDisguiseSpells SPELL_ORC_DISGUISE_FEMALE = 45762 }; -class spell_gen_orc_disguise : public SpellScriptLoader +class spell_gen_orc_disguise : public SpellScript { - public: - spell_gen_orc_disguise() : SpellScriptLoader("spell_gen_orc_disguise") { } + PrepareSpellScript(spell_gen_orc_disguise); - class spell_gen_orc_disguise_SpellScript : public SpellScript + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( { - PrepareSpellScript(spell_gen_orc_disguise_SpellScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_ORC_DISGUISE_TRIGGER, - SPELL_ORC_DISGUISE_MALE, - SPELL_ORC_DISGUISE_FEMALE - }); - } - - void HandleScript(SpellEffIndex /*effIndex*/) - { - Unit* caster = GetCaster(); - if (Player* target = GetHitPlayer()) - { - uint8 gender = target->getGender(); - if (!gender) - caster->CastSpell(target, SPELL_ORC_DISGUISE_MALE, true); - else - caster->CastSpell(target, SPELL_ORC_DISGUISE_FEMALE, true); - } - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_gen_orc_disguise_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - } - }; + SPELL_ORC_DISGUISE_TRIGGER, + SPELL_ORC_DISGUISE_MALE, + SPELL_ORC_DISGUISE_FEMALE + }); + } - SpellScript* GetSpellScript() const override + void HandleScript(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + if (Player* target = GetHitPlayer()) { - return new spell_gen_orc_disguise_SpellScript(); + uint8 gender = target->getGender(); + if (!gender) + caster->CastSpell(target, SPELL_ORC_DISGUISE_MALE, true); + else + caster->CastSpell(target, SPELL_ORC_DISGUISE_FEMALE, true); } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_gen_orc_disguise::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } }; enum ParalyticPoison @@ -2532,38 +2102,27 @@ enum ParalyticPoison }; // 35201 - Paralytic Poison -class spell_gen_paralytic_poison : public SpellScriptLoader +class spell_gen_paralytic_poison : public AuraScript { - public: - spell_gen_paralytic_poison() : SpellScriptLoader("spell_gen_paralytic_poison") { } - - class spell_gen_paralytic_poison_AuraScript : public AuraScript - { - PrepareAuraScript(spell_gen_paralytic_poison_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_PARALYSIS }); - } + PrepareAuraScript(spell_gen_paralytic_poison); - void HandleStun(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) - { - if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE) - return; + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_PARALYSIS }); + } - GetTarget()->CastSpell((Unit*)nullptr, SPELL_PARALYSIS, true, nullptr, aurEff); - } + void HandleStun(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) + { + if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE) + return; - void Register() override - { - AfterEffectRemove += AuraEffectRemoveFn(spell_gen_paralytic_poison_AuraScript::HandleStun, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL); - } - }; + GetTarget()->CastSpell(nullptr, SPELL_PARALYSIS, true, nullptr, aurEff); + } - AuraScript* GetAuraScript() const override - { - return new spell_gen_paralytic_poison_AuraScript(); - } + void Register() override + { + AfterEffectRemove += AuraEffectRemoveFn(spell_gen_paralytic_poison::HandleStun, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL); + } }; class spell_gen_proc_below_pct_damaged : public SpellScriptLoader @@ -2601,30 +2160,19 @@ class spell_gen_proc_below_pct_damaged : public SpellScriptLoader } }; -class spell_gen_proc_charge_drop_only : public SpellScriptLoader +class spell_gen_proc_charge_drop_only : public AuraScript { - public: - spell_gen_proc_charge_drop_only() : SpellScriptLoader("spell_gen_proc_charge_drop_only") { } - - class spell_gen_proc_charge_drop_only_AuraScript : public AuraScript - { - PrepareAuraScript(spell_gen_proc_charge_drop_only_AuraScript); + PrepareAuraScript(spell_gen_proc_charge_drop_only); - void HandleChargeDrop(ProcEventInfo& /*eventInfo*/) - { - PreventDefaultAction(); - } - - void Register() override - { - OnProc += AuraProcFn(spell_gen_proc_charge_drop_only_AuraScript::HandleChargeDrop); - } - }; + void HandleChargeDrop(ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + } - AuraScript* GetAuraScript() const override - { - return new spell_gen_proc_charge_drop_only_AuraScript(); - } + void Register() override + { + OnProc += AuraProcFn(spell_gen_proc_charge_drop_only::HandleChargeDrop); + } }; enum ParachuteSpells @@ -2634,44 +2182,33 @@ enum ParachuteSpells }; // 45472 Parachute -class spell_gen_parachute : public SpellScriptLoader +class spell_gen_parachute : public AuraScript { - public: - spell_gen_parachute() : SpellScriptLoader("spell_gen_parachute") { } + PrepareAuraScript(spell_gen_parachute); - class spell_gen_parachute_AuraScript : public AuraScript + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( { - PrepareAuraScript(spell_gen_parachute_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_PARACHUTE, - SPELL_PARACHUTE_BUFF - }); - } - - void HandleEffectPeriodic(AuraEffect const* /*aurEff*/) - { - if (Player* target = GetTarget()->ToPlayer()) - if (target->IsFalling()) - { - target->RemoveAurasDueToSpell(SPELL_PARACHUTE); - target->CastSpell(target, SPELL_PARACHUTE_BUFF, true); - } - } + SPELL_PARACHUTE, + SPELL_PARACHUTE_BUFF + }); + } - void Register() override + void HandleEffectPeriodic(AuraEffect const* /*aurEff*/) + { + if (Player* target = GetTarget()->ToPlayer()) + if (target->IsFalling()) { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_gen_parachute_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + target->RemoveAurasDueToSpell(SPELL_PARACHUTE); + target->CastSpell(target, SPELL_PARACHUTE_BUFF, true); } - }; + } - AuraScript* GetAuraScript() const override - { - return new spell_gen_parachute_AuraScript(); - } + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_gen_parachute::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + } }; enum PetSummoned @@ -2681,141 +2218,108 @@ enum PetSummoned NPC_IMP = 416 }; -class spell_gen_pet_summoned : public SpellScriptLoader +class spell_gen_pet_summoned : public SpellScript { - public: - spell_gen_pet_summoned() : SpellScriptLoader("spell_gen_pet_summoned") { } - - class spell_gen_pet_summoned_SpellScript : public SpellScript - { - PrepareSpellScript(spell_gen_pet_summoned_SpellScript); + PrepareSpellScript(spell_gen_pet_summoned); - bool Load() override - { - return GetCaster()->GetTypeId() == TYPEID_PLAYER; - } + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } - void HandleScript(SpellEffIndex /*effIndex*/) + void HandleScript(SpellEffIndex /*effIndex*/) + { + Player* player = GetCaster()->ToPlayer(); + if (player->GetLastPetNumber()) + { + PetType newPetType = (player->getClass() == CLASS_HUNTER) ? HUNTER_PET : SUMMON_PET; + Pet* newPet = new Pet(player, newPetType); + if (newPet->LoadPetFromDB(player, 0, player->GetLastPetNumber(), true)) { - Player* player = GetCaster()->ToPlayer(); - if (player->GetLastPetNumber()) - { - PetType newPetType = (player->getClass() == CLASS_HUNTER) ? HUNTER_PET : SUMMON_PET; - Pet* newPet = new Pet(player, newPetType); - if (newPet->LoadPetFromDB(player, 0, player->GetLastPetNumber(), true)) - { - // revive the pet if it is dead - if (newPet->getDeathState() == DEAD) - newPet->setDeathState(ALIVE); + // revive the pet if it is dead + if (newPet->getDeathState() == DEAD) + newPet->setDeathState(ALIVE); - newPet->SetFullHealth(); - newPet->SetPower(newPet->getPowerType(), newPet->GetMaxPower(newPet->getPowerType())); + newPet->SetFullHealth(); + newPet->SetPower(newPet->getPowerType(), newPet->GetMaxPower(newPet->getPowerType())); - switch (newPet->GetEntry()) - { - case NPC_DOOMGUARD: - case NPC_INFERNAL: - newPet->SetEntry(NPC_IMP); - break; - default: - break; - } - } - else - delete newPet; + switch (newPet->GetEntry()) + { + case NPC_DOOMGUARD: + case NPC_INFERNAL: + newPet->SetEntry(NPC_IMP); + break; + default: + break; } } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_gen_pet_summoned_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - } - }; - - SpellScript* GetSpellScript() const override - { - return new spell_gen_pet_summoned_SpellScript(); + else + delete newPet; } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_gen_pet_summoned::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } }; -class spell_gen_profession_research : public SpellScriptLoader +class spell_gen_profession_research : public SpellScript { - public: - spell_gen_profession_research() : SpellScriptLoader("spell_gen_profession_research") { } + PrepareSpellScript(spell_gen_profession_research); - class spell_gen_profession_research_SpellScript : public SpellScript - { - PrepareSpellScript(spell_gen_profession_research_SpellScript); - - bool Load() override - { - return GetCaster()->GetTypeId() == TYPEID_PLAYER; - } - - SpellCastResult CheckRequirement() - { - if (HasDiscoveredAllSpells(GetSpellInfo()->Id, GetCaster()->ToPlayer())) - { - SetCustomCastResultMessage(SPELL_CUSTOM_ERROR_NOTHING_TO_DISCOVER); - return SPELL_FAILED_CUSTOM_ERROR; - } + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } - return SPELL_CAST_OK; - } + SpellCastResult CheckRequirement() + { + if (HasDiscoveredAllSpells(GetSpellInfo()->Id, GetCaster()->ToPlayer())) + { + SetCustomCastResultMessage(SPELL_CUSTOM_ERROR_NOTHING_TO_DISCOVER); + return SPELL_FAILED_CUSTOM_ERROR; + } - void HandleScript(SpellEffIndex /*effIndex*/) - { - Player* caster = GetCaster()->ToPlayer(); - uint32 spellId = GetSpellInfo()->Id; + return SPELL_CAST_OK; + } - // learn random explicit discovery recipe (if any) - if (uint32 discoveredSpellId = GetExplicitDiscoverySpell(spellId, caster)) - caster->LearnSpell(discoveredSpellId, false); + void HandleScript(SpellEffIndex /*effIndex*/) + { + Player* caster = GetCaster()->ToPlayer(); + uint32 spellId = GetSpellInfo()->Id; - caster->UpdateCraftSkill(spellId); - } + // learn random explicit discovery recipe (if any) + if (uint32 discoveredSpellId = GetExplicitDiscoverySpell(spellId, caster)) + caster->LearnSpell(discoveredSpellId, false); - void Register() override - { - OnCheckCast += SpellCheckCastFn(spell_gen_profession_research_SpellScript::CheckRequirement); - OnEffectHitTarget += SpellEffectFn(spell_gen_profession_research_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); - } - }; + caster->UpdateCraftSkill(spellId); + } - SpellScript* GetSpellScript() const override - { - return new spell_gen_profession_research_SpellScript(); - } + void Register() override + { + OnCheckCast += SpellCheckCastFn(spell_gen_profession_research::CheckRequirement); + OnEffectHitTarget += SpellEffectFn(spell_gen_profession_research::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); + } }; -class spell_gen_remove_flight_auras : public SpellScriptLoader +class spell_gen_remove_flight_auras : public SpellScript { - public: - spell_gen_remove_flight_auras() : SpellScriptLoader("spell_gen_remove_flight_auras") { } - - class spell_gen_remove_flight_auras_SpellScript : public SpellScript - { - PrepareSpellScript(spell_gen_remove_flight_auras_SpellScript); - - void HandleScript(SpellEffIndex /*effIndex*/) - { - if (Unit* target = GetHitUnit()) - { - target->RemoveAurasByType(SPELL_AURA_FLY); - target->RemoveAurasByType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED); - } - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_gen_remove_flight_auras_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); - } - }; + PrepareSpellScript(spell_gen_remove_flight_auras); - SpellScript* GetSpellScript() const override + void HandleScript(SpellEffIndex /*effIndex*/) + { + if (Unit* target = GetHitUnit()) { - return new spell_gen_remove_flight_auras_SpellScript(); + target->RemoveAurasByType(SPELL_AURA_FLY); + target->RemoveAurasByType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED); } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_gen_remove_flight_auras::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); + } }; enum Replenishment @@ -2836,84 +2340,68 @@ public: } }; -class spell_gen_replenishment : public SpellScriptLoader +class spell_gen_replenishment : public SpellScript { - public: - spell_gen_replenishment() : SpellScriptLoader("spell_gen_replenishment") { } + PrepareSpellScript(spell_gen_replenishment); - class spell_gen_replenishment_SpellScript : public SpellScript + void RemoveInvalidTargets(std::list<WorldObject*>& targets) + { + // In arenas Replenishment may only affect the caster + if (Player* caster = GetCaster()->ToPlayer()) { - PrepareSpellScript(spell_gen_replenishment_SpellScript); - - void RemoveInvalidTargets(std::list<WorldObject*>& targets) + if (caster->InArena()) { - // In arenas Replenishment may only affect the caster - if (Player* caster = GetCaster()->ToPlayer()) - { - if (caster->InArena()) - { - targets.clear(); - targets.push_back(caster); - return; - } - } - - targets.remove_if(ReplenishmentCheck()); - - uint8 const maxTargets = 10; - - if (targets.size() > maxTargets) - { - targets.sort(Trinity::PowerPctOrderPred(POWER_MANA)); - targets.resize(maxTargets); - } + targets.clear(); + targets.push_back(caster); + return; } + } - void Register() override - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_gen_replenishment_SpellScript::RemoveInvalidTargets, EFFECT_ALL, TARGET_UNIT_CASTER_AREA_RAID); - } - }; + targets.remove_if(ReplenishmentCheck()); - SpellScript* GetSpellScript() const override - { - return new spell_gen_replenishment_SpellScript(); - } + uint8 const maxTargets = 10; - class spell_gen_replenishment_AuraScript : public AuraScript + if (targets.size() > maxTargets) { - PrepareAuraScript(spell_gen_replenishment_AuraScript); + targets.sort(Trinity::PowerPctOrderPred(POWER_MANA)); + targets.resize(maxTargets); + } + } - bool Load() override - { - return GetUnitOwner()->getPowerType() == POWER_MANA; - } + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_gen_replenishment::RemoveInvalidTargets, EFFECT_ALL, TARGET_UNIT_CASTER_AREA_RAID); + } +}; - void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/) - { - switch (GetSpellInfo()->Id) - { - case SPELL_REPLENISHMENT: - amount = GetUnitOwner()->GetMaxPower(POWER_MANA) * 0.002f; - break; - case SPELL_INFINITE_REPLENISHMENT: - amount = GetUnitOwner()->GetMaxPower(POWER_MANA) * 0.0025f; - break; - default: - break; - } - } +class spell_gen_replenishment_aura : public AuraScript +{ + PrepareAuraScript(spell_gen_replenishment_aura); - void Register() override - { - DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_replenishment_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_PERIODIC_ENERGIZE); - } - }; + bool Load() override + { + return GetUnitOwner()->getPowerType() == POWER_MANA; + } - AuraScript* GetAuraScript() const override + void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/) + { + switch (GetSpellInfo()->Id) { - return new spell_gen_replenishment_AuraScript(); + case SPELL_REPLENISHMENT: + amount = GetUnitOwner()->GetMaxPower(POWER_MANA) * 0.002f; + break; + case SPELL_INFINITE_REPLENISHMENT: + amount = GetUnitOwner()->GetMaxPower(POWER_MANA) * 0.0025f; + break; + default: + break; } + } + + void Register() override + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_replenishment_aura::CalculateAmount, EFFECT_0, SPELL_AURA_PERIODIC_ENERGIZE); + } }; enum SeaforiumSpells @@ -2921,45 +2409,34 @@ enum SeaforiumSpells SPELL_PLANT_CHARGES_CREDIT_ACHIEVEMENT = 60937 }; -class spell_gen_seaforium_blast : public SpellScriptLoader +class spell_gen_seaforium_blast : public SpellScript { - public: - spell_gen_seaforium_blast() : SpellScriptLoader("spell_gen_seaforium_blast") { } - - class spell_gen_seaforium_blast_SpellScript : public SpellScript - { - PrepareSpellScript(spell_gen_seaforium_blast_SpellScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_PLANT_CHARGES_CREDIT_ACHIEVEMENT }); - } + PrepareSpellScript(spell_gen_seaforium_blast); - bool Load() override - { - // OriginalCaster is always available in Spell::prepare - return GetOriginalCaster()->GetTypeId() == TYPEID_PLAYER; - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_PLANT_CHARGES_CREDIT_ACHIEVEMENT }); + } - void AchievementCredit(SpellEffIndex /*effIndex*/) - { - // but in effect handling OriginalCaster can become nullptr - if (Unit* originalCaster = GetOriginalCaster()) - if (GameObject* go = GetHitGObj()) - if (go->GetGOInfo()->type == GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING) - originalCaster->CastSpell(originalCaster, SPELL_PLANT_CHARGES_CREDIT_ACHIEVEMENT, true); - } + bool Load() override + { + // OriginalCaster is always available in Spell::prepare + return GetOriginalCaster()->GetTypeId() == TYPEID_PLAYER; + } - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_gen_seaforium_blast_SpellScript::AchievementCredit, EFFECT_1, SPELL_EFFECT_GAMEOBJECT_DAMAGE); - } - }; + void AchievementCredit(SpellEffIndex /*effIndex*/) + { + // but in effect handling OriginalCaster can become nullptr + if (Unit* originalCaster = GetOriginalCaster()) + if (GameObject* go = GetHitGObj()) + if (go->GetGOInfo()->type == GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING) + originalCaster->CastSpell(originalCaster, SPELL_PLANT_CHARGES_CREDIT_ACHIEVEMENT, true); + } - SpellScript* GetSpellScript() const override - { - return new spell_gen_seaforium_blast_SpellScript(); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_gen_seaforium_blast::AchievementCredit, EFFECT_1, SPELL_EFFECT_GAMEOBJECT_DAMAGE); + } }; enum SpectatorCheerTrigger @@ -2971,67 +2448,45 @@ enum SpectatorCheerTrigger uint8 const EmoteArray[3] = { EMOTE_ONE_SHOT_CHEER, EMOTE_ONE_SHOT_EXCLAMATION, EMOTE_ONE_SHOT_APPLAUD }; -class spell_gen_spectator_cheer_trigger : public SpellScriptLoader +class spell_gen_spectator_cheer_trigger : public SpellScript { - public: - spell_gen_spectator_cheer_trigger() : SpellScriptLoader("spell_gen_spectator_cheer_trigger") { } - - class spell_gen_spectator_cheer_trigger_SpellScript : public SpellScript - { - PrepareSpellScript(spell_gen_spectator_cheer_trigger_SpellScript); + PrepareSpellScript(spell_gen_spectator_cheer_trigger); - void HandleDummy(SpellEffIndex /*effIndex*/) - { - GetCaster()->HandleEmoteCommand(EmoteArray[urand(0, 2)]); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_gen_spectator_cheer_trigger_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + void HandleDummy(SpellEffIndex /*effIndex*/) + { + GetCaster()->HandleEmoteCommand(EmoteArray[urand(0, 2)]); + } - SpellScript* GetSpellScript() const override - { - return new spell_gen_spectator_cheer_trigger_SpellScript(); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_gen_spectator_cheer_trigger::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; -class spell_gen_spirit_healer_res : public SpellScriptLoader +class spell_gen_spirit_healer_res : public SpellScript { - public: - spell_gen_spirit_healer_res(): SpellScriptLoader("spell_gen_spirit_healer_res") { } - - class spell_gen_spirit_healer_res_SpellScript : public SpellScript - { - PrepareSpellScript(spell_gen_spirit_healer_res_SpellScript); - - bool Load() override - { - return GetOriginalCaster() && GetOriginalCaster()->GetTypeId() == TYPEID_PLAYER; - } - - void HandleDummy(SpellEffIndex /* effIndex */) - { - Player* originalCaster = GetOriginalCaster()->ToPlayer(); - if (Unit* target = GetHitUnit()) - { - WorldPacket data(SMSG_SPIRIT_HEALER_CONFIRM, 8); - data << uint64(target->GetGUID()); - originalCaster->SendDirectMessage(&data); - } - } + PrepareSpellScript(spell_gen_spirit_healer_res); - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_gen_spirit_healer_res_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + bool Load() override + { + return GetOriginalCaster() && GetOriginalCaster()->GetTypeId() == TYPEID_PLAYER; + } - SpellScript* GetSpellScript() const override + void HandleDummy(SpellEffIndex /* effIndex */) + { + Player* originalCaster = GetOriginalCaster()->ToPlayer(); + if (Unit* target = GetHitUnit()) { - return new spell_gen_spirit_healer_res_SpellScript(); + WorldPacket data(SMSG_SPIRIT_HEALER_CONFIRM, 8); + data << uint64(target->GetGUID()); + originalCaster->SendDirectMessage(&data); } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_gen_spirit_healer_res::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; enum SummonElemental @@ -3096,72 +2551,50 @@ enum TournamentMountsSpells SPELL_LANCE_EQUIPPED = 62853 }; -class spell_gen_summon_tournament_mount : public SpellScriptLoader +class spell_gen_summon_tournament_mount : public SpellScript { - public: - spell_gen_summon_tournament_mount() : SpellScriptLoader("spell_gen_summon_tournament_mount") { } - - class spell_gen_summon_tournament_mount_SpellScript : public SpellScript - { - PrepareSpellScript(spell_gen_summon_tournament_mount_SpellScript); + PrepareSpellScript(spell_gen_summon_tournament_mount); - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_LANCE_EQUIPPED }); - } - - SpellCastResult CheckIfLanceEquiped() - { - if (GetCaster()->IsInDisallowedMountForm()) - GetCaster()->RemoveAurasByType(SPELL_AURA_MOD_SHAPESHIFT); - - if (!GetCaster()->HasAura(SPELL_LANCE_EQUIPPED)) - { - SetCustomCastResultMessage(SPELL_CUSTOM_ERROR_MUST_HAVE_LANCE_EQUIPPED); - return SPELL_FAILED_CUSTOM_ERROR; - } - - return SPELL_CAST_OK; - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_LANCE_EQUIPPED }); + } - void Register() override - { - OnCheckCast += SpellCheckCastFn(spell_gen_summon_tournament_mount_SpellScript::CheckIfLanceEquiped); - } - }; + SpellCastResult CheckIfLanceEquiped() + { + if (GetCaster()->IsInDisallowedMountForm()) + GetCaster()->RemoveAurasByType(SPELL_AURA_MOD_SHAPESHIFT); - SpellScript* GetSpellScript() const override + if (!GetCaster()->HasAura(SPELL_LANCE_EQUIPPED)) { - return new spell_gen_summon_tournament_mount_SpellScript(); + SetCustomCastResultMessage(SPELL_CUSTOM_ERROR_MUST_HAVE_LANCE_EQUIPPED); + return SPELL_FAILED_CUSTOM_ERROR; } + + return SPELL_CAST_OK; + } + + void Register() override + { + OnCheckCast += SpellCheckCastFn(spell_gen_summon_tournament_mount::CheckIfLanceEquiped); + } }; // 41213, 43416, 69222, 73076 - Throw Shield -class spell_gen_throw_shield : public SpellScriptLoader +class spell_gen_throw_shield : public SpellScript { - public: - spell_gen_throw_shield() : SpellScriptLoader("spell_gen_throw_shield") { } - - class spell_gen_throw_shield_SpellScript : public SpellScript - { - PrepareSpellScript(spell_gen_throw_shield_SpellScript); - - void HandleScriptEffect(SpellEffIndex effIndex) - { - PreventHitDefaultEffect(effIndex); - GetCaster()->CastSpell(GetHitUnit(), uint32(GetEffectValue()), true); - } + PrepareSpellScript(spell_gen_throw_shield); - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_gen_throw_shield_SpellScript::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); - } - }; + void HandleScriptEffect(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + GetCaster()->CastSpell(GetHitUnit(), uint32(GetEffectValue()), true); + } - SpellScript* GetSpellScript() const override - { - return new spell_gen_throw_shield_SpellScript(); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_gen_throw_shield::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); + } }; enum MountedDuelSpells @@ -3170,84 +2603,62 @@ enum MountedDuelSpells SPELL_MOUNTED_DUEL = 62875 }; -class spell_gen_tournament_duel : public SpellScriptLoader +class spell_gen_tournament_duel : public SpellScript { - public: - spell_gen_tournament_duel() : SpellScriptLoader("spell_gen_tournament_duel") { } + PrepareSpellScript(spell_gen_tournament_duel); - class spell_gen_tournament_duel_SpellScript : public SpellScript + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( { - PrepareSpellScript(spell_gen_tournament_duel_SpellScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_ON_TOURNAMENT_MOUNT, - SPELL_MOUNTED_DUEL - }); - } + SPELL_ON_TOURNAMENT_MOUNT, + SPELL_MOUNTED_DUEL + }); + } - void HandleScriptEffect(SpellEffIndex /*effIndex*/) + void HandleScriptEffect(SpellEffIndex /*effIndex*/) + { + if (Unit* rider = GetCaster()->GetCharmer()) + { + if (Player* playerTarget = GetHitPlayer()) { - if (Unit* rider = GetCaster()->GetCharmer()) - { - if (Player* playerTarget = GetHitPlayer()) - { - if (playerTarget->HasAura(SPELL_ON_TOURNAMENT_MOUNT) && playerTarget->GetVehicleBase()) - rider->CastSpell(playerTarget, SPELL_MOUNTED_DUEL, true); - } - else if (Unit* unitTarget = GetHitUnit()) - { - if (unitTarget->GetCharmer() && unitTarget->GetCharmer()->GetTypeId() == TYPEID_PLAYER && unitTarget->GetCharmer()->HasAura(SPELL_ON_TOURNAMENT_MOUNT)) - rider->CastSpell(unitTarget->GetCharmer(), SPELL_MOUNTED_DUEL, true); - } - } + if (playerTarget->HasAura(SPELL_ON_TOURNAMENT_MOUNT) && playerTarget->GetVehicleBase()) + rider->CastSpell(playerTarget, SPELL_MOUNTED_DUEL, true); } - - void Register() override + else if (Unit* unitTarget = GetHitUnit()) { - OnEffectHitTarget += SpellEffectFn(spell_gen_tournament_duel_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + if (unitTarget->GetCharmer() && unitTarget->GetCharmer()->GetTypeId() == TYPEID_PLAYER && unitTarget->GetCharmer()->HasAura(SPELL_ON_TOURNAMENT_MOUNT)) + rider->CastSpell(unitTarget->GetCharmer(), SPELL_MOUNTED_DUEL, true); } - }; - - SpellScript* GetSpellScript() const override - { - return new spell_gen_tournament_duel_SpellScript(); } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_gen_tournament_duel::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } }; -class spell_gen_tournament_pennant : public SpellScriptLoader +class spell_gen_tournament_pennant : public AuraScript { - public: - spell_gen_tournament_pennant() : SpellScriptLoader("spell_gen_tournament_pennant") { } - - class spell_gen_tournament_pennant_AuraScript : public AuraScript - { - PrepareAuraScript(spell_gen_tournament_pennant_AuraScript); - - bool Load() override - { - return GetCaster() && GetCaster()->GetTypeId() == TYPEID_PLAYER; - } + PrepareAuraScript(spell_gen_tournament_pennant); - void HandleApplyEffect(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - if (Unit* caster = GetCaster()) - if (!caster->GetVehicleBase()) - caster->RemoveAurasDueToSpell(GetId()); - } + bool Load() override + { + return GetCaster() && GetCaster()->GetTypeId() == TYPEID_PLAYER; + } - void Register() override - { - OnEffectApply += AuraEffectApplyFn(spell_gen_tournament_pennant_AuraScript::HandleApplyEffect, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); - } - }; + void HandleApplyEffect(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Unit* caster = GetCaster()) + if (!caster->GetVehicleBase()) + caster->RemoveAurasDueToSpell(GetId()); + } - AuraScript* GetAuraScript() const override - { - return new spell_gen_tournament_pennant_AuraScript(); - } + void Register() override + { + OnEffectApply += AuraEffectApplyFn(spell_gen_tournament_pennant::HandleApplyEffect, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); + } }; enum PvPTrinketTriggeredSpells @@ -3294,7 +2705,7 @@ class spell_pvp_trinket_wotf_shared_cd : public SpellScriptLoader */ // Spell flags need further research, until then just cast not triggered - GetCaster()->CastSpell((Unit*)nullptr, Triggered, false); + GetCaster()->CastSpell(nullptr, Triggered, false); } void Register() override @@ -3314,49 +2725,38 @@ enum FriendOrFowl SPELL_TURKEY_VENGEANCE = 25285 }; -class spell_gen_turkey_marker : public SpellScriptLoader +class spell_gen_turkey_marker : public AuraScript { - public: - spell_gen_turkey_marker() : SpellScriptLoader("spell_gen_turkey_marker") { } - - class spell_gen_turkey_marker_AuraScript : public AuraScript - { - PrepareAuraScript(spell_gen_turkey_marker_AuraScript); - - void OnApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) - { - // store stack apply times, so we can pop them while they expire - _applyTimes.push_back(GameTime::GetGameTimeMS()); - Unit* target = GetTarget(); + PrepareAuraScript(spell_gen_turkey_marker); - // on stack 15 cast the achievement crediting spell - if (GetStackAmount() >= 15) - target->CastSpell(target, SPELL_TURKEY_VENGEANCE, true, nullptr, aurEff, GetCasterGUID()); - } + void OnApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) + { + // store stack apply times, so we can pop them while they expire + _applyTimes.push_back(GameTime::GetGameTimeMS()); + Unit* target = GetTarget(); - void OnPeriodic(AuraEffect const* /*aurEff*/) - { - if (_applyTimes.empty()) - return; + // on stack 15 cast the achievement crediting spell + if (GetStackAmount() >= 15) + target->CastSpell(target, SPELL_TURKEY_VENGEANCE, true, nullptr, aurEff, GetCasterGUID()); + } - // pop stack if it expired for us - if (_applyTimes.front() + GetMaxDuration() < GameTime::GetGameTimeMS()) - ModStackAmount(-1, AURA_REMOVE_BY_EXPIRE); - } + void OnPeriodic(AuraEffect const* /*aurEff*/) + { + if (_applyTimes.empty()) + return; - void Register() override - { - AfterEffectApply += AuraEffectApplyFn(spell_gen_turkey_marker_AuraScript::OnApply, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); - OnEffectPeriodic += AuraEffectPeriodicFn(spell_gen_turkey_marker_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); - } + // pop stack if it expired for us + if (_applyTimes.front() + GetMaxDuration() < GameTime::GetGameTimeMS()) + ModStackAmount(-1, AURA_REMOVE_BY_EXPIRE); + } - std::list<uint32> _applyTimes; - }; + void Register() override + { + AfterEffectApply += AuraEffectApplyFn(spell_gen_turkey_marker::OnApply, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); + OnEffectPeriodic += AuraEffectPeriodicFn(spell_gen_turkey_marker::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + } - AuraScript* GetAuraScript() const override - { - return new spell_gen_turkey_marker_AuraScript(); - } + std::list<uint32> _applyTimes; }; enum FoamSword @@ -3368,41 +2768,30 @@ enum FoamSword ITEM_FOAM_SWORD_YELLOW = 45179 }; -class spell_gen_upper_deck_create_foam_sword : public SpellScriptLoader +class spell_gen_upper_deck_create_foam_sword : public SpellScript { - public: - spell_gen_upper_deck_create_foam_sword() : SpellScriptLoader("spell_gen_upper_deck_create_foam_sword") { } + PrepareSpellScript(spell_gen_upper_deck_create_foam_sword); - class spell_gen_upper_deck_create_foam_sword_SpellScript : public SpellScript + void HandleScript(SpellEffIndex effIndex) + { + if (Player* player = GetHitPlayer()) { - PrepareSpellScript(spell_gen_upper_deck_create_foam_sword_SpellScript); - - void HandleScript(SpellEffIndex effIndex) - { - if (Player* player = GetHitPlayer()) - { - static uint32 const itemId[5] = { ITEM_FOAM_SWORD_GREEN, ITEM_FOAM_SWORD_PINK, ITEM_FOAM_SWORD_BLUE, ITEM_FOAM_SWORD_RED, ITEM_FOAM_SWORD_YELLOW }; - // player can only have one of these items - for (uint8 i = 0; i < 5; ++i) - { - if (player->HasItemCount(itemId[i], 1, true)) - return; - } - - CreateItem(effIndex, itemId[urand(0, 4)]); - } - } - - void Register() override + static uint32 const itemId[5] = { ITEM_FOAM_SWORD_GREEN, ITEM_FOAM_SWORD_PINK, ITEM_FOAM_SWORD_BLUE, ITEM_FOAM_SWORD_RED, ITEM_FOAM_SWORD_YELLOW }; + // player can only have one of these items + for (uint8 i = 0; i < 5; ++i) { - OnEffectHitTarget += SpellEffectFn(spell_gen_upper_deck_create_foam_sword_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + if (player->HasItemCount(itemId[i], 1, true)) + return; } - }; - SpellScript* GetSpellScript() const override - { - return new spell_gen_upper_deck_create_foam_sword_SpellScript(); + CreateItem(effIndex, itemId[urand(0, 4)]); } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_gen_upper_deck_create_foam_sword::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } }; enum VampiricTouch @@ -3412,42 +2801,31 @@ enum VampiricTouch // 52723 - Vampiric Touch // 60501 - Vampiric Touch -class spell_gen_vampiric_touch : public SpellScriptLoader +class spell_gen_vampiric_touch : public AuraScript { - public: - spell_gen_vampiric_touch() : SpellScriptLoader("spell_gen_vampiric_touch") { } + PrepareAuraScript(spell_gen_vampiric_touch); - class spell_gen_vampiric_touch_AuraScript : public AuraScript - { - PrepareAuraScript(spell_gen_vampiric_touch_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_VAMPIRIC_TOUCH_HEAL }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - DamageInfo* damageInfo = eventInfo.GetDamageInfo(); - if (!damageInfo || !damageInfo->GetDamage()) - return; - - Unit* caster = eventInfo.GetActor(); - int32 bp = damageInfo->GetDamage() / 2; - caster->CastCustomSpell(SPELL_VAMPIRIC_TOUCH_HEAL, SPELLVALUE_BASE_POINT0, bp, caster, true, nullptr, aurEff); - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_VAMPIRIC_TOUCH_HEAL }); + } - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_gen_vampiric_touch_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } - }; + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + DamageInfo* damageInfo = eventInfo.GetDamageInfo(); + if (!damageInfo || !damageInfo->GetDamage()) + return; + + Unit* caster = eventInfo.GetActor(); + int32 bp = damageInfo->GetDamage() / 2; + caster->CastCustomSpell(SPELL_VAMPIRIC_TOUCH_HEAL, SPELLVALUE_BASE_POINT0, bp, caster, true, nullptr, aurEff); + } - AuraScript* GetAuraScript() const override - { - return new spell_gen_vampiric_touch_AuraScript(); - } + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_gen_vampiric_touch::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } }; enum VehicleScaling @@ -3455,58 +2833,47 @@ enum VehicleScaling SPELL_GEAR_SCALING = 66668 }; -class spell_gen_vehicle_scaling : public SpellScriptLoader +class spell_gen_vehicle_scaling : public AuraScript { - public: - spell_gen_vehicle_scaling() : SpellScriptLoader("spell_gen_vehicle_scaling") { } - - class spell_gen_vehicle_scaling_AuraScript : public AuraScript - { - PrepareAuraScript(spell_gen_vehicle_scaling_AuraScript); + PrepareAuraScript(spell_gen_vehicle_scaling); - bool Load() override - { - return GetCaster() && GetCaster()->GetTypeId() == TYPEID_PLAYER; - } - - void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/) - { - Unit* caster = GetCaster(); - float factor; - uint16 baseItemLevel; + bool Load() override + { + return GetCaster() && GetCaster()->GetTypeId() == TYPEID_PLAYER; + } - /// @todo Reserach coeffs for different vehicles - switch (GetId()) - { - case SPELL_GEAR_SCALING: - factor = 1.0f; - baseItemLevel = 205; - break; - default: - factor = 1.0f; - baseItemLevel = 170; - break; - } + void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/) + { + Unit* caster = GetCaster(); + float factor; + uint16 baseItemLevel; - float avgILvl = caster->ToPlayer()->GetAverageItemLevel(); - if (avgILvl < baseItemLevel) - return; /// @todo Research possibility of scaling down + /// @todo Reserach coeffs for different vehicles + switch (GetId()) + { + case SPELL_GEAR_SCALING: + factor = 1.0f; + baseItemLevel = 205; + break; + default: + factor = 1.0f; + baseItemLevel = 170; + break; + } - amount = uint16((avgILvl - baseItemLevel) * factor); - } + float avgILvl = caster->ToPlayer()->GetAverageItemLevel(); + if (avgILvl < baseItemLevel) + return; /// @todo Research possibility of scaling down - void Register() override - { - DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_vehicle_scaling_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_MOD_HEALING_PCT); - DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_vehicle_scaling_AuraScript::CalculateAmount, EFFECT_1, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); - DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_vehicle_scaling_AuraScript::CalculateAmount, EFFECT_2, SPELL_AURA_MOD_INCREASE_HEALTH_PERCENT); - } - }; + amount = uint16((avgILvl - baseItemLevel) * factor); + } - AuraScript* GetAuraScript() const override - { - return new spell_gen_vehicle_scaling_AuraScript(); - } + void Register() override + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_vehicle_scaling::CalculateAmount, EFFECT_0, SPELL_AURA_MOD_HEALING_PCT); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_vehicle_scaling::CalculateAmount, EFFECT_1, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_vehicle_scaling::CalculateAmount, EFFECT_2, SPELL_AURA_MOD_INCREASE_HEALTH_PERCENT); + } }; enum VendorBarkTrigger @@ -3515,61 +2882,38 @@ enum VendorBarkTrigger SAY_AMPHITHEATER_VENDOR = 0 }; -class spell_gen_vendor_bark_trigger : public SpellScriptLoader +class spell_gen_vendor_bark_trigger : public SpellScript { - public: - spell_gen_vendor_bark_trigger() : SpellScriptLoader("spell_gen_vendor_bark_trigger") { } - - class spell_gen_vendor_bark_trigger_SpellScript : public SpellScript - { - PrepareSpellScript(spell_gen_vendor_bark_trigger_SpellScript); + PrepareSpellScript(spell_gen_vendor_bark_trigger); - void HandleDummy(SpellEffIndex /* effIndex */) - { - if (Creature* vendor = GetCaster()->ToCreature()) - if (vendor->GetEntry() == NPC_AMPHITHEATER_VENDOR) - vendor->AI()->Talk(SAY_AMPHITHEATER_VENDOR); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_gen_vendor_bark_trigger_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; - - SpellScript* GetSpellScript() const override - { - return new spell_gen_vendor_bark_trigger_SpellScript(); - } + void HandleDummy(SpellEffIndex /* effIndex */) + { + if (Creature* vendor = GetCaster()->ToCreature()) + if (vendor->GetEntry() == NPC_AMPHITHEATER_VENDOR) + vendor->AI()->Talk(SAY_AMPHITHEATER_VENDOR); + } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_gen_vendor_bark_trigger::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; -class spell_gen_wg_water : public SpellScriptLoader +class spell_gen_wg_water : public SpellScript { - public: - spell_gen_wg_water() : SpellScriptLoader("spell_gen_wg_water") { } - - class spell_gen_wg_water_SpellScript : public SpellScript - { - PrepareSpellScript(spell_gen_wg_water_SpellScript); - - SpellCastResult CheckCast() - { - if (!GetSpellInfo()->CheckTargetCreatureType(GetCaster())) - return SPELL_FAILED_DONT_REPORT; - return SPELL_CAST_OK; - } + PrepareSpellScript(spell_gen_wg_water); - void Register() override - { - OnCheckCast += SpellCheckCastFn(spell_gen_wg_water_SpellScript::CheckCast); - } - }; + SpellCastResult CheckCast() + { + if (!GetSpellInfo()->CheckTargetCreatureType(GetCaster())) + return SPELL_FAILED_DONT_REPORT; + return SPELL_CAST_OK; + } - SpellScript* GetSpellScript() const override - { - return new spell_gen_wg_water_SpellScript(); - } + void Register() override + { + OnCheckCast += SpellCheckCastFn(spell_gen_wg_water::CheckCast); + } }; enum WhisperGulchYoggSaronWhisper @@ -3577,100 +2921,67 @@ enum WhisperGulchYoggSaronWhisper SPELL_YOGG_SARON_WHISPER_DUMMY = 29072 }; -class spell_gen_whisper_gulch_yogg_saron_whisper : public SpellScriptLoader +class spell_gen_whisper_gulch_yogg_saron_whisper : public AuraScript { - public: - spell_gen_whisper_gulch_yogg_saron_whisper() : SpellScriptLoader("spell_gen_whisper_gulch_yogg_saron_whisper") { } - - class spell_gen_whisper_gulch_yogg_saron_whisper_AuraScript : public AuraScript - { - PrepareAuraScript(spell_gen_whisper_gulch_yogg_saron_whisper_AuraScript); + PrepareAuraScript(spell_gen_whisper_gulch_yogg_saron_whisper); - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_YOGG_SARON_WHISPER_DUMMY }); - } - - void HandleEffectPeriodic(AuraEffect const* /*aurEff*/) - { - PreventDefaultAction(); - GetTarget()->CastSpell((Unit*)nullptr, SPELL_YOGG_SARON_WHISPER_DUMMY, true); - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_YOGG_SARON_WHISPER_DUMMY }); + } - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_gen_whisper_gulch_yogg_saron_whisper_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); - } - }; + void HandleEffectPeriodic(AuraEffect const* /*aurEff*/) + { + PreventDefaultAction(); + GetTarget()->CastSpell(nullptr, SPELL_YOGG_SARON_WHISPER_DUMMY, true); + } - AuraScript* GetAuraScript() const override - { - return new spell_gen_whisper_gulch_yogg_saron_whisper_AuraScript(); - } + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_gen_whisper_gulch_yogg_saron_whisper::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + } }; -class spell_gen_eject_all_passengers : public SpellScriptLoader +class spell_gen_eject_all_passengers : public SpellScript { - public: - spell_gen_eject_all_passengers() : SpellScriptLoader("spell_gen_eject_all_passengers") { } - - class spell_gen_eject_all_passengers_SpellScript : public SpellScript - { - PrepareSpellScript(spell_gen_eject_all_passengers_SpellScript); - - void RemoveVehicleAuras() - { - if (Vehicle* vehicle = GetHitUnit()->GetVehicleKit()) - vehicle->RemoveAllPassengers(); - } + PrepareSpellScript(spell_gen_eject_all_passengers); - void Register() override - { - AfterHit += SpellHitFn(spell_gen_eject_all_passengers_SpellScript::RemoveVehicleAuras); - } - }; + void RemoveVehicleAuras() + { + if (Vehicle* vehicle = GetHitUnit()->GetVehicleKit()) + vehicle->RemoveAllPassengers(); + } - SpellScript* GetSpellScript() const override - { - return new spell_gen_eject_all_passengers_SpellScript(); - } + void Register() override + { + AfterHit += SpellHitFn(spell_gen_eject_all_passengers::RemoveVehicleAuras); + } }; -class spell_gen_eject_passenger : public SpellScriptLoader +class spell_gen_eject_passenger : public SpellScript { - public: - spell_gen_eject_passenger() : SpellScriptLoader("spell_gen_eject_passenger") { } - - class spell_gen_eject_passenger_SpellScript : public SpellScript - { - PrepareSpellScript(spell_gen_eject_passenger_SpellScript); - - bool Validate(SpellInfo const* spellInfo) override - { - if (spellInfo->Effects[EFFECT_0].CalcValue() < 1) - return false; - return true; - } - - void EjectPassenger(SpellEffIndex /*effIndex*/) - { - if (Vehicle* vehicle = GetHitUnit()->GetVehicleKit()) - { - if (Unit* passenger = vehicle->GetPassenger(GetEffectValue() - 1)) - passenger->ExitVehicle(); - } - } + PrepareSpellScript(spell_gen_eject_passenger); - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_gen_eject_passenger_SpellScript::EjectPassenger, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - } - }; + bool Validate(SpellInfo const* spellInfo) override + { + if (spellInfo->Effects[EFFECT_0].CalcValue() < 1) + return false; + return true; + } - SpellScript* GetSpellScript() const override + void EjectPassenger(SpellEffIndex /*effIndex*/) + { + if (Vehicle* vehicle = GetHitUnit()->GetVehicleKit()) { - return new spell_gen_eject_passenger_SpellScript(); + if (Unit* passenger = vehicle->GetPassenger(GetEffectValue() - 1)) + passenger->ExitVehicle(); } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_gen_eject_passenger::EjectPassenger, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } }; enum GMFreeze @@ -3678,100 +2989,78 @@ enum GMFreeze SPELL_GM_FREEZE = 9454 }; -class spell_gen_gm_freeze : public SpellScriptLoader +class spell_gen_gm_freeze : public AuraScript { - public: - spell_gen_gm_freeze() : SpellScriptLoader("spell_gen_gm_freeze") { } - - class spell_gen_gm_freeze_AuraScript : public AuraScript - { - PrepareAuraScript(spell_gen_gm_freeze_AuraScript); + PrepareAuraScript(spell_gen_gm_freeze); - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_GM_FREEZE }); - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_GM_FREEZE }); + } - void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - // Do what was done before to the target in HandleFreezeCommand - if (Player* player = GetTarget()->ToPlayer()) - { - // stop combat + make player unattackable + duel stop + stop some spells - player->SetFaction(FACTION_FRIENDLY); - player->CombatStop(); - if (player->IsNonMeleeSpellCast(true)) - player->InterruptNonMeleeSpells(true); - player->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - - // if player class = hunter || warlock remove pet if alive - if ((player->getClass() == CLASS_HUNTER) || (player->getClass() == CLASS_WARLOCK)) - { - if (Pet* pet = player->GetPet()) - { - pet->SavePetToDB(PET_SAVE_AS_CURRENT); - // not let dismiss dead pet - if (pet->IsAlive()) - player->RemovePet(pet, PET_SAVE_NOT_IN_SLOT); - } - } - } - } + void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + // Do what was done before to the target in HandleFreezeCommand + if (Player* player = GetTarget()->ToPlayer()) + { + // stop combat + make player unattackable + duel stop + stop some spells + player->SetFaction(FACTION_FRIENDLY); + player->CombatStop(); + if (player->IsNonMeleeSpellCast(true)) + player->InterruptNonMeleeSpells(true); + player->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + // if player class = hunter || warlock remove pet if alive + if ((player->getClass() == CLASS_HUNTER) || (player->getClass() == CLASS_WARLOCK)) { - // Do what was done before to the target in HandleUnfreezeCommand - if (Player* player = GetTarget()->ToPlayer()) + if (Pet* pet = player->GetPet()) { - // Reset player faction + allow combat + allow duels - player->setFactionForRace(player->getRace()); - player->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - // save player - player->SaveToDB(); + pet->SavePetToDB(PET_SAVE_AS_CURRENT); + // not let dismiss dead pet + if (pet->IsAlive()) + player->RemovePet(pet, PET_SAVE_NOT_IN_SLOT); } } + } + } - void Register() override - { - OnEffectApply += AuraEffectApplyFn(spell_gen_gm_freeze_AuraScript::OnApply, EFFECT_0, SPELL_AURA_MOD_STUN, AURA_EFFECT_HANDLE_REAL); - OnEffectRemove += AuraEffectRemoveFn(spell_gen_gm_freeze_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_MOD_STUN, AURA_EFFECT_HANDLE_REAL); - } - }; - - AuraScript* GetAuraScript() const override + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + // Do what was done before to the target in HandleUnfreezeCommand + if (Player* player = GetTarget()->ToPlayer()) { - return new spell_gen_gm_freeze_AuraScript(); + // Reset player faction + allow combat + allow duels + player->setFactionForRace(player->getRace()); + player->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + // save player + player->SaveToDB(); } + } + + void Register() override + { + OnEffectApply += AuraEffectApplyFn(spell_gen_gm_freeze::OnApply, EFFECT_0, SPELL_AURA_MOD_STUN, AURA_EFFECT_HANDLE_REAL); + OnEffectRemove += AuraEffectRemoveFn(spell_gen_gm_freeze::OnRemove, EFFECT_0, SPELL_AURA_MOD_STUN, AURA_EFFECT_HANDLE_REAL); + } }; -class spell_gen_stand : public SpellScriptLoader +class spell_gen_stand : public SpellScript { -public: - spell_gen_stand() : SpellScriptLoader("spell_gen_stand") { } + PrepareSpellScript(spell_gen_stand); - class spell_gen_stand_SpellScript : public SpellScript + void HandleScript(SpellEffIndex /*eff*/) { - PrepareSpellScript(spell_gen_stand_SpellScript); - - void HandleScript(SpellEffIndex /*eff*/) - { - Creature* target = GetHitCreature(); - if (!target) - return; + Creature* target = GetHitCreature(); + if (!target) + return; - target->SetStandState(UNIT_STAND_STATE_STAND); - target->HandleEmoteCommand(EMOTE_STATE_NONE); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_gen_stand_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - } - }; + target->SetStandState(UNIT_STAND_STATE_STAND); + target->HandleEmoteCommand(EMOTE_STATE_NONE); + } - SpellScript* GetSpellScript() const override + void Register() override { - return new spell_gen_stand_SpellScript(); + OnEffectHitTarget += SpellEffectFn(spell_gen_stand::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; @@ -3863,214 +3152,203 @@ enum RequiredMixologySpells SPELL_ELIXIR_OF_MINOR_DEFENSE = 673 }; -class spell_gen_mixology_bonus : public SpellScriptLoader +class spell_gen_mixology_bonus : public AuraScript { -public: - spell_gen_mixology_bonus() : SpellScriptLoader("spell_gen_mixology_bonus") { } + PrepareAuraScript(spell_gen_mixology_bonus); - class spell_gen_mixology_bonus_AuraScript : public AuraScript + bool Validate(SpellInfo const* /*spellInfo*/) override { - PrepareAuraScript(spell_gen_mixology_bonus_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_MIXOLOGY }); - } + return ValidateSpellInfo({ SPELL_MIXOLOGY }); + } - bool Load() override - { - return GetCaster() && GetCaster()->GetTypeId() == TYPEID_PLAYER; - } + bool Load() override + { + return GetCaster() && GetCaster()->GetTypeId() == TYPEID_PLAYER; + } - void SetBonusValueForEffect(SpellEffIndex effIndex, int32 value, AuraEffect const* aurEff) - { - if (aurEff->GetEffIndex() == uint32(effIndex)) - bonus = value; - } + void SetBonusValueForEffect(SpellEffIndex effIndex, int32 value, AuraEffect const* aurEff) + { + if (aurEff->GetEffIndex() == uint32(effIndex)) + bonus = value; + } - void CalculateAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/) - { - if (GetCaster()->HasAura(SPELL_MIXOLOGY) && GetCaster()->HasSpell(GetSpellInfo()->Effects[EFFECT_0].TriggerSpell)) - { - switch (GetId()) - { - case SPELL_WEAK_TROLLS_BLOOD_ELIXIR: - case SPELL_MAGEBLOOD_ELIXIR: - bonus = amount; - break; - case SPELL_ELIXIR_OF_FROST_POWER: - case SPELL_LESSER_FLASK_OF_TOUGHNESS: - case SPELL_LESSER_FLASK_OF_RESISTANCE: - bonus = CalculatePct(amount, 80); - break; - case SPELL_ELIXIR_OF_MINOR_DEFENSE: - case SPELL_ELIXIR_OF_LIONS_STRENGTH: - case SPELL_ELIXIR_OF_MINOR_AGILITY: - case SPELL_MAJOR_TROLLS_BLLOOD_ELIXIR: - case SPELL_ELIXIR_OF_SHADOW_POWER: - case SPELL_ELIXIR_OF_BRUTE_FORCE: - case SPELL_MIGHTY_TROLLS_BLOOD_ELIXIR: - case SPELL_ELIXIR_OF_GREATER_FIREPOWER: - case SPELL_ONSLAUGHT_ELIXIR: - case SPELL_EARTHEN_ELIXIR: - case SPELL_ELIXIR_OF_MAJOR_AGILITY: - case SPELL_FLASK_OF_THE_TITANS: - case SPELL_FLASK_OF_RELENTLESS_ASSAULT: - case SPELL_FLASK_OF_STONEBLOOD: - case SPELL_ELIXIR_OF_MINOR_ACCURACY: - bonus = CalculatePct(amount, 50); - break; - case SPELL_ELIXIR_OF_PROTECTION: - bonus = 280; - break; - case SPELL_ELIXIR_OF_MAJOR_DEFENSE: - bonus = 200; - break; - case SPELL_ELIXIR_OF_GREATER_DEFENSE: - case SPELL_ELIXIR_OF_SUPERIOR_DEFENSE: - bonus = 140; - break; - case SPELL_ELIXIR_OF_FORTITUDE: - bonus = 100; - break; - case SPELL_FLASK_OF_ENDLESS_RAGE: - bonus = 82; - break; - case SPELL_ELIXIR_OF_DEFENSE: - bonus = 70; - break; - case SPELL_ELIXIR_OF_DEMONSLAYING: - bonus = 50; - break; - case SPELL_FLASK_OF_THE_FROST_WYRM: - bonus = 47; - break; - case SPELL_WRATH_ELIXIR: - bonus = 32; - break; - case SPELL_ELIXIR_OF_MAJOR_FROST_POWER: - case SPELL_ELIXIR_OF_MAJOR_FIREPOWER: - case SPELL_ELIXIR_OF_MAJOR_SHADOW_POWER: - bonus = 29; - break; - case SPELL_ELIXIR_OF_MIGHTY_TOUGHTS: - bonus = 27; - break; - case SPELL_FLASK_OF_SUPREME_POWER: - case SPELL_FLASK_OF_BLINDING_LIGHT: - case SPELL_FLASK_OF_PURE_DEATH: - case SPELL_SHADOWPOWER_ELIXIR: - bonus = 23; - break; - case SPELL_ELIXIR_OF_MIGHTY_AGILITY: - case SPELL_FLASK_OF_DISTILLED_WISDOM: - case SPELL_ELIXIR_OF_SPIRIT: - case SPELL_ELIXIR_OF_MIGHTY_STRENGTH: - case SPELL_FLASK_OF_PURE_MOJO: - case SPELL_ELIXIR_OF_ACCURACY: - case SPELL_ELIXIR_OF_DEADLY_STRIKES: - case SPELL_ELIXIR_OF_MIGHTY_DEFENSE: - case SPELL_ELIXIR_OF_EXPERTISE: - case SPELL_ELIXIR_OF_ARMOR_PIERCING: - case SPELL_ELIXIR_OF_LIGHTNING_SPEED: - bonus = 20; - break; - case SPELL_FLASK_OF_CHROMATIC_RESISTANCE: - bonus = 17; - break; - case SPELL_ELIXIR_OF_MINOR_FORTITUDE: - case SPELL_ELIXIR_OF_MAJOR_STRENGTH: - bonus = 15; - break; - case SPELL_FLASK_OF_MIGHTY_RESTORATION: - bonus = 13; - break; - case SPELL_ARCANE_ELIXIR: - bonus = 12; - break; - case SPELL_ELIXIR_OF_GREATER_AGILITY: - case SPELL_ELIXIR_OF_GIANTS: - bonus = 11; - break; - case SPELL_ELIXIR_OF_AGILITY: - case SPELL_ELIXIR_OF_GREATER_INTELLECT: - case SPELL_ELIXIR_OF_SAGES: - case SPELL_ELIXIR_OF_IRONSKIN: - case SPELL_ELIXIR_OF_MIGHTY_MAGEBLOOD: - bonus = 10; - break; - case SPELL_ELIXIR_OF_HEALING_POWER: - bonus = 9; - break; - case SPELL_ELIXIR_OF_DRAENIC_WISDOM: - case SPELL_GURUS_ELIXIR: - bonus = 8; - break; - case SPELL_ELIXIR_OF_FIREPOWER: - case SPELL_ELIXIR_OF_MAJOR_MAGEBLOOD: - case SPELL_ELIXIR_OF_MASTERY: - bonus = 6; - break; - case SPELL_ELIXIR_OF_LESSER_AGILITY: - case SPELL_ELIXIR_OF_OGRES_STRENGTH: - case SPELL_ELIXIR_OF_WISDOM: - case SPELL_ELIXIR_OF_THE_MONGOOSE: - bonus = 5; - break; - case SPELL_STRONG_TROLLS_BLOOD_ELIXIR: - case SPELL_FLASK_OF_CHROMATIC_WONDER: - bonus = 4; - break; - case SPELL_ELIXIR_OF_EMPOWERMENT: - bonus = -10; - break; - case SPELL_ADEPTS_ELIXIR: - SetBonusValueForEffect(EFFECT_0, 13, aurEff); - SetBonusValueForEffect(EFFECT_1, 13, aurEff); - SetBonusValueForEffect(EFFECT_2, 8, aurEff); - break; - case SPELL_ELIXIR_OF_MIGHTY_FORTITUDE: - SetBonusValueForEffect(EFFECT_0, 160, aurEff); - break; - case SPELL_ELIXIR_OF_MAJOR_FORTITUDE: - SetBonusValueForEffect(EFFECT_0, 116, aurEff); - SetBonusValueForEffect(EFFECT_1, 6, aurEff); - break; - case SPELL_FEL_STRENGTH_ELIXIR: - SetBonusValueForEffect(EFFECT_0, 40, aurEff); - SetBonusValueForEffect(EFFECT_1, 40, aurEff); - break; - case SPELL_FLASK_OF_FORTIFICATION: - SetBonusValueForEffect(EFFECT_0, 210, aurEff); - SetBonusValueForEffect(EFFECT_1, 5, aurEff); - break; - case SPELL_GREATER_ARCANE_ELIXIR: - SetBonusValueForEffect(EFFECT_0, 19, aurEff); - SetBonusValueForEffect(EFFECT_1, 19, aurEff); - SetBonusValueForEffect(EFFECT_2, 5, aurEff); - break; - case SPELL_ELIXIR_OF_GIANTH_GROWTH: - SetBonusValueForEffect(EFFECT_0, 5, aurEff); - break; - default: - TC_LOG_ERROR("spells", "SpellId %u couldn't be processed in spell_gen_mixology_bonus", GetId()); - break; - } - amount += bonus; - } + void CalculateAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/) + { + if (GetCaster()->HasAura(SPELL_MIXOLOGY) && GetCaster()->HasSpell(GetSpellInfo()->Effects[EFFECT_0].TriggerSpell)) + { + switch (GetId()) + { + case SPELL_WEAK_TROLLS_BLOOD_ELIXIR: + case SPELL_MAGEBLOOD_ELIXIR: + bonus = amount; + break; + case SPELL_ELIXIR_OF_FROST_POWER: + case SPELL_LESSER_FLASK_OF_TOUGHNESS: + case SPELL_LESSER_FLASK_OF_RESISTANCE: + bonus = CalculatePct(amount, 80); + break; + case SPELL_ELIXIR_OF_MINOR_DEFENSE: + case SPELL_ELIXIR_OF_LIONS_STRENGTH: + case SPELL_ELIXIR_OF_MINOR_AGILITY: + case SPELL_MAJOR_TROLLS_BLLOOD_ELIXIR: + case SPELL_ELIXIR_OF_SHADOW_POWER: + case SPELL_ELIXIR_OF_BRUTE_FORCE: + case SPELL_MIGHTY_TROLLS_BLOOD_ELIXIR: + case SPELL_ELIXIR_OF_GREATER_FIREPOWER: + case SPELL_ONSLAUGHT_ELIXIR: + case SPELL_EARTHEN_ELIXIR: + case SPELL_ELIXIR_OF_MAJOR_AGILITY: + case SPELL_FLASK_OF_THE_TITANS: + case SPELL_FLASK_OF_RELENTLESS_ASSAULT: + case SPELL_FLASK_OF_STONEBLOOD: + case SPELL_ELIXIR_OF_MINOR_ACCURACY: + bonus = CalculatePct(amount, 50); + break; + case SPELL_ELIXIR_OF_PROTECTION: + bonus = 280; + break; + case SPELL_ELIXIR_OF_MAJOR_DEFENSE: + bonus = 200; + break; + case SPELL_ELIXIR_OF_GREATER_DEFENSE: + case SPELL_ELIXIR_OF_SUPERIOR_DEFENSE: + bonus = 140; + break; + case SPELL_ELIXIR_OF_FORTITUDE: + bonus = 100; + break; + case SPELL_FLASK_OF_ENDLESS_RAGE: + bonus = 82; + break; + case SPELL_ELIXIR_OF_DEFENSE: + bonus = 70; + break; + case SPELL_ELIXIR_OF_DEMONSLAYING: + bonus = 50; + break; + case SPELL_FLASK_OF_THE_FROST_WYRM: + bonus = 47; + break; + case SPELL_WRATH_ELIXIR: + bonus = 32; + break; + case SPELL_ELIXIR_OF_MAJOR_FROST_POWER: + case SPELL_ELIXIR_OF_MAJOR_FIREPOWER: + case SPELL_ELIXIR_OF_MAJOR_SHADOW_POWER: + bonus = 29; + break; + case SPELL_ELIXIR_OF_MIGHTY_TOUGHTS: + bonus = 27; + break; + case SPELL_FLASK_OF_SUPREME_POWER: + case SPELL_FLASK_OF_BLINDING_LIGHT: + case SPELL_FLASK_OF_PURE_DEATH: + case SPELL_SHADOWPOWER_ELIXIR: + bonus = 23; + break; + case SPELL_ELIXIR_OF_MIGHTY_AGILITY: + case SPELL_FLASK_OF_DISTILLED_WISDOM: + case SPELL_ELIXIR_OF_SPIRIT: + case SPELL_ELIXIR_OF_MIGHTY_STRENGTH: + case SPELL_FLASK_OF_PURE_MOJO: + case SPELL_ELIXIR_OF_ACCURACY: + case SPELL_ELIXIR_OF_DEADLY_STRIKES: + case SPELL_ELIXIR_OF_MIGHTY_DEFENSE: + case SPELL_ELIXIR_OF_EXPERTISE: + case SPELL_ELIXIR_OF_ARMOR_PIERCING: + case SPELL_ELIXIR_OF_LIGHTNING_SPEED: + bonus = 20; + break; + case SPELL_FLASK_OF_CHROMATIC_RESISTANCE: + bonus = 17; + break; + case SPELL_ELIXIR_OF_MINOR_FORTITUDE: + case SPELL_ELIXIR_OF_MAJOR_STRENGTH: + bonus = 15; + break; + case SPELL_FLASK_OF_MIGHTY_RESTORATION: + bonus = 13; + break; + case SPELL_ARCANE_ELIXIR: + bonus = 12; + break; + case SPELL_ELIXIR_OF_GREATER_AGILITY: + case SPELL_ELIXIR_OF_GIANTS: + bonus = 11; + break; + case SPELL_ELIXIR_OF_AGILITY: + case SPELL_ELIXIR_OF_GREATER_INTELLECT: + case SPELL_ELIXIR_OF_SAGES: + case SPELL_ELIXIR_OF_IRONSKIN: + case SPELL_ELIXIR_OF_MIGHTY_MAGEBLOOD: + bonus = 10; + break; + case SPELL_ELIXIR_OF_HEALING_POWER: + bonus = 9; + break; + case SPELL_ELIXIR_OF_DRAENIC_WISDOM: + case SPELL_GURUS_ELIXIR: + bonus = 8; + break; + case SPELL_ELIXIR_OF_FIREPOWER: + case SPELL_ELIXIR_OF_MAJOR_MAGEBLOOD: + case SPELL_ELIXIR_OF_MASTERY: + bonus = 6; + break; + case SPELL_ELIXIR_OF_LESSER_AGILITY: + case SPELL_ELIXIR_OF_OGRES_STRENGTH: + case SPELL_ELIXIR_OF_WISDOM: + case SPELL_ELIXIR_OF_THE_MONGOOSE: + bonus = 5; + break; + case SPELL_STRONG_TROLLS_BLOOD_ELIXIR: + case SPELL_FLASK_OF_CHROMATIC_WONDER: + bonus = 4; + break; + case SPELL_ELIXIR_OF_EMPOWERMENT: + bonus = -10; + break; + case SPELL_ADEPTS_ELIXIR: + SetBonusValueForEffect(EFFECT_0, 13, aurEff); + SetBonusValueForEffect(EFFECT_1, 13, aurEff); + SetBonusValueForEffect(EFFECT_2, 8, aurEff); + break; + case SPELL_ELIXIR_OF_MIGHTY_FORTITUDE: + SetBonusValueForEffect(EFFECT_0, 160, aurEff); + break; + case SPELL_ELIXIR_OF_MAJOR_FORTITUDE: + SetBonusValueForEffect(EFFECT_0, 116, aurEff); + SetBonusValueForEffect(EFFECT_1, 6, aurEff); + break; + case SPELL_FEL_STRENGTH_ELIXIR: + SetBonusValueForEffect(EFFECT_0, 40, aurEff); + SetBonusValueForEffect(EFFECT_1, 40, aurEff); + break; + case SPELL_FLASK_OF_FORTIFICATION: + SetBonusValueForEffect(EFFECT_0, 210, aurEff); + SetBonusValueForEffect(EFFECT_1, 5, aurEff); + break; + case SPELL_GREATER_ARCANE_ELIXIR: + SetBonusValueForEffect(EFFECT_0, 19, aurEff); + SetBonusValueForEffect(EFFECT_1, 19, aurEff); + SetBonusValueForEffect(EFFECT_2, 5, aurEff); + break; + case SPELL_ELIXIR_OF_GIANTH_GROWTH: + SetBonusValueForEffect(EFFECT_0, 5, aurEff); + break; + default: + TC_LOG_ERROR("spells", "SpellId %u couldn't be processed in spell_gen_mixology_bonus", GetId()); + break; + } + amount += bonus; } + } - int32 bonus = 0; - - void Register() override - { - DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_mixology_bonus_AuraScript::CalculateAmount, EFFECT_ALL, SPELL_AURA_ANY); - } - }; + int32 bonus = 0; - AuraScript* GetAuraScript() const override + void Register() override { - return new spell_gen_mixology_bonus_AuraScript(); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_mixology_bonus::CalculateAmount, EFFECT_ALL, SPELL_AURA_ANY); } }; @@ -4079,71 +3357,49 @@ enum LandmineKnockbackAchievement SPELL_LANDMINE_KNOCKBACK_ACHIEVEMENT = 57064 }; -class spell_gen_landmine_knockback_achievement : public SpellScriptLoader +class spell_gen_landmine_knockback_achievement : public SpellScript { -public: - spell_gen_landmine_knockback_achievement() : SpellScriptLoader("spell_gen_landmine_knockback_achievement") { } + PrepareSpellScript(spell_gen_landmine_knockback_achievement); - class spell_gen_landmine_knockback_achievement_SpellScript : public SpellScript + void HandleScript(SpellEffIndex /*effIndex*/) { - PrepareSpellScript(spell_gen_landmine_knockback_achievement_SpellScript); - - void HandleScript(SpellEffIndex /*effIndex*/) + if (Player* target = GetHitPlayer()) { - if (Player* target = GetHitPlayer()) - { - Aura const* aura = GetHitAura(); - if (!aura || aura->GetStackAmount() < 10) - return; - - target->CastSpell(target, SPELL_LANDMINE_KNOCKBACK_ACHIEVEMENT, true); - } - } + Aura const* aura = GetHitAura(); + if (!aura || aura->GetStackAmount() < 10) + return; - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_gen_landmine_knockback_achievement_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + target->CastSpell(target, SPELL_LANDMINE_KNOCKBACK_ACHIEVEMENT, true); } - }; + } - SpellScript* GetSpellScript() const override + void Register() override { - return new spell_gen_landmine_knockback_achievement_SpellScript(); + OnEffectHitTarget += SpellEffectFn(spell_gen_landmine_knockback_achievement::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; // 34098 - ClearAllDebuffs -class spell_gen_clear_debuffs : public SpellScriptLoader +class spell_gen_clear_debuffs : public SpellScript { - public: - spell_gen_clear_debuffs() : SpellScriptLoader("spell_gen_clear_debuffs") { } + PrepareSpellScript(spell_gen_clear_debuffs); - class spell_gen_clear_debuffs_SpellScript : public SpellScript + void HandleScript(SpellEffIndex /*effIndex*/) + { + if (Unit* target = GetHitUnit()) { - PrepareSpellScript(spell_gen_clear_debuffs_SpellScript); - - void HandleScript(SpellEffIndex /*effIndex*/) - { - if (Unit* target = GetHitUnit()) - { - target->RemoveOwnedAuras([](Aura const* aura) - { - SpellInfo const* spellInfo = aura->GetSpellInfo(); - return !spellInfo->IsPositive() && !spellInfo->IsPassive(); - }); - } - } - - void Register() override + target->RemoveOwnedAuras([](Aura const* aura) { - OnEffectHitTarget += SpellEffectFn(spell_gen_clear_debuffs_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - } - }; - - SpellScript* GetSpellScript() const override - { - return new spell_gen_clear_debuffs_SpellScript(); + SpellInfo const* spellInfo = aura->GetSpellInfo(); + return !spellInfo->IsPositive() && !spellInfo->IsPassive(); + }); } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_gen_clear_debuffs::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } }; enum PonySpells @@ -4152,93 +3408,82 @@ enum PonySpells MOUNT_PONY = 29736 }; -class spell_gen_pony_mount_check : public SpellScriptLoader +class spell_gen_pony_mount_check : public AuraScript { - public: - spell_gen_pony_mount_check() : SpellScriptLoader("spell_gen_pony_mount_check") { } - - class spell_gen_pony_mount_check_AuraScript : public AuraScript - { - PrepareAuraScript(spell_gen_pony_mount_check_AuraScript); - - void HandleEffectPeriodic(AuraEffect const* /*aurEff*/) - { - Unit* caster = GetCaster(); - if (!caster) - return; - Player* owner = caster->GetOwner()->ToPlayer(); - if (!owner || !owner->HasAchieved(ACHIEV_PONY_UP)) - return; - - if (owner->IsMounted()) - { - caster->Mount(MOUNT_PONY); - caster->SetSpeedRate(MOVE_RUN, owner->GetSpeedRate(MOVE_RUN)); - } - else if (caster->IsMounted()) - { - caster->Dismount(); - caster->SetSpeedRate(MOVE_RUN, owner->GetSpeedRate(MOVE_RUN)); - } - } + PrepareAuraScript(spell_gen_pony_mount_check); - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_gen_pony_mount_check_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); - } - }; + void HandleEffectPeriodic(AuraEffect const* /*aurEff*/) + { + Unit* caster = GetCaster(); + if (!caster) + return; + Player* owner = caster->GetOwner()->ToPlayer(); + if (!owner || !owner->HasAchieved(ACHIEV_PONY_UP)) + return; - AuraScript* GetAuraScript() const + if (owner->IsMounted()) + { + caster->Mount(MOUNT_PONY); + caster->SetSpeedRate(MOVE_RUN, owner->GetSpeedRate(MOVE_RUN)); + } + else if (caster->IsMounted()) { - return new spell_gen_pony_mount_check_AuraScript(); + caster->Dismount(); + caster->SetSpeedRate(MOVE_RUN, owner->GetSpeedRate(MOVE_RUN)); } + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_gen_pony_mount_check::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + } }; void AddSC_generic_spell_scripts() { - new spell_gen_absorb0_hitlimit1(); - new spell_gen_adaptive_warding(); - new spell_gen_allow_cast_from_item_only(); - new spell_gen_animal_blood(); - new spell_gen_aura_of_anger(); - new spell_gen_aura_service_uniform(); - new spell_gen_av_drekthar_presence(); - new spell_gen_bandage(); - new spell_gen_blood_reserve(); - new spell_gen_blade_warding(); - new spell_gen_bonked(); + RegisterAuraScript(spell_gen_absorb0_hitlimit1); + RegisterAuraScript(spell_gen_adaptive_warding); + RegisterSpellScript(spell_gen_allow_cast_from_item_only); + RegisterAuraScript(spell_gen_animal_blood); + RegisterAuraScript(spell_gen_aura_of_anger); + RegisterAuraScript(spell_gen_aura_service_uniform); + RegisterAuraScript(spell_gen_av_drekthar_presence); + RegisterSpellScript(spell_gen_bandage); + RegisterAuraScript(spell_gen_blood_reserve); + RegisterAuraScript(spell_gen_blade_warding); + RegisterSpellScript(spell_gen_bonked); new spell_gen_break_shield("spell_gen_break_shield"); new spell_gen_break_shield("spell_gen_tournament_counterattack"); - new spell_gen_burn_brutallus(); - new spell_gen_burning_depths_necrolyte_image(); - new spell_gen_cannibalize(); - new spell_gen_chaos_blast(); - new spell_gen_clone(); - new spell_gen_clone_weapon(); - new spell_gen_clone_weapon_aura(); + RegisterAuraScript(spell_gen_burn_brutallus); + RegisterAuraScript(spell_gen_burning_depths_necrolyte_image); + RegisterSpellScript(spell_gen_cannibalize); + RegisterSpellScript(spell_gen_chaos_blast); + RegisterSpellScript(spell_gen_clone); + RegisterSpellScript(spell_gen_clone_weapon); + RegisterAuraScript(spell_gen_clone_weapon_aura); new spell_gen_count_pct_from_max_hp("spell_gen_default_count_pct_from_max_hp"); new spell_gen_count_pct_from_max_hp("spell_gen_50pct_count_pct_from_max_hp", 50); - new spell_gen_create_lance(); - new spell_gen_creature_permanent_feign_death(); + RegisterSpellScript(spell_gen_create_lance); + RegisterAuraScript(spell_gen_creature_permanent_feign_death); new spell_gen_dalaran_disguise("spell_gen_sunreaver_disguise"); new spell_gen_dalaran_disguise("spell_gen_silver_covenant_disguise"); - new spell_gen_damage_reduction_aura(); - new spell_gen_defend(); - new spell_gen_despawn_self(); - new spell_gen_divine_storm_cd_reset(); - new spell_gen_ds_flush_knockback(); - new spell_gen_dungeon_credit(); - new spell_gen_elune_candle(); - new spell_gen_gadgetzan_transporter_backfire(); - new spell_gen_gift_of_naaru(); - new spell_gen_gnomish_transporter(); - new spell_gen_lifeblood(); + RegisterAuraScript(spell_gen_damage_reduction_aura); + RegisterAuraScript(spell_gen_defend); + RegisterSpellScript(spell_gen_despawn_self); + RegisterSpellScript(spell_gen_divine_storm_cd_reset); + RegisterSpellScript(spell_gen_ds_flush_knockback); + RegisterSpellScript(spell_gen_dungeon_credit); + RegisterSpellScript(spell_gen_elune_candle); + RegisterSpellScript(spell_gen_gadgetzan_transporter_backfire); + RegisterAuraScript(spell_gen_gift_of_naaru); + RegisterSpellScript(spell_gen_gnomish_transporter); + RegisterAuraScript(spell_gen_lifeblood); new spell_gen_lifebloom("spell_hexlord_lifebloom", SPELL_HEXLORD_MALACRASS_LIFEBLOOM_FINAL_HEAL); new spell_gen_lifebloom("spell_tur_ragepaw_lifebloom", SPELL_TUR_RAGEPAW_LIFEBLOOM_FINAL_HEAL); new spell_gen_lifebloom("spell_cenarion_scout_lifebloom", SPELL_CENARION_SCOUT_LIFEBLOOM_FINAL_HEAL); new spell_gen_lifebloom("spell_twisted_visage_lifebloom", SPELL_TWISTED_VISAGE_LIFEBLOOM_FINAL_HEAL); new spell_gen_lifebloom("spell_faction_champion_dru_lifebloom", SPELL_FACTION_CHAMPIONS_DRU_LIFEBLOOM_FINAL_HEAL); - new spell_gen_magic_rooster(); + RegisterSpellScript(spell_gen_magic_rooster); new spell_gen_mount("spell_magic_broom", 0, SPELL_MAGIC_BROOM_60, SPELL_MAGIC_BROOM_100, SPELL_MAGIC_BROOM_150, SPELL_MAGIC_BROOM_280); new spell_gen_mount("spell_headless_horseman_mount", 0, SPELL_HEADLESS_HORSEMAN_MOUNT_60, SPELL_HEADLESS_HORSEMAN_MOUNT_100, SPELL_HEADLESS_HORSEMAN_MOUNT_150, SPELL_HEADLESS_HORSEMAN_MOUNT_280); new spell_gen_mount("spell_winged_steed_of_the_ebon_blade", 0, 0, 0, SPELL_WINGED_STEED_150, SPELL_WINGED_STEED_280); @@ -4248,50 +3493,50 @@ void AddSC_generic_spell_scripts() new spell_gen_mount("spell_blazing_hippogryph", 0, 0, 0, SPELL_BLAZING_HIPPOGRYPH_150, SPELL_BLAZING_HIPPOGRYPH_280); new spell_gen_mount("spell_celestial_steed", 0, SPELL_CELESTIAL_STEED_60, SPELL_CELESTIAL_STEED_100, SPELL_CELESTIAL_STEED_150, SPELL_CELESTIAL_STEED_280, SPELL_CELESTIAL_STEED_310); new spell_gen_mount("spell_x53_touring_rocket", 0, 0, 0, SPELL_X53_TOURING_ROCKET_150, SPELL_X53_TOURING_ROCKET_280, SPELL_X53_TOURING_ROCKET_310); - new spell_gen_mounted_charge(); - new spell_gen_moss_covered_feet(); - new spell_gen_netherbloom(); - new spell_gen_nightmare_vine(); - new spell_gen_obsidian_armor(); - new spell_gen_oracle_wolvar_reputation(); - new spell_gen_orc_disguise(); - new spell_gen_paralytic_poison(); + RegisterSpellScript(spell_gen_mounted_charge); + RegisterAuraScript(spell_gen_moss_covered_feet); + RegisterSpellScript(spell_gen_netherbloom); + RegisterSpellScript(spell_gen_nightmare_vine); + RegisterAuraScript(spell_gen_obsidian_armor); + RegisterSpellScript(spell_gen_oracle_wolvar_reputation); + RegisterSpellScript(spell_gen_orc_disguise); + RegisterAuraScript(spell_gen_paralytic_poison); new spell_gen_proc_below_pct_damaged("spell_item_soul_harvesters_charm"); new spell_gen_proc_below_pct_damaged("spell_item_commendation_of_kaelthas"); new spell_gen_proc_below_pct_damaged("spell_item_corpse_tongue_coin"); new spell_gen_proc_below_pct_damaged("spell_item_corpse_tongue_coin_heroic"); new spell_gen_proc_below_pct_damaged("spell_item_petrified_twilight_scale"); new spell_gen_proc_below_pct_damaged("spell_item_petrified_twilight_scale_heroic"); - new spell_gen_proc_charge_drop_only(); - new spell_gen_parachute(); - new spell_gen_pet_summoned(); - new spell_gen_profession_research(); - new spell_gen_remove_flight_auras(); - new spell_gen_replenishment(); - new spell_gen_seaforium_blast(); - new spell_gen_spectator_cheer_trigger(); - new spell_gen_spirit_healer_res(); + RegisterAuraScript(spell_gen_proc_charge_drop_only); + RegisterAuraScript(spell_gen_parachute); + RegisterSpellScript(spell_gen_pet_summoned); + RegisterSpellScript(spell_gen_profession_research); + RegisterSpellScript(spell_gen_remove_flight_auras); + RegisterSpellAndAuraScriptPair(spell_gen_replenishment, spell_gen_replenishment_aura); + RegisterSpellScript(spell_gen_seaforium_blast); + RegisterSpellScript(spell_gen_spectator_cheer_trigger); + RegisterSpellScript(spell_gen_spirit_healer_res); new spell_gen_summon_elemental("spell_gen_summon_fire_elemental", SPELL_SUMMON_FIRE_ELEMENTAL); new spell_gen_summon_elemental("spell_gen_summon_earth_elemental", SPELL_SUMMON_EARTH_ELEMENTAL); - new spell_gen_summon_tournament_mount(); - new spell_gen_throw_shield(); - new spell_gen_tournament_duel(); - new spell_gen_tournament_pennant(); + RegisterSpellScript(spell_gen_summon_tournament_mount); + RegisterSpellScript(spell_gen_throw_shield); + RegisterSpellScript(spell_gen_tournament_duel); + RegisterAuraScript(spell_gen_tournament_pennant); new spell_pvp_trinket_wotf_shared_cd<SPELL_WILL_OF_THE_FORSAKEN_COOLDOWN_TRIGGER>("spell_pvp_trinket_shared_cd"); new spell_pvp_trinket_wotf_shared_cd<SPELL_WILL_OF_THE_FORSAKEN_COOLDOWN_TRIGGER_WOTF>("spell_wotf_shared_cd"); - new spell_gen_turkey_marker(); - new spell_gen_upper_deck_create_foam_sword(); - new spell_gen_vampiric_touch(); - new spell_gen_vehicle_scaling(); - new spell_gen_vendor_bark_trigger(); - new spell_gen_wg_water(); - new spell_gen_whisper_gulch_yogg_saron_whisper(); - new spell_gen_eject_all_passengers(); - new spell_gen_eject_passenger(); - new spell_gen_gm_freeze(); - new spell_gen_stand(); - new spell_gen_mixology_bonus(); - new spell_gen_landmine_knockback_achievement(); - new spell_gen_clear_debuffs(); - new spell_gen_pony_mount_check(); + RegisterAuraScript(spell_gen_turkey_marker); + RegisterSpellScript(spell_gen_upper_deck_create_foam_sword); + RegisterAuraScript(spell_gen_vampiric_touch); + RegisterAuraScript(spell_gen_vehicle_scaling); + RegisterSpellScript(spell_gen_vendor_bark_trigger); + RegisterSpellScript(spell_gen_wg_water); + RegisterAuraScript(spell_gen_whisper_gulch_yogg_saron_whisper); + RegisterSpellScript(spell_gen_eject_all_passengers); + RegisterSpellScript(spell_gen_eject_passenger); + RegisterAuraScript(spell_gen_gm_freeze); + RegisterSpellScript(spell_gen_stand); + RegisterAuraScript(spell_gen_mixology_bonus); + RegisterSpellScript(spell_gen_landmine_knockback_achievement); + RegisterSpellScript(spell_gen_clear_debuffs); + RegisterAuraScript(spell_gen_pony_mount_check); } diff --git a/src/server/scripts/Spells/spell_holiday.cpp b/src/server/scripts/Spells/spell_holiday.cpp index eac0ff10c23..8c395077c96 100644 --- a/src/server/scripts/Spells/spell_holiday.cpp +++ b/src/server/scripts/Spells/spell_holiday.cpp @@ -921,14 +921,14 @@ class spell_pilgrims_bounty_a_serving_of : public SpellScriptLoader void OnApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) { Unit* target = GetTarget(); - target->CastSpell(target, uint32(aurEff->GetBaseAmount()), true); + target->CastSpell(target, uint32(aurEff->GetAmount()), true); HandlePlate(target, true); } void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) { Unit* target = GetTarget(); - target->RemoveAurasDueToSpell(aurEff->GetBaseAmount()); + target->RemoveAurasDueToSpell(aurEff->GetAmount()); HandlePlate(target, false); } @@ -1318,7 +1318,7 @@ class spell_brewfest_relay_race_intro_force_player_to_throw : public SpellScript PreventHitDefaultEffect(effIndex); // All this spells trigger a spell that requires reagents; if the // triggered spell is cast as "triggered", reagents are not consumed - GetHitUnit()->CastSpell((Unit*)nullptr, GetSpellInfo()->Effects[effIndex].TriggerSpell, TriggerCastFlags(TRIGGERED_FULL_MASK & ~TRIGGERED_IGNORE_POWER_AND_REAGENT_COST)); + GetHitUnit()->CastSpell(nullptr, GetSpellInfo()->Effects[effIndex].TriggerSpell, TriggerCastFlags(TRIGGERED_FULL_MASK & ~TRIGGERED_IGNORE_POWER_AND_REAGENT_COST)); } void Register() override @@ -1489,117 +1489,175 @@ enum TorchSpells SPELL_TORCH_TOSSING_PRACTICE = 46630, SPELL_TORCH_TOSSING_TRAINING_SUCCESS_ALLIANCE = 45719, SPELL_TORCH_TOSSING_TRAINING_SUCCESS_HORDE = 46651, + SPELL_TARGET_INDICATOR_COSMETIC = 46901, + SPELL_TARGET_INDICATOR = 45723, SPELL_BRAZIERS_HIT = 45724 }; // 45724 - Braziers Hit! -class spell_midsummer_braziers_hit : public SpellScriptLoader +class spell_midsummer_braziers_hit : public AuraScript { - public: - spell_midsummer_braziers_hit() : SpellScriptLoader("spell_midsummer_braziers_hit") { } + PrepareAuraScript(spell_midsummer_braziers_hit); - class spell_midsummer_braziers_hit_AuraScript : public AuraScript + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( { - PrepareAuraScript(spell_midsummer_braziers_hit_AuraScript); + SPELL_TORCH_TOSSING_TRAINING, + SPELL_TORCH_TOSSING_PRACTICE, + SPELL_TORCH_TOSSING_TRAINING_SUCCESS_ALLIANCE, + SPELL_TORCH_TOSSING_TRAINING_SUCCESS_HORDE + }); + } - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_TORCH_TOSSING_TRAINING, SPELL_TORCH_TOSSING_PRACTICE }); - } + void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Player* player = GetTarget()->ToPlayer(); + if (!player) + return; - void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - Player* player = GetTarget()->ToPlayer(); - if (!player) - return; + if ((player->HasAura(SPELL_TORCH_TOSSING_TRAINING) && GetStackAmount() == 8) || (player->HasAura(SPELL_TORCH_TOSSING_PRACTICE) && GetStackAmount() == 20)) + { + if (player->GetTeam() == ALLIANCE) + player->CastSpell(player, SPELL_TORCH_TOSSING_TRAINING_SUCCESS_ALLIANCE, true); + else if (player->GetTeam() == HORDE) + player->CastSpell(player, SPELL_TORCH_TOSSING_TRAINING_SUCCESS_HORDE, true); + Remove(); + } + } - if ((player->HasAura(SPELL_TORCH_TOSSING_TRAINING) && GetStackAmount() == 8) || (player->HasAura(SPELL_TORCH_TOSSING_PRACTICE) && GetStackAmount() == 20)) - { - if (player->GetTeam() == ALLIANCE) - player->CastSpell(player, SPELL_TORCH_TOSSING_TRAINING_SUCCESS_ALLIANCE, true); - else if (player->GetTeam() == HORDE) - player->CastSpell(player, SPELL_TORCH_TOSSING_TRAINING_SUCCESS_HORDE, true); - Remove(); - } - } + void Register() override + { + AfterEffectApply += AuraEffectApplyFn(spell_midsummer_braziers_hit::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAPPLY); + } +}; - void Register() override - { - AfterEffectApply += AuraEffectApplyFn(spell_midsummer_braziers_hit_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AuraEffectHandleModes(AURA_EFFECT_HANDLE_REAPPLY)); - } - }; +// 45907 - Torch Target Picker +class spell_midsummer_torch_target_picker : public SpellScript +{ + PrepareSpellScript(spell_midsummer_torch_target_picker); - AuraScript* GetAuraScript() const override - { - return new spell_midsummer_braziers_hit_AuraScript(); - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_TARGET_INDICATOR_COSMETIC, SPELL_TARGET_INDICATOR }); + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + Unit* target = GetHitUnit(); + target->CastSpell(target, SPELL_TARGET_INDICATOR_COSMETIC, true); + target->CastSpell(target, SPELL_TARGET_INDICATOR, true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_midsummer_torch_target_picker::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); + } +}; + +// 46054 - Torch Toss (land) +class spell_midsummer_torch_toss_land : public SpellScript +{ + PrepareSpellScript(spell_midsummer_torch_toss_land); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_BRAZIERS_HIT }); + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + GetHitUnit()->CastSpell(GetCaster(), SPELL_BRAZIERS_HIT, true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_midsummer_torch_toss_land::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } }; enum RibbonPoleData { - SPELL_HAS_FULL_MIDSUMMER_SET = 58933, - SPELL_BURNING_HOT_POLE_DANCE = 58934, - SPELL_RIBBON_DANCE_COSMETIC = 29726, - SPELL_RIBBON_DANCE = 29175, - GO_RIBBON_POLE = 181605, + SPELL_HAS_FULL_MIDSUMMER_SET = 58933, + SPELL_BURNING_HOT_POLE_DANCE = 58934, + SPELL_RIBBON_POLE_PERIODIC_VISUAL = 45406, + SPELL_RIBBON_DANCE = 29175, + SPELL_TEST_RIBBON_POLE_1 = 29705, + SPELL_TEST_RIBBON_POLE_2 = 29726, + SPELL_TEST_RIBBON_POLE_3 = 29727 }; -class spell_gen_ribbon_pole_dancer_check : public SpellScriptLoader +// 29705, 29726, 29727 - Test Ribbon Pole Channel +class spell_midsummer_test_ribbon_pole_channel : public AuraScript { - public: - spell_gen_ribbon_pole_dancer_check() : SpellScriptLoader("spell_gen_ribbon_pole_dancer_check") { } + PrepareAuraScript(spell_midsummer_test_ribbon_pole_channel); - class spell_gen_ribbon_pole_dancer_check_AuraScript : public AuraScript + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( { - PrepareAuraScript(spell_gen_ribbon_pole_dancer_check_AuraScript); + SPELL_RIBBON_POLE_PERIODIC_VISUAL, + SPELL_BURNING_HOT_POLE_DANCE, + SPELL_HAS_FULL_MIDSUMMER_SET, + SPELL_RIBBON_DANCE + }); + } - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_HAS_FULL_MIDSUMMER_SET, - SPELL_RIBBON_DANCE, - SPELL_BURNING_HOT_POLE_DANCE - }); - } + void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->RemoveAurasDueToSpell(SPELL_RIBBON_POLE_PERIODIC_VISUAL); + } - void PeriodicTick(AuraEffect const* /*aurEff*/) - { - Unit* target = GetTarget(); + void PeriodicTick(AuraEffect const* /*aurEff*/) + { + Unit* target = GetTarget(); + target->CastSpell(target, SPELL_RIBBON_POLE_PERIODIC_VISUAL, true); - // check if aura needs to be removed - if (!target->FindNearestGameObject(GO_RIBBON_POLE, 8.0f) || !target->HasUnitState(UNIT_STATE_CASTING)) - { - target->InterruptNonMeleeSpells(false); - target->RemoveAurasDueToSpell(GetId()); - target->RemoveAura(SPELL_RIBBON_DANCE_COSMETIC); - return; - } + if (Aura* aur = target->GetAura(SPELL_RIBBON_DANCE)) + { + aur->SetMaxDuration(std::min(3600000, aur->GetMaxDuration() + 180000)); + aur->RefreshDuration(); - // set xp buff duration - if (Aura* aur = target->GetAura(SPELL_RIBBON_DANCE)) - { - aur->SetMaxDuration(std::min(3600000, aur->GetMaxDuration() + 180000)); - aur->RefreshDuration(); + if (aur->GetMaxDuration() == 3600000 && target->HasAura(SPELL_HAS_FULL_MIDSUMMER_SET)) + target->CastSpell(target, SPELL_BURNING_HOT_POLE_DANCE, true); + } + else + target->CastSpell(target, SPELL_RIBBON_DANCE, true); + } - // reward achievement criteria - if (aur->GetMaxDuration() == 3600000 && target->HasAura(SPELL_HAS_FULL_MIDSUMMER_SET)) - target->CastSpell(target, SPELL_BURNING_HOT_POLE_DANCE, true); - } - else - target->AddAura(SPELL_RIBBON_DANCE, target); - } + void Register() override + { + AfterEffectRemove += AuraEffectRemoveFn(spell_midsummer_test_ribbon_pole_channel::HandleRemove, EFFECT_1, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL); + OnEffectPeriodic += AuraEffectPeriodicFn(spell_midsummer_test_ribbon_pole_channel::PeriodicTick, EFFECT_1, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } +}; - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_gen_ribbon_pole_dancer_check_AuraScript::PeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); - } - }; +// 45406 - Holiday - Midsummer, Ribbon Pole Periodic Visual +class spell_midsummer_ribbon_pole_periodic_visual : public AuraScript +{ + PrepareAuraScript(spell_midsummer_ribbon_pole_periodic_visual); - AuraScript* GetAuraScript() const override + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( { - return new spell_gen_ribbon_pole_dancer_check_AuraScript(); - } + SPELL_TEST_RIBBON_POLE_1, + SPELL_TEST_RIBBON_POLE_2, + SPELL_TEST_RIBBON_POLE_3 + }); + } + + void PeriodicTick(AuraEffect const* /*aurEff*/) + { + Unit* target = GetTarget(); + if (!target->HasAura(SPELL_TEST_RIBBON_POLE_1) && !target->HasAura(SPELL_TEST_RIBBON_POLE_2) && !target->HasAura(SPELL_TEST_RIBBON_POLE_3)) + Remove(); + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_midsummer_ribbon_pole_periodic_visual::PeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + } }; void AddSC_holiday_spell_scripts() @@ -1650,6 +1708,9 @@ void AddSC_holiday_spell_scripts() new spell_brewfest_dismount_ram(); new spell_brewfest_barker_bunny(); // Midsummer Fire Festival - new spell_midsummer_braziers_hit(); - new spell_gen_ribbon_pole_dancer_check(); + RegisterAuraScript(spell_midsummer_braziers_hit); + RegisterSpellScript(spell_midsummer_torch_target_picker); + RegisterSpellScript(spell_midsummer_torch_toss_land); + RegisterAuraScript(spell_midsummer_test_ribbon_pole_channel); + RegisterAuraScript(spell_midsummer_ribbon_pole_periodic_visual); } diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp index 2b9bfac79e9..a7fed99dccf 100644 --- a/src/server/scripts/Spells/spell_hunter.cpp +++ b/src/server/scripts/Spells/spell_hunter.cpp @@ -443,7 +443,7 @@ class spell_hun_glyph_of_mend_pet : public SpellScriptLoader void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) { PreventDefaultAction(); - eventInfo.GetProcTarget()->CastSpell((Unit*)nullptr, SPELL_HUNTER_GLYPH_OF_MEND_PET_HAPPINESS, true, nullptr, aurEff); + eventInfo.GetProcTarget()->CastSpell(nullptr, SPELL_HUNTER_GLYPH_OF_MEND_PET_HAPPINESS, true, nullptr, aurEff); } void Register() override @@ -476,7 +476,7 @@ class spell_hun_hunting_party : public SpellScriptLoader void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) { PreventDefaultAction(); - eventInfo.GetActor()->CastSpell((Unit*)nullptr, SPELL_REPLENISHMENT, true, nullptr, aurEff); + eventInfo.GetActor()->CastSpell(nullptr, SPELL_REPLENISHMENT, true, nullptr, aurEff); } void Register() override @@ -775,7 +775,7 @@ class spell_hun_masters_call : public SpellScriptLoader void HandleScriptEffect(SpellEffIndex /*effIndex*/) { - GetHitUnit()->CastSpell((Unit*)nullptr, SPELL_HUNTER_MASTERS_CALL_TRIGGERED, true); + GetHitUnit()->CastSpell(nullptr, SPELL_HUNTER_MASTERS_CALL_TRIGGERED, true); } void Register() override @@ -1105,7 +1105,7 @@ class spell_hun_rapid_recuperation_trigger : public SpellScriptLoader uint8 rank = GetSpellInfo()->GetRank(); uint32 spellId = triggerSpells[rank - 1]; - eventInfo.GetActor()->CastSpell((Unit*)nullptr, spellId, true, nullptr, aurEff); + eventInfo.GetActor()->CastSpell(nullptr, spellId, true, nullptr, aurEff); } void Register() override diff --git a/src/server/scripts/Spells/spell_item.cpp b/src/server/scripts/Spells/spell_item.cpp index 0de0c0c00b9..e78bd3804be 100644 --- a/src/server/scripts/Spells/spell_item.cpp +++ b/src/server/scripts/Spells/spell_item.cpp @@ -85,36 +85,25 @@ enum AegisOfPreservation }; // 23780 - Aegis of Preservation -class spell_item_aegis_of_preservation : public SpellScriptLoader +class spell_item_aegis_of_preservation : public AuraScript { - public: - spell_item_aegis_of_preservation() : SpellScriptLoader("spell_item_aegis_of_preservation") { } - - class spell_item_aegis_of_preservation_AuraScript : public AuraScript - { - PrepareAuraScript(spell_item_aegis_of_preservation_AuraScript); + PrepareAuraScript(spell_item_aegis_of_preservation); - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_AEGIS_HEAL }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) - { - PreventDefaultAction(); - GetTarget()->CastSpell(GetTarget(), SPELL_AEGIS_HEAL, true, nullptr, aurEff); - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_AEGIS_HEAL }); + } - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_item_aegis_of_preservation_AuraScript::HandleProc, EFFECT_1, SPELL_AURA_PROC_TRIGGER_SPELL); - } - }; + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + GetTarget()->CastSpell(GetTarget(), SPELL_AEGIS_HEAL, true, nullptr, aurEff); + } - AuraScript* GetAuraScript() const override - { - return new spell_item_aegis_of_preservation_AuraScript(); - } + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_aegis_of_preservation::HandleProc, EFFECT_1, SPELL_AURA_PROC_TRIGGER_SPELL); + } }; enum AlchemistStone @@ -133,62 +122,51 @@ enum AlchemistStone // Item - 44324: Mighty Alchemist's Stone // 17619 - Alchemist's Stone -class spell_item_alchemists_stone : public SpellScriptLoader +class spell_item_alchemists_stone : public AuraScript { - public: - spell_item_alchemists_stone() : SpellScriptLoader("spell_item_alchemists_stone") { } + PrepareAuraScript(spell_item_alchemists_stone); - class spell_item_alchemists_stone_AuraScript : public AuraScript + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( { - PrepareAuraScript(spell_item_alchemists_stone_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_ALCHEMISTS_STONE_EXTRA_HEAL, - SPELL_ALCHEMISTS_STONE_EXTRA_MANA - }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); - if (!spellInfo) - return; + SPELL_ALCHEMISTS_STONE_EXTRA_HEAL, + SPELL_ALCHEMISTS_STONE_EXTRA_MANA + }); + } - Unit* caster = eventInfo.GetActionTarget(); - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) - { - uint32 spellId; - switch (spellInfo->Effects[i].Effect) - { - case SPELL_EFFECT_HEAL: - spellId = SPELL_ALCHEMISTS_STONE_EXTRA_HEAL; - break; - case SPELL_EFFECT_ENERGIZE: - spellId = SPELL_ALCHEMISTS_STONE_EXTRA_MANA; - break; - default: - continue; - } - - int32 amount = CalculatePct(spellInfo->Effects[i].CalcValue(caster), 40); - caster->CastCustomSpell(spellId, SPELLVALUE_BASE_POINT0, amount, (Unit*)nullptr, true, nullptr, aurEff); - } - } + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); + if (!spellInfo) + return; - void Register() override + Unit* caster = eventInfo.GetActionTarget(); + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + { + uint32 spellId; + switch (spellInfo->Effects[i].Effect) { - OnEffectProc += AuraEffectProcFn(spell_item_alchemists_stone_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + case SPELL_EFFECT_HEAL: + spellId = SPELL_ALCHEMISTS_STONE_EXTRA_HEAL; + break; + case SPELL_EFFECT_ENERGIZE: + spellId = SPELL_ALCHEMISTS_STONE_EXTRA_MANA; + break; + default: + continue; } - }; - AuraScript* GetAuraScript() const override - { - return new spell_item_alchemists_stone_AuraScript(); + int32 amount = CalculatePct(spellInfo->Effects[i].CalcValue(caster), 40); + caster->CastCustomSpell(spellId, SPELLVALUE_BASE_POINT0, amount, (Unit*)nullptr, true, nullptr, aurEff); } + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_alchemists_stone::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } }; enum AngerCapacitor @@ -230,7 +208,7 @@ class spell_item_anger_capacitor : public SpellScriptLoader Unit* caster = eventInfo.GetActor(); Unit* target = eventInfo.GetProcTarget(); - caster->CastSpell((Unit*)nullptr, SPELL_MOTE_OF_ANGER, true); + caster->CastSpell(nullptr, SPELL_MOTE_OF_ANGER, true); Aura const* motes = caster->GetAura(SPELL_MOTE_OF_ANGER); if (!motes || motes->GetStackAmount() < Stacks) return; @@ -257,32 +235,21 @@ class spell_item_anger_capacitor : public SpellScriptLoader }; // 26400 - Arcane Shroud -class spell_item_arcane_shroud : public SpellScriptLoader +class spell_item_arcane_shroud : public AuraScript { - public: - spell_item_arcane_shroud() : SpellScriptLoader("spell_item_arcane_shroud") { } - - class spell_item_arcane_shroud_AuraScript : public AuraScript - { - PrepareAuraScript(spell_item_arcane_shroud_AuraScript); + PrepareAuraScript(spell_item_arcane_shroud); - void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/) - { - int32 diff = GetUnitOwner()->getLevel() - 60; - if (diff > 0) - amount += 2 * diff; - } - - void Register() override - { - DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_item_arcane_shroud_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_MOD_THREAT); - } - }; + void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/) + { + int32 diff = GetUnitOwner()->getLevel() - 60; + if (diff > 0) + amount += 2 * diff; + } - AuraScript* GetAuraScript() const override - { - return new spell_item_arcane_shroud_AuraScript(); - } + void Register() override + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_item_arcane_shroud::CalculateAmount, EFFECT_0, SPELL_AURA_MOD_THREAT); + } }; enum AuraOfMadness @@ -305,117 +272,95 @@ enum AuraOfMadness // Item - 31859: Darkmoon Card: Madness // 39446 - Aura of Madness -class spell_item_aura_of_madness : public SpellScriptLoader +class spell_item_aura_of_madness : public AuraScript { - public: - spell_item_aura_of_madness() : SpellScriptLoader("spell_item_aura_of_madness") { } - - class spell_item_aura_of_madness_AuraScript : public AuraScript - { - PrepareAuraScript(spell_item_aura_of_madness_AuraScript); + PrepareAuraScript(spell_item_aura_of_madness); - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_SOCIOPATH, - SPELL_DELUSIONAL, - SPELL_KLEPTOMANIA, - SPELL_MEGALOMANIA, - SPELL_PARANOIA, - SPELL_MANIC, - SPELL_NARCISSISM, - SPELL_MARTYR_COMPLEX, - SPELL_DEMENTIA - }) && sObjectMgr->GetBroadcastText(SAY_MADNESS); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - static std::vector<uint32> const triggeredSpells[MAX_CLASSES] = - { - //CLASS_NONE - { }, - //CLASS_WARRIOR - { SPELL_SOCIOPATH, SPELL_DELUSIONAL, SPELL_KLEPTOMANIA, SPELL_PARANOIA, SPELL_MANIC, SPELL_MARTYR_COMPLEX }, - //CLASS_PALADIN - { SPELL_SOCIOPATH, SPELL_DELUSIONAL, SPELL_KLEPTOMANIA, SPELL_MEGALOMANIA, SPELL_PARANOIA, SPELL_MANIC, SPELL_NARCISSISM, SPELL_MARTYR_COMPLEX, SPELL_DEMENTIA }, - //CLASS_HUNTER - { SPELL_DELUSIONAL, SPELL_MEGALOMANIA, SPELL_PARANOIA, SPELL_MANIC, SPELL_NARCISSISM, SPELL_MARTYR_COMPLEX, SPELL_DEMENTIA }, - //CLASS_ROGUE - { SPELL_SOCIOPATH, SPELL_DELUSIONAL, SPELL_KLEPTOMANIA, SPELL_PARANOIA, SPELL_MANIC, SPELL_MARTYR_COMPLEX }, - //CLASS_PRIEST - { SPELL_MEGALOMANIA, SPELL_PARANOIA, SPELL_MANIC, SPELL_NARCISSISM, SPELL_MARTYR_COMPLEX, SPELL_DEMENTIA }, - //CLASS_DEATH_KNIGHT - { SPELL_SOCIOPATH, SPELL_DELUSIONAL, SPELL_KLEPTOMANIA, SPELL_PARANOIA, SPELL_MANIC, SPELL_MARTYR_COMPLEX }, - //CLASS_SHAMAN - { SPELL_MEGALOMANIA, SPELL_PARANOIA, SPELL_MANIC, SPELL_NARCISSISM, SPELL_MARTYR_COMPLEX, SPELL_DEMENTIA }, - //CLASS_MAGE - { SPELL_MEGALOMANIA, SPELL_PARANOIA, SPELL_MANIC, SPELL_NARCISSISM, SPELL_MARTYR_COMPLEX, SPELL_DEMENTIA }, - //CLASS_WARLOCK - { SPELL_MEGALOMANIA, SPELL_PARANOIA, SPELL_MANIC, SPELL_NARCISSISM, SPELL_MARTYR_COMPLEX, SPELL_DEMENTIA }, - //CLASS_UNK - { }, - //CLASS_DRUID - { SPELL_SOCIOPATH, SPELL_DELUSIONAL, SPELL_KLEPTOMANIA, SPELL_MEGALOMANIA, SPELL_PARANOIA, SPELL_MANIC, SPELL_NARCISSISM, SPELL_MARTYR_COMPLEX, SPELL_DEMENTIA } - }; - - PreventDefaultAction(); - Unit* caster = eventInfo.GetActor(); - uint32 spellId = Trinity::Containers::SelectRandomContainerElement(triggeredSpells[caster->getClass()]); - caster->CastSpell(caster, spellId, true, nullptr, aurEff); - - if (roll_chance_i(10)) - caster->Unit::Say(SAY_MADNESS); - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( + { + SPELL_SOCIOPATH, + SPELL_DELUSIONAL, + SPELL_KLEPTOMANIA, + SPELL_MEGALOMANIA, + SPELL_PARANOIA, + SPELL_MANIC, + SPELL_NARCISSISM, + SPELL_MARTYR_COMPLEX, + SPELL_DEMENTIA + }) && sObjectMgr->GetBroadcastText(SAY_MADNESS); + } - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_item_aura_of_madness_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } - }; + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + static std::vector<uint32> const triggeredSpells[MAX_CLASSES] = + { + //CLASS_NONE + { }, + //CLASS_WARRIOR + { SPELL_SOCIOPATH, SPELL_DELUSIONAL, SPELL_KLEPTOMANIA, SPELL_PARANOIA, SPELL_MANIC, SPELL_MARTYR_COMPLEX }, + //CLASS_PALADIN + { SPELL_SOCIOPATH, SPELL_DELUSIONAL, SPELL_KLEPTOMANIA, SPELL_MEGALOMANIA, SPELL_PARANOIA, SPELL_MANIC, SPELL_NARCISSISM, SPELL_MARTYR_COMPLEX, SPELL_DEMENTIA }, + //CLASS_HUNTER + { SPELL_DELUSIONAL, SPELL_MEGALOMANIA, SPELL_PARANOIA, SPELL_MANIC, SPELL_NARCISSISM, SPELL_MARTYR_COMPLEX, SPELL_DEMENTIA }, + //CLASS_ROGUE + { SPELL_SOCIOPATH, SPELL_DELUSIONAL, SPELL_KLEPTOMANIA, SPELL_PARANOIA, SPELL_MANIC, SPELL_MARTYR_COMPLEX }, + //CLASS_PRIEST + { SPELL_MEGALOMANIA, SPELL_PARANOIA, SPELL_MANIC, SPELL_NARCISSISM, SPELL_MARTYR_COMPLEX, SPELL_DEMENTIA }, + //CLASS_DEATH_KNIGHT + { SPELL_SOCIOPATH, SPELL_DELUSIONAL, SPELL_KLEPTOMANIA, SPELL_PARANOIA, SPELL_MANIC, SPELL_MARTYR_COMPLEX }, + //CLASS_SHAMAN + { SPELL_MEGALOMANIA, SPELL_PARANOIA, SPELL_MANIC, SPELL_NARCISSISM, SPELL_MARTYR_COMPLEX, SPELL_DEMENTIA }, + //CLASS_MAGE + { SPELL_MEGALOMANIA, SPELL_PARANOIA, SPELL_MANIC, SPELL_NARCISSISM, SPELL_MARTYR_COMPLEX, SPELL_DEMENTIA }, + //CLASS_WARLOCK + { SPELL_MEGALOMANIA, SPELL_PARANOIA, SPELL_MANIC, SPELL_NARCISSISM, SPELL_MARTYR_COMPLEX, SPELL_DEMENTIA }, + //CLASS_UNK + { }, + //CLASS_DRUID + { SPELL_SOCIOPATH, SPELL_DELUSIONAL, SPELL_KLEPTOMANIA, SPELL_MEGALOMANIA, SPELL_PARANOIA, SPELL_MANIC, SPELL_NARCISSISM, SPELL_MARTYR_COMPLEX, SPELL_DEMENTIA } + }; + + PreventDefaultAction(); + Unit* caster = eventInfo.GetActor(); + uint32 spellId = Trinity::Containers::SelectRandomContainerElement(triggeredSpells[caster->getClass()]); + caster->CastSpell(caster, spellId, true, nullptr, aurEff); + + if (roll_chance_i(10)) + caster->Unit::Say(SAY_MADNESS); + } - AuraScript* GetAuraScript() const override - { - return new spell_item_aura_of_madness_AuraScript(); - } + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_aura_of_madness::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } }; // 41404 - Dementia -class spell_item_dementia : public SpellScriptLoader +class spell_item_dementia : public AuraScript { - public: - spell_item_dementia() : SpellScriptLoader("spell_item_dementia") { } + PrepareAuraScript(spell_item_dementia); - class spell_item_dementia_AuraScript : public AuraScript + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( { - PrepareAuraScript(spell_item_dementia_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_DEMENTIA_POS, - SPELL_DEMENTIA_NEG - }); - } - - void HandlePeriodicDummy(AuraEffect const* aurEff) - { - PreventDefaultAction(); - GetTarget()->CastSpell(GetTarget(), RAND(SPELL_DEMENTIA_POS, SPELL_DEMENTIA_NEG), true, nullptr, aurEff); - } + SPELL_DEMENTIA_POS, + SPELL_DEMENTIA_NEG + }); + } - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_item_dementia_AuraScript::HandlePeriodicDummy, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); - } - }; + void HandlePeriodicDummy(AuraEffect const* aurEff) + { + PreventDefaultAction(); + GetTarget()->CastSpell(GetTarget(), RAND(SPELL_DEMENTIA_POS, SPELL_DEMENTIA_NEG), true, nullptr, aurEff); + } - AuraScript* GetAuraScript() const override - { - return new spell_item_dementia_AuraScript(); - } + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_item_dementia::HandlePeriodicDummy, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + } }; // 64411 - Blessing of Ancient Kings (Val'anyr, Hammer of Ancient Kings) @@ -424,57 +369,46 @@ enum BlessingOfAncientKings SPELL_PROTECTION_OF_ANCIENT_KINGS = 64413 }; -class spell_item_blessing_of_ancient_kings : public SpellScriptLoader +class spell_item_blessing_of_ancient_kings : public AuraScript { - public: - spell_item_blessing_of_ancient_kings() : SpellScriptLoader("spell_item_blessing_of_ancient_kings") { } - - class spell_item_blessing_of_ancient_kings_AuraScript : public AuraScript - { - PrepareAuraScript(spell_item_blessing_of_ancient_kings_AuraScript); + PrepareAuraScript(spell_item_blessing_of_ancient_kings); - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_PROTECTION_OF_ANCIENT_KINGS }); - } - - bool CheckProc(ProcEventInfo& eventInfo) - { - return eventInfo.GetProcTarget() != nullptr; - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - HealInfo* healInfo = eventInfo.GetHealInfo(); - if (!healInfo || !healInfo->GetHeal()) - return; + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_PROTECTION_OF_ANCIENT_KINGS }); + } - int32 absorb = int32(CalculatePct(healInfo->GetHeal(), 15.0f)); - if (AuraEffect* protEff = eventInfo.GetProcTarget()->GetAuraEffect(SPELL_PROTECTION_OF_ANCIENT_KINGS, 0, eventInfo.GetActor()->GetGUID())) - { - // The shield can grow to a maximum size of 20,000 damage absorbtion - protEff->SetAmount(std::min<int32>(protEff->GetAmount() + absorb, 20000)); + bool CheckProc(ProcEventInfo& eventInfo) + { + return eventInfo.GetProcTarget() != nullptr; + } - // Refresh and return to prevent replacing the aura - protEff->GetBase()->RefreshDuration(); - } - else - GetTarget()->CastCustomSpell(SPELL_PROTECTION_OF_ANCIENT_KINGS, SPELLVALUE_BASE_POINT0, absorb, eventInfo.GetProcTarget(), true, nullptr, aurEff); - } + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_item_blessing_of_ancient_kings_AuraScript::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_item_blessing_of_ancient_kings_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } - }; + HealInfo* healInfo = eventInfo.GetHealInfo(); + if (!healInfo || !healInfo->GetHeal()) + return; - AuraScript* GetAuraScript() const override + int32 absorb = int32(CalculatePct(healInfo->GetHeal(), 15.0f)); + if (AuraEffect* protEff = eventInfo.GetProcTarget()->GetAuraEffect(SPELL_PROTECTION_OF_ANCIENT_KINGS, 0, eventInfo.GetActor()->GetGUID())) { - return new spell_item_blessing_of_ancient_kings_AuraScript(); + // The shield can grow to a maximum size of 20,000 damage absorbtion + protEff->SetAmount(std::min<int32>(protEff->GetAmount() + absorb, 20000)); + + // Refresh and return to prevent replacing the aura + protEff->GetBase()->RefreshDuration(); } + else + GetTarget()->CastCustomSpell(SPELL_PROTECTION_OF_ANCIENT_KINGS, SPELLVALUE_BASE_POINT0, absorb, eventInfo.GetProcTarget(), true, nullptr, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_item_blessing_of_ancient_kings::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_item_blessing_of_ancient_kings::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } }; enum DeadlyPrecision @@ -483,64 +417,42 @@ enum DeadlyPrecision }; // 71564 - Deadly Precision -class spell_item_deadly_precision : public SpellScriptLoader +class spell_item_deadly_precision : public AuraScript { - public: - spell_item_deadly_precision() : SpellScriptLoader("spell_item_deadly_precision") { } + PrepareAuraScript(spell_item_deadly_precision); - class spell_item_deadly_precision_charm_AuraScript : public AuraScript - { - PrepareAuraScript(spell_item_deadly_precision_charm_AuraScript); - - void HandleStackDrop(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/) - { - PreventDefaultAction(); - GetTarget()->RemoveAuraFromStack(GetId(), GetTarget()->GetGUID()); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_item_deadly_precision_charm_AuraScript::HandleStackDrop, EFFECT_0, SPELL_AURA_MOD_RATING); - } - }; + void HandleStackDrop(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + GetTarget()->RemoveAuraFromStack(GetId(), GetTarget()->GetGUID()); + } - AuraScript* GetAuraScript() const override - { - return new spell_item_deadly_precision_charm_AuraScript(); - } + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_deadly_precision::HandleStackDrop, EFFECT_0, SPELL_AURA_MOD_RATING); + } }; // 71563 - Deadly Precision Dummy -class spell_item_deadly_precision_dummy : public SpellScriptLoader +class spell_item_deadly_precision_dummy : public SpellScript { - public: - spell_item_deadly_precision_dummy() : SpellScriptLoader("spell_item_deadly_precision_dummy") { } - - class spell_item_deadly_precision_dummy_SpellScript : public SpellScript - { - PrepareSpellScript(spell_item_deadly_precision_dummy_SpellScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DEADLY_PRECISION }); - } + PrepareSpellScript(spell_item_deadly_precision_dummy); - void HandleDummy(SpellEffIndex /*effIndex*/) - { - SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(SPELL_DEADLY_PRECISION); - GetCaster()->CastCustomSpell(spellInfo->Id, SPELLVALUE_AURA_STACK, spellInfo->StackAmount, GetCaster(), true); - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_DEADLY_PRECISION }); + } - void Register() override - { - OnEffectHit += SpellEffectFn(spell_item_deadly_precision_dummy_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_APPLY_AURA); - } - }; + void HandleDummy(SpellEffIndex /*effIndex*/) + { + SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(SPELL_DEADLY_PRECISION); + GetCaster()->CastCustomSpell(spellInfo->Id, SPELLVALUE_AURA_STACK, spellInfo->StackAmount, GetCaster(), true); + } - SpellScript* GetSpellScript() const override - { - return new spell_item_deadly_precision_dummy_SpellScript(); - } + void Register() override + { + OnEffectHit += SpellEffectFn(spell_item_deadly_precision_dummy::HandleDummy, EFFECT_0, SPELL_EFFECT_APPLY_AURA); + } }; enum DeathbringersWill @@ -639,52 +551,41 @@ class spell_item_deathbringers_will : public SpellScriptLoader }; // 47770 - Roll Dice -class spell_item_decahedral_dwarven_dice : public SpellScriptLoader +class spell_item_decahedral_dwarven_dice : public SpellScript { - public: - spell_item_decahedral_dwarven_dice() : SpellScriptLoader("spell_item_decahedral_dwarven_dice") { } - - class spell_item_decahedral_dwarven_dice_SpellScript : public SpellScript - { - PrepareSpellScript(spell_item_decahedral_dwarven_dice_SpellScript); + PrepareSpellScript(spell_item_decahedral_dwarven_dice); - enum - { - TEXT_DECAHEDRAL_DWARVEN_DICE = 26147 - }; - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - if (!sObjectMgr->GetBroadcastText(TEXT_DECAHEDRAL_DWARVEN_DICE)) - return false; - return true; - } + enum + { + TEXT_DECAHEDRAL_DWARVEN_DICE = 26147 + }; - bool Load() override - { - return GetCaster()->GetTypeId() == TYPEID_PLAYER; - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sObjectMgr->GetBroadcastText(TEXT_DECAHEDRAL_DWARVEN_DICE)) + return false; + return true; + } - void HandleScript(SpellEffIndex /*effIndex*/) - { - GetCaster()->TextEmote(TEXT_DECAHEDRAL_DWARVEN_DICE, GetHitUnit()); + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } - static uint32 const minimum = 1; - static uint32 const maximum = 100; + void HandleScript(SpellEffIndex /*effIndex*/) + { + GetCaster()->TextEmote(TEXT_DECAHEDRAL_DWARVEN_DICE, GetHitUnit()); - GetCaster()->ToPlayer()->DoRandomRoll(minimum, maximum); - } + static uint32 const minimum = 1; + static uint32 const maximum = 100; - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_item_decahedral_dwarven_dice_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - } - }; + GetCaster()->ToPlayer()->DoRandomRoll(minimum, maximum); + } - SpellScript* GetSpellScript() const override - { - return new spell_item_decahedral_dwarven_dice_SpellScript(); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_item_decahedral_dwarven_dice::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } }; // 8342 - Defibrillate (Goblin Jumper Cables) have 33% chance on success @@ -749,36 +650,25 @@ enum DesperateDefense }; // 33896 - Desperate Defense -class spell_item_desperate_defense : public SpellScriptLoader +class spell_item_desperate_defense : public AuraScript { - public: - spell_item_desperate_defense() : SpellScriptLoader("spell_item_desperate_defense") { } - - class spell_item_desperate_defense_AuraScript : public AuraScript - { - PrepareAuraScript(spell_item_desperate_defense_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DESPERATE_RAGE }); - } + PrepareAuraScript(spell_item_desperate_defense); - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) - { - PreventDefaultAction(); - GetTarget()->CastSpell(GetTarget(), SPELL_DESPERATE_RAGE, true, nullptr, aurEff); - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_DESPERATE_RAGE }); + } - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_item_desperate_defense_AuraScript::HandleProc, EFFECT_2, SPELL_AURA_PROC_TRIGGER_SPELL); - } - }; + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + GetTarget()->CastSpell(GetTarget(), SPELL_DESPERATE_RAGE, true, nullptr, aurEff); + } - AuraScript* GetAuraScript() const override - { - return new spell_item_desperate_defense_AuraScript(); - } + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_desperate_defense::HandleProc, EFFECT_2, SPELL_AURA_PROC_TRIGGER_SPELL); + } }; // http://www.wowhead.com/item=6522 Deviate Fish @@ -792,42 +682,31 @@ enum DeviateFishSpells SPELL_HEALTHY_SPIRIT = 8068, }; -class spell_item_deviate_fish : public SpellScriptLoader +class spell_item_deviate_fish : public SpellScript { - public: - spell_item_deviate_fish() : SpellScriptLoader("spell_item_deviate_fish") { } + PrepareSpellScript(spell_item_deviate_fish); - class spell_item_deviate_fish_SpellScript : public SpellScript - { - PrepareSpellScript(spell_item_deviate_fish_SpellScript); - - bool Load() override - { - return GetCaster()->GetTypeId() == TYPEID_PLAYER; - } - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_SLEEPY, SPELL_INVIGORATE, SPELL_SHRINK, SPELL_PARTY_TIME, SPELL_HEALTHY_SPIRIT }); - } + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } - void HandleDummy(SpellEffIndex /*effIndex*/) - { - Unit* caster = GetCaster(); - uint32 spellId = urand(SPELL_SLEEPY, SPELL_HEALTHY_SPIRIT); - caster->CastSpell(caster, spellId, true, nullptr); - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SLEEPY, SPELL_INVIGORATE, SPELL_SHRINK, SPELL_PARTY_TIME, SPELL_HEALTHY_SPIRIT }); + } - void Register() override - { - OnEffectHit += SpellEffectFn(spell_item_deviate_fish_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + void HandleDummy(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + uint32 spellId = urand(SPELL_SLEEPY, SPELL_HEALTHY_SPIRIT); + caster->CastSpell(caster, spellId, true, nullptr); + } - SpellScript* GetSpellScript() const override - { - return new spell_item_deviate_fish_SpellScript(); - } + void Register() override + { + OnEffectHit += SpellEffectFn(spell_item_deviate_fish::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; enum DiscerningEyeBeastMisc @@ -836,70 +715,48 @@ enum DiscerningEyeBeastMisc }; // 59915 - Discerning Eye of the Beast Dummy -class spell_item_discerning_eye_beast_dummy : public SpellScriptLoader +class spell_item_discerning_eye_beast_dummy : public AuraScript { - public: - spell_item_discerning_eye_beast_dummy() : SpellScriptLoader("spell_item_discerning_eye_beast_dummy") { } - - class spell_item_discerning_eye_beast_dummy_AuraScript : public AuraScript - { - PrepareAuraScript(spell_item_discerning_eye_beast_dummy_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DISCERNING_EYE_BEAST }); - } + PrepareAuraScript(spell_item_discerning_eye_beast_dummy); - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - eventInfo.GetActor()->CastSpell((Unit*)nullptr, SPELL_DISCERNING_EYE_BEAST, true, nullptr, aurEff); - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_DISCERNING_EYE_BEAST }); + } - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_item_discerning_eye_beast_dummy_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } - }; + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + eventInfo.GetActor()->CastSpell(nullptr, SPELL_DISCERNING_EYE_BEAST, true, nullptr, aurEff); + } - AuraScript* GetAuraScript() const override - { - return new spell_item_discerning_eye_beast_dummy_AuraScript(); - } + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_discerning_eye_beast_dummy::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } }; // 71610, 71641 - Echoes of Light (Althor's Abacus) -class spell_item_echoes_of_light : public SpellScriptLoader +class spell_item_echoes_of_light : public SpellScript { - public: - spell_item_echoes_of_light() : SpellScriptLoader("spell_item_echoes_of_light") { } - - class spell_item_echoes_of_light_SpellScript : public SpellScript - { - PrepareSpellScript(spell_item_echoes_of_light_SpellScript); - - void FilterTargets(std::list<WorldObject*>& targets) - { - if (targets.size() < 2) - return; + PrepareSpellScript(spell_item_echoes_of_light); - targets.sort(Trinity::HealthPctOrderPred()); + void FilterTargets(std::list<WorldObject*>& targets) + { + if (targets.size() < 2) + return; - WorldObject* target = targets.front(); - targets.clear(); - targets.push_back(target); - } + targets.sort(Trinity::HealthPctOrderPred()); - void Register() override - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_item_echoes_of_light_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ALLY); - } - }; + WorldObject* target = targets.front(); + targets.clear(); + targets.push_back(target); + } - SpellScript* GetSpellScript() const override - { - return new spell_item_echoes_of_light_SpellScript(); - } + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_item_echoes_of_light::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ALLY); + } }; // 7434 - Fate Rune of Unsurpassed Vigor @@ -908,36 +765,25 @@ enum FateRuneOfUnsurpassedVigor SPELL_UNSURPASSED_VIGOR = 25733 }; -class spell_item_fate_rune_of_unsurpassed_vigor : public SpellScriptLoader +class spell_item_fate_rune_of_unsurpassed_vigor : public AuraScript { - public: - spell_item_fate_rune_of_unsurpassed_vigor() : SpellScriptLoader("spell_item_fate_rune_of_unsurpassed_vigor") { } - - class spell_item_fate_rune_of_unsurpassed_vigor_AuraScript : public AuraScript - { - PrepareAuraScript(spell_item_fate_rune_of_unsurpassed_vigor_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_UNSURPASSED_VIGOR }); - } + PrepareAuraScript(spell_item_fate_rune_of_unsurpassed_vigor); - void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/) - { - PreventDefaultAction(); - GetTarget()->CastSpell(GetTarget(), SPELL_UNSURPASSED_VIGOR, true); - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_UNSURPASSED_VIGOR }); + } - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_item_fate_rune_of_unsurpassed_vigor_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } - }; + void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + GetTarget()->CastSpell(GetTarget(), SPELL_UNSURPASSED_VIGOR, true); + } - AuraScript* GetAuraScript() const override - { - return new spell_item_fate_rune_of_unsurpassed_vigor_AuraScript(); - } + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_fate_rune_of_unsurpassed_vigor::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } }; // http://www.wowhead.com/item=47499 Flask of the North @@ -949,63 +795,52 @@ enum FlaskOfTheNorthSpells SPELL_FLASK_OF_THE_NORTH_STR = 67018, }; -class spell_item_flask_of_the_north : public SpellScriptLoader +class spell_item_flask_of_the_north : public SpellScript { - public: - spell_item_flask_of_the_north() : SpellScriptLoader("spell_item_flask_of_the_north") { } - - class spell_item_flask_of_the_north_SpellScript : public SpellScript - { - PrepareSpellScript(spell_item_flask_of_the_north_SpellScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_FLASK_OF_THE_NORTH_SP, SPELL_FLASK_OF_THE_NORTH_AP, SPELL_FLASK_OF_THE_NORTH_STR }); - } - - void HandleDummy(SpellEffIndex /*effIndex*/) - { - Unit* caster = GetCaster(); - std::vector<uint32> possibleSpells; - switch (caster->getClass()) - { - case CLASS_WARLOCK: - case CLASS_MAGE: - case CLASS_PRIEST: - possibleSpells.push_back(SPELL_FLASK_OF_THE_NORTH_SP); - break; - case CLASS_DEATH_KNIGHT: - case CLASS_WARRIOR: - possibleSpells.push_back(SPELL_FLASK_OF_THE_NORTH_STR); - break; - case CLASS_ROGUE: - case CLASS_HUNTER: - possibleSpells.push_back(SPELL_FLASK_OF_THE_NORTH_AP); - break; - case CLASS_DRUID: - case CLASS_PALADIN: - possibleSpells.push_back(SPELL_FLASK_OF_THE_NORTH_SP); - possibleSpells.push_back(SPELL_FLASK_OF_THE_NORTH_STR); - break; - case CLASS_SHAMAN: - possibleSpells.push_back(SPELL_FLASK_OF_THE_NORTH_SP); - possibleSpells.push_back(SPELL_FLASK_OF_THE_NORTH_AP); - break; - } + PrepareSpellScript(spell_item_flask_of_the_north); - caster->CastSpell(caster, possibleSpells[urand(0, (possibleSpells.size() - 1))], true, nullptr); - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_FLASK_OF_THE_NORTH_SP, SPELL_FLASK_OF_THE_NORTH_AP, SPELL_FLASK_OF_THE_NORTH_STR }); + } - void Register() override - { - OnEffectHit += SpellEffectFn(spell_item_flask_of_the_north_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + void HandleDummy(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + std::vector<uint32> possibleSpells; + switch (caster->getClass()) + { + case CLASS_WARLOCK: + case CLASS_MAGE: + case CLASS_PRIEST: + possibleSpells.push_back(SPELL_FLASK_OF_THE_NORTH_SP); + break; + case CLASS_DEATH_KNIGHT: + case CLASS_WARRIOR: + possibleSpells.push_back(SPELL_FLASK_OF_THE_NORTH_STR); + break; + case CLASS_ROGUE: + case CLASS_HUNTER: + possibleSpells.push_back(SPELL_FLASK_OF_THE_NORTH_AP); + break; + case CLASS_DRUID: + case CLASS_PALADIN: + possibleSpells.push_back(SPELL_FLASK_OF_THE_NORTH_SP); + possibleSpells.push_back(SPELL_FLASK_OF_THE_NORTH_STR); + break; + case CLASS_SHAMAN: + possibleSpells.push_back(SPELL_FLASK_OF_THE_NORTH_SP); + possibleSpells.push_back(SPELL_FLASK_OF_THE_NORTH_AP); + break; + } + + caster->CastSpell(caster, possibleSpells[urand(0, (possibleSpells.size() - 1))], true, nullptr); + } - SpellScript* GetSpellScript() const override - { - return new spell_item_flask_of_the_north_SpellScript(); - } + void Register() override + { + OnEffectHit += SpellEffectFn(spell_item_flask_of_the_north::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; enum FrozenShadoweave @@ -1015,42 +850,31 @@ enum FrozenShadoweave // 39372 - Frozen Shadoweave // Frozen Shadoweave set 3p bonus -class spell_item_frozen_shadoweave : public SpellScriptLoader +class spell_item_frozen_shadoweave : public AuraScript { - public: - spell_item_frozen_shadoweave() : SpellScriptLoader("spell_item_frozen_shadoweave") { } - - class spell_item_frozen_shadoweave_AuraScript : public AuraScript - { - PrepareAuraScript(spell_item_frozen_shadoweave_AuraScript); + PrepareAuraScript(spell_item_frozen_shadoweave); - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_SHADOWMEND }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - DamageInfo* damageInfo = eventInfo.GetDamageInfo(); - if (!damageInfo || !damageInfo->GetDamage()) - return; - - int32 amount = CalculatePct(static_cast<int32>(damageInfo->GetDamage()), aurEff->GetAmount()); - Unit* caster = eventInfo.GetActor(); - caster->CastCustomSpell(SPELL_SHADOWMEND, SPELLVALUE_BASE_POINT0, amount, (Unit*)nullptr, true, nullptr, aurEff); - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SHADOWMEND }); + } - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_item_frozen_shadoweave_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } - }; + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + DamageInfo* damageInfo = eventInfo.GetDamageInfo(); + if (!damageInfo || !damageInfo->GetDamage()) + return; + + int32 amount = CalculatePct(static_cast<int32>(damageInfo->GetDamage()), aurEff->GetAmount()); + Unit* caster = eventInfo.GetActor(); + caster->CastCustomSpell(SPELL_SHADOWMEND, SPELLVALUE_BASE_POINT0, amount, (Unit*)nullptr, true, nullptr, aurEff); + } - AuraScript* GetAuraScript() const override - { - return new spell_item_frozen_shadoweave_AuraScript(); - } + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_frozen_shadoweave::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } }; // http://www.wowhead.com/item=10645 Gnomish Death Ray @@ -1061,42 +885,31 @@ enum GnomishDeathRay SPELL_GNOMISH_DEATH_RAY_TARGET = 13279, }; -class spell_item_gnomish_death_ray : public SpellScriptLoader +class spell_item_gnomish_death_ray : public SpellScript { - public: - spell_item_gnomish_death_ray() : SpellScriptLoader("spell_item_gnomish_death_ray") { } - - class spell_item_gnomish_death_ray_SpellScript : public SpellScript - { - PrepareSpellScript(spell_item_gnomish_death_ray_SpellScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_GNOMISH_DEATH_RAY_SELF, SPELL_GNOMISH_DEATH_RAY_TARGET }); - } - - void HandleDummy(SpellEffIndex /*effIndex*/) - { - Unit* caster = GetCaster(); - if (Unit* target = GetHitUnit()) - { - if (urand(0, 99) < 15) - caster->CastSpell(caster, SPELL_GNOMISH_DEATH_RAY_SELF, true); // failure - else - caster->CastSpell(target, SPELL_GNOMISH_DEATH_RAY_TARGET, true); - } - } + PrepareSpellScript(spell_item_gnomish_death_ray); - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_item_gnomish_death_ray_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_GNOMISH_DEATH_RAY_SELF, SPELL_GNOMISH_DEATH_RAY_TARGET }); + } - SpellScript* GetSpellScript() const override + void HandleDummy(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + if (Unit* target = GetHitUnit()) { - return new spell_item_gnomish_death_ray_SpellScript(); + if (urand(0, 99) < 15) + caster->CastSpell(caster, SPELL_GNOMISH_DEATH_RAY_SELF, true); // failure + else + caster->CastSpell(target, SPELL_GNOMISH_DEATH_RAY_TARGET, true); } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_item_gnomish_death_ray::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; // Item 10721: Gnomish Harm Prevention Belt @@ -1106,35 +919,24 @@ enum HarmPreventionBelt SPELL_FORCEFIELD_COLLAPSE = 13235 }; -class spell_item_harm_prevention_belt : public SpellScriptLoader +class spell_item_harm_prevention_belt : public AuraScript { - public: - spell_item_harm_prevention_belt() : SpellScriptLoader("spell_item_harm_prevention_belt") { } - - class spell_item_harm_prevention_belt_AuraScript : public AuraScript - { - PrepareAuraScript(spell_item_harm_prevention_belt_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_FORCEFIELD_COLLAPSE }); - } + PrepareAuraScript(spell_item_harm_prevention_belt); - void HandleProc(ProcEventInfo& /*eventInfo*/) - { - GetTarget()->CastSpell((Unit*)nullptr, SPELL_FORCEFIELD_COLLAPSE, true); - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_FORCEFIELD_COLLAPSE }); + } - void Register() override - { - OnProc += AuraProcFn(spell_item_harm_prevention_belt_AuraScript::HandleProc); - } - }; + void HandleProc(ProcEventInfo& /*eventInfo*/) + { + GetTarget()->CastSpell(nullptr, SPELL_FORCEFIELD_COLLAPSE, true); + } - AuraScript* GetAuraScript() const override - { - return new spell_item_harm_prevention_belt_AuraScript(); - } + void Register() override + { + OnProc += AuraProcFn(spell_item_harm_prevention_belt::HandleProc); + } }; // Item 23004 - Idol of Longevity @@ -1144,36 +946,25 @@ enum IdolOfLongevity SPELL_HEALING_TOUCH_MANA = 28848 }; -class spell_item_healing_touch_refund : public SpellScriptLoader +class spell_item_healing_touch_refund : public AuraScript { - public: - spell_item_healing_touch_refund() : SpellScriptLoader("spell_item_healing_touch_refund") { } - - class spell_item_healing_touch_refund_AuraScript : public AuraScript - { - PrepareAuraScript(spell_item_healing_touch_refund_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_HEALING_TOUCH_MANA }); - } + PrepareAuraScript(spell_item_healing_touch_refund); - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - eventInfo.GetActor()->CastSpell((Unit*)nullptr, SPELL_HEALING_TOUCH_MANA, true, nullptr, aurEff); - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_HEALING_TOUCH_MANA }); + } - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_item_healing_touch_refund_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } - }; + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + eventInfo.GetActor()->CastSpell(nullptr, SPELL_HEALING_TOUCH_MANA, true, nullptr, aurEff); + } - AuraScript* GetAuraScript() const override - { - return new spell_item_healing_touch_refund_AuraScript(); - } + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_healing_touch_refund::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } }; enum Heartpierce @@ -1241,7 +1032,7 @@ class spell_item_heartpierce : public SpellScriptLoader return; } - caster->CastSpell((Unit*)nullptr, spellId, true, nullptr, aurEff); + caster->CastSpell(nullptr, spellId, true, nullptr, aurEff); } void Register() override @@ -1257,36 +1048,25 @@ class spell_item_heartpierce : public SpellScriptLoader }; // 40971 - Bonus Healing (Crystal Spire of Karabor) -class spell_item_crystal_spire_of_karabor : public SpellScriptLoader +class spell_item_crystal_spire_of_karabor : public AuraScript { - public: - spell_item_crystal_spire_of_karabor() : SpellScriptLoader("spell_item_crystal_spire_of_karabor") { } - - class spell_item_crystal_spire_of_karabor_AuraScript : public AuraScript - { - PrepareAuraScript(spell_item_crystal_spire_of_karabor_AuraScript); - - bool CheckProc(ProcEventInfo& eventInfo) - { - int32 pct = GetSpellInfo()->Effects[EFFECT_0].BasePoints; - if (HealInfo* healInfo = eventInfo.GetHealInfo()) - if (Unit* healTarget = healInfo->GetTarget()) - if (healTarget->GetHealth() - healInfo->GetEffectiveHeal() <= healTarget->CountPctFromMaxHealth(pct)) - return true; + PrepareAuraScript(spell_item_crystal_spire_of_karabor); - return false; - } + bool CheckProc(ProcEventInfo& eventInfo) + { + int32 pct = GetSpellInfo()->Effects[EFFECT_0].BasePoints; + if (HealInfo* healInfo = eventInfo.GetHealInfo()) + if (Unit* healTarget = healInfo->GetTarget()) + if (healTarget->GetHealth() - healInfo->GetEffectiveHeal() <= healTarget->CountPctFromMaxHealth(pct)) + return true; - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_item_crystal_spire_of_karabor_AuraScript::CheckProc); - } - }; + return false; + } - AuraScript* GetAuraScript() const override - { - return new spell_item_crystal_spire_of_karabor_AuraScript(); - } + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_item_crystal_spire_of_karabor::CheckProc); + } }; // http://www.wowhead.com/item=27388 Mr. Pinchy @@ -1300,56 +1080,45 @@ enum MakeAWish SPELL_MR_PINCHYS_GIFT = 33064, }; -class spell_item_make_a_wish : public SpellScriptLoader +class spell_item_make_a_wish : public SpellScript { - public: - spell_item_make_a_wish() : SpellScriptLoader("spell_item_make_a_wish") { } + PrepareSpellScript(spell_item_make_a_wish); - class spell_item_make_a_wish_SpellScript : public SpellScript - { - PrepareSpellScript(spell_item_make_a_wish_SpellScript); - - bool Load() override - { - return GetCaster()->GetTypeId() == TYPEID_PLAYER; - } - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_MR_PINCHYS_BLESSING, - SPELL_SUMMON_MIGHTY_MR_PINCHY, - SPELL_SUMMON_FURIOUS_MR_PINCHY, - SPELL_TINY_MAGICAL_CRAWDAD, - SPELL_MR_PINCHYS_GIFT - }); - } - - void HandleDummy(SpellEffIndex /*effIndex*/) - { - Unit* caster = GetCaster(); - uint32 spellId = SPELL_MR_PINCHYS_GIFT; - switch (urand(1, 5)) - { - case 1: spellId = SPELL_MR_PINCHYS_BLESSING; break; - case 2: spellId = SPELL_SUMMON_MIGHTY_MR_PINCHY; break; - case 3: spellId = SPELL_SUMMON_FURIOUS_MR_PINCHY; break; - case 4: spellId = SPELL_TINY_MAGICAL_CRAWDAD; break; - } - caster->CastSpell(caster, spellId, true, nullptr); - } + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } - void Register() override - { - OnEffectHit += SpellEffectFn(spell_item_make_a_wish_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( + { + SPELL_MR_PINCHYS_BLESSING, + SPELL_SUMMON_MIGHTY_MR_PINCHY, + SPELL_SUMMON_FURIOUS_MR_PINCHY, + SPELL_TINY_MAGICAL_CRAWDAD, + SPELL_MR_PINCHYS_GIFT + }); + } - SpellScript* GetSpellScript() const override + void HandleDummy(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + uint32 spellId = SPELL_MR_PINCHYS_GIFT; + switch (urand(1, 5)) { - return new spell_item_make_a_wish_SpellScript(); + case 1: spellId = SPELL_MR_PINCHYS_BLESSING; break; + case 2: spellId = SPELL_SUMMON_MIGHTY_MR_PINCHY; break; + case 3: spellId = SPELL_SUMMON_FURIOUS_MR_PINCHY; break; + case 4: spellId = SPELL_TINY_MAGICAL_CRAWDAD; break; } + caster->CastSpell(caster, spellId, true, nullptr); + } + + void Register() override + { + OnEffectHit += SpellEffectFn(spell_item_make_a_wish::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; enum MarkOfConquest @@ -1360,97 +1129,75 @@ enum MarkOfConquest // Item - 27920: Mark of Conquest // Item - 27921: Mark of Conquest // 33510 - Health Restore -class spell_item_mark_of_conquest : public SpellScriptLoader +class spell_item_mark_of_conquest : public AuraScript { - public: - spell_item_mark_of_conquest() : SpellScriptLoader("spell_item_mark_of_conquest") { } - - class spell_item_mark_of_conquest_AuraScript : public AuraScript - { - PrepareAuraScript(spell_item_mark_of_conquest_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_MARK_OF_CONQUEST_ENERGIZE }); - } + PrepareAuraScript(spell_item_mark_of_conquest); - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - if (eventInfo.GetTypeMask() & (PROC_FLAG_DONE_RANGED_AUTO_ATTACK | PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS)) - { - // in that case, do not cast heal spell - PreventDefaultAction(); - // but mana instead - eventInfo.GetActor()->CastSpell((Unit*)nullptr, SPELL_MARK_OF_CONQUEST_ENERGIZE, true, nullptr, aurEff); - } - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_item_mark_of_conquest_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } - }; + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_MARK_OF_CONQUEST_ENERGIZE }); + } - AuraScript* GetAuraScript() const override + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + if (eventInfo.GetTypeMask() & (PROC_FLAG_DONE_RANGED_AUTO_ATTACK | PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS)) { - return new spell_item_mark_of_conquest_AuraScript(); + // in that case, do not cast heal spell + PreventDefaultAction(); + // but mana instead + eventInfo.GetActor()->CastSpell(nullptr, SPELL_MARK_OF_CONQUEST_ENERGIZE, true, nullptr, aurEff); } + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_mark_of_conquest::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } }; // http://www.wowhead.com/item=32686 Mingo's Fortune Giblets // 40802 Mingo's Fortune Generator -class spell_item_mingos_fortune_generator : public SpellScriptLoader +class spell_item_mingos_fortune_generator : public SpellScript { - public: - spell_item_mingos_fortune_generator() : SpellScriptLoader("spell_item_mingos_fortune_generator") { } - - class spell_item_mingos_fortune_generator_SpellScript : public SpellScript - { - PrepareSpellScript(spell_item_mingos_fortune_generator_SpellScript); - - void HandleDummy(SpellEffIndex effIndex) - { - // Selecting one from Bloodstained Fortune item - uint32 newitemid; - switch (urand(1, 20)) - { - case 1: newitemid = 32688; break; - case 2: newitemid = 32689; break; - case 3: newitemid = 32690; break; - case 4: newitemid = 32691; break; - case 5: newitemid = 32692; break; - case 6: newitemid = 32693; break; - case 7: newitemid = 32700; break; - case 8: newitemid = 32701; break; - case 9: newitemid = 32702; break; - case 10: newitemid = 32703; break; - case 11: newitemid = 32704; break; - case 12: newitemid = 32705; break; - case 13: newitemid = 32706; break; - case 14: newitemid = 32707; break; - case 15: newitemid = 32708; break; - case 16: newitemid = 32709; break; - case 17: newitemid = 32710; break; - case 18: newitemid = 32711; break; - case 19: newitemid = 32712; break; - case 20: newitemid = 32713; break; - default: - return; - } + PrepareSpellScript(spell_item_mingos_fortune_generator); - CreateItem(effIndex, newitemid); - } + void HandleDummy(SpellEffIndex effIndex) + { + // Selecting one from Bloodstained Fortune item + uint32 newitemid; + switch (urand(1, 20)) + { + case 1: newitemid = 32688; break; + case 2: newitemid = 32689; break; + case 3: newitemid = 32690; break; + case 4: newitemid = 32691; break; + case 5: newitemid = 32692; break; + case 6: newitemid = 32693; break; + case 7: newitemid = 32700; break; + case 8: newitemid = 32701; break; + case 9: newitemid = 32702; break; + case 10: newitemid = 32703; break; + case 11: newitemid = 32704; break; + case 12: newitemid = 32705; break; + case 13: newitemid = 32706; break; + case 14: newitemid = 32707; break; + case 15: newitemid = 32708; break; + case 16: newitemid = 32709; break; + case 17: newitemid = 32710; break; + case 18: newitemid = 32711; break; + case 19: newitemid = 32712; break; + case 20: newitemid = 32713; break; + default: + return; + } - void Register() override - { - OnEffectHit += SpellEffectFn(spell_item_mingos_fortune_generator_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + CreateItem(effIndex, newitemid); + } - SpellScript* GetSpellScript() const override - { - return new spell_item_mingos_fortune_generator_SpellScript(); - } + void Register() override + { + OnEffectHit += SpellEffectFn(spell_item_mingos_fortune_generator::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; // 71875, 71877 - Item - Black Bruise: Necrotic Touch Proc @@ -1459,47 +1206,36 @@ enum NecroticTouch SPELL_ITEM_NECROTIC_TOUCH_PROC = 71879 }; -class spell_item_necrotic_touch : public SpellScriptLoader +class spell_item_necrotic_touch : public AuraScript { - public: - spell_item_necrotic_touch() : SpellScriptLoader("spell_item_necrotic_touch") { } - - class spell_item_necrotic_touch_AuraScript : public AuraScript - { - PrepareAuraScript(spell_item_necrotic_touch_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_ITEM_NECROTIC_TOUCH_PROC }); - } + PrepareAuraScript(spell_item_necrotic_touch); - bool CheckProc(ProcEventInfo& eventInfo) - { - return eventInfo.GetProcTarget() && eventInfo.GetProcTarget()->IsAlive(); - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_ITEM_NECROTIC_TOUCH_PROC }); + } - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - DamageInfo* damageInfo = eventInfo.GetDamageInfo(); - if (!damageInfo || !damageInfo->GetDamage()) - return; + bool CheckProc(ProcEventInfo& eventInfo) + { + return eventInfo.GetProcTarget() && eventInfo.GetProcTarget()->IsAlive(); + } - int32 bp = CalculatePct(static_cast<int32>(damageInfo->GetDamage()), aurEff->GetAmount()); - GetTarget()->CastCustomSpell(SPELL_ITEM_NECROTIC_TOUCH_PROC, SPELLVALUE_BASE_POINT0, bp, eventInfo.GetProcTarget(), true, nullptr, aurEff); - } + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + DamageInfo* damageInfo = eventInfo.GetDamageInfo(); + if (!damageInfo || !damageInfo->GetDamage()) + return; - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_item_necrotic_touch_AuraScript::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_item_necrotic_touch_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } - }; + int32 bp = CalculatePct(static_cast<int32>(damageInfo->GetDamage()), aurEff->GetAmount()); + GetTarget()->CastCustomSpell(SPELL_ITEM_NECROTIC_TOUCH_PROC, SPELLVALUE_BASE_POINT0, bp, eventInfo.GetProcTarget(), true, nullptr, aurEff); + } - AuraScript* GetAuraScript() const override - { - return new spell_item_necrotic_touch_AuraScript(); - } + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_item_necrotic_touch::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_item_necrotic_touch::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } }; // http://www.wowhead.com/item=10720 Gnomish Net-o-Matic Projector @@ -1511,50 +1247,39 @@ enum NetOMaticSpells SPELL_NET_O_MATIC_TRIGGERED3 = 13099, }; -class spell_item_net_o_matic : public SpellScriptLoader +class spell_item_net_o_matic : public SpellScript { - public: - spell_item_net_o_matic() : SpellScriptLoader("spell_item_net_o_matic") { } + PrepareSpellScript(spell_item_net_o_matic); - class spell_item_net_o_matic_SpellScript : public SpellScript + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( { - PrepareSpellScript(spell_item_net_o_matic_SpellScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_NET_O_MATIC_TRIGGERED1, - SPELL_NET_O_MATIC_TRIGGERED2, - SPELL_NET_O_MATIC_TRIGGERED3 - }); - } - - void HandleDummy(SpellEffIndex /*effIndex*/) - { - if (Unit* target = GetHitUnit()) - { - uint32 spellId = SPELL_NET_O_MATIC_TRIGGERED3; - uint32 roll = urand(0, 99); - if (roll < 2) // 2% for 30 sec self root (off-like chance unknown) - spellId = SPELL_NET_O_MATIC_TRIGGERED1; - else if (roll < 4) // 2% for 20 sec root, charge to target (off-like chance unknown) - spellId = SPELL_NET_O_MATIC_TRIGGERED2; - - GetCaster()->CastSpell(target, spellId, true, nullptr); - } - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_item_net_o_matic_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + SPELL_NET_O_MATIC_TRIGGERED1, + SPELL_NET_O_MATIC_TRIGGERED2, + SPELL_NET_O_MATIC_TRIGGERED3 + }); + } - SpellScript* GetSpellScript() const override + void HandleDummy(SpellEffIndex /*effIndex*/) + { + if (Unit* target = GetHitUnit()) { - return new spell_item_net_o_matic_SpellScript(); + uint32 spellId = SPELL_NET_O_MATIC_TRIGGERED3; + uint32 roll = urand(0, 99); + if (roll < 2) // 2% for 30 sec self root (off-like chance unknown) + spellId = SPELL_NET_O_MATIC_TRIGGERED1; + else if (roll < 4) // 2% for 20 sec root, charge to target (off-like chance unknown) + spellId = SPELL_NET_O_MATIC_TRIGGERED2; + + GetCaster()->CastSpell(target, spellId, true, nullptr); } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_item_net_o_matic::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; // http://www.wowhead.com/item=8529 Noggenfogger Elixir @@ -1566,83 +1291,61 @@ enum NoggenfoggerElixirSpells SPELL_NOGGENFOGGER_ELIXIR_TRIGGERED3 = 16591, }; -class spell_item_noggenfogger_elixir : public SpellScriptLoader +class spell_item_noggenfogger_elixir : public SpellScript { - public: - spell_item_noggenfogger_elixir() : SpellScriptLoader("spell_item_noggenfogger_elixir") { } - - class spell_item_noggenfogger_elixir_SpellScript : public SpellScript - { - PrepareSpellScript(spell_item_noggenfogger_elixir_SpellScript); - - bool Load() override - { - return GetCaster()->GetTypeId() == TYPEID_PLAYER; - } + PrepareSpellScript(spell_item_noggenfogger_elixir); - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_NOGGENFOGGER_ELIXIR_TRIGGERED1, - SPELL_NOGGENFOGGER_ELIXIR_TRIGGERED2, - SPELL_NOGGENFOGGER_ELIXIR_TRIGGERED3 - }); - } - - void HandleDummy(SpellEffIndex /*effIndex*/) - { - Unit* caster = GetCaster(); - uint32 spellId = SPELL_NOGGENFOGGER_ELIXIR_TRIGGERED3; - switch (urand(1, 3)) - { - case 1: spellId = SPELL_NOGGENFOGGER_ELIXIR_TRIGGERED1; break; - case 2: spellId = SPELL_NOGGENFOGGER_ELIXIR_TRIGGERED2; break; - } - - caster->CastSpell(caster, spellId, true, nullptr); - } + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } - void Register() override - { - OnEffectHit += SpellEffectFn(spell_item_noggenfogger_elixir_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( + { + SPELL_NOGGENFOGGER_ELIXIR_TRIGGERED1, + SPELL_NOGGENFOGGER_ELIXIR_TRIGGERED2, + SPELL_NOGGENFOGGER_ELIXIR_TRIGGERED3 + }); + } - SpellScript* GetSpellScript() const override + void HandleDummy(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + uint32 spellId = SPELL_NOGGENFOGGER_ELIXIR_TRIGGERED3; + switch (urand(1, 3)) { - return new spell_item_noggenfogger_elixir_SpellScript(); + case 1: spellId = SPELL_NOGGENFOGGER_ELIXIR_TRIGGERED1; break; + case 2: spellId = SPELL_NOGGENFOGGER_ELIXIR_TRIGGERED2; break; } + + caster->CastSpell(caster, spellId, true, nullptr); + } + + void Register() override + { + OnEffectHit += SpellEffectFn(spell_item_noggenfogger_elixir::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; // 29601 - Enlightenment (Pendant of the Violet Eye) -class spell_item_pendant_of_the_violet_eye : public SpellScriptLoader +class spell_item_pendant_of_the_violet_eye : public AuraScript { - public: - spell_item_pendant_of_the_violet_eye() : SpellScriptLoader("spell_item_pendant_of_the_violet_eye") { } - - class spell_item_pendant_of_the_violet_eye_AuraScript : public AuraScript - { - PrepareAuraScript(spell_item_pendant_of_the_violet_eye_AuraScript); - - bool CheckProc(ProcEventInfo& eventInfo) - { - if (SpellInfo const* spellInfo = eventInfo.GetSpellInfo()) - return spellInfo->PowerType == POWER_MANA || (spellInfo->ManaCost != 0 && spellInfo->ManaCostPercentage != 0 && spellInfo->ManaCostPerlevel != 0); + PrepareAuraScript(spell_item_pendant_of_the_violet_eye); - return false; - } + bool CheckProc(ProcEventInfo& eventInfo) + { + if (SpellInfo const* spellInfo = eventInfo.GetSpellInfo()) + return spellInfo->PowerType == POWER_MANA || (spellInfo->ManaCost != 0 && spellInfo->ManaCostPercentage != 0 && spellInfo->ManaCostPerlevel != 0); - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_item_pendant_of_the_violet_eye_AuraScript::CheckProc); - } - }; + return false; + } - AuraScript* GetAuraScript() const override - { - return new spell_item_pendant_of_the_violet_eye_AuraScript(); - } + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_item_pendant_of_the_violet_eye::CheckProc); + } }; enum PersistentShieldMisc @@ -1651,50 +1354,39 @@ enum PersistentShieldMisc }; // 26467 - Persistent Shield -class spell_item_persistent_shield : public SpellScriptLoader +class spell_item_persistent_shield : public AuraScript { - public: - spell_item_persistent_shield() : SpellScriptLoader("spell_item_persistent_shield") { } - - class spell_item_persistent_shield_AuraScript : public AuraScript - { - PrepareAuraScript(spell_item_persistent_shield_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_PERSISTENT_SHIELD_TRIGGERED }); - } + PrepareAuraScript(spell_item_persistent_shield); - bool CheckProc(ProcEventInfo& eventInfo) - { - return eventInfo.GetHealInfo() && eventInfo.GetHealInfo()->GetHeal(); - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_PERSISTENT_SHIELD_TRIGGERED }); + } - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - Unit* caster = eventInfo.GetActor(); - Unit* target = eventInfo.GetProcTarget(); - int32 bp0 = CalculatePct(eventInfo.GetHealInfo()->GetHeal(), 15); + bool CheckProc(ProcEventInfo& eventInfo) + { + return eventInfo.GetHealInfo() && eventInfo.GetHealInfo()->GetHeal(); + } - // Scarab Brooch does not replace stronger shields - if (AuraEffect const* shield = target->GetAuraEffect(SPELL_PERSISTENT_SHIELD_TRIGGERED, EFFECT_0, caster->GetGUID())) - if (shield->GetAmount() > bp0) - return; + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + Unit* caster = eventInfo.GetActor(); + Unit* target = eventInfo.GetProcTarget(); + int32 bp0 = CalculatePct(eventInfo.GetHealInfo()->GetHeal(), 15); - caster->CastCustomSpell(SPELL_PERSISTENT_SHIELD_TRIGGERED, SPELLVALUE_BASE_POINT0, bp0, target, true, nullptr, aurEff); - } + // Scarab Brooch does not replace stronger shields + if (AuraEffect const* shield = target->GetAuraEffect(SPELL_PERSISTENT_SHIELD_TRIGGERED, EFFECT_0, caster->GetGUID())) + if (shield->GetAmount() > bp0) + return; - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_item_persistent_shield_AuraScript::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_item_persistent_shield_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } - }; + caster->CastCustomSpell(SPELL_PERSISTENT_SHIELD_TRIGGERED, SPELLVALUE_BASE_POINT0, bp0, target, true, nullptr, aurEff); + } - AuraScript* GetAuraScript() const override - { - return new spell_item_persistent_shield_AuraScript(); - } + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_item_persistent_shield::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_item_persistent_shield::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } }; enum PetHealing @@ -1705,71 +1397,49 @@ enum PetHealing // 37381 - Pet Healing // Hunter T5 2P Bonus // Warlock T5 2P Bonus -class spell_item_pet_healing : public SpellScriptLoader +class spell_item_pet_healing : public AuraScript { - public: - spell_item_pet_healing() : SpellScriptLoader("spell_item_pet_healing") { } - - class spell_item_pet_healing_AuraScript : public AuraScript - { - PrepareAuraScript(spell_item_pet_healing_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_HEALTH_LINK }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - DamageInfo* damageInfo = eventInfo.GetDamageInfo(); - if (!damageInfo || !damageInfo->GetDamage()) - return; + PrepareAuraScript(spell_item_pet_healing); - int32 bp = CalculatePct(static_cast<int32>(damageInfo->GetDamage()), aurEff->GetAmount()); - Unit* caster = eventInfo.GetActor(); - caster->CastCustomSpell(SPELL_HEALTH_LINK, SPELLVALUE_BASE_POINT0, bp, (Unit*)nullptr, true, nullptr, aurEff); - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_HEALTH_LINK }); + } - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_item_pet_healing_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } - }; + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + DamageInfo* damageInfo = eventInfo.GetDamageInfo(); + if (!damageInfo || !damageInfo->GetDamage()) + return; + + int32 bp = CalculatePct(static_cast<int32>(damageInfo->GetDamage()), aurEff->GetAmount()); + Unit* caster = eventInfo.GetActor(); + caster->CastCustomSpell(SPELL_HEALTH_LINK, SPELLVALUE_BASE_POINT0, bp, (Unit*)nullptr, true, nullptr, aurEff); + } - AuraScript* GetAuraScript() const override - { - return new spell_item_pet_healing_AuraScript(); - } + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_pet_healing::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } }; // 17512 - Piccolo of the Flaming Fire -class spell_item_piccolo_of_the_flaming_fire : public SpellScriptLoader +class spell_item_piccolo_of_the_flaming_fire : public SpellScript { - public: - spell_item_piccolo_of_the_flaming_fire() : SpellScriptLoader("spell_item_piccolo_of_the_flaming_fire") { } - - class spell_item_piccolo_of_the_flaming_fire_SpellScript : public SpellScript - { - PrepareSpellScript(spell_item_piccolo_of_the_flaming_fire_SpellScript); + PrepareSpellScript(spell_item_piccolo_of_the_flaming_fire); - void HandleScript(SpellEffIndex effIndex) - { - PreventHitDefaultEffect(effIndex); - if (Player* target = GetHitPlayer()) - target->HandleEmoteCommand(EMOTE_STATE_DANCE); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_item_piccolo_of_the_flaming_fire_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - } - }; + void HandleScript(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + if (Player* target = GetHitPlayer()) + target->HandleEmoteCommand(EMOTE_STATE_DANCE); + } - SpellScript* GetSpellScript() const override - { - return new spell_item_piccolo_of_the_flaming_fire_SpellScript(); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_item_piccolo_of_the_flaming_fire::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } }; // http://www.wowhead.com/item=6657 Savory Deviate Delight @@ -1782,55 +1452,44 @@ enum SavoryDeviateDelight SPELL_YAAARRRR_FEMALE = 8222, }; -class spell_item_savory_deviate_delight : public SpellScriptLoader +class spell_item_savory_deviate_delight : public SpellScript { - public: - spell_item_savory_deviate_delight() : SpellScriptLoader("spell_item_savory_deviate_delight") { } + PrepareSpellScript(spell_item_savory_deviate_delight); - class spell_item_savory_deviate_delight_SpellScript : public SpellScript - { - PrepareSpellScript(spell_item_savory_deviate_delight_SpellScript); - - bool Load() override - { - return GetCaster()->GetTypeId() == TYPEID_PLAYER; - } - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_FLIP_OUT_MALE, - SPELL_FLIP_OUT_FEMALE, - SPELL_YAAARRRR_MALE, - SPELL_YAAARRRR_FEMALE - }); - } - - void HandleDummy(SpellEffIndex /*effIndex*/) - { - Unit* caster = GetCaster(); - uint32 spellId = 0; - switch (urand(1, 2)) - { - // Flip Out - ninja - case 1: spellId = (caster->getGender() == GENDER_MALE ? SPELL_FLIP_OUT_MALE : SPELL_FLIP_OUT_FEMALE); break; - // Yaaarrrr - pirate - case 2: spellId = (caster->getGender() == GENDER_MALE ? SPELL_YAAARRRR_MALE : SPELL_YAAARRRR_FEMALE); break; - } - caster->CastSpell(caster, spellId, true, nullptr); - } + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } - void Register() override - { - OnEffectHit += SpellEffectFn(spell_item_savory_deviate_delight_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( + { + SPELL_FLIP_OUT_MALE, + SPELL_FLIP_OUT_FEMALE, + SPELL_YAAARRRR_MALE, + SPELL_YAAARRRR_FEMALE + }); + } - SpellScript* GetSpellScript() const override + void HandleDummy(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + uint32 spellId = 0; + switch (urand(1, 2)) { - return new spell_item_savory_deviate_delight_SpellScript(); + // Flip Out - ninja + case 1: spellId = (caster->getGender() == GENDER_MALE ? SPELL_FLIP_OUT_MALE : SPELL_FLIP_OUT_FEMALE); break; + // Yaaarrrr - pirate + case 2: spellId = (caster->getGender() == GENDER_MALE ? SPELL_YAAARRRR_MALE : SPELL_YAAARRRR_FEMALE); break; } + caster->CastSpell(caster, spellId, true, nullptr); + } + + void Register() override + { + OnEffectHit += SpellEffectFn(spell_item_savory_deviate_delight::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; // 48129 - Scroll of Recall @@ -1846,64 +1505,53 @@ enum ScrollOfRecall SPELL_SCROLL_OF_RECALL_FAIL_HORDE_1 = 60328, }; -class spell_item_scroll_of_recall : public SpellScriptLoader +class spell_item_scroll_of_recall : public SpellScript { - public: - spell_item_scroll_of_recall() : SpellScriptLoader("spell_item_scroll_of_recall") { } - - class spell_item_scroll_of_recall_SpellScript : public SpellScript - { - PrepareSpellScript(spell_item_scroll_of_recall_SpellScript); - - bool Load() override - { - return GetCaster()->GetTypeId() == TYPEID_PLAYER; - } + PrepareSpellScript(spell_item_scroll_of_recall); - void HandleScript(SpellEffIndex effIndex) - { - Unit* caster = GetCaster(); - uint8 maxSafeLevel = 0; - switch (GetSpellInfo()->Id) - { - case SPELL_SCROLL_OF_RECALL_I: // Scroll of Recall - maxSafeLevel = 40; - break; - case SPELL_SCROLL_OF_RECALL_II: // Scroll of Recall II - maxSafeLevel = 70; - break; - case SPELL_SCROLL_OF_RECALL_III: // Scroll of Recal III - maxSafeLevel = 80; - break; - default: - break; - } - - if (caster->getLevel() > maxSafeLevel) - { - caster->CastSpell(caster, SPELL_LOST, true); + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } - // ALLIANCE from 60323 to 60330 - HORDE from 60328 to 60335 - uint32 spellId = SPELL_SCROLL_OF_RECALL_FAIL_ALLIANCE_1; - if (GetCaster()->ToPlayer()->GetTeam() == HORDE) - spellId = SPELL_SCROLL_OF_RECALL_FAIL_HORDE_1; + void HandleScript(SpellEffIndex effIndex) + { + Unit* caster = GetCaster(); + uint8 maxSafeLevel = 0; + switch (GetSpellInfo()->Id) + { + case SPELL_SCROLL_OF_RECALL_I: // Scroll of Recall + maxSafeLevel = 40; + break; + case SPELL_SCROLL_OF_RECALL_II: // Scroll of Recall II + maxSafeLevel = 70; + break; + case SPELL_SCROLL_OF_RECALL_III: // Scroll of Recal III + maxSafeLevel = 80; + break; + default: + break; + } - GetCaster()->CastSpell(GetCaster(), spellId + urand(0, 7), true); + if (caster->getLevel() > maxSafeLevel) + { + caster->CastSpell(caster, SPELL_LOST, true); - PreventHitDefaultEffect(effIndex); - } - } + // ALLIANCE from 60323 to 60330 - HORDE from 60328 to 60335 + uint32 spellId = SPELL_SCROLL_OF_RECALL_FAIL_ALLIANCE_1; + if (GetCaster()->ToPlayer()->GetTeam() == HORDE) + spellId = SPELL_SCROLL_OF_RECALL_FAIL_HORDE_1; - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_item_scroll_of_recall_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_TELEPORT_UNITS); - } - }; + GetCaster()->CastSpell(GetCaster(), spellId + urand(0, 7), true); - SpellScript* GetSpellScript() const override - { - return new spell_item_scroll_of_recall_SpellScript(); + PreventHitDefaultEffect(effIndex); } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_item_scroll_of_recall::HandleScript, EFFECT_0, SPELL_EFFECT_TELEPORT_UNITS); + } }; // 71169 - Shadow's Fate (Shadowmourne questline) @@ -1913,71 +1561,49 @@ enum ShadowsFate NPC_SINDRAGOSA = 36853 }; -class spell_item_unsated_craving : public SpellScriptLoader +class spell_item_unsated_craving : public AuraScript { - public: - spell_item_unsated_craving() : SpellScriptLoader("spell_item_unsated_craving") { } - - class spell_item_unsated_craving_AuraScript : public AuraScript - { - PrepareAuraScript(spell_item_unsated_craving_AuraScript); + PrepareAuraScript(spell_item_unsated_craving); - bool CheckProc(ProcEventInfo& procInfo) - { - Unit* caster = procInfo.GetActor(); - if (!caster || caster->GetTypeId() != TYPEID_PLAYER) - return false; - - Unit* target = procInfo.GetActionTarget(); - if (!target || target->GetTypeId() != TYPEID_UNIT || target->IsCritter() || (target->GetEntry() != NPC_SINDRAGOSA && target->IsSummon())) - return false; + bool CheckProc(ProcEventInfo& procInfo) + { + Unit* caster = procInfo.GetActor(); + if (!caster || caster->GetTypeId() != TYPEID_PLAYER) + return false; - return true; - } + Unit* target = procInfo.GetActionTarget(); + if (!target || target->GetTypeId() != TYPEID_UNIT || target->IsCritter() || (target->GetEntry() != NPC_SINDRAGOSA && target->IsSummon())) + return false; - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_item_unsated_craving_AuraScript::CheckProc); - } - }; + return true; + } - AuraScript* GetAuraScript() const override - { - return new spell_item_unsated_craving_AuraScript(); - } + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_item_unsated_craving::CheckProc); + } }; -class spell_item_shadows_fate : public SpellScriptLoader +class spell_item_shadows_fate : public AuraScript { - public: - spell_item_shadows_fate() : SpellScriptLoader("spell_item_shadows_fate") { } - - class spell_item_shadows_fate_AuraScript : public AuraScript - { - PrepareAuraScript(spell_item_shadows_fate_AuraScript); + PrepareAuraScript(spell_item_shadows_fate); - void HandleProc(ProcEventInfo& procInfo) - { - PreventDefaultAction(); - - Unit* caster = procInfo.GetActor(); - Unit* target = GetCaster(); - if (!caster || !target) - return; + void HandleProc(ProcEventInfo& procInfo) + { + PreventDefaultAction(); - caster->CastSpell(target, SPELL_SOUL_FEAST, TRIGGERED_FULL_MASK); - } + Unit* caster = procInfo.GetActor(); + Unit* target = GetCaster(); + if (!caster || !target) + return; - void Register() override - { - OnProc += AuraProcFn(spell_item_shadows_fate_AuraScript::HandleProc); - } - }; + caster->CastSpell(target, SPELL_SOUL_FEAST, true); + } - AuraScript* GetAuraScript() const override - { - return new spell_item_shadows_fate_AuraScript(); - } + void Register() override + { + OnProc += AuraProcFn(spell_item_shadows_fate::HandleProc); + } }; enum Shadowmourne @@ -1990,120 +1616,98 @@ enum Shadowmourne }; // 71903 - Item - Shadowmourne Legendary -class spell_item_shadowmourne : public SpellScriptLoader +class spell_item_shadowmourne : public AuraScript { - public: - spell_item_shadowmourne() : SpellScriptLoader("spell_item_shadowmourne") { } + PrepareAuraScript(spell_item_shadowmourne); - class spell_item_shadowmourne_AuraScript : public AuraScript + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( { - PrepareAuraScript(spell_item_shadowmourne_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_SHADOWMOURNE_CHAOS_BANE_DAMAGE, - SPELL_SHADOWMOURNE_SOUL_FRAGMENT, - SPELL_SHADOWMOURNE_CHAOS_BANE_BUFF - }); - } - - bool CheckProc(ProcEventInfo& eventInfo) - { - if (GetTarget()->HasAura(SPELL_SHADOWMOURNE_CHAOS_BANE_BUFF)) // cant collect shards while under effect of Chaos Bane buff - return false; - return eventInfo.GetProcTarget() && eventInfo.GetProcTarget()->IsAlive(); - } + SPELL_SHADOWMOURNE_CHAOS_BANE_DAMAGE, + SPELL_SHADOWMOURNE_SOUL_FRAGMENT, + SPELL_SHADOWMOURNE_CHAOS_BANE_BUFF + }); + } - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - GetTarget()->CastSpell(GetTarget(), SPELL_SHADOWMOURNE_SOUL_FRAGMENT, true, nullptr, aurEff); + bool CheckProc(ProcEventInfo& eventInfo) + { + if (GetTarget()->HasAura(SPELL_SHADOWMOURNE_CHAOS_BANE_BUFF)) // cant collect shards while under effect of Chaos Bane buff + return false; + return eventInfo.GetProcTarget() && eventInfo.GetProcTarget()->IsAlive(); + } - // this can't be handled in AuraScript of SoulFragments because we need to know victim - if (Aura* soulFragments = GetTarget()->GetAura(SPELL_SHADOWMOURNE_SOUL_FRAGMENT)) - { - if (soulFragments->GetStackAmount() >= 10) - { - GetTarget()->CastSpell(eventInfo.GetProcTarget(), SPELL_SHADOWMOURNE_CHAOS_BANE_DAMAGE, true, nullptr, aurEff); - soulFragments->Remove(); - } - } - } + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + GetTarget()->CastSpell(GetTarget(), SPELL_SHADOWMOURNE_SOUL_FRAGMENT, true, nullptr, aurEff); - void Register() override + // this can't be handled in AuraScript of SoulFragments because we need to know victim + if (Aura* soulFragments = GetTarget()->GetAura(SPELL_SHADOWMOURNE_SOUL_FRAGMENT)) + { + if (soulFragments->GetStackAmount() >= 10) { - DoCheckProc += AuraCheckProcFn(spell_item_shadowmourne_AuraScript::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_item_shadowmourne_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + GetTarget()->CastSpell(eventInfo.GetProcTarget(), SPELL_SHADOWMOURNE_CHAOS_BANE_DAMAGE, true, nullptr, aurEff); + soulFragments->Remove(); } - }; - - AuraScript* GetAuraScript() const override - { - return new spell_item_shadowmourne_AuraScript(); } + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_item_shadowmourne::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_item_shadowmourne::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } }; // 71905 - Soul Fragment -class spell_item_shadowmourne_soul_fragment : public SpellScriptLoader +class spell_item_shadowmourne_soul_fragment : public AuraScript { - public: - spell_item_shadowmourne_soul_fragment() : SpellScriptLoader("spell_item_shadowmourne_soul_fragment") { } + PrepareAuraScript(spell_item_shadowmourne_soul_fragment); - class spell_item_shadowmourne_soul_fragment_AuraScript : public AuraScript + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( { - PrepareAuraScript(spell_item_shadowmourne_soul_fragment_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_SHADOWMOURNE_VISUAL_LOW, - SPELL_SHADOWMOURNE_VISUAL_HIGH, - SPELL_SHADOWMOURNE_CHAOS_BANE_BUFF - }); - } - - void OnStackChange(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - Unit* target = GetTarget(); - switch (GetStackAmount()) - { - case 1: - target->CastSpell(target, SPELL_SHADOWMOURNE_VISUAL_LOW, true); - break; - case 6: - target->RemoveAurasDueToSpell(SPELL_SHADOWMOURNE_VISUAL_LOW); - target->CastSpell(target, SPELL_SHADOWMOURNE_VISUAL_HIGH, true); - break; - case 10: - target->RemoveAurasDueToSpell(SPELL_SHADOWMOURNE_VISUAL_HIGH); - target->CastSpell(target, SPELL_SHADOWMOURNE_CHAOS_BANE_BUFF, true); - break; - default: - break; - } - } + SPELL_SHADOWMOURNE_VISUAL_LOW, + SPELL_SHADOWMOURNE_VISUAL_HIGH, + SPELL_SHADOWMOURNE_CHAOS_BANE_BUFF + }); + } - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - Unit* target = GetTarget(); + void OnStackChange(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + switch (GetStackAmount()) + { + case 1: + target->CastSpell(target, SPELL_SHADOWMOURNE_VISUAL_LOW, true); + break; + case 6: target->RemoveAurasDueToSpell(SPELL_SHADOWMOURNE_VISUAL_LOW); + target->CastSpell(target, SPELL_SHADOWMOURNE_VISUAL_HIGH, true); + break; + case 10: target->RemoveAurasDueToSpell(SPELL_SHADOWMOURNE_VISUAL_HIGH); - } + target->CastSpell(target, SPELL_SHADOWMOURNE_CHAOS_BANE_BUFF, true); + break; + default: + break; + } + } - void Register() override - { - AfterEffectApply += AuraEffectApplyFn(spell_item_shadowmourne_soul_fragment_AuraScript::OnStackChange, EFFECT_0, SPELL_AURA_MOD_STAT, AuraEffectHandleModes(AURA_EFFECT_HANDLE_REAL | AURA_EFFECT_HANDLE_REAPPLY)); - AfterEffectRemove += AuraEffectRemoveFn(spell_item_shadowmourne_soul_fragment_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_MOD_STAT, AURA_EFFECT_HANDLE_REAL); - } - }; + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + target->RemoveAurasDueToSpell(SPELL_SHADOWMOURNE_VISUAL_LOW); + target->RemoveAurasDueToSpell(SPELL_SHADOWMOURNE_VISUAL_HIGH); + } - AuraScript* GetAuraScript() const override - { - return new spell_item_shadowmourne_soul_fragment_AuraScript(); - } + void Register() override + { + AfterEffectApply += AuraEffectApplyFn(spell_item_shadowmourne_soul_fragment::OnStackChange, EFFECT_0, SPELL_AURA_MOD_STAT, AuraEffectHandleModes(AURA_EFFECT_HANDLE_REAL | AURA_EFFECT_HANDLE_REAPPLY)); + AfterEffectRemove += AuraEffectRemoveFn(spell_item_shadowmourne_soul_fragment::OnRemove, EFFECT_0, SPELL_AURA_MOD_STAT, AURA_EFFECT_HANDLE_REAL); + } }; // http://www.wowhead.com/item=7734 Six Demon Bag @@ -2118,69 +1722,58 @@ enum SixDemonBagSpells SPELL_ENVELOPING_WINDS = 25189, }; -class spell_item_six_demon_bag : public SpellScriptLoader +class spell_item_six_demon_bag : public SpellScript { - public: - spell_item_six_demon_bag() : SpellScriptLoader("spell_item_six_demon_bag") { } - - class spell_item_six_demon_bag_SpellScript : public SpellScript - { - PrepareSpellScript(spell_item_six_demon_bag_SpellScript); + PrepareSpellScript(spell_item_six_demon_bag); - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_FROSTBOLT, - SPELL_POLYMORPH, - SPELL_SUMMON_FELHOUND_MINION, - SPELL_FIREBALL, - SPELL_CHAIN_LIGHTNING, - SPELL_ENVELOPING_WINDS - }); - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( + { + SPELL_FROSTBOLT, + SPELL_POLYMORPH, + SPELL_SUMMON_FELHOUND_MINION, + SPELL_FIREBALL, + SPELL_CHAIN_LIGHTNING, + SPELL_ENVELOPING_WINDS + }); + } - void HandleDummy(SpellEffIndex /*effIndex*/) + void HandleDummy(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + if (Unit* target = GetHitUnit()) + { + uint32 spellId = 0; + uint32 rand = urand(0, 99); + if (rand < 25) // Fireball (25% chance) + spellId = SPELL_FIREBALL; + else if (rand < 50) // Frostball (25% chance) + spellId = SPELL_FROSTBOLT; + else if (rand < 70) // Chain Lighting (20% chance) + spellId = SPELL_CHAIN_LIGHTNING; + else if (rand < 80) // Polymorph (10% chance) { - Unit* caster = GetCaster(); - if (Unit* target = GetHitUnit()) - { - uint32 spellId = 0; - uint32 rand = urand(0, 99); - if (rand < 25) // Fireball (25% chance) - spellId = SPELL_FIREBALL; - else if (rand < 50) // Frostball (25% chance) - spellId = SPELL_FROSTBOLT; - else if (rand < 70) // Chain Lighting (20% chance) - spellId = SPELL_CHAIN_LIGHTNING; - else if (rand < 80) // Polymorph (10% chance) - { - spellId = SPELL_POLYMORPH; - if (urand(0, 100) <= 30) // 30% chance to self-cast - target = caster; - } - else if (rand < 95) // Enveloping Winds (15% chance) - spellId = SPELL_ENVELOPING_WINDS; - else // Summon Felhund minion (5% chance) - { - spellId = SPELL_SUMMON_FELHOUND_MINION; - target = caster; - } - - caster->CastSpell(target, spellId, true, GetCastItem()); - } + spellId = SPELL_POLYMORPH; + if (urand(0, 100) <= 30) // 30% chance to self-cast + target = caster; } - - void Register() override + else if (rand < 95) // Enveloping Winds (15% chance) + spellId = SPELL_ENVELOPING_WINDS; + else // Summon Felhund minion (5% chance) { - OnEffectHitTarget += SpellEffectFn(spell_item_six_demon_bag_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + spellId = SPELL_SUMMON_FELHOUND_MINION; + target = caster; } - }; - SpellScript* GetSpellScript() const override - { - return new spell_item_six_demon_bag_SpellScript(); + caster->CastSpell(target, spellId, true, GetCastItem()); } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_item_six_demon_bag::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; enum SwiftHandJusticeMisc @@ -2189,39 +1782,28 @@ enum SwiftHandJusticeMisc }; // 59906 - Swift Hand of Justice Dummy -class spell_item_swift_hand_justice_dummy : public SpellScriptLoader +class spell_item_swift_hand_justice_dummy : public AuraScript { - public: - spell_item_swift_hand_justice_dummy() : SpellScriptLoader("spell_item_swift_hand_justice_dummy") { } - - class spell_item_swift_hand_justice_dummy_AuraScript : public AuraScript - { - PrepareAuraScript(spell_item_swift_hand_justice_dummy_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_SWIFT_HAND_OF_JUSTICE_HEAL }); - } + PrepareAuraScript(spell_item_swift_hand_justice_dummy); - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SWIFT_HAND_OF_JUSTICE_HEAL }); + } - Unit* caster = eventInfo.GetActor(); - int32 amount = caster->CountPctFromMaxHealth(aurEff->GetAmount()); - caster->CastCustomSpell(SPELL_SWIFT_HAND_OF_JUSTICE_HEAL, SPELLVALUE_BASE_POINT0, amount, (Unit*)nullptr, true, nullptr, aurEff); - } + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_item_swift_hand_justice_dummy_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } - }; + Unit* caster = eventInfo.GetActor(); + int32 amount = caster->CountPctFromMaxHealth(aurEff->GetAmount()); + caster->CastCustomSpell(SPELL_SWIFT_HAND_OF_JUSTICE_HEAL, SPELLVALUE_BASE_POINT0, amount, (Unit*)nullptr, true, nullptr, aurEff); + } - AuraScript* GetAuraScript() const override - { - return new spell_item_swift_hand_justice_dummy_AuraScript(); - } + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_swift_hand_justice_dummy::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } }; enum TotemOfFlowingWater @@ -2231,66 +1813,43 @@ enum TotemOfFlowingWater // Item - 23005: Totem of Flowing Water // 28849 - Lesser Healing Wave -class spell_item_totem_of_flowing_water : public SpellScriptLoader +class spell_item_totem_of_flowing_water : public AuraScript { - public: - spell_item_totem_of_flowing_water() : SpellScriptLoader("spell_item_totem_of_flowing_water") { } - - class spell_item_totem_of_flowing_water_AuraScript : public AuraScript - { - PrepareAuraScript(spell_item_totem_of_flowing_water_AuraScript); + PrepareAuraScript(spell_item_totem_of_flowing_water); - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_LESSER_HEALING_WAVE_MANA }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - eventInfo.GetActor()->CastSpell((Unit*)nullptr, SPELL_LESSER_HEALING_WAVE_MANA, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_item_totem_of_flowing_water_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } - }; + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_LESSER_HEALING_WAVE_MANA }); + } - AuraScript* GetAuraScript() const override - { - return new spell_item_totem_of_flowing_water_AuraScript(); - } + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + eventInfo.GetActor()->CastSpell(nullptr, SPELL_LESSER_HEALING_WAVE_MANA, true, nullptr, aurEff); + } + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_totem_of_flowing_water::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } }; // 28862 - The Eye of Diminution -class spell_item_the_eye_of_diminution : public SpellScriptLoader +class spell_item_the_eye_of_diminution : public AuraScript { - public: - spell_item_the_eye_of_diminution() : SpellScriptLoader("spell_item_the_eye_of_diminution") { } - - class spell_item_the_eye_of_diminution_AuraScript : public AuraScript - { - PrepareAuraScript(spell_item_the_eye_of_diminution_AuraScript); + PrepareAuraScript(spell_item_the_eye_of_diminution); - void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/) - { - int32 diff = GetUnitOwner()->getLevel() - 60; - if (diff > 0) - amount += diff; - } - - void Register() override - { - DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_item_the_eye_of_diminution_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_MOD_THREAT); - } - }; + void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/) + { + int32 diff = GetUnitOwner()->getLevel() - 60; + if (diff > 0) + amount += diff; + } - AuraScript* GetAuraScript() const override - { - return new spell_item_the_eye_of_diminution_AuraScript(); - } + void Register() override + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_item_the_eye_of_diminution::CalculateAmount, EFFECT_0, SPELL_AURA_MOD_THREAT); + } }; // http://www.wowhead.com/item=44012 Underbelly Elixir @@ -2302,102 +1861,80 @@ enum UnderbellyElixirSpells SPELL_UNDERBELLY_ELIXIR_TRIGGERED3 = 59843, }; -class spell_item_underbelly_elixir : public SpellScriptLoader +class spell_item_underbelly_elixir : public SpellScript { - public: - spell_item_underbelly_elixir() : SpellScriptLoader("spell_item_underbelly_elixir") { } + PrepareSpellScript(spell_item_underbelly_elixir); - class spell_item_underbelly_elixir_SpellScript : public SpellScript + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( { - PrepareSpellScript(spell_item_underbelly_elixir_SpellScript); - - bool Load() override - { - return GetCaster()->GetTypeId() == TYPEID_PLAYER; - } - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_UNDERBELLY_ELIXIR_TRIGGERED1, - SPELL_UNDERBELLY_ELIXIR_TRIGGERED2, - SPELL_UNDERBELLY_ELIXIR_TRIGGERED3 - }); - } - - void HandleDummy(SpellEffIndex /*effIndex*/) - { - Unit* caster = GetCaster(); - uint32 spellId = SPELL_UNDERBELLY_ELIXIR_TRIGGERED3; - switch (urand(1, 3)) - { - case 1: spellId = SPELL_UNDERBELLY_ELIXIR_TRIGGERED1; break; - case 2: spellId = SPELL_UNDERBELLY_ELIXIR_TRIGGERED2; break; - } - caster->CastSpell(caster, spellId, true, nullptr); - } - - void Register() override - { - OnEffectHit += SpellEffectFn(spell_item_underbelly_elixir_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + SPELL_UNDERBELLY_ELIXIR_TRIGGERED1, + SPELL_UNDERBELLY_ELIXIR_TRIGGERED2, + SPELL_UNDERBELLY_ELIXIR_TRIGGERED3 + }); + } - SpellScript* GetSpellScript() const override + void HandleDummy(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + uint32 spellId = SPELL_UNDERBELLY_ELIXIR_TRIGGERED3; + switch (urand(1, 3)) { - return new spell_item_underbelly_elixir_SpellScript(); + case 1: spellId = SPELL_UNDERBELLY_ELIXIR_TRIGGERED1; break; + case 2: spellId = SPELL_UNDERBELLY_ELIXIR_TRIGGERED2; break; } + caster->CastSpell(caster, spellId, true, nullptr); + } + + void Register() override + { + OnEffectHit += SpellEffectFn(spell_item_underbelly_elixir::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; // 47776 - Roll 'dem Bones -class spell_item_worn_troll_dice : public SpellScriptLoader +class spell_item_worn_troll_dice : public SpellScript { - public: - spell_item_worn_troll_dice() : SpellScriptLoader("spell_item_worn_troll_dice") { } - - class spell_item_worn_troll_dice_SpellScript : public SpellScript - { - PrepareSpellScript(spell_item_worn_troll_dice_SpellScript); - - enum - { - TEXT_WORN_TROLL_DICE = 26152 - }; + PrepareSpellScript(spell_item_worn_troll_dice); - bool Validate(SpellInfo const* /*spellInfo*/) override - { - if (!sObjectMgr->GetBroadcastText(TEXT_WORN_TROLL_DICE)) - return false; - return true; - } + enum + { + TEXT_WORN_TROLL_DICE = 26152 + }; - bool Load() override - { - return GetCaster()->GetTypeId() == TYPEID_PLAYER; - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sObjectMgr->GetBroadcastText(TEXT_WORN_TROLL_DICE)) + return false; + return true; + } - void HandleScript(SpellEffIndex /*effIndex*/) - { - GetCaster()->TextEmote(TEXT_WORN_TROLL_DICE, GetHitUnit()); + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } - static uint32 const minimum = 1; - static uint32 const maximum = 6; + void HandleScript(SpellEffIndex /*effIndex*/) + { + GetCaster()->TextEmote(TEXT_WORN_TROLL_DICE, GetHitUnit()); - // roll twice - GetCaster()->ToPlayer()->DoRandomRoll(minimum, maximum); - GetCaster()->ToPlayer()->DoRandomRoll(minimum, maximum); - } + static uint32 const minimum = 1; + static uint32 const maximum = 6; - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_item_worn_troll_dice_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - } - }; + // roll twice + GetCaster()->ToPlayer()->DoRandomRoll(minimum, maximum); + GetCaster()->ToPlayer()->DoRandomRoll(minimum, maximum); + } - SpellScript* GetSpellScript() const override - { - return new spell_item_worn_troll_dice_SpellScript(); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_item_worn_troll_dice::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } }; enum AirRifleSpells @@ -2407,52 +1944,41 @@ enum AirRifleSpells SPELL_AIR_RIFLE_SHOOT_SELF = 65577, }; -class spell_item_red_rider_air_rifle : public SpellScriptLoader +class spell_item_red_rider_air_rifle : public SpellScript { - public: - spell_item_red_rider_air_rifle() : SpellScriptLoader("spell_item_red_rider_air_rifle") { } + PrepareSpellScript(spell_item_red_rider_air_rifle); - class spell_item_red_rider_air_rifle_SpellScript : public SpellScript + bool Validate(SpellInfo const* /*spell*/) override + { + return ValidateSpellInfo( { - PrepareSpellScript(spell_item_red_rider_air_rifle_SpellScript); - - bool Validate(SpellInfo const* /*spell*/) override - { - return ValidateSpellInfo( - { - SPELL_AIR_RIFLE_HOLD_VISUAL, - SPELL_AIR_RIFLE_SHOOT, - SPELL_AIR_RIFLE_SHOOT_SELF - }); - } - - void HandleScript(SpellEffIndex effIndex) - { - PreventHitDefaultEffect(effIndex); - Unit* caster = GetCaster(); - if (Unit* target = GetHitUnit()) - { - caster->CastSpell(caster, SPELL_AIR_RIFLE_HOLD_VISUAL, true); - // needed because this spell shares GCD with its triggered spells (which must not be cast with triggered flag) - if (Player* player = caster->ToPlayer()) - player->GetSpellHistory()->CancelGlobalCooldown(GetSpellInfo()); - if (urand(0, 4)) - caster->CastSpell(target, SPELL_AIR_RIFLE_SHOOT, false); - else - caster->CastSpell(caster, SPELL_AIR_RIFLE_SHOOT_SELF, false); - } - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_item_red_rider_air_rifle_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - } - }; + SPELL_AIR_RIFLE_HOLD_VISUAL, + SPELL_AIR_RIFLE_SHOOT, + SPELL_AIR_RIFLE_SHOOT_SELF + }); + } - SpellScript* GetSpellScript() const override - { - return new spell_item_red_rider_air_rifle_SpellScript(); + void HandleScript(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + Unit* caster = GetCaster(); + if (Unit* target = GetHitUnit()) + { + caster->CastSpell(caster, SPELL_AIR_RIFLE_HOLD_VISUAL, true); + // needed because this spell shares GCD with its triggered spells (which must not be cast with triggered flag) + if (Player* player = caster->ToPlayer()) + player->GetSpellHistory()->CancelGlobalCooldown(GetSpellInfo()); + if (urand(0, 4)) + caster->CastSpell(target, SPELL_AIR_RIFLE_SHOOT, false); + else + caster->CastSpell(caster, SPELL_AIR_RIFLE_SHOOT_SELF, false); } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_item_red_rider_air_rifle::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } }; enum GenericData @@ -2475,83 +2001,61 @@ enum CreateHeartCandy ITEM_HEART_CANDY_8 = 21820, }; -class spell_item_create_heart_candy : public SpellScriptLoader +class spell_item_create_heart_candy : public SpellScript { - public: - spell_item_create_heart_candy() : SpellScriptLoader("spell_item_create_heart_candy") { } - - class spell_item_create_heart_candy_SpellScript : public SpellScript - { - PrepareSpellScript(spell_item_create_heart_candy_SpellScript); + PrepareSpellScript(spell_item_create_heart_candy); - void HandleScript(SpellEffIndex effIndex) - { - PreventHitDefaultEffect(effIndex); - if (Player* target = GetHitPlayer()) - { - static const uint32 items[] = {ITEM_HEART_CANDY_1, ITEM_HEART_CANDY_2, ITEM_HEART_CANDY_3, ITEM_HEART_CANDY_4, ITEM_HEART_CANDY_5, ITEM_HEART_CANDY_6, ITEM_HEART_CANDY_7, ITEM_HEART_CANDY_8}; - target->AddItem(items[urand(0, 7)], 1); - } - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_item_create_heart_candy_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - } - }; - - SpellScript* GetSpellScript() const override + void HandleScript(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + if (Player* target = GetHitPlayer()) { - return new spell_item_create_heart_candy_SpellScript(); + static const uint32 items[] = {ITEM_HEART_CANDY_1, ITEM_HEART_CANDY_2, ITEM_HEART_CANDY_3, ITEM_HEART_CANDY_4, ITEM_HEART_CANDY_5, ITEM_HEART_CANDY_6, ITEM_HEART_CANDY_7, ITEM_HEART_CANDY_8}; + target->AddItem(items[urand(0, 7)], 1); } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_item_create_heart_candy::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } }; -class spell_item_book_of_glyph_mastery : public SpellScriptLoader +class spell_item_book_of_glyph_mastery : public SpellScript { - public: - spell_item_book_of_glyph_mastery() : SpellScriptLoader("spell_item_book_of_glyph_mastery") { } - - class spell_item_book_of_glyph_mastery_SpellScript : public SpellScript - { - PrepareSpellScript(spell_item_book_of_glyph_mastery_SpellScript); + PrepareSpellScript(spell_item_book_of_glyph_mastery); - bool Load() override - { - return GetCaster()->GetTypeId() == TYPEID_PLAYER; - } - - SpellCastResult CheckRequirement() - { - if (HasDiscoveredAllSpells(GetSpellInfo()->Id, GetCaster()->ToPlayer())) - { - SetCustomCastResultMessage(SPELL_CUSTOM_ERROR_LEARNED_EVERYTHING); - return SPELL_FAILED_CUSTOM_ERROR; - } + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } - return SPELL_CAST_OK; - } + SpellCastResult CheckRequirement() + { + if (HasDiscoveredAllSpells(GetSpellInfo()->Id, GetCaster()->ToPlayer())) + { + SetCustomCastResultMessage(SPELL_CUSTOM_ERROR_LEARNED_EVERYTHING); + return SPELL_FAILED_CUSTOM_ERROR; + } - void HandleScript(SpellEffIndex /*effIndex*/) - { - Player* caster = GetCaster()->ToPlayer(); - uint32 spellId = GetSpellInfo()->Id; + return SPELL_CAST_OK; + } - // learn random explicit discovery recipe (if any) - if (uint32 discoveredSpellId = GetExplicitDiscoverySpell(spellId, caster)) - caster->LearnSpell(discoveredSpellId, false); - } + void HandleScript(SpellEffIndex /*effIndex*/) + { + Player* caster = GetCaster()->ToPlayer(); + uint32 spellId = GetSpellInfo()->Id; - void Register() override - { - OnCheckCast += SpellCheckCastFn(spell_item_book_of_glyph_mastery_SpellScript::CheckRequirement); - OnEffectHitTarget += SpellEffectFn(spell_item_book_of_glyph_mastery_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - } - }; + // learn random explicit discovery recipe (if any) + if (uint32 discoveredSpellId = GetExplicitDiscoverySpell(spellId, caster)) + caster->LearnSpell(discoveredSpellId, false); + } - SpellScript* GetSpellScript() const override - { - return new spell_item_book_of_glyph_mastery_SpellScript(); - } + void Register() override + { + OnCheckCast += SpellCheckCastFn(spell_item_book_of_glyph_mastery::CheckRequirement); + OnEffectHitTarget += SpellEffectFn(spell_item_book_of_glyph_mastery::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } }; enum GiftOfTheHarvester @@ -2560,38 +2064,27 @@ enum GiftOfTheHarvester MAX_GHOULS = 5, }; -class spell_item_gift_of_the_harvester : public SpellScriptLoader +class spell_item_gift_of_the_harvester : public SpellScript { - public: - spell_item_gift_of_the_harvester() : SpellScriptLoader("spell_item_gift_of_the_harvester") { } + PrepareSpellScript(spell_item_gift_of_the_harvester); - class spell_item_gift_of_the_harvester_SpellScript : public SpellScript + SpellCastResult CheckRequirement() + { + std::list<Creature*> ghouls; + GetCaster()->GetAllMinionsByEntry(ghouls, NPC_GHOUL); + if (ghouls.size() >= MAX_GHOULS) { - PrepareSpellScript(spell_item_gift_of_the_harvester_SpellScript); - - SpellCastResult CheckRequirement() - { - std::list<Creature*> ghouls; - GetCaster()->GetAllMinionsByEntry(ghouls, NPC_GHOUL); - if (ghouls.size() >= MAX_GHOULS) - { - SetCustomCastResultMessage(SPELL_CUSTOM_ERROR_TOO_MANY_GHOULS); - return SPELL_FAILED_CUSTOM_ERROR; - } - - return SPELL_CAST_OK; - } + SetCustomCastResultMessage(SPELL_CUSTOM_ERROR_TOO_MANY_GHOULS); + return SPELL_FAILED_CUSTOM_ERROR; + } - void Register() override - { - OnCheckCast += SpellCheckCastFn(spell_item_gift_of_the_harvester_SpellScript::CheckRequirement); - } - }; + return SPELL_CAST_OK; + } - SpellScript* GetSpellScript() const override - { - return new spell_item_gift_of_the_harvester_SpellScript(); - } + void Register() override + { + OnCheckCast += SpellCheckCastFn(spell_item_gift_of_the_harvester::CheckRequirement); + } }; enum Sinkholes @@ -2601,37 +2094,26 @@ enum Sinkholes NPC_NORTHWEST_SINKHOLE = 25666, }; -class spell_item_map_of_the_geyser_fields : public SpellScriptLoader +class spell_item_map_of_the_geyser_fields : public SpellScript { - public: - spell_item_map_of_the_geyser_fields() : SpellScriptLoader("spell_item_map_of_the_geyser_fields") { } + PrepareSpellScript(spell_item_map_of_the_geyser_fields); - class spell_item_map_of_the_geyser_fields_SpellScript : public SpellScript - { - PrepareSpellScript(spell_item_map_of_the_geyser_fields_SpellScript); - - SpellCastResult CheckSinkholes() - { - Unit* caster = GetCaster(); - if (caster->FindNearestCreature(NPC_SOUTH_SINKHOLE, 30.0f, true) || - caster->FindNearestCreature(NPC_NORTHEAST_SINKHOLE, 30.0f, true) || - caster->FindNearestCreature(NPC_NORTHWEST_SINKHOLE, 30.0f, true)) - return SPELL_CAST_OK; - - SetCustomCastResultMessage(SPELL_CUSTOM_ERROR_MUST_BE_CLOSE_TO_SINKHOLE); - return SPELL_FAILED_CUSTOM_ERROR; - } - - void Register() override - { - OnCheckCast += SpellCheckCastFn(spell_item_map_of_the_geyser_fields_SpellScript::CheckSinkholes); - } - }; + SpellCastResult CheckSinkholes() + { + Unit* caster = GetCaster(); + if (caster->FindNearestCreature(NPC_SOUTH_SINKHOLE, 30.0f, true) || + caster->FindNearestCreature(NPC_NORTHEAST_SINKHOLE, 30.0f, true) || + caster->FindNearestCreature(NPC_NORTHWEST_SINKHOLE, 30.0f, true)) + return SPELL_CAST_OK; + + SetCustomCastResultMessage(SPELL_CUSTOM_ERROR_MUST_BE_CLOSE_TO_SINKHOLE); + return SPELL_FAILED_CUSTOM_ERROR; + } - SpellScript* GetSpellScript() const override - { - return new spell_item_map_of_the_geyser_fields_SpellScript(); - } + void Register() override + { + OnCheckCast += SpellCheckCastFn(spell_item_map_of_the_geyser_fields::CheckSinkholes); + } }; enum VanquishedClutchesSpells @@ -2641,42 +2123,31 @@ enum VanquishedClutchesSpells SPELL_CORRUPTOR = 64984, }; -class spell_item_vanquished_clutches : public SpellScriptLoader +class spell_item_vanquished_clutches : public SpellScript { - public: - spell_item_vanquished_clutches() : SpellScriptLoader("spell_item_vanquished_clutches") { } + PrepareSpellScript(spell_item_vanquished_clutches); - class spell_item_vanquished_clutches_SpellScript : public SpellScript + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( { - PrepareSpellScript(spell_item_vanquished_clutches_SpellScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_CRUSHER, - SPELL_CONSTRICTOR, - SPELL_CORRUPTOR - }); - } - - void HandleDummy(SpellEffIndex /*effIndex*/) - { - uint32 spellId = RAND(SPELL_CRUSHER, SPELL_CONSTRICTOR, SPELL_CORRUPTOR); - Unit* caster = GetCaster(); - caster->CastSpell(caster, spellId, true); - } + SPELL_CRUSHER, + SPELL_CONSTRICTOR, + SPELL_CORRUPTOR + }); + } - void Register() override - { - OnEffectHit += SpellEffectFn(spell_item_vanquished_clutches_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + void HandleDummy(SpellEffIndex /*effIndex*/) + { + uint32 spellId = RAND(SPELL_CRUSHER, SPELL_CONSTRICTOR, SPELL_CORRUPTOR); + Unit* caster = GetCaster(); + caster->CastSpell(caster, spellId, true); + } - SpellScript* GetSpellScript() const override - { - return new spell_item_vanquished_clutches_SpellScript(); - } + void Register() override + { + OnEffectHit += SpellEffectFn(spell_item_vanquished_clutches::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; enum AshbringerSounds @@ -2695,43 +2166,32 @@ enum AshbringerSounds SOUND_ASHBRINGER_12 = 8928, // "Kill them all!" }; -class spell_item_ashbringer : public SpellScriptLoader +class spell_item_ashbringer : public SpellScript { - public: - spell_item_ashbringer() : SpellScriptLoader("spell_item_ashbringer") { } - - class spell_item_ashbringer_SpellScript : public SpellScript - { - PrepareSpellScript(spell_item_ashbringer_SpellScript); - - bool Load() override - { - return GetCaster()->GetTypeId() == TYPEID_PLAYER; - } + PrepareSpellScript(spell_item_ashbringer); - void OnDummyEffect(SpellEffIndex effIndex) - { - PreventHitDefaultEffect(effIndex); + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } - Player* player = GetCaster()->ToPlayer(); - uint32 sound_id = RAND( SOUND_ASHBRINGER_1, SOUND_ASHBRINGER_2, SOUND_ASHBRINGER_3, SOUND_ASHBRINGER_4, SOUND_ASHBRINGER_5, SOUND_ASHBRINGER_6, - SOUND_ASHBRINGER_7, SOUND_ASHBRINGER_8, SOUND_ASHBRINGER_9, SOUND_ASHBRINGER_10, SOUND_ASHBRINGER_11, SOUND_ASHBRINGER_12 ); + void OnDummyEffect(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); - // Ashbringers effect (spellID 28441) retriggers every 5 seconds, with a chance of making it say one of the above 12 sounds - if (urand(0, 60) < 1) - player->PlayDirectSound(sound_id, player); - } + Player* player = GetCaster()->ToPlayer(); + uint32 sound_id = RAND( SOUND_ASHBRINGER_1, SOUND_ASHBRINGER_2, SOUND_ASHBRINGER_3, SOUND_ASHBRINGER_4, SOUND_ASHBRINGER_5, SOUND_ASHBRINGER_6, + SOUND_ASHBRINGER_7, SOUND_ASHBRINGER_8, SOUND_ASHBRINGER_9, SOUND_ASHBRINGER_10, SOUND_ASHBRINGER_11, SOUND_ASHBRINGER_12 ); - void Register() override - { - OnEffectHit += SpellEffectFn(spell_item_ashbringer_SpellScript::OnDummyEffect, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + // Ashbringers effect (spellID 28441) retriggers every 5 seconds, with a chance of making it say one of the above 12 sounds + if (urand(0, 60) < 1) + player->PlayDirectSound(sound_id, player); + } - SpellScript* GetSpellScript() const override - { - return new spell_item_ashbringer_SpellScript(); - } + void Register() override + { + OnEffectHit += SpellEffectFn(spell_item_ashbringer::OnDummyEffect, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; enum MagicEater @@ -2744,79 +2204,57 @@ enum MagicEater SPELL_WELL_FED_5 = 57291, }; -class spell_magic_eater_food : public SpellScriptLoader +class spell_magic_eater_food : public AuraScript { - public: - spell_magic_eater_food() : SpellScriptLoader("spell_magic_eater_food") { } - - class spell_magic_eater_food_AuraScript : public AuraScript - { - PrepareAuraScript(spell_magic_eater_food_AuraScript); + PrepareAuraScript(spell_magic_eater_food); - void HandleTriggerSpell(AuraEffect const* /*aurEff*/) - { - PreventDefaultAction(); - Unit* target = GetTarget(); - switch (urand(0, 5)) - { - case 0: - target->CastSpell(target, SPELL_WILD_MAGIC, true); - break; - case 1: - target->CastSpell(target, SPELL_WELL_FED_1, true); - break; - case 2: - target->CastSpell(target, SPELL_WELL_FED_2, true); - break; - case 3: - target->CastSpell(target, SPELL_WELL_FED_3, true); - break; - case 4: - target->CastSpell(target, SPELL_WELL_FED_4, true); - break; - case 5: - target->CastSpell(target, SPELL_WELL_FED_5, true); - break; - } - } - - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_magic_eater_food_AuraScript::HandleTriggerSpell, EFFECT_1, SPELL_AURA_PERIODIC_TRIGGER_SPELL); - } - }; - - AuraScript* GetAuraScript() const override - { - return new spell_magic_eater_food_AuraScript(); + void HandleTriggerSpell(AuraEffect const* /*aurEff*/) + { + PreventDefaultAction(); + Unit* target = GetTarget(); + switch (urand(0, 5)) + { + case 0: + target->CastSpell(target, SPELL_WILD_MAGIC, true); + break; + case 1: + target->CastSpell(target, SPELL_WELL_FED_1, true); + break; + case 2: + target->CastSpell(target, SPELL_WELL_FED_2, true); + break; + case 3: + target->CastSpell(target, SPELL_WELL_FED_3, true); + break; + case 4: + target->CastSpell(target, SPELL_WELL_FED_4, true); + break; + case 5: + target->CastSpell(target, SPELL_WELL_FED_5, true); + break; } + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_magic_eater_food::HandleTriggerSpell, EFFECT_1, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } }; -class spell_item_shimmering_vessel : public SpellScriptLoader +class spell_item_shimmering_vessel : public SpellScript { - public: - spell_item_shimmering_vessel() : SpellScriptLoader("spell_item_shimmering_vessel") { } - - class spell_item_shimmering_vessel_SpellScript : public SpellScript - { - PrepareSpellScript(spell_item_shimmering_vessel_SpellScript); - - void HandleDummy(SpellEffIndex /* effIndex */) - { - if (Creature* target = GetHitCreature()) - target->setDeathState(JUST_RESPAWNED); - } + PrepareSpellScript(spell_item_shimmering_vessel); - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_item_shimmering_vessel_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + void HandleDummy(SpellEffIndex /* effIndex */) + { + if (Creature* target = GetHitCreature()) + target->setDeathState(JUST_RESPAWNED); + } - SpellScript* GetSpellScript() const override - { - return new spell_item_shimmering_vessel_SpellScript(); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_item_shimmering_vessel::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; enum PurifyHelboarMeat @@ -2825,45 +2263,34 @@ enum PurifyHelboarMeat SPELL_SUMMON_TOXIC_HELBOAR_MEAT = 29278, }; -class spell_item_purify_helboar_meat : public SpellScriptLoader +class spell_item_purify_helboar_meat : public SpellScript { - public: - spell_item_purify_helboar_meat() : SpellScriptLoader("spell_item_purify_helboar_meat") { } - - class spell_item_purify_helboar_meat_SpellScript : public SpellScript - { - PrepareSpellScript(spell_item_purify_helboar_meat_SpellScript); - - bool Load() override - { - return GetCaster()->GetTypeId() == TYPEID_PLAYER; - } + PrepareSpellScript(spell_item_purify_helboar_meat); - bool Validate(SpellInfo const* /*spell*/) override - { - return ValidateSpellInfo( - { - SPELL_SUMMON_PURIFIED_HELBOAR_MEAT, - SPELL_SUMMON_TOXIC_HELBOAR_MEAT - }); - } + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } - void HandleDummy(SpellEffIndex /* effIndex */) - { - Unit* caster = GetCaster(); - caster->CastSpell(caster, roll_chance_i(50) ? SPELL_SUMMON_PURIFIED_HELBOAR_MEAT : SPELL_SUMMON_TOXIC_HELBOAR_MEAT, true, nullptr); - } + bool Validate(SpellInfo const* /*spell*/) override + { + return ValidateSpellInfo( + { + SPELL_SUMMON_PURIFIED_HELBOAR_MEAT, + SPELL_SUMMON_TOXIC_HELBOAR_MEAT + }); + } - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_item_purify_helboar_meat_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + void HandleDummy(SpellEffIndex /* effIndex */) + { + Unit* caster = GetCaster(); + caster->CastSpell(caster, roll_chance_i(50) ? SPELL_SUMMON_PURIFIED_HELBOAR_MEAT : SPELL_SUMMON_TOXIC_HELBOAR_MEAT, true, nullptr); + } - SpellScript* GetSpellScript() const override - { - return new spell_item_purify_helboar_meat_SpellScript(); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_item_purify_helboar_meat::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; enum CrystalPrison @@ -2871,42 +2298,31 @@ enum CrystalPrison OBJECT_IMPRISONED_DOOMGUARD = 179644, }; -class spell_item_crystal_prison_dummy_dnd : public SpellScriptLoader +class spell_item_crystal_prison_dummy_dnd : public SpellScript { - public: - spell_item_crystal_prison_dummy_dnd() : SpellScriptLoader("spell_item_crystal_prison_dummy_dnd") { } - - class spell_item_crystal_prison_dummy_dnd_SpellScript : public SpellScript - { - PrepareSpellScript(spell_item_crystal_prison_dummy_dnd_SpellScript); - - bool Validate(SpellInfo const* /*spell*/) override - { - if (!sObjectMgr->GetGameObjectTemplate(OBJECT_IMPRISONED_DOOMGUARD)) - return false; - return true; - } + PrepareSpellScript(spell_item_crystal_prison_dummy_dnd); - void HandleDummy(SpellEffIndex /* effIndex */) - { - if (Creature* target = GetHitCreature()) - if (target->isDead() && !target->IsPet()) - { - GetCaster()->SummonGameObject(OBJECT_IMPRISONED_DOOMGUARD, *target, QuaternionData(), uint32(target->GetRespawnTime()-time(nullptr))); - target->DespawnOrUnsummon(); - } - } + bool Validate(SpellInfo const* /*spell*/) override + { + if (!sObjectMgr->GetGameObjectTemplate(OBJECT_IMPRISONED_DOOMGUARD)) + return false; + return true; + } - void Register() override + void HandleDummy(SpellEffIndex /* effIndex */) + { + if (Creature* target = GetHitCreature()) + if (target->isDead() && !target->IsPet()) { - OnEffectHitTarget += SpellEffectFn(spell_item_crystal_prison_dummy_dnd_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + GetCaster()->SummonGameObject(OBJECT_IMPRISONED_DOOMGUARD, *target, QuaternionData(), uint32(target->GetRespawnTime()-time(nullptr))); + target->DespawnOrUnsummon(); } - }; + } - SpellScript* GetSpellScript() const override - { - return new spell_item_crystal_prison_dummy_dnd_SpellScript(); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_item_crystal_prison_dummy_dnd::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; enum ReindeerTransformation @@ -2918,65 +2334,55 @@ enum ReindeerTransformation SPELL_REINDEER_60 = 25858, }; -class spell_item_reindeer_transformation : public SpellScriptLoader -{ - public: - spell_item_reindeer_transformation() : SpellScriptLoader("spell_item_reindeer_transformation") { } - - class spell_item_reindeer_transformation_SpellScript : public SpellScript - { - PrepareSpellScript(spell_item_reindeer_transformation_SpellScript); - bool Validate(SpellInfo const* /*spell*/) override - { - return ValidateSpellInfo( - { - SPELL_FLYING_REINDEER_310, - SPELL_FLYING_REINDEER_280, - SPELL_FLYING_REINDEER_60, - SPELL_REINDEER_100, - SPELL_REINDEER_60 - }); - } +class spell_item_reindeer_transformation : public SpellScript +{ + PrepareSpellScript(spell_item_reindeer_transformation); - void HandleDummy(SpellEffIndex /* effIndex */) - { - Unit* caster = GetCaster(); - if (caster->HasAuraType(SPELL_AURA_MOUNTED)) - { - float flyspeed = caster->GetSpeedRate(MOVE_FLIGHT); - float speed = caster->GetSpeedRate(MOVE_RUN); - - caster->RemoveAurasByType(SPELL_AURA_MOUNTED); - //5 different spells used depending on mounted speed and if mount can fly or not - - if (flyspeed >= 4.1f) - // Flying Reindeer - caster->CastSpell(caster, SPELL_FLYING_REINDEER_310, true); //310% flying Reindeer - else if (flyspeed >= 3.8f) - // Flying Reindeer - caster->CastSpell(caster, SPELL_FLYING_REINDEER_280, true); //280% flying Reindeer - else if (flyspeed >= 1.6f) - // Flying Reindeer - caster->CastSpell(caster, SPELL_FLYING_REINDEER_60, true); //60% flying Reindeer - else if (speed >= 2.0f) - // Reindeer - caster->CastSpell(caster, SPELL_REINDEER_100, true); //100% ground Reindeer - else - // Reindeer - caster->CastSpell(caster, SPELL_REINDEER_60, true); //60% ground Reindeer - } - } + bool Validate(SpellInfo const* /*spell*/) override + { + return ValidateSpellInfo( + { + SPELL_FLYING_REINDEER_310, + SPELL_FLYING_REINDEER_280, + SPELL_FLYING_REINDEER_60, + SPELL_REINDEER_100, + SPELL_REINDEER_60 + }); + } - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_item_reindeer_transformation_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + void HandleDummy(SpellEffIndex /* effIndex */) + { + Unit* caster = GetCaster(); + if (caster->HasAuraType(SPELL_AURA_MOUNTED)) + { + float flyspeed = caster->GetSpeedRate(MOVE_FLIGHT); + float speed = caster->GetSpeedRate(MOVE_RUN); + + caster->RemoveAurasByType(SPELL_AURA_MOUNTED); + //5 different spells used depending on mounted speed and if mount can fly or not + + if (flyspeed >= 4.1f) + // Flying Reindeer + caster->CastSpell(caster, SPELL_FLYING_REINDEER_310, true); //310% flying Reindeer + else if (flyspeed >= 3.8f) + // Flying Reindeer + caster->CastSpell(caster, SPELL_FLYING_REINDEER_280, true); //280% flying Reindeer + else if (flyspeed >= 1.6f) + // Flying Reindeer + caster->CastSpell(caster, SPELL_FLYING_REINDEER_60, true); //60% flying Reindeer + else if (speed >= 2.0f) + // Reindeer + caster->CastSpell(caster, SPELL_REINDEER_100, true); //100% ground Reindeer + else + // Reindeer + caster->CastSpell(caster, SPELL_REINDEER_60, true); //60% ground Reindeer + } + } - SpellScript* GetSpellScript() const override + void Register() override { - return new spell_item_reindeer_transformation_SpellScript(); + OnEffectHitTarget += SpellEffectFn(spell_item_reindeer_transformation::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -2986,42 +2392,31 @@ enum NighInvulnerability SPELL_COMPLETE_VULNERABILITY = 30457, }; -class spell_item_nigh_invulnerability : public SpellScriptLoader +class spell_item_nigh_invulnerability : public SpellScript { - public: - spell_item_nigh_invulnerability() : SpellScriptLoader("spell_item_nigh_invulnerability") { } - - class spell_item_nigh_invulnerability_SpellScript : public SpellScript - { - PrepareSpellScript(spell_item_nigh_invulnerability_SpellScript); - - bool Validate(SpellInfo const* /*spell*/) override - { - return ValidateSpellInfo({ SPELL_NIGH_INVULNERABILITY, SPELL_COMPLETE_VULNERABILITY }); - } - - void HandleDummy(SpellEffIndex /* effIndex */) - { - Unit* caster = GetCaster(); - if (Item* castItem = GetCastItem()) - { - if (roll_chance_i(86)) // Nigh-Invulnerability - success - caster->CastSpell(caster, SPELL_NIGH_INVULNERABILITY, true, castItem); - else // Complete Vulnerability - backfire in 14% casts - caster->CastSpell(caster, SPELL_COMPLETE_VULNERABILITY, true, castItem); - } - } + PrepareSpellScript(spell_item_nigh_invulnerability); - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_item_nigh_invulnerability_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + bool Validate(SpellInfo const* /*spell*/) override + { + return ValidateSpellInfo({ SPELL_NIGH_INVULNERABILITY, SPELL_COMPLETE_VULNERABILITY }); + } - SpellScript* GetSpellScript() const override + void HandleDummy(SpellEffIndex /* effIndex */) + { + Unit* caster = GetCaster(); + if (Item* castItem = GetCastItem()) { - return new spell_item_nigh_invulnerability_SpellScript(); + if (roll_chance_i(86)) // Nigh-Invulnerability - success + caster->CastSpell(caster, SPELL_NIGH_INVULNERABILITY, true, castItem); + else // Complete Vulnerability - backfire in 14% casts + caster->CastSpell(caster, SPELL_COMPLETE_VULNERABILITY, true, castItem); } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_item_nigh_invulnerability::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; enum Poultryzer @@ -3030,36 +2425,25 @@ enum Poultryzer SPELL_POULTRYIZER_BACKFIRE = 30504, }; -class spell_item_poultryizer : public SpellScriptLoader +class spell_item_poultryizer : public SpellScript { - public: - spell_item_poultryizer() : SpellScriptLoader("spell_item_poultryizer") { } + PrepareSpellScript(spell_item_poultryizer); - class spell_item_poultryizer_SpellScript : public SpellScript - { - PrepareSpellScript(spell_item_poultryizer_SpellScript); - - bool Validate(SpellInfo const* /*spell*/) override - { - return ValidateSpellInfo({ SPELL_POULTRYIZER_SUCCESS, SPELL_POULTRYIZER_BACKFIRE }); - } - - void HandleDummy(SpellEffIndex /* effIndex */) - { - if (GetCastItem() && GetHitUnit()) - GetCaster()->CastSpell(GetHitUnit(), roll_chance_i(80) ? SPELL_POULTRYIZER_SUCCESS : SPELL_POULTRYIZER_BACKFIRE, true, GetCastItem()); - } + bool Validate(SpellInfo const* /*spell*/) override + { + return ValidateSpellInfo({ SPELL_POULTRYIZER_SUCCESS, SPELL_POULTRYIZER_BACKFIRE }); + } - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_item_poultryizer_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + void HandleDummy(SpellEffIndex /* effIndex */) + { + if (GetCastItem() && GetHitUnit()) + GetCaster()->CastSpell(GetHitUnit(), roll_chance_i(80) ? SPELL_POULTRYIZER_SUCCESS : SPELL_POULTRYIZER_BACKFIRE, true, GetCastItem()); + } - SpellScript* GetSpellScript() const override - { - return new spell_item_poultryizer_SpellScript(); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_item_poultryizer::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; enum SocretharsStone @@ -3068,50 +2452,39 @@ enum SocretharsStone SPELL_SOCRETHAR_FROM_SEAT = 35744, }; -class spell_item_socrethars_stone : public SpellScriptLoader +class spell_item_socrethars_stone : public SpellScript { - public: - spell_item_socrethars_stone() : SpellScriptLoader("spell_item_socrethars_stone") { } - - class spell_item_socrethars_stone_SpellScript : public SpellScript - { - PrepareSpellScript(spell_item_socrethars_stone_SpellScript); - - bool Load() override - { - return (GetCaster()->GetAreaId() == 3900 || GetCaster()->GetAreaId() == 3742); - } - bool Validate(SpellInfo const* /*spell*/) override - { - return ValidateSpellInfo({ SPELL_SOCRETHAR_TO_SEAT, SPELL_SOCRETHAR_FROM_SEAT }); - } - - void HandleDummy(SpellEffIndex /* effIndex */) - { - Unit* caster = GetCaster(); - switch (caster->GetAreaId()) - { - case 3900: - caster->CastSpell(caster, SPELL_SOCRETHAR_TO_SEAT, true); - break; - case 3742: - caster->CastSpell(caster, SPELL_SOCRETHAR_FROM_SEAT, true); - break; - default: - return; - } - } + PrepareSpellScript(spell_item_socrethars_stone); - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_item_socrethars_stone_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + bool Load() override + { + return (GetCaster()->GetAreaId() == 3900 || GetCaster()->GetAreaId() == 3742); + } + bool Validate(SpellInfo const* /*spell*/) override + { + return ValidateSpellInfo({ SPELL_SOCRETHAR_TO_SEAT, SPELL_SOCRETHAR_FROM_SEAT }); + } - SpellScript* GetSpellScript() const override - { - return new spell_item_socrethars_stone_SpellScript(); + void HandleDummy(SpellEffIndex /* effIndex */) + { + Unit* caster = GetCaster(); + switch (caster->GetAreaId()) + { + case 3900: + caster->CastSpell(caster, SPELL_SOCRETHAR_TO_SEAT, true); + break; + case 3742: + caster->CastSpell(caster, SPELL_SOCRETHAR_FROM_SEAT, true); + break; + default: + return; } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_item_socrethars_stone::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; enum DemonBroiledSurprise @@ -3121,56 +2494,45 @@ enum DemonBroiledSurprise NPC_ABYSSAL_FLAMEBRINGER = 19973, }; -class spell_item_demon_broiled_surprise : public SpellScriptLoader +class spell_item_demon_broiled_surprise : public SpellScript { - public: - spell_item_demon_broiled_surprise() : SpellScriptLoader("spell_item_demon_broiled_surprise") { } - - class spell_item_demon_broiled_surprise_SpellScript : public SpellScript - { - PrepareSpellScript(spell_item_demon_broiled_surprise_SpellScript); + PrepareSpellScript(spell_item_demon_broiled_surprise); - bool Validate(SpellInfo const* /*spell*/) override - { - return ValidateSpellInfo({ SPELL_CREATE_DEMON_BROILED_SURPRISE }) && - sObjectMgr->GetCreatureTemplate(NPC_ABYSSAL_FLAMEBRINGER) && - sObjectMgr->GetQuestTemplate(QUEST_SUPER_HOT_STEW); - } + bool Validate(SpellInfo const* /*spell*/) override + { + return ValidateSpellInfo({ SPELL_CREATE_DEMON_BROILED_SURPRISE }) && + sObjectMgr->GetCreatureTemplate(NPC_ABYSSAL_FLAMEBRINGER) && + sObjectMgr->GetQuestTemplate(QUEST_SUPER_HOT_STEW); + } - bool Load() override - { - return GetCaster()->GetTypeId() == TYPEID_PLAYER; - } + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } - void HandleDummy(SpellEffIndex /* effIndex */) - { - Unit* player = GetCaster(); - player->CastSpell(player, SPELL_CREATE_DEMON_BROILED_SURPRISE, false); - } + void HandleDummy(SpellEffIndex /* effIndex */) + { + Unit* player = GetCaster(); + player->CastSpell(player, SPELL_CREATE_DEMON_BROILED_SURPRISE, false); + } - SpellCastResult CheckRequirement() - { - Player* player = GetCaster()->ToPlayer(); - if (player->GetQuestStatus(QUEST_SUPER_HOT_STEW) != QUEST_STATUS_INCOMPLETE) - return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW; - - if (Creature* creature = player->FindNearestCreature(NPC_ABYSSAL_FLAMEBRINGER, 10, false)) - if (creature->isDead()) - return SPELL_CAST_OK; - return SPELL_FAILED_NOT_HERE; - } + SpellCastResult CheckRequirement() + { + Player* player = GetCaster()->ToPlayer(); + if (player->GetQuestStatus(QUEST_SUPER_HOT_STEW) != QUEST_STATUS_INCOMPLETE) + return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW; - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_item_demon_broiled_surprise_SpellScript::HandleDummy, EFFECT_1, SPELL_EFFECT_DUMMY); - OnCheckCast += SpellCheckCastFn(spell_item_demon_broiled_surprise_SpellScript::CheckRequirement); - } - }; + if (Creature* creature = player->FindNearestCreature(NPC_ABYSSAL_FLAMEBRINGER, 10, false)) + if (creature->isDead()) + return SPELL_CAST_OK; + return SPELL_FAILED_NOT_HERE; + } - SpellScript* GetSpellScript() const override - { - return new spell_item_demon_broiled_surprise_SpellScript(); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_item_demon_broiled_surprise::HandleDummy, EFFECT_1, SPELL_EFFECT_DUMMY); + OnCheckCast += SpellCheckCastFn(spell_item_demon_broiled_surprise::CheckRequirement); + } }; enum CompleteRaptorCapture @@ -3178,42 +2540,31 @@ enum CompleteRaptorCapture SPELL_RAPTOR_CAPTURE_CREDIT = 42337, }; -class spell_item_complete_raptor_capture : public SpellScriptLoader +class spell_item_complete_raptor_capture : public SpellScript { - public: - spell_item_complete_raptor_capture() : SpellScriptLoader("spell_item_complete_raptor_capture") { } - - class spell_item_complete_raptor_capture_SpellScript : public SpellScript - { - PrepareSpellScript(spell_item_complete_raptor_capture_SpellScript); - - bool Validate(SpellInfo const* /*spell*/) override - { - return ValidateSpellInfo({ SPELL_RAPTOR_CAPTURE_CREDIT }); - } + PrepareSpellScript(spell_item_complete_raptor_capture); - void HandleDummy(SpellEffIndex /* effIndex */) - { - Unit* caster = GetCaster(); - if (GetHitCreature()) - { - GetHitCreature()->DespawnOrUnsummon(); - - //cast spell Raptor Capture Credit - caster->CastSpell(caster, SPELL_RAPTOR_CAPTURE_CREDIT, true, nullptr); - } - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_item_complete_raptor_capture_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + bool Validate(SpellInfo const* /*spell*/) override + { + return ValidateSpellInfo({ SPELL_RAPTOR_CAPTURE_CREDIT }); + } - SpellScript* GetSpellScript() const override + void HandleDummy(SpellEffIndex /* effIndex */) + { + Unit* caster = GetCaster(); + if (GetHitCreature()) { - return new spell_item_complete_raptor_capture_SpellScript(); + GetHitCreature()->DespawnOrUnsummon(); + + //cast spell Raptor Capture Credit + caster->CastSpell(caster, SPELL_RAPTOR_CAPTURE_CREDIT, true, nullptr); } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_item_complete_raptor_capture::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; enum ImpaleLeviroth @@ -3222,42 +2573,31 @@ enum ImpaleLeviroth SPELL_LEVIROTH_SELF_IMPALE = 49882 }; -class spell_item_impale_leviroth : public SpellScriptLoader +class spell_item_impale_leviroth : public SpellScript { - public: - spell_item_impale_leviroth() : SpellScriptLoader("spell_item_impale_leviroth") { } - - class spell_item_impale_leviroth_SpellScript : public SpellScript - { - PrepareSpellScript(spell_item_impale_leviroth_SpellScript); + PrepareSpellScript(spell_item_impale_leviroth); - bool Validate(SpellInfo const* /*spell*/) override - { - if (!sObjectMgr->GetCreatureTemplate(NPC_LEVIROTH)) - return false; - return true; - } - - void HandleDummy(SpellEffIndex /*effIndex*/) - { - if (Creature* target = GetHitCreature()) - if (target->GetEntry() == NPC_LEVIROTH && !target->HealthBelowPct(95)) - { - target->CastSpell(target, SPELL_LEVIROTH_SELF_IMPALE, true); - target->ResetPlayerDamageReq(); - } - } + bool Validate(SpellInfo const* /*spell*/) override + { + if (!sObjectMgr->GetCreatureTemplate(NPC_LEVIROTH)) + return false; + return true; + } - void Register() override + void HandleDummy(SpellEffIndex /*effIndex*/) + { + if (Creature* target = GetHitCreature()) + if (target->GetEntry() == NPC_LEVIROTH && !target->HealthBelowPct(95)) { - OnEffectHitTarget += SpellEffectFn(spell_item_impale_leviroth_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + target->CastSpell(target, SPELL_LEVIROTH_SELF_IMPALE, true); + target->ResetPlayerDamageReq(); } - }; + } - SpellScript* GetSpellScript() const override - { - return new spell_item_impale_leviroth_SpellScript(); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_item_impale_leviroth::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; enum BrewfestMountTransformation @@ -3270,111 +2610,130 @@ enum BrewfestMountTransformation SPELL_BREWFEST_MOUNT_TRANSFORM_REVERSE = 52845, }; -class spell_item_brewfest_mount_transformation : public SpellScriptLoader +class spell_item_brewfest_mount_transformation : public SpellScript { - public: - spell_item_brewfest_mount_transformation() : SpellScriptLoader("spell_item_brewfest_mount_transformation") { } + PrepareSpellScript(spell_item_brewfest_mount_transformation); - class spell_item_brewfest_mount_transformation_SpellScript : public SpellScript + bool Validate(SpellInfo const* /*spell*/) override + { + return ValidateSpellInfo( { - PrepareSpellScript(spell_item_brewfest_mount_transformation_SpellScript); + SPELL_MOUNT_RAM_100, + SPELL_MOUNT_RAM_60, + SPELL_MOUNT_KODO_100, + SPELL_MOUNT_KODO_60 + }); + } - bool Validate(SpellInfo const* /*spell*/) override - { - return ValidateSpellInfo( - { - SPELL_MOUNT_RAM_100, - SPELL_MOUNT_RAM_60, - SPELL_MOUNT_KODO_100, - SPELL_MOUNT_KODO_60 - }); - } + void HandleDummy(SpellEffIndex /* effIndex */) + { + Player* caster = GetCaster()->ToPlayer(); + if (caster->HasAuraType(SPELL_AURA_MOUNTED)) + { + caster->RemoveAurasByType(SPELL_AURA_MOUNTED); + uint32 spell_id; - void HandleDummy(SpellEffIndex /* effIndex */) + switch (GetSpellInfo()->Id) { - Player* caster = GetCaster()->ToPlayer(); - if (caster->HasAuraType(SPELL_AURA_MOUNTED)) - { - caster->RemoveAurasByType(SPELL_AURA_MOUNTED); - uint32 spell_id; - - switch (GetSpellInfo()->Id) - { - case SPELL_BREWFEST_MOUNT_TRANSFORM: - if (caster->GetSpeedRate(MOVE_RUN) >= 2.0f) - spell_id = caster->GetTeam() == ALLIANCE ? SPELL_MOUNT_RAM_100 : SPELL_MOUNT_KODO_100; - else - spell_id = caster->GetTeam() == ALLIANCE ? SPELL_MOUNT_RAM_60 : SPELL_MOUNT_KODO_60; - break; - case SPELL_BREWFEST_MOUNT_TRANSFORM_REVERSE: - if (caster->GetSpeedRate(MOVE_RUN) >= 2.0f) - spell_id = caster->GetTeam() == HORDE ? SPELL_MOUNT_RAM_100 : SPELL_MOUNT_KODO_100; - else - spell_id = caster->GetTeam() == HORDE ? SPELL_MOUNT_RAM_60 : SPELL_MOUNT_KODO_60; - break; - default: - return; - } - caster->CastSpell(caster, spell_id, true); - } - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_item_brewfest_mount_transformation_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + case SPELL_BREWFEST_MOUNT_TRANSFORM: + if (caster->GetSpeedRate(MOVE_RUN) >= 2.0f) + spell_id = caster->GetTeam() == ALLIANCE ? SPELL_MOUNT_RAM_100 : SPELL_MOUNT_KODO_100; + else + spell_id = caster->GetTeam() == ALLIANCE ? SPELL_MOUNT_RAM_60 : SPELL_MOUNT_KODO_60; + break; + case SPELL_BREWFEST_MOUNT_TRANSFORM_REVERSE: + if (caster->GetSpeedRate(MOVE_RUN) >= 2.0f) + spell_id = caster->GetTeam() == HORDE ? SPELL_MOUNT_RAM_100 : SPELL_MOUNT_KODO_100; + else + spell_id = caster->GetTeam() == HORDE ? SPELL_MOUNT_RAM_60 : SPELL_MOUNT_KODO_60; + break; + default: + return; } - }; - - SpellScript* GetSpellScript() const override - { - return new spell_item_brewfest_mount_transformation_SpellScript(); + caster->CastSpell(caster, spell_id, true); } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_item_brewfest_mount_transformation::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; -enum NitroBoots +enum NitroBoosts { - SPELL_NITRO_BOOTS_SUCCESS = 54861, - SPELL_NITRO_BOOTS_BACKFIRE = 46014, + SPELL_NITRO_BOOSTS_SUCCESS = 54861, + SPELL_NITRO_BOOSTS_BACKFIRE = 54621, + SPELL_NITRO_BOOSTS_PARACHUTE = 54649, }; -class spell_item_nitro_boots : public SpellScriptLoader +class spell_item_nitro_boosts : public SpellScript { - public: - spell_item_nitro_boots() : SpellScriptLoader("spell_item_nitro_boots") { } + PrepareSpellScript(spell_item_nitro_boosts); - class spell_item_nitro_boots_SpellScript : public SpellScript - { - PrepareSpellScript(spell_item_nitro_boots_SpellScript); + bool Load() override + { + if (!GetCastItem()) + return false; + return true; + } - bool Load() override - { - if (!GetCastItem()) - return false; - return true; - } + bool Validate(SpellInfo const* /*spell*/) override + { + return ValidateSpellInfo({ SPELL_NITRO_BOOSTS_SUCCESS, SPELL_NITRO_BOOSTS_BACKFIRE }); + } - bool Validate(SpellInfo const* /*spell*/) override - { - return ValidateSpellInfo({ SPELL_NITRO_BOOTS_SUCCESS, SPELL_NITRO_BOOTS_BACKFIRE }); - } + void HandleDummy(SpellEffIndex /* effIndex */) + { + Unit* caster = GetCaster(); + AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(caster->GetAreaId()); + bool success = true; + if (areaEntry && areaEntry->IsFlyable() && !caster->GetMap()->IsDungeon()) + success = roll_chance_i(95); // nitro boosts can only fail in flying-enabled locations on 3.3.5 + caster->CastSpell(caster, success ? SPELL_NITRO_BOOSTS_SUCCESS : SPELL_NITRO_BOOSTS_BACKFIRE, true, GetCastItem()); + } - void HandleDummy(SpellEffIndex /* effIndex */) - { - Unit* caster = GetCaster(); - bool success = caster->GetMap()->IsDungeon() || roll_chance_i(95); - caster->CastSpell(caster, success ? SPELL_NITRO_BOOTS_SUCCESS : SPELL_NITRO_BOOTS_BACKFIRE, true, GetCastItem()); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_item_nitro_boosts::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } +}; - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_item_nitro_boots_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; +class spell_item_nitro_boosts_backfire : public AuraScript +{ + PrepareAuraScript(spell_item_nitro_boosts_backfire); - SpellScript* GetSpellScript() const override + bool Validate(SpellInfo const* /*spell*/) override + { + return ValidateSpellInfo({ SPELL_NITRO_BOOSTS_PARACHUTE }); + } + + void HandleApply(AuraEffect const* /*effect*/, AuraEffectHandleModes /*mode*/) + { + lastZ = GetTarget()->GetPositionZ(); + } + + void HandlePeriodicDummy(AuraEffect const* effect) + { + PreventDefaultAction(); + float curZ = GetTarget()->GetPositionZ(); + if (curZ < lastZ) { - return new spell_item_nitro_boots_SpellScript(); + if (roll_chance_i(80)) // we don't have enough sniffs to verify this, guesstimate + GetTarget()->CastSpell(GetTarget(), SPELL_NITRO_BOOSTS_PARACHUTE, true, nullptr, effect); + GetAura()->Remove(); } + else + lastZ = curZ; + } + + void Register() override + { + OnEffectApply += AuraEffectApplyFn(spell_item_nitro_boosts_backfire::HandleApply, EFFECT_1, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL); + OnEffectPeriodic += AuraEffectPeriodicFn(spell_item_nitro_boosts_backfire::HandlePeriodicDummy, EFFECT_1, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } + + float lastZ = INVALID_HEIGHT; }; enum TeachLanguage @@ -3383,43 +2742,32 @@ enum TeachLanguage SPELL_LEARN_GOBLIN_BINARY = 50246, }; -class spell_item_teach_language : public SpellScriptLoader +class spell_item_teach_language : public SpellScript { - public: - spell_item_teach_language() : SpellScriptLoader("spell_item_teach_language") { } - - class spell_item_teach_language_SpellScript : public SpellScript - { - PrepareSpellScript(spell_item_teach_language_SpellScript); + PrepareSpellScript(spell_item_teach_language); - bool Load() override - { - return GetCaster()->GetTypeId() == TYPEID_PLAYER; - } - - bool Validate(SpellInfo const* /*spell*/) override - { - return ValidateSpellInfo({ SPELL_LEARN_GNOMISH_BINARY, SPELL_LEARN_GOBLIN_BINARY }); - } + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } - void HandleDummy(SpellEffIndex /* effIndex */) - { - Player* caster = GetCaster()->ToPlayer(); + bool Validate(SpellInfo const* /*spell*/) override + { + return ValidateSpellInfo({ SPELL_LEARN_GNOMISH_BINARY, SPELL_LEARN_GOBLIN_BINARY }); + } - if (roll_chance_i(34)) - caster->CastSpell(caster, caster->GetTeam() == ALLIANCE ? SPELL_LEARN_GNOMISH_BINARY : SPELL_LEARN_GOBLIN_BINARY, true); - } + void HandleDummy(SpellEffIndex /* effIndex */) + { + Player* caster = GetCaster()->ToPlayer(); - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_item_teach_language_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + if (roll_chance_i(34)) + caster->CastSpell(caster, caster->GetTeam() == ALLIANCE ? SPELL_LEARN_GNOMISH_BINARY : SPELL_LEARN_GOBLIN_BINARY, true); + } - SpellScript* GetSpellScript() const override - { - return new spell_item_teach_language_SpellScript(); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_item_teach_language::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; enum RocketBoots @@ -3427,53 +2775,42 @@ enum RocketBoots SPELL_ROCKET_BOOTS_PROC = 30452, }; -class spell_item_rocket_boots : public SpellScriptLoader +class spell_item_rocket_boots : public SpellScript { - public: - spell_item_rocket_boots() : SpellScriptLoader("spell_item_rocket_boots") { } - - class spell_item_rocket_boots_SpellScript : public SpellScript - { - PrepareSpellScript(spell_item_rocket_boots_SpellScript); - - bool Load() override - { - return GetCaster()->GetTypeId() == TYPEID_PLAYER; - } + PrepareSpellScript(spell_item_rocket_boots); - bool Validate(SpellInfo const* /*spell*/) override - { - return ValidateSpellInfo({ SPELL_ROCKET_BOOTS_PROC }); - } + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } - void HandleDummy(SpellEffIndex /* effIndex */) - { - Player* caster = GetCaster()->ToPlayer(); - if (Battleground* bg = caster->GetBattleground()) - bg->EventPlayerDroppedFlag(caster); + bool Validate(SpellInfo const* /*spell*/) override + { + return ValidateSpellInfo({ SPELL_ROCKET_BOOTS_PROC }); + } - caster->GetSpellHistory()->ResetCooldown(SPELL_ROCKET_BOOTS_PROC); - caster->CastSpell(caster, SPELL_ROCKET_BOOTS_PROC, true, nullptr); - } + void HandleDummy(SpellEffIndex /* effIndex */) + { + Player* caster = GetCaster()->ToPlayer(); + if (Battleground* bg = caster->GetBattleground()) + bg->EventPlayerDroppedFlag(caster); - SpellCastResult CheckCast() - { - if (GetCaster()->IsInWater()) - return SPELL_FAILED_ONLY_ABOVEWATER; - return SPELL_CAST_OK; - } + caster->GetSpellHistory()->ResetCooldown(SPELL_ROCKET_BOOTS_PROC); + caster->CastSpell(caster, SPELL_ROCKET_BOOTS_PROC, true, nullptr); + } - void Register() override - { - OnCheckCast += SpellCheckCastFn(spell_item_rocket_boots_SpellScript::CheckCast); - OnEffectHitTarget += SpellEffectFn(spell_item_rocket_boots_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + SpellCastResult CheckCast() + { + if (GetCaster()->IsInWater()) + return SPELL_FAILED_ONLY_ABOVEWATER; + return SPELL_CAST_OK; + } - SpellScript* GetSpellScript() const override - { - return new spell_item_rocket_boots_SpellScript(); - } + void Register() override + { + OnCheckCast += SpellCheckCastFn(spell_item_rocket_boots::CheckCast); + OnEffectHitTarget += SpellEffectFn(spell_item_rocket_boots::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; enum PygmyOil @@ -3482,75 +2819,53 @@ enum PygmyOil SPELL_PYGMY_OIL_SMALLER_AURA = 53805, }; -class spell_item_pygmy_oil : public SpellScriptLoader +class spell_item_pygmy_oil : public SpellScript { - public: - spell_item_pygmy_oil() : SpellScriptLoader("spell_item_pygmy_oil") { } + PrepareSpellScript(spell_item_pygmy_oil); - class spell_item_pygmy_oil_SpellScript : public SpellScript - { - PrepareSpellScript(spell_item_pygmy_oil_SpellScript); - - bool Validate(SpellInfo const* /*spell*/) override - { - return ValidateSpellInfo({ SPELL_PYGMY_OIL_PYGMY_AURA, SPELL_PYGMY_OIL_SMALLER_AURA }); - } - - void HandleDummy(SpellEffIndex /* effIndex */) - { - Unit* caster = GetCaster(); - if (Aura* aura = caster->GetAura(SPELL_PYGMY_OIL_PYGMY_AURA)) - aura->RefreshDuration(); - else - { - aura = caster->GetAura(SPELL_PYGMY_OIL_SMALLER_AURA); - if (!aura || aura->GetStackAmount() < 5 || !roll_chance_i(50)) - caster->CastSpell(caster, SPELL_PYGMY_OIL_SMALLER_AURA, true); - else - { - aura->Remove(); - caster->CastSpell(caster, SPELL_PYGMY_OIL_PYGMY_AURA, true); - } - } - } + bool Validate(SpellInfo const* /*spell*/) override + { + return ValidateSpellInfo({ SPELL_PYGMY_OIL_PYGMY_AURA, SPELL_PYGMY_OIL_SMALLER_AURA }); + } - void Register() override + void HandleDummy(SpellEffIndex /* effIndex */) + { + Unit* caster = GetCaster(); + if (Aura* aura = caster->GetAura(SPELL_PYGMY_OIL_PYGMY_AURA)) + aura->RefreshDuration(); + else + { + aura = caster->GetAura(SPELL_PYGMY_OIL_SMALLER_AURA); + if (!aura || aura->GetStackAmount() < 5 || !roll_chance_i(50)) + caster->CastSpell(caster, SPELL_PYGMY_OIL_SMALLER_AURA, true); + else { - OnEffectHitTarget += SpellEffectFn(spell_item_pygmy_oil_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + aura->Remove(); + caster->CastSpell(caster, SPELL_PYGMY_OIL_PYGMY_AURA, true); } - }; - - SpellScript* GetSpellScript() const override - { - return new spell_item_pygmy_oil_SpellScript(); } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_item_pygmy_oil::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; -class spell_item_unusual_compass : public SpellScriptLoader +class spell_item_unusual_compass : public SpellScript { - public: - spell_item_unusual_compass() : SpellScriptLoader("spell_item_unusual_compass") { } - - class spell_item_unusual_compass_SpellScript : public SpellScript - { - PrepareSpellScript(spell_item_unusual_compass_SpellScript); + PrepareSpellScript(spell_item_unusual_compass); - void HandleDummy(SpellEffIndex /* effIndex */) - { - Unit* caster = GetCaster(); - caster->SetFacingTo(frand(0.0f, 2.0f * float(M_PI))); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_item_unusual_compass_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + void HandleDummy(SpellEffIndex /* effIndex */) + { + Unit* caster = GetCaster(); + caster->SetFacingTo(frand(0.0f, 2.0f * float(M_PI))); + } - SpellScript* GetSpellScript() const override - { - return new spell_item_unusual_compass_SpellScript(); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_item_unusual_compass::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; enum ChickenCover @@ -3561,50 +2876,39 @@ enum ChickenCover QUEST_FLOWN_THE_COOP = 12532, }; -class spell_item_chicken_cover : public SpellScriptLoader +class spell_item_chicken_cover : public SpellScript { - public: - spell_item_chicken_cover() : SpellScriptLoader("spell_item_chicken_cover") { } + PrepareSpellScript(spell_item_chicken_cover); - class spell_item_chicken_cover_SpellScript : public SpellScript - { - PrepareSpellScript(spell_item_chicken_cover_SpellScript); - - bool Load() override - { - return GetCaster()->GetTypeId() == TYPEID_PLAYER; - } - - bool Validate(SpellInfo const* /*spell*/) override - { - return ValidateSpellInfo({ SPELL_CHICKEN_NET, SPELL_CAPTURE_CHICKEN_ESCAPE }) && - sObjectMgr->GetQuestTemplate(QUEST_CHICKEN_PARTY) && - sObjectMgr->GetQuestTemplate(QUEST_FLOWN_THE_COOP); - } + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } - void HandleDummy(SpellEffIndex /* effIndex */) - { - Player* caster = GetCaster()->ToPlayer(); - if (Unit* target = GetHitUnit()) - { - if (!target->HasAura(SPELL_CHICKEN_NET) && (caster->GetQuestStatus(QUEST_CHICKEN_PARTY) == QUEST_STATUS_INCOMPLETE || caster->GetQuestStatus(QUEST_FLOWN_THE_COOP) == QUEST_STATUS_INCOMPLETE)) - { - caster->CastSpell(caster, SPELL_CAPTURE_CHICKEN_ESCAPE, true); - target->KillSelf(); - } - } - } + bool Validate(SpellInfo const* /*spell*/) override + { + return ValidateSpellInfo({ SPELL_CHICKEN_NET, SPELL_CAPTURE_CHICKEN_ESCAPE }) && + sObjectMgr->GetQuestTemplate(QUEST_CHICKEN_PARTY) && + sObjectMgr->GetQuestTemplate(QUEST_FLOWN_THE_COOP); + } - void Register() override + void HandleDummy(SpellEffIndex /* effIndex */) + { + Player* caster = GetCaster()->ToPlayer(); + if (Unit* target = GetHitUnit()) + { + if (!target->HasAura(SPELL_CHICKEN_NET) && (caster->GetQuestStatus(QUEST_CHICKEN_PARTY) == QUEST_STATUS_INCOMPLETE || caster->GetQuestStatus(QUEST_FLOWN_THE_COOP) == QUEST_STATUS_INCOMPLETE)) { - OnEffectHitTarget += SpellEffectFn(spell_item_chicken_cover_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + caster->CastSpell(caster, SPELL_CAPTURE_CHICKEN_ESCAPE, true); + target->KillSelf(); } - }; - - SpellScript* GetSpellScript() const override - { - return new spell_item_chicken_cover_SpellScript(); } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_item_chicken_cover::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; enum Refocus @@ -3614,100 +2918,67 @@ enum Refocus SPELL_VOLLEY = 42243, }; -class spell_item_refocus : public SpellScriptLoader +class spell_item_refocus : public SpellScript { - public: - spell_item_refocus() : SpellScriptLoader("spell_item_refocus") { } - - class spell_item_refocus_SpellScript : public SpellScript - { - PrepareSpellScript(spell_item_refocus_SpellScript); - - void HandleDummy(SpellEffIndex /*effIndex*/) - { - Player* caster = GetCaster()->ToPlayer(); + PrepareSpellScript(spell_item_refocus); - if (!caster || caster->getClass() != CLASS_HUNTER) - return; + void HandleDummy(SpellEffIndex /*effIndex*/) + { + Player* caster = GetCaster()->ToPlayer(); - if (caster->GetSpellHistory()->HasCooldown(SPELL_AIMED_SHOT)) - caster->GetSpellHistory()->ResetCooldown(SPELL_AIMED_SHOT, true); + if (!caster || caster->getClass() != CLASS_HUNTER) + return; - if (caster->GetSpellHistory()->HasCooldown(SPELL_MULTISHOT)) - caster->GetSpellHistory()->ResetCooldown(SPELL_MULTISHOT, true); + if (caster->GetSpellHistory()->HasCooldown(SPELL_AIMED_SHOT)) + caster->GetSpellHistory()->ResetCooldown(SPELL_AIMED_SHOT, true); - if (caster->GetSpellHistory()->HasCooldown(SPELL_VOLLEY)) - caster->GetSpellHistory()->ResetCooldown(SPELL_VOLLEY, true); - } + if (caster->GetSpellHistory()->HasCooldown(SPELL_MULTISHOT)) + caster->GetSpellHistory()->ResetCooldown(SPELL_MULTISHOT, true); - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_item_refocus_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + if (caster->GetSpellHistory()->HasCooldown(SPELL_VOLLEY)) + caster->GetSpellHistory()->ResetCooldown(SPELL_VOLLEY, true); + } - SpellScript* GetSpellScript() const override - { - return new spell_item_refocus_SpellScript(); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_item_refocus::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; -class spell_item_muisek_vessel : public SpellScriptLoader +class spell_item_muisek_vessel : public SpellScript { - public: - spell_item_muisek_vessel() : SpellScriptLoader("spell_item_muisek_vessel") { } - - class spell_item_muisek_vessel_SpellScript : public SpellScript - { - PrepareSpellScript(spell_item_muisek_vessel_SpellScript); + PrepareSpellScript(spell_item_muisek_vessel); - void HandleDummy(SpellEffIndex /*effIndex*/) - { - if (Creature* target = GetHitCreature()) - if (target->isDead()) - target->DespawnOrUnsummon(); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_item_muisek_vessel_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + void HandleDummy(SpellEffIndex /*effIndex*/) + { + if (Creature* target = GetHitCreature()) + if (target->isDead()) + target->DespawnOrUnsummon(); + } - SpellScript* GetSpellScript() const override - { - return new spell_item_muisek_vessel_SpellScript(); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_item_muisek_vessel::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; enum GreatmothersSoulcather { SPELL_FORCE_CAST_SUMMON_GNOME_SOUL = 46486, }; -class spell_item_greatmothers_soulcatcher : public SpellScriptLoader +class spell_item_greatmothers_soulcatcher : public SpellScript { -public: - spell_item_greatmothers_soulcatcher() : SpellScriptLoader("spell_item_greatmothers_soulcatcher") { } + PrepareSpellScript(spell_item_greatmothers_soulcatcher); - class spell_item_greatmothers_soulcatcher_SpellScript : public SpellScript + void HandleDummy(SpellEffIndex /*effIndex*/) { - PrepareSpellScript(spell_item_greatmothers_soulcatcher_SpellScript); - - void HandleDummy(SpellEffIndex /*effIndex*/) - { - if (GetHitUnit()) - GetCaster()->CastSpell(GetCaster(), SPELL_FORCE_CAST_SUMMON_GNOME_SOUL); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_item_greatmothers_soulcatcher_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + if (GetHitUnit()) + GetCaster()->CastSpell(GetCaster(), SPELL_FORCE_CAST_SUMMON_GNOME_SOUL); + } - SpellScript* GetSpellScript() const override + void Register() override { - return new spell_item_greatmothers_soulcatcher_SpellScript(); + OnEffectHitTarget += SpellEffectFn(spell_item_greatmothers_soulcatcher::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -3778,60 +3049,49 @@ enum SoulPreserver SPELL_SOUL_PRESERVER_SHAMAN = 60515, }; -class spell_item_soul_preserver : public SpellScriptLoader +class spell_item_soul_preserver : public AuraScript { -public: - spell_item_soul_preserver() : SpellScriptLoader("spell_item_soul_preserver") { } + PrepareAuraScript(spell_item_soul_preserver); - class spell_item_soul_preserver_AuraScript : public AuraScript + bool Validate(SpellInfo const* /*spellInfo*/) override { - PrepareAuraScript(spell_item_soul_preserver_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_SOUL_PRESERVER_DRUID, - SPELL_SOUL_PRESERVER_PALADIN, - SPELL_SOUL_PRESERVER_PRIEST, - SPELL_SOUL_PRESERVER_SHAMAN - }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + return ValidateSpellInfo( { - PreventDefaultAction(); - - Unit* caster = eventInfo.GetActor(); - - switch (caster->getClass()) - { - case CLASS_DRUID: - caster->CastSpell(caster, SPELL_SOUL_PRESERVER_DRUID, true, nullptr, aurEff); - break; - case CLASS_PALADIN: - caster->CastSpell(caster, SPELL_SOUL_PRESERVER_PALADIN, true, nullptr, aurEff); - break; - case CLASS_PRIEST: - caster->CastSpell(caster, SPELL_SOUL_PRESERVER_PRIEST, true, nullptr, aurEff); - break; - case CLASS_SHAMAN: - caster->CastSpell(caster, SPELL_SOUL_PRESERVER_SHAMAN, true, nullptr, aurEff); - break; - default: - break; - } - } + SPELL_SOUL_PRESERVER_DRUID, + SPELL_SOUL_PRESERVER_PALADIN, + SPELL_SOUL_PRESERVER_PRIEST, + SPELL_SOUL_PRESERVER_SHAMAN + }); + } - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_item_soul_preserver_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + Unit* caster = eventInfo.GetActor(); + + switch (caster->getClass()) + { + case CLASS_DRUID: + caster->CastSpell(caster, SPELL_SOUL_PRESERVER_DRUID, true, nullptr, aurEff); + break; + case CLASS_PALADIN: + caster->CastSpell(caster, SPELL_SOUL_PRESERVER_PALADIN, true, nullptr, aurEff); + break; + case CLASS_PRIEST: + caster->CastSpell(caster, SPELL_SOUL_PRESERVER_PRIEST, true, nullptr, aurEff); + break; + case CLASS_SHAMAN: + caster->CastSpell(caster, SPELL_SOUL_PRESERVER_SHAMAN, true, nullptr, aurEff); + break; + default: + break; } - }; + } - AuraScript* GetAuraScript() const override + void Register() override { - return new spell_item_soul_preserver_AuraScript(); + OnEffectProc += AuraEffectProcFn(spell_item_soul_preserver::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); } }; @@ -3916,40 +3176,29 @@ class spell_item_sunwell_neck : public SpellScriptLoader } }; -class spell_item_toy_train_set_pulse : public SpellScriptLoader +class spell_item_toy_train_set_pulse : public SpellScript { -public: - spell_item_toy_train_set_pulse() : SpellScriptLoader("spell_item_toy_train_set_pulse") { } + PrepareSpellScript(spell_item_toy_train_set_pulse); - class spell_item_toy_train_set_pulse_SpellScript : public SpellScript + void HandleDummy(SpellEffIndex /*index*/) { - PrepareSpellScript(spell_item_toy_train_set_pulse_SpellScript); - - void HandleDummy(SpellEffIndex /*index*/) + if (Player* target = GetHitUnit()->ToPlayer()) { - if (Player* target = GetHitUnit()->ToPlayer()) - { - target->HandleEmoteCommand(EMOTE_ONESHOT_TRAIN); - if (EmotesTextSoundEntry const* soundEntry = FindTextSoundEmoteFor(TEXT_EMOTE_TRAIN, target->getRace(), target->getGender())) - target->PlayDistanceSound(soundEntry->SoundId); - } - } - - void HandleTargets(std::list<WorldObject*>& targetList) - { - targetList.remove_if([](WorldObject const* obj) { return obj->GetTypeId() != TYPEID_PLAYER; }); + target->HandleEmoteCommand(EMOTE_ONESHOT_TRAIN); + if (EmotesTextSoundEntry const* soundEntry = FindTextSoundEmoteFor(TEXT_EMOTE_TRAIN, target->getRace(), target->getGender())) + target->PlayDistanceSound(soundEntry->SoundId); } + } - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_item_toy_train_set_pulse_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_item_toy_train_set_pulse_SpellScript::HandleTargets, EFFECT_ALL, TARGET_UNIT_SRC_AREA_ALLY); - } - }; + void HandleTargets(std::list<WorldObject*>& targetList) + { + targetList.remove_if([](WorldObject const* obj) { return obj->GetTypeId() != TYPEID_PLAYER; }); + } - SpellScript* GetSpellScript() const override + void Register() override { - return new spell_item_toy_train_set_pulse_SpellScript(); + OnEffectHitTarget += SpellEffectFn(spell_item_toy_train_set_pulse::HandleDummy, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_item_toy_train_set_pulse::HandleTargets, EFFECT_ALL, TARGET_UNIT_SRC_AREA_ALLY); } }; @@ -3963,66 +3212,55 @@ enum DeathChoiceSpells SPELL_DEATH_CHOICE_HEROIC_STRENGTH = 67773 }; -class spell_item_death_choice : public SpellScriptLoader +class spell_item_death_choice : public AuraScript { -public: - spell_item_death_choice() : SpellScriptLoader("spell_item_death_choice") { } + PrepareAuraScript(spell_item_death_choice); - class spell_item_death_choice_AuraScript : public AuraScript + bool Validate(SpellInfo const* /*spellInfo*/) override { - PrepareAuraScript(spell_item_death_choice_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override + return ValidateSpellInfo( { - return ValidateSpellInfo( - { - SPELL_DEATH_CHOICE_NORMAL_STRENGTH, - SPELL_DEATH_CHOICE_NORMAL_AGILITY, - SPELL_DEATH_CHOICE_HEROIC_STRENGTH, - SPELL_DEATH_CHOICE_HEROIC_AGILITY - }); - } + SPELL_DEATH_CHOICE_NORMAL_STRENGTH, + SPELL_DEATH_CHOICE_NORMAL_AGILITY, + SPELL_DEATH_CHOICE_HEROIC_STRENGTH, + SPELL_DEATH_CHOICE_HEROIC_AGILITY + }); + } - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); - Unit* caster = eventInfo.GetActor(); - float str = caster->GetStat(STAT_STRENGTH); - float agi = caster->GetStat(STAT_AGILITY); + Unit* caster = eventInfo.GetActor(); + float str = caster->GetStat(STAT_STRENGTH); + float agi = caster->GetStat(STAT_AGILITY); - switch (aurEff->GetId()) + switch (aurEff->GetId()) + { + case SPELL_DEATH_CHOICE_NORMAL_AURA: { - case SPELL_DEATH_CHOICE_NORMAL_AURA: - { - if (str > agi) - caster->CastSpell(caster, SPELL_DEATH_CHOICE_NORMAL_STRENGTH, true, nullptr, aurEff); - else - caster->CastSpell(caster, SPELL_DEATH_CHOICE_NORMAL_AGILITY, true, nullptr, aurEff); - break; - } - case SPELL_DEATH_CHOICE_HEROIC_AURA: - { - if (str > agi) - caster->CastSpell(caster, SPELL_DEATH_CHOICE_HEROIC_STRENGTH, true, nullptr, aurEff); - else - caster->CastSpell(caster, SPELL_DEATH_CHOICE_HEROIC_AGILITY, true, nullptr, aurEff); - break; - } - default: - break; + if (str > agi) + caster->CastSpell(caster, SPELL_DEATH_CHOICE_NORMAL_STRENGTH, true, nullptr, aurEff); + else + caster->CastSpell(caster, SPELL_DEATH_CHOICE_NORMAL_AGILITY, true, nullptr, aurEff); + break; } + case SPELL_DEATH_CHOICE_HEROIC_AURA: + { + if (str > agi) + caster->CastSpell(caster, SPELL_DEATH_CHOICE_HEROIC_STRENGTH, true, nullptr, aurEff); + else + caster->CastSpell(caster, SPELL_DEATH_CHOICE_HEROIC_AGILITY, true, nullptr, aurEff); + break; + } + default: + break; } + } - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_item_death_choice_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } - }; - - AuraScript* GetAuraScript() const override + void Register() override { - return new spell_item_death_choice_AuraScript(); + OnEffectProc += AuraEffectProcFn(spell_item_death_choice::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); } }; @@ -4113,75 +3351,64 @@ enum DarkmoonCardSpells SPELL_DARKMOON_CARD_SPIRIT = 60235, }; -class spell_item_darkmoon_card_greatness : public SpellScriptLoader +class spell_item_darkmoon_card_greatness : public AuraScript { -public: - spell_item_darkmoon_card_greatness() : SpellScriptLoader("spell_item_darkmoon_card_greatness") { } + PrepareAuraScript(spell_item_darkmoon_card_greatness); - class spell_item_darkmoon_card_greatness_AuraScript : public AuraScript + bool Validate(SpellInfo const* /*spellInfo*/) override { - PrepareAuraScript(spell_item_darkmoon_card_greatness_AuraScript); + return ValidateSpellInfo( + { + SPELL_DARKMOON_CARD_STRENGTH, + SPELL_DARKMOON_CARD_AGILITY, + SPELL_DARKMOON_CARD_INTELLECT, + SPELL_DARKMOON_CARD_SPIRIT + }); + } - bool Validate(SpellInfo const* /*spellInfo*/) override + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + Unit* caster = eventInfo.GetActor(); + float str = caster->GetStat(STAT_STRENGTH); + float agi = caster->GetStat(STAT_AGILITY); + float intl = caster->GetStat(STAT_INTELLECT); + float spi = caster->GetStat(STAT_SPIRIT); + float stat = 0.0f; + + uint32 spellTrigger = SPELL_DARKMOON_CARD_STRENGTH; + + if (str > stat) { - return ValidateSpellInfo( - { - SPELL_DARKMOON_CARD_STRENGTH, - SPELL_DARKMOON_CARD_AGILITY, - SPELL_DARKMOON_CARD_INTELLECT, - SPELL_DARKMOON_CARD_SPIRIT - }); + spellTrigger = SPELL_DARKMOON_CARD_STRENGTH; + stat = str; } - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + if (agi > stat) { - PreventDefaultAction(); + spellTrigger = SPELL_DARKMOON_CARD_AGILITY; + stat = agi; + } - Unit* caster = eventInfo.GetActor(); - float str = caster->GetStat(STAT_STRENGTH); - float agi = caster->GetStat(STAT_AGILITY); - float intl = caster->GetStat(STAT_INTELLECT); - float spi = caster->GetStat(STAT_SPIRIT); - float stat = 0.0f; - - uint32 spellTrigger = SPELL_DARKMOON_CARD_STRENGTH; - - if (str > stat) - { - spellTrigger = SPELL_DARKMOON_CARD_STRENGTH; - stat = str; - } - - if (agi > stat) - { - spellTrigger = SPELL_DARKMOON_CARD_AGILITY; - stat = agi; - } - - if (intl > stat) - { - spellTrigger = SPELL_DARKMOON_CARD_INTELLECT; - stat = intl; - } - - if (spi > stat) - { - spellTrigger = SPELL_DARKMOON_CARD_SPIRIT; - stat = spi; - } - - caster->CastSpell(caster, spellTrigger, true, nullptr, aurEff); + if (intl > stat) + { + spellTrigger = SPELL_DARKMOON_CARD_INTELLECT; + stat = intl; } - void Register() override + if (spi > stat) { - OnEffectProc += AuraEffectProcFn(spell_item_darkmoon_card_greatness_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + spellTrigger = SPELL_DARKMOON_CARD_SPIRIT; + stat = spi; } - }; - AuraScript* GetAuraScript() const override + caster->CastSpell(caster, spellTrigger, true, nullptr, aurEff); + } + + void Register() override { - return new spell_item_darkmoon_card_greatness_AuraScript(); + OnEffectProc += AuraEffectProcFn(spell_item_darkmoon_card_greatness::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); } }; @@ -4191,43 +3418,32 @@ enum CharmWitchDoctor SPELL_CHARM_WITCH_DOCTOR_PROC = 43821 }; -class spell_item_charm_witch_doctor : public SpellScriptLoader +class spell_item_charm_witch_doctor : public AuraScript { -public: - spell_item_charm_witch_doctor() : SpellScriptLoader("spell_item_charm_witch_doctor") { } + PrepareAuraScript(spell_item_charm_witch_doctor); - class spell_item_charm_witch_doctor_AuraScript : public AuraScript + bool Validate(SpellInfo const* /*spellInfo*/) override { - PrepareAuraScript(spell_item_charm_witch_doctor_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_CHARM_WITCH_DOCTOR_PROC }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); + return ValidateSpellInfo({ SPELL_CHARM_WITCH_DOCTOR_PROC }); + } - Unit* caster = eventInfo.GetActor(); - Unit* target = eventInfo.GetActionTarget(); + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); - if (target) - { - int32 bp = CalculatePct(target->GetCreateHealth(),aurEff->GetSpellInfo()->Effects[1].CalcValue()); - caster->CastCustomSpell(target, SPELL_CHARM_WITCH_DOCTOR_PROC, &bp, nullptr, nullptr, true, nullptr, aurEff); - } - } + Unit* caster = eventInfo.GetActor(); + Unit* target = eventInfo.GetActionTarget(); - void Register() override + if (target) { - OnEffectProc += AuraEffectProcFn(spell_item_charm_witch_doctor_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + int32 bp = CalculatePct(target->GetCreateHealth(),aurEff->GetSpellInfo()->Effects[1].CalcValue()); + caster->CastCustomSpell(target, SPELL_CHARM_WITCH_DOCTOR_PROC, &bp, nullptr, nullptr, true, nullptr, aurEff); } - }; + } - AuraScript* GetAuraScript() const override + void Register() override { - return new spell_item_charm_witch_doctor_AuraScript(); + OnEffectProc += AuraEffectProcFn(spell_item_charm_witch_doctor::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); } }; @@ -4238,47 +3454,36 @@ enum ManaDrainSpells SPELL_MANA_DRAIN_LEECH = 27526 }; -class spell_item_mana_drain : public SpellScriptLoader +class spell_item_mana_drain : public AuraScript { -public: - spell_item_mana_drain() : SpellScriptLoader("spell_item_mana_drain") { } + PrepareAuraScript(spell_item_mana_drain); - class spell_item_mana_drain_AuraScript : public AuraScript + bool Validate(SpellInfo const* /*spellInfo*/) override { - PrepareAuraScript(spell_item_mana_drain_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_MANA_DRAIN_ENERGIZE, - SPELL_MANA_DRAIN_LEECH - }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + return ValidateSpellInfo( { - PreventDefaultAction(); + SPELL_MANA_DRAIN_ENERGIZE, + SPELL_MANA_DRAIN_LEECH + }); + } - Unit* caster = eventInfo.GetActor(); - Unit* target = eventInfo.GetActionTarget(); + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); - if (caster->IsAlive()) - caster->CastSpell(caster, SPELL_MANA_DRAIN_ENERGIZE, true, nullptr, aurEff); + Unit* caster = eventInfo.GetActor(); + Unit* target = eventInfo.GetActionTarget(); - if (target && target->IsAlive()) - caster->CastSpell(target, SPELL_MANA_DRAIN_LEECH, true, nullptr, aurEff); - } + if (caster->IsAlive()) + caster->CastSpell(caster, SPELL_MANA_DRAIN_ENERGIZE, true, nullptr, aurEff); - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_item_mana_drain_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } - }; + if (target && target->IsAlive()) + caster->CastSpell(target, SPELL_MANA_DRAIN_LEECH, true, nullptr, aurEff); + } - AuraScript* GetAuraScript() const override + void Register() override { - return new spell_item_mana_drain_AuraScript(); + OnEffectProc += AuraEffectProcFn(spell_item_mana_drain::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); } }; @@ -4290,57 +3495,46 @@ enum TauntFlag }; // 51640 - Taunt Flag Targeting -class spell_item_taunt_flag_targeting : public SpellScriptLoader +class spell_item_taunt_flag_targeting : public SpellScript { - public: - spell_item_taunt_flag_targeting() : SpellScriptLoader("spell_item_taunt_flag_targeting") { } + PrepareSpellScript(spell_item_taunt_flag_targeting); - class spell_item_taunt_flag_targeting_SpellScript : public SpellScript - { - PrepareSpellScript(spell_item_taunt_flag_targeting_SpellScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_TAUNT_FLAG }) && - sObjectMgr->GetBroadcastText(EMOTE_PLANTS_FLAG); - } - - void FilterTargets(std::list<WorldObject*>& targets) - { - targets.remove_if([](WorldObject* obj) -> bool - { - return obj->GetTypeId() != TYPEID_PLAYER && obj->GetTypeId() != TYPEID_CORPSE; - }); + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_TAUNT_FLAG }) && + sObjectMgr->GetBroadcastText(EMOTE_PLANTS_FLAG); + } - if (targets.empty()) - { - FinishCast(SPELL_FAILED_NO_VALID_TARGETS); - return; - } + void FilterTargets(std::list<WorldObject*>& targets) + { + targets.remove_if([](WorldObject* obj) -> bool + { + return obj->GetTypeId() != TYPEID_PLAYER && obj->GetTypeId() != TYPEID_CORPSE; + }); - Trinity::Containers::RandomResize(targets, 1); - } + if (targets.empty()) + { + FinishCast(SPELL_FAILED_NO_VALID_TARGETS); + return; + } - void HandleDummy(SpellEffIndex /*effIndex*/) - { - // we *really* want the unit implementation here - // it sends a packet like seen on sniff - GetCaster()->Unit::TextEmote(EMOTE_PLANTS_FLAG, GetHitUnit(), false); + Trinity::Containers::RandomResize(targets, 1); + } - GetCaster()->CastSpell(GetHitUnit(), SPELL_TAUNT_FLAG, true); - } + void HandleDummy(SpellEffIndex /*effIndex*/) + { + // we *really* want the unit implementation here + // it sends a packet like seen on sniff + GetCaster()->Unit::TextEmote(EMOTE_PLANTS_FLAG, GetHitUnit(), false); - void Register() override - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_item_taunt_flag_targeting_SpellScript::FilterTargets, EFFECT_0, TARGET_CORPSE_SRC_AREA_ENEMY); - OnEffectHitTarget += SpellEffectFn(spell_item_taunt_flag_targeting_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + GetCaster()->CastSpell(GetHitUnit(), SPELL_TAUNT_FLAG, true); + } - SpellScript* GetSpellScript() const override - { - return new spell_item_taunt_flag_targeting_SpellScript(); - } + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_item_taunt_flag_targeting::FilterTargets, EFFECT_0, TARGET_CORPSE_SRC_AREA_ENEMY); + OnEffectHitTarget += SpellEffectFn(spell_item_taunt_flag_targeting::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; // 13180 - Gnomish Mind Control Cap @@ -4352,49 +3546,38 @@ enum MindControlCap SPELL_DULLARD = 67809 }; -class spell_item_mind_control_cap : public SpellScriptLoader +class spell_item_mind_control_cap : public SpellScript { - public: - spell_item_mind_control_cap() : SpellScriptLoader("spell_item_mind_control_cap") { } - - class spell_item_mind_control_cap_SpellScript : public SpellScript - { - PrepareSpellScript(spell_item_mind_control_cap_SpellScript); - - bool Load() override - { - if (!GetCastItem()) - return false; - return true; - } - - bool Validate(SpellInfo const* /*spell*/) override - { - return ValidateSpellInfo({ SPELL_GNOMISH_MIND_CONTROL_CAP, SPELL_DULLARD }); - } + PrepareSpellScript(spell_item_mind_control_cap); - void HandleDummy(SpellEffIndex /* effIndex */) - { - Unit* caster = GetCaster(); - if (Unit* target = GetHitUnit()) - { - if (roll_chance_i(ROLL_CHANCE_NO_BACKFIRE)) - caster->CastSpell(target, roll_chance_i(ROLL_CHANCE_DULLARD) ? SPELL_DULLARD : SPELL_GNOMISH_MIND_CONTROL_CAP, true, GetCastItem()); - else - target->CastSpell(caster, SPELL_GNOMISH_MIND_CONTROL_CAP, true); // backfire - 5% chance - } - } + bool Load() override + { + if (!GetCastItem()) + return false; + return true; + } - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_item_mind_control_cap_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + bool Validate(SpellInfo const* /*spell*/) override + { + return ValidateSpellInfo({ SPELL_GNOMISH_MIND_CONTROL_CAP, SPELL_DULLARD }); + } - SpellScript* GetSpellScript() const override + void HandleDummy(SpellEffIndex /* effIndex */) + { + Unit* caster = GetCaster(); + if (Unit* target = GetHitUnit()) { - return new spell_item_mind_control_cap_SpellScript(); + if (roll_chance_i(ROLL_CHANCE_NO_BACKFIRE)) + caster->CastSpell(target, roll_chance_i(ROLL_CHANCE_DULLARD) ? SPELL_DULLARD : SPELL_GNOMISH_MIND_CONTROL_CAP, true, GetCastItem()); + else + target->CastSpell(caster, SPELL_GNOMISH_MIND_CONTROL_CAP, true); // backfire - 5% chance } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_item_mind_control_cap::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; // 8344 - Universal Remote (Gnomish Universal Remote) @@ -4405,51 +3588,40 @@ enum UniversalRemote SPELL_TARGET_LOCK = 8347 }; -class spell_item_universal_remote : public SpellScriptLoader +class spell_item_universal_remote : public SpellScript { - public: - spell_item_universal_remote() : SpellScriptLoader("spell_item_universal_remote") { } - - class spell_item_universal_remote_SpellScript : public SpellScript - { - PrepareSpellScript(spell_item_universal_remote_SpellScript); - - bool Load() override - { - if (!GetCastItem()) - return false; - return true; - } - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_CONTROL_MACHINE, SPELL_MOBILITY_MALFUNCTION, SPELL_TARGET_LOCK }); - } + PrepareSpellScript(spell_item_universal_remote); - void HandleDummy(SpellEffIndex /*effIndex*/) - { - if (Unit* target = GetHitUnit()) - { - uint8 chance = urand(0, 99); - if (chance < 15) - GetCaster()->CastSpell(target, SPELL_TARGET_LOCK, true, GetCastItem()); - else if (chance < 25) - GetCaster()->CastSpell(target, SPELL_MOBILITY_MALFUNCTION, true, GetCastItem()); - else - GetCaster()->CastSpell(target, SPELL_CONTROL_MACHINE, true, GetCastItem()); - } - } + bool Load() override + { + if (!GetCastItem()) + return false; + return true; + } - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_item_universal_remote_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_CONTROL_MACHINE, SPELL_MOBILITY_MALFUNCTION, SPELL_TARGET_LOCK }); + } - SpellScript* GetSpellScript() const override + void HandleDummy(SpellEffIndex /*effIndex*/) + { + if (Unit* target = GetHitUnit()) { - return new spell_item_universal_remote_SpellScript(); + uint8 chance = urand(0, 99); + if (chance < 15) + GetCaster()->CastSpell(target, SPELL_TARGET_LOCK, true, GetCastItem()); + else if (chance < 25) + GetCaster()->CastSpell(target, SPELL_MOBILITY_MALFUNCTION, true, GetCastItem()); + else + GetCaster()->CastSpell(target, SPELL_CONTROL_MACHINE, true, GetCastItem()); } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_item_universal_remote::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; enum ZandalarianCharms @@ -4514,137 +3686,113 @@ class spell_item_zandalarian_charm : public SpellScriptLoader }; // 45051 - Mad Alchemist's Potion (34440) -class spell_item_mad_alchemists_potion : public SpellScriptLoader +class spell_item_mad_alchemists_potion : public SpellScript { -public: - spell_item_mad_alchemists_potion() : SpellScriptLoader("spell_item_mad_alchemists_potion") {} + PrepareSpellScript(spell_item_mad_alchemists_potion); - class mad_alchemists_potion_SpellScript : public SpellScript + void SecondaryEffect() { - PrepareSpellScript(mad_alchemists_potion_SpellScript); - - void SecondaryEffect() - { - std::vector<uint32> availableElixirs = - { - // Battle Elixirs - 33720, // Onslaught Elixir (28102) - 54452, // Adept's Elixir (28103) - 33726, // Elixir of Mastery (28104) - 28490, // Elixir of Major Strength (22824) - 28491, // Elixir of Healing Power (22825) - 28493, // Elixir of Major Frost Power (22827) - 54494, // Elixir of Major Agility (22831) - 28501, // Elixir of Major Firepower (22833) - 28503,// Elixir of Major Shadow Power (22835) - 38954, // Fel Strength Elixir (31679) - // Guardian Elixirs - 39625, // Elixir of Major Fortitude (32062) - 39626, // Earthen Elixir (32063) - 39627, // Elixir of Draenic Wisdom (32067) - 39628, // Elixir of Ironskin (32068) - 28502, // Elixir of Major Defense (22834) - 28514, // Elixir of Empowerment (22848) - // Other - 28489, // Elixir of Camouflage (22823) - 28496 // Elixir of the Searching Eye (22830) - }; - - Unit* target = GetCaster(); - - if (target->getPowerType() == POWER_MANA) - availableElixirs.push_back(28509); // Elixir of Major Mageblood (22840) - - uint32 chosenElixir = Trinity::Containers::SelectRandomContainerElement(availableElixirs); - - bool useElixir = true; - - SpellGroup chosenSpellGroup = SPELL_GROUP_NONE; - if (sSpellMgr->IsSpellMemberOfSpellGroup(chosenElixir, SPELL_GROUP_ELIXIR_BATTLE)) - chosenSpellGroup = SPELL_GROUP_ELIXIR_BATTLE; - if (sSpellMgr->IsSpellMemberOfSpellGroup(chosenElixir, SPELL_GROUP_ELIXIR_GUARDIAN)) - chosenSpellGroup = SPELL_GROUP_ELIXIR_GUARDIAN; - // If another spell of the same group is already active the elixir should not be cast - if (chosenSpellGroup != SPELL_GROUP_NONE) - { - Unit::AuraApplicationMap const& auraMap = target->GetAppliedAuras(); - for (auto itr = auraMap.begin(); itr != auraMap.end(); ++itr) + std::vector<uint32> availableElixirs = + { + // Battle Elixirs + 33720, // Onslaught Elixir (28102) + 54452, // Adept's Elixir (28103) + 33726, // Elixir of Mastery (28104) + 28490, // Elixir of Major Strength (22824) + 28491, // Elixir of Healing Power (22825) + 28493, // Elixir of Major Frost Power (22827) + 54494, // Elixir of Major Agility (22831) + 28501, // Elixir of Major Firepower (22833) + 28503,// Elixir of Major Shadow Power (22835) + 38954, // Fel Strength Elixir (31679) + // Guardian Elixirs + 39625, // Elixir of Major Fortitude (32062) + 39626, // Earthen Elixir (32063) + 39627, // Elixir of Draenic Wisdom (32067) + 39628, // Elixir of Ironskin (32068) + 28502, // Elixir of Major Defense (22834) + 28514, // Elixir of Empowerment (22848) + // Other + 28489, // Elixir of Camouflage (22823) + 28496 // Elixir of the Searching Eye (22830) + }; + + Unit* target = GetCaster(); + + if (target->getPowerType() == POWER_MANA) + availableElixirs.push_back(28509); // Elixir of Major Mageblood (22840) + + uint32 chosenElixir = Trinity::Containers::SelectRandomContainerElement(availableElixirs); + + bool useElixir = true; + + SpellGroup chosenSpellGroup = SPELL_GROUP_NONE; + if (sSpellMgr->IsSpellMemberOfSpellGroup(chosenElixir, SPELL_GROUP_ELIXIR_BATTLE)) + chosenSpellGroup = SPELL_GROUP_ELIXIR_BATTLE; + if (sSpellMgr->IsSpellMemberOfSpellGroup(chosenElixir, SPELL_GROUP_ELIXIR_GUARDIAN)) + chosenSpellGroup = SPELL_GROUP_ELIXIR_GUARDIAN; + // If another spell of the same group is already active the elixir should not be cast + if (chosenSpellGroup != SPELL_GROUP_NONE) + { + Unit::AuraApplicationMap const& auraMap = target->GetAppliedAuras(); + for (auto itr = auraMap.begin(); itr != auraMap.end(); ++itr) + { + uint32 spellId = itr->second->GetBase()->GetId(); + if (sSpellMgr->IsSpellMemberOfSpellGroup(spellId, chosenSpellGroup) && spellId != chosenElixir) { - uint32 spellId = itr->second->GetBase()->GetId(); - if (sSpellMgr->IsSpellMemberOfSpellGroup(spellId, chosenSpellGroup) && spellId != chosenElixir) - { - useElixir = false; - break; - } + useElixir = false; + break; } } - - if (useElixir) - target->CastSpell(target, chosenElixir, true, GetCastItem()); - } - - void Register() override - { - AfterCast += SpellCastFn(mad_alchemists_potion_SpellScript::SecondaryEffect); } - }; + if (useElixir) + target->CastSpell(target, chosenElixir, true, GetCastItem()); + } - SpellScript* GetSpellScript() const override + void Register() override { - return new mad_alchemists_potion_SpellScript(); + AfterCast += SpellCastFn(spell_item_mad_alchemists_potion::SecondaryEffect); } }; // 53750 - Crazy Alchemist's Potion (40077) -class spell_item_crazy_alchemists_potion : public SpellScriptLoader +class spell_item_crazy_alchemists_potion : public SpellScript { -public: - spell_item_crazy_alchemists_potion() : SpellScriptLoader("spell_item_crazy_alchemists_potion") {} + PrepareSpellScript(spell_item_crazy_alchemists_potion); - class crazy_alchemists_potion_SpellScript : public SpellScript + void SecondaryEffect() { - PrepareSpellScript(crazy_alchemists_potion_SpellScript); - - void SecondaryEffect() + std::vector<uint32> availableElixirs = { - std::vector<uint32> availableElixirs = - { - 43185, // Runic Healing Potion (33447) - 53750, // Crazy Alchemist's Potion (40077) - 53761, // Powerful Rejuvenation Potion (40087) - 53762, // Indestructible Potion (40093) - 53908, // Potion of Speed (40211) - 53909, // Potion of Wild Magic (40212) - 53910, // Mighty Arcane Protection Potion (40213) - 53911, // Mighty Fire Protection Potion (40214) - 53913, // Mighty Frost Protection Potion (40215) - 53914, // Mighty Nature Protection Potion (40216) - 53915 // Mighty Shadow Protection Potion (40217) - }; - - Unit* target = GetCaster(); - - if (!target->IsInCombat()) - availableElixirs.push_back(53753); // Potion of Nightmares (40081) - if (target->getPowerType() == POWER_MANA) - availableElixirs.push_back(43186); // Runic Mana Potion(33448) - - uint32 chosenElixir = Trinity::Containers::SelectRandomContainerElement(availableElixirs); + 43185, // Runic Healing Potion (33447) + 53750, // Crazy Alchemist's Potion (40077) + 53761, // Powerful Rejuvenation Potion (40087) + 53762, // Indestructible Potion (40093) + 53908, // Potion of Speed (40211) + 53909, // Potion of Wild Magic (40212) + 53910, // Mighty Arcane Protection Potion (40213) + 53911, // Mighty Fire Protection Potion (40214) + 53913, // Mighty Frost Protection Potion (40215) + 53914, // Mighty Nature Protection Potion (40216) + 53915 // Mighty Shadow Protection Potion (40217) + }; - target->CastSpell(target, chosenElixir, true, GetCastItem()); - } + Unit* target = GetCaster(); - void Register() override - { - AfterCast += SpellCastFn(crazy_alchemists_potion_SpellScript::SecondaryEffect); - } + if (!target->IsInCombat()) + availableElixirs.push_back(53753); // Potion of Nightmares (40081) + if (target->getPowerType() == POWER_MANA) + availableElixirs.push_back(43186); // Runic Mana Potion(33448) - }; + uint32 chosenElixir = Trinity::Containers::SelectRandomContainerElement(availableElixirs); + + target->CastSpell(target, chosenElixir, true, GetCastItem()); + } - SpellScript* GetSpellScript() const override + void Register() override { - return new crazy_alchemists_potion_SpellScript(); + AfterCast += SpellCastFn(spell_item_crazy_alchemists_potion::SecondaryEffect); } }; @@ -4659,110 +3807,111 @@ void AddSC_item_spell_scripts() // 23075 Mithril Mechanical Dragonling new spell_item_trigger_spell("spell_item_mithril_mechanical_dragonling", SPELL_MITHRIL_MECHANICAL_DRAGONLING); - new spell_item_aegis_of_preservation(); - new spell_item_arcane_shroud(); - new spell_item_alchemists_stone(); + RegisterAuraScript(spell_item_aegis_of_preservation); + RegisterAuraScript(spell_item_alchemists_stone); new spell_item_anger_capacitor<8>("spell_item_tiny_abomination_in_a_jar"); new spell_item_anger_capacitor<7>("spell_item_tiny_abomination_in_a_jar_hero"); - new spell_item_aura_of_madness(); - new spell_item_dementia(); - new spell_item_blessing_of_ancient_kings(); - new spell_item_deadly_precision(); - new spell_item_deadly_precision_dummy(); + RegisterAuraScript(spell_item_arcane_shroud); + RegisterAuraScript(spell_item_aura_of_madness); + RegisterAuraScript(spell_item_dementia); + RegisterAuraScript(spell_item_blessing_of_ancient_kings); + RegisterAuraScript(spell_item_deadly_precision); + RegisterSpellScript(spell_item_deadly_precision_dummy); new spell_item_deathbringers_will<SPELL_STRENGTH_OF_THE_TAUNKA, SPELL_AGILITY_OF_THE_VRYKUL, SPELL_POWER_OF_THE_TAUNKA, SPELL_AIM_OF_THE_IRON_DWARVES, SPELL_SPEED_OF_THE_VRYKUL>("spell_item_deathbringers_will_normal"); new spell_item_deathbringers_will<SPELL_STRENGTH_OF_THE_TAUNKA_HERO, SPELL_AGILITY_OF_THE_VRYKUL_HERO, SPELL_POWER_OF_THE_TAUNKA_HERO, SPELL_AIM_OF_THE_IRON_DWARVES_HERO, SPELL_SPEED_OF_THE_VRYKUL_HERO>("spell_item_deathbringers_will_heroic"); - new spell_item_decahedral_dwarven_dice(); + RegisterSpellScript(spell_item_decahedral_dwarven_dice); new spell_item_defibrillate("spell_item_goblin_jumper_cables", 67, SPELL_GOBLIN_JUMPER_CABLES_FAIL); new spell_item_defibrillate("spell_item_goblin_jumper_cables_xl", 50, SPELL_GOBLIN_JUMPER_CABLES_XL_FAIL); new spell_item_defibrillate("spell_item_gnomish_army_knife", 33); - new spell_item_desperate_defense(); - new spell_item_deviate_fish(); - new spell_item_discerning_eye_beast_dummy(); - new spell_item_echoes_of_light(); - new spell_item_fate_rune_of_unsurpassed_vigor(); - new spell_item_flask_of_the_north(); - new spell_item_frozen_shadoweave(); - new spell_item_gnomish_death_ray(); - new spell_item_harm_prevention_belt(); - new spell_item_healing_touch_refund(); + RegisterAuraScript(spell_item_desperate_defense); + RegisterSpellScript(spell_item_deviate_fish); + RegisterAuraScript(spell_item_discerning_eye_beast_dummy); + RegisterSpellScript(spell_item_echoes_of_light); + RegisterAuraScript(spell_item_fate_rune_of_unsurpassed_vigor); + RegisterSpellScript(spell_item_flask_of_the_north); + RegisterAuraScript(spell_item_frozen_shadoweave); + RegisterSpellScript(spell_item_gnomish_death_ray); + RegisterAuraScript(spell_item_harm_prevention_belt); + RegisterAuraScript(spell_item_healing_touch_refund); new spell_item_heartpierce<SPELL_INVIGORATION_ENERGY, SPELL_INVIGORATION_MANA, SPELL_INVIGORATION_RAGE, SPELL_INVIGORATION_RP>("spell_item_heartpierce"); new spell_item_heartpierce<SPELL_INVIGORATION_ENERGY_HERO, SPELL_INVIGORATION_MANA_HERO, SPELL_INVIGORATION_RAGE_HERO, SPELL_INVIGORATION_RP_HERO>("spell_item_heartpierce_hero"); - new spell_item_crystal_spire_of_karabor(); - new spell_item_make_a_wish(); - new spell_item_mark_of_conquest(); - new spell_item_mingos_fortune_generator(); - new spell_item_necrotic_touch(); - new spell_item_net_o_matic(); - new spell_item_noggenfogger_elixir(); - new spell_item_pendant_of_the_violet_eye(); - new spell_item_persistent_shield(); - new spell_item_pet_healing(); - new spell_item_piccolo_of_the_flaming_fire(); - new spell_item_savory_deviate_delight(); - new spell_item_scroll_of_recall(); - new spell_item_unsated_craving(); - new spell_item_shadows_fate(); - new spell_item_shadowmourne(); - new spell_item_shadowmourne_soul_fragment(); - new spell_item_six_demon_bag(); - new spell_item_swift_hand_justice_dummy(); - new spell_item_totem_of_flowing_water(); - new spell_item_the_eye_of_diminution(); - new spell_item_underbelly_elixir(); - new spell_item_worn_troll_dice(); - new spell_item_red_rider_air_rifle(); - - new spell_item_create_heart_candy(); - new spell_item_book_of_glyph_mastery(); - new spell_item_gift_of_the_harvester(); - new spell_item_map_of_the_geyser_fields(); - new spell_item_vanquished_clutches(); - - new spell_item_ashbringer(); - new spell_magic_eater_food(); - new spell_item_refocus(); - new spell_item_shimmering_vessel(); - new spell_item_purify_helboar_meat(); - new spell_item_crystal_prison_dummy_dnd(); - new spell_item_reindeer_transformation(); - new spell_item_nigh_invulnerability(); - new spell_item_poultryizer(); - new spell_item_socrethars_stone(); - new spell_item_demon_broiled_surprise(); - new spell_item_complete_raptor_capture(); - new spell_item_impale_leviroth(); - new spell_item_brewfest_mount_transformation(); - new spell_item_nitro_boots(); - new spell_item_teach_language(); - new spell_item_rocket_boots(); - new spell_item_pygmy_oil(); - new spell_item_unusual_compass(); - new spell_item_chicken_cover(); - new spell_item_muisek_vessel(); - new spell_item_greatmothers_soulcatcher(); + RegisterAuraScript(spell_item_crystal_spire_of_karabor); + RegisterSpellScript(spell_item_make_a_wish); + RegisterAuraScript(spell_item_mark_of_conquest); + RegisterSpellScript(spell_item_mingos_fortune_generator); + RegisterAuraScript(spell_item_necrotic_touch); + RegisterSpellScript(spell_item_net_o_matic); + RegisterSpellScript(spell_item_noggenfogger_elixir); + RegisterAuraScript(spell_item_pendant_of_the_violet_eye); + RegisterAuraScript(spell_item_persistent_shield); + RegisterAuraScript(spell_item_pet_healing); + RegisterSpellScript(spell_item_piccolo_of_the_flaming_fire); + RegisterSpellScript(spell_item_savory_deviate_delight); + RegisterSpellScript(spell_item_scroll_of_recall); + RegisterAuraScript(spell_item_unsated_craving); + RegisterAuraScript(spell_item_shadows_fate); + RegisterAuraScript(spell_item_shadowmourne); + RegisterAuraScript(spell_item_shadowmourne_soul_fragment); + RegisterSpellScript(spell_item_six_demon_bag); + RegisterAuraScript(spell_item_swift_hand_justice_dummy); + RegisterAuraScript(spell_item_totem_of_flowing_water); + RegisterAuraScript(spell_item_the_eye_of_diminution); + RegisterSpellScript(spell_item_underbelly_elixir); + RegisterSpellScript(spell_item_worn_troll_dice); + RegisterSpellScript(spell_item_red_rider_air_rifle); + + RegisterSpellScript(spell_item_create_heart_candy); + RegisterSpellScript(spell_item_book_of_glyph_mastery); + RegisterSpellScript(spell_item_gift_of_the_harvester); + RegisterSpellScript(spell_item_map_of_the_geyser_fields); + RegisterSpellScript(spell_item_vanquished_clutches); + + RegisterSpellScript(spell_item_ashbringer); + RegisterAuraScript(spell_magic_eater_food); + RegisterSpellScript(spell_item_shimmering_vessel); + RegisterSpellScript(spell_item_purify_helboar_meat); + RegisterSpellScript(spell_item_crystal_prison_dummy_dnd); + RegisterSpellScript(spell_item_reindeer_transformation); + RegisterSpellScript(spell_item_nigh_invulnerability); + RegisterSpellScript(spell_item_poultryizer); + RegisterSpellScript(spell_item_socrethars_stone); + RegisterSpellScript(spell_item_demon_broiled_surprise); + RegisterSpellScript(spell_item_complete_raptor_capture); + RegisterSpellScript(spell_item_impale_leviroth); + RegisterSpellScript(spell_item_brewfest_mount_transformation); + RegisterSpellScript(spell_item_nitro_boosts); + RegisterAuraScript(spell_item_nitro_boosts_backfire); + RegisterSpellScript(spell_item_teach_language); + RegisterSpellScript(spell_item_rocket_boots); + RegisterSpellScript(spell_item_pygmy_oil); + RegisterSpellScript(spell_item_unusual_compass); + RegisterSpellScript(spell_item_chicken_cover); + RegisterSpellScript(spell_item_refocus); + RegisterSpellScript(spell_item_muisek_vessel); + RegisterSpellScript(spell_item_greatmothers_soulcatcher); new spell_item_shard_of_the_scale<SPELL_PURIFIED_CAUTERIZING_HEAL, SPELL_PURIFIED_SEARING_FLAMES>("spell_item_purified_shard_of_the_scale"); new spell_item_shard_of_the_scale<SPELL_SHINY_CAUTERIZING_HEAL, SPELL_SHINY_SEARING_FLAMES>("spell_item_shiny_shard_of_the_scale"); - new spell_item_soul_preserver(); + RegisterAuraScript(spell_item_soul_preserver); new spell_item_sunwell_neck<SPELL_LIGHTS_WRATH, SPELL_ARCANE_BOLT>("spell_item_sunwell_exalted_caster_neck"); new spell_item_sunwell_neck<SPELL_LIGHTS_STRENGTH, SPELL_ARCANE_STRIKE>("spell_item_sunwell_exalted_melee_neck"); new spell_item_sunwell_neck<SPELL_LIGHTS_WARD, SPELL_ARCANE_INSIGHT>("spell_item_sunwell_exalted_tank_neck"); new spell_item_sunwell_neck<SPELL_LIGHTS_SALVATION, SPELL_ARCANE_SURGE>("spell_item_sunwell_exalted_healer_neck"); - new spell_item_toy_train_set_pulse(); - new spell_item_death_choice(); + RegisterSpellScript(spell_item_toy_train_set_pulse); + RegisterAuraScript(spell_item_death_choice); new spell_item_trinket_stack("spell_item_lightning_capacitor", SPELL_LIGHTNING_CAPACITOR_STACK, SPELL_LIGHTNING_CAPACITOR_TRIGGER); new spell_item_trinket_stack("spell_item_thunder_capacitor", SPELL_THUNDER_CAPACITOR_STACK, SPELL_THUNDER_CAPACITOR_TRIGGER); new spell_item_trinket_stack("spell_item_toc25_normal_caster_trinket", SPELL_TOC25_CASTER_TRINKET_NORMAL_STACK, SPELL_TOC25_CASTER_TRINKET_NORMAL_TRIGGER); new spell_item_trinket_stack("spell_item_toc25_heroic_caster_trinket", SPELL_TOC25_CASTER_TRINKET_HEROIC_STACK, SPELL_TOC25_CASTER_TRINKET_HEROIC_TRIGGER); - new spell_item_darkmoon_card_greatness(); - new spell_item_charm_witch_doctor(); - new spell_item_mana_drain(); - new spell_item_taunt_flag_targeting(); - new spell_item_mind_control_cap(); - new spell_item_universal_remote(); + RegisterAuraScript(spell_item_darkmoon_card_greatness); + RegisterAuraScript(spell_item_charm_witch_doctor); + RegisterAuraScript(spell_item_mana_drain); + RegisterSpellScript(spell_item_taunt_flag_targeting); + RegisterSpellScript(spell_item_mind_control_cap); + RegisterSpellScript(spell_item_universal_remote); new spell_item_zandalarian_charm("spell_item_unstable_power", SPELL_UNSTABLE_POWER_AURA_STACK); new spell_item_zandalarian_charm("spell_item_restless_strength", SPELL_RESTLESS_STRENGTH_AURA_STACK); - new spell_item_mad_alchemists_potion(); - new spell_item_crazy_alchemists_potion(); + RegisterSpellScript(spell_item_mad_alchemists_potion); + RegisterSpellScript(spell_item_crazy_alchemists_potion); } diff --git a/src/server/scripts/Spells/spell_mage.cpp b/src/server/scripts/Spells/spell_mage.cpp index 440c0ba4c5e..e45ed806ec2 100644 --- a/src/server/scripts/Spells/spell_mage.cpp +++ b/src/server/scripts/Spells/spell_mage.cpp @@ -74,7 +74,8 @@ enum MageSpellIcons { SPELL_ICON_MAGE_SHATTERED_BARRIER = 2945, SPELL_ICON_MAGE_PRESENCE_OF_MIND = 139, - SPELL_ICON_MAGE_CLEARCASTING = 212 + SPELL_ICON_MAGE_CLEARCASTING = 212, + SPELL_ICON_MAGE_LIVING_BOMB = 3000 }; // Incanter's Absorbtion @@ -357,7 +358,7 @@ class spell_mage_combustion : public SpellScriptLoader // Do not take charges, add a stack of crit buff if (!(eventInfo.GetHitMask() & PROC_HIT_CRITICAL)) { - eventInfo.GetActor()->CastSpell((Unit*)nullptr, SPELL_MAGE_COMBUSTION_PROC, true); + eventInfo.GetActor()->CastSpell(nullptr, SPELL_MAGE_COMBUSTION_PROC, true); return false; } @@ -408,6 +409,26 @@ class spell_mage_combustion_proc : public SpellScriptLoader } }; +// -31661 - Dragon's Breath +class spell_mage_dragon_breath : public AuraScript +{ + PrepareAuraScript(spell_mage_dragon_breath); + + bool CheckProc(ProcEventInfo& eventInfo) + { + // Dont proc with Living Bomb explosion + SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); + if (spellInfo && spellInfo->SpellIconID == SPELL_ICON_MAGE_LIVING_BOMB && spellInfo->SpellFamilyName == SPELLFAMILY_MAGE) + return false; + return true; + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_mage_dragon_breath::CheckProc); + } +}; + // -11185 - Improved Blizzard class spell_mage_imp_blizzard : public SpellScriptLoader { @@ -461,7 +482,7 @@ class spell_mage_imp_mana_gems : public SpellScriptLoader void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) { PreventDefaultAction(); - eventInfo.GetActor()->CastSpell((Unit*)nullptr, SPELL_MAGE_MANA_SURGE, true, nullptr, aurEff); + eventInfo.GetActor()->CastSpell(nullptr, SPELL_MAGE_MANA_SURGE, true, nullptr, aurEff); } void Register() override @@ -712,7 +733,7 @@ class spell_mage_gen_extra_effects : public SpellScriptLoader Unit* caster = eventInfo.GetActor(); if (caster->HasAura(SPELL_MAGE_T10_2P_BONUS)) - caster->CastSpell((Unit*)nullptr, SPELL_MAGE_T10_2P_BONUS_EFFECT, true); + caster->CastSpell(nullptr, SPELL_MAGE_T10_2P_BONUS_EFFECT, true); } void Register() override @@ -1295,6 +1316,7 @@ void AddSC_mage_spell_scripts() new spell_mage_cold_snap(); new spell_mage_combustion(); new spell_mage_combustion_proc(); + RegisterAuraScript(spell_mage_dragon_breath); new spell_mage_imp_blizzard(); new spell_mage_imp_mana_gems(); new spell_mage_empowered_fire(); diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp index 08ea6472a8d..28455808c01 100644 --- a/src/server/scripts/Spells/spell_paladin.cpp +++ b/src/server/scripts/Spells/spell_paladin.cpp @@ -1631,8 +1631,8 @@ class spell_pal_judgements_of_the_wise : public SpellScriptLoader PreventDefaultAction(); Unit* caster = eventInfo.GetActor(); - caster->CastSpell((Unit*)nullptr, SPELL_PALADIN_JUDGEMENTS_OF_THE_WISE_MANA, true, nullptr, aurEff); - caster->CastSpell((Unit*)nullptr, SPELL_REPLENISHMENT, true, nullptr, aurEff); + caster->CastSpell(nullptr, SPELL_PALADIN_JUDGEMENTS_OF_THE_WISE_MANA, true, nullptr, aurEff); + caster->CastSpell(nullptr, SPELL_REPLENISHMENT, true, nullptr, aurEff); } void Register() override @@ -2223,7 +2223,7 @@ class spell_pal_sheath_of_light : public SpellScriptLoader Unit* target = eventInfo.GetProcTarget(); SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(SPELL_PALADIN_SHEATH_OF_LIGHT_HEAL); - int32 amount = CalculatePct(static_cast<int32>(healInfo->GetHeal()), aurEff->GetAmount()); + int32 amount = CalculatePct(static_cast<int32>(healInfo->GetEffectiveHeal()), aurEff->GetAmount()); amount /= spellInfo->GetMaxTicks(); // Add remaining ticks to healing done amount += target->GetRemainingPeriodicAmount(caster->GetGUID(), SPELL_PALADIN_SHEATH_OF_LIGHT_HEAL, SPELL_AURA_PERIODIC_HEAL); diff --git a/src/server/scripts/Spells/spell_priest.cpp b/src/server/scripts/Spells/spell_priest.cpp index 4ba231b021c..74c728a6cb0 100644 --- a/src/server/scripts/Spells/spell_priest.cpp +++ b/src/server/scripts/Spells/spell_priest.cpp @@ -648,10 +648,10 @@ class spell_pri_item_t6_trinket : public SpellScriptLoader PreventDefaultAction(); Unit* caster = eventInfo.GetActor(); if (eventInfo.GetSpellTypeMask() & PROC_SPELL_TYPE_HEAL) - caster->CastSpell((Unit*)nullptr, SPELL_PRIEST_DIVINE_BLESSING, true, nullptr, aurEff); + caster->CastSpell(nullptr, SPELL_PRIEST_DIVINE_BLESSING, true, nullptr, aurEff); if (eventInfo.GetSpellTypeMask() & PROC_SPELL_TYPE_DAMAGE) - caster->CastSpell((Unit*)nullptr, SPELL_PRIEST_DIVINE_WRATH, true, nullptr, aurEff); + caster->CastSpell(nullptr, SPELL_PRIEST_DIVINE_WRATH, true, nullptr, aurEff); } void Register() override @@ -1287,7 +1287,7 @@ class spell_pri_vampiric_touch : public SpellScriptLoader void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) { PreventDefaultAction(); - eventInfo.GetActor()->CastSpell((Unit*)nullptr, SPELL_REPLENISHMENT, true, nullptr, aurEff); + eventInfo.GetActor()->CastSpell(nullptr, SPELL_REPLENISHMENT, true, nullptr, aurEff); } void Register() override diff --git a/src/server/scripts/Spells/spell_quest.cpp b/src/server/scripts/Spells/spell_quest.cpp index e3ef1faee6f..7cc32340665 100644 --- a/src/server/scripts/Spells/spell_quest.cpp +++ b/src/server/scripts/Spells/spell_quest.cpp @@ -2149,7 +2149,7 @@ class spell_q12641_death_comes_from_on_high : public SpellScriptLoader return; } - GetCaster()->CastSpell((Unit*)nullptr, spellId, true); + GetCaster()->CastSpell(nullptr, spellId, true); } void Register() override diff --git a/src/server/scripts/Spells/spell_rogue.cpp b/src/server/scripts/Spells/spell_rogue.cpp index 750b5073a7c..0476c4c09df 100644 --- a/src/server/scripts/Spells/spell_rogue.cpp +++ b/src/server/scripts/Spells/spell_rogue.cpp @@ -1022,7 +1022,7 @@ public: return; if (Player* player = caster->ToPlayer()) - player->CastSpell((Unit*)nullptr, SPELL_ROGUE_HONOR_AMONG_THIEVES_2, true); + player->CastSpell(nullptr, SPELL_ROGUE_HONOR_AMONG_THIEVES_2, true); } void Register() override @@ -1060,7 +1060,7 @@ class spell_rog_turn_the_tables : public SpellScriptLoader if (!caster) return; - caster->CastSpell((Unit*)nullptr, GetSpellInfo()->Effects[EFFECT_0].TriggerSpell, true, nullptr, aurEff); + caster->CastSpell(nullptr, GetSpellInfo()->Effects[EFFECT_0].TriggerSpell, true, nullptr, aurEff); } void Register() override diff --git a/src/server/scripts/Spells/spell_shaman.cpp b/src/server/scripts/Spells/spell_shaman.cpp index 72208d73653..ecde34a4b8e 100644 --- a/src/server/scripts/Spells/spell_shaman.cpp +++ b/src/server/scripts/Spells/spell_shaman.cpp @@ -455,7 +455,7 @@ class spell_sha_earthbind_totem : public SpellScriptLoader if (Player* owner = GetCaster()->GetCharmerOrOwnerPlayerOrPlayerItself()) if (AuraEffect* aur = owner->GetDummyAuraEffect(SPELLFAMILY_SHAMAN, 2289, 0)) if (roll_chance_i(aur->GetBaseAmount())) - GetTarget()->CastSpell((Unit*)nullptr, SPELL_SHAMAN_TOTEM_EARTHEN_POWER, true); + GetTarget()->CastSpell(nullptr, SPELL_SHAMAN_TOTEM_EARTHEN_POWER, true); } void Apply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) @@ -1075,7 +1075,7 @@ class spell_sha_imp_water_shield : public SpellScriptLoader return; uint32 spellId = waterShield->GetSpellInfo()->Effects[waterShield->GetEffIndex()].TriggerSpell; - caster->CastSpell((Unit*)nullptr, spellId, true, nullptr, aurEff); + caster->CastSpell(nullptr, spellId, true, nullptr, aurEff); } void Register() override @@ -1308,7 +1308,7 @@ class spell_sha_item_t6_trinket : public SpellScriptLoader return; if (roll_chance_i(chance)) - eventInfo.GetActor()->CastSpell((Unit*)nullptr, spellId, true, nullptr, aurEff); + eventInfo.GetActor()->CastSpell(nullptr, spellId, true, nullptr, aurEff); } void Register() override @@ -1474,7 +1474,7 @@ class spell_sha_maelstrom_weapon : public SpellScriptLoader if (!aurEff || !roll_chance_i(aurEff->GetAmount())) return; - caster->CastSpell((Unit*)nullptr, SPELL_SHAMAN_MAELSTROM_POWER, true, nullptr, aurEff); + caster->CastSpell(nullptr, SPELL_SHAMAN_MAELSTROM_POWER, true, nullptr, aurEff); } void Register() override diff --git a/src/server/scripts/Spells/spell_warlock.cpp b/src/server/scripts/Spells/spell_warlock.cpp index 4ff38244435..3ee5f8f4e7c 100644 --- a/src/server/scripts/Spells/spell_warlock.cpp +++ b/src/server/scripts/Spells/spell_warlock.cpp @@ -1334,11 +1334,11 @@ class spell_warl_soul_leech : public SpellScriptLoader uint32 selfSpellId = casterMana[impSoulLeechRank - 1]; uint32 petSpellId = petMana[impSoulLeechRank - 1]; - caster->CastSpell((Unit*)nullptr, selfSpellId, true, nullptr, aurEff); - caster->CastSpell((Unit*)nullptr, petSpellId, true, nullptr, aurEff); + caster->CastSpell(nullptr, selfSpellId, true, nullptr, aurEff); + caster->CastSpell(nullptr, petSpellId, true, nullptr, aurEff); if (roll_chance_i(impSoulLeech->GetAmount())) - caster->CastSpell((Unit*)nullptr, SPELL_REPLENISHMENT, true, nullptr, aurEff); + caster->CastSpell(nullptr, SPELL_REPLENISHMENT, true, nullptr, aurEff); } void Register() override diff --git a/src/server/scripts/Spells/spell_warrior.cpp b/src/server/scripts/Spells/spell_warrior.cpp index 4c859f5c8bc..3d6791a0391 100644 --- a/src/server/scripts/Spells/spell_warrior.cpp +++ b/src/server/scripts/Spells/spell_warrior.cpp @@ -444,13 +444,13 @@ class spell_warr_extra_proc : public SpellScriptLoader if (!roll_chance_i(bonusAurEff->GetAmount())) return; - target->CastSpell((Unit*)nullptr, SPELL_WARRIOR_EXTRA_CHARGE, true, nullptr, aurEff); + target->CastSpell(nullptr, SPELL_WARRIOR_EXTRA_CHARGE, true, nullptr, aurEff); SpellInfo const* auraInfo = aurEff->GetSpellInfo(); if (auraInfo->IsRankOf(sSpellMgr->AssertSpellInfo(SPELL_WARRIOR_BLOODSURGE_R1))) - target->CastSpell((Unit*)nullptr, SPELL_WARRIOR_SLAM_GCD_REDUCED, true, nullptr, aurEff); + target->CastSpell(nullptr, SPELL_WARRIOR_SLAM_GCD_REDUCED, true, nullptr, aurEff); else if (auraInfo->IsRankOf(sSpellMgr->AssertSpellInfo(SPELL_WARRIOR_SUDDEN_DEATH_R1))) - target->CastSpell((Unit*)nullptr, SPELL_WARRIOR_EXECUTE_GCD_REDUCED, true, nullptr, aurEff); + target->CastSpell(nullptr, SPELL_WARRIOR_EXECUTE_GCD_REDUCED, true, nullptr, aurEff); } void Register() override diff --git a/src/server/scripts/World/action_ip_logger.cpp b/src/server/scripts/World/action_ip_logger.cpp index 9dc3fba9896..9e894a52104 100644 --- a/src/server/scripts/World/action_ip_logger.cpp +++ b/src/server/scripts/World/action_ip_logger.cpp @@ -144,7 +144,7 @@ class AccountActionIpLogger : public AccountScript stmt->setUInt32(1, characterGuid); stmt->setUInt8(2, aType); stmt->setUInt32(3, playerGuid); - stmt->setString(4, systemNote.c_str()); + stmt->setString(4, systemNote); LoginDatabase.Execute(stmt); } else // ... but for failed login, we query last_attempt_ip from account table. Which we do with an unique query @@ -155,7 +155,7 @@ class AccountActionIpLogger : public AccountScript stmt->setUInt32(1, characterGuid); stmt->setUInt8(2, aType); stmt->setUInt32(3, playerGuid); - stmt->setString(4, systemNote.c_str()); + stmt->setString(4, systemNote); LoginDatabase.Execute(stmt); } return; @@ -236,8 +236,8 @@ class CharacterActionIpLogger : public PlayerScript stmt->setUInt32(0, playerGuid); stmt->setUInt32(1, characterGuid); stmt->setUInt8(2, aType); - stmt->setString(3, currentIp.c_str()); // We query the ip here. - stmt->setString(4, systemNote.c_str()); + stmt->setString(3, currentIp); // We query the ip here. + stmt->setString(4, systemNote); // Seeing as the time differences should be minimal, we do not get unixtime and the timestamp right now; // Rather, we let it be added with the SQL query. @@ -297,7 +297,7 @@ public: stmt2->setUInt32(1, characterGuid); stmt2->setUInt8(2, aType); stmt2->setUInt32(3, playerGuid); - stmt2->setString(4, systemNote.c_str()); + stmt2->setString(4, systemNote); // Seeing as the time differences should be minimal, we do not get unixtime and the timestamp right now; // Rather, we let it be added with the SQL query. diff --git a/src/server/scripts/World/areatrigger_scripts.cpp b/src/server/scripts/World/areatrigger_scripts.cpp index a7d730f185a..0e603e515e1 100644 --- a/src/server/scripts/World/areatrigger_scripts.cpp +++ b/src/server/scripts/World/areatrigger_scripts.cpp @@ -291,6 +291,38 @@ class AreaTrigger_at_nats_landing : public AreaTriggerScript }; /*###### +## at_sentry_point +######*/ + +enum SentryPoint +{ + SPELL_TELEPORT_VISUAL = 799, // TODO Find the correct spell + QUEST_MISSING_DIPLO_PT14 = 1265, + NPC_TERVOSH = 4967 +}; + +class AreaTrigger_at_sentry_point : public AreaTriggerScript +{ +public: + AreaTrigger_at_sentry_point() : AreaTriggerScript("at_sentry_point") { } + + bool OnTrigger(Player* player, AreaTriggerEntry const* /*trigger*/) + { + QuestStatus quest_status = player->GetQuestStatus(QUEST_MISSING_DIPLO_PT14); + if (!player->IsAlive() || quest_status == QUEST_STATUS_NONE || quest_status == QUEST_STATUS_REWARDED) + return false; + + if (!player->FindNearestCreature(NPC_TERVOSH, 100.0f)) + { + if (Creature* tervosh = player->SummonCreature(NPC_TERVOSH, -3476.51f, -4105.94f, 17.1f, 5.3816f, TEMPSUMMON_TIMED_DESPAWN, 60000)) + tervosh->CastSpell(tervosh, SPELL_TELEPORT_VISUAL, true); + } + + return true; + } +}; + +/*###### ## at_brewfest ######*/ @@ -488,6 +520,7 @@ void AddSC_areatrigger_scripts() new AreaTrigger_at_last_rites(); new AreaTrigger_at_sholazar_waygate(); new AreaTrigger_at_nats_landing(); + new AreaTrigger_at_sentry_point(); new AreaTrigger_at_brewfest(); new AreaTrigger_at_area_52_entrance(); new AreaTrigger_at_frostgrips_hollow(); diff --git a/src/server/scripts/World/boss_emerald_dragons.cpp b/src/server/scripts/World/boss_emerald_dragons.cpp index f510b5c6839..96daefc124c 100644 --- a/src/server/scripts/World/boss_emerald_dragons.cpp +++ b/src/server/scripts/World/boss_emerald_dragons.cpp @@ -398,7 +398,7 @@ class boss_lethon : public CreatureScript switch (eventId) { case EVENT_SHADOW_BOLT_WHIRL: - me->CastSpell((Unit*)nullptr, SPELL_SHADOW_BOLT_WHIRL, false); + me->CastSpell(nullptr, SPELL_SHADOW_BOLT_WHIRL, false); events.ScheduleEvent(EVENT_SHADOW_BOLT_WHIRL, urand(15000, 30000)); break; default: @@ -438,7 +438,7 @@ class npc_spirit_shade : public CreatureScript { if (moveType == FOLLOW_MOTION_TYPE && data == _summonerGuid.GetCounter()) { - me->CastSpell((Unit*)nullptr, SPELL_DARK_OFFERING, false); + me->CastSpell(nullptr, SPELL_DARK_OFFERING, false); me->DespawnOrUnsummon(1000); } } diff --git a/src/server/scripts/World/go_scripts.cpp b/src/server/scripts/World/go_scripts.cpp index d9aa9358ee7..91b7bf30ad7 100644 --- a/src/server/scripts/World/go_scripts.cpp +++ b/src/server/scripts/World/go_scripts.cpp @@ -37,7 +37,6 @@ go_soulwell go_bashir_crystalforge go_soulwell go_dragonflayer_cage -go_tadpole_cage go_amberpine_outhouse go_hive_pod go_veil_skith_cage @@ -1232,49 +1231,6 @@ public: }; /*###### -## Quest 11560: Oh Noes, the Tadpoles! -## go_tadpole_cage -######*/ - -enum Tadpoles -{ - QUEST_OH_NOES_THE_TADPOLES = 11560, - NPC_WINTERFIN_TADPOLE = 25201 -}; - -class go_tadpole_cage : public GameObjectScript -{ -public: - go_tadpole_cage() : GameObjectScript("go_tadpole_cage") { } - - struct go_tadpole_cageAI : public GameObjectAI - { - go_tadpole_cageAI(GameObject* go) : GameObjectAI(go) { } - - bool GossipHello(Player* player) override - { - me->UseDoorOrButton(); - if (player->GetQuestStatus(QUEST_OH_NOES_THE_TADPOLES) == QUEST_STATUS_INCOMPLETE) - { - Creature* pTadpole = me->FindNearestCreature(NPC_WINTERFIN_TADPOLE, 1.0f); - if (pTadpole) - { - pTadpole->DisappearAndDie(); - player->KilledMonsterCredit(NPC_WINTERFIN_TADPOLE); - //FIX: Summon minion tadpole - } - } - return true; - } - }; - - GameObjectAI* GetAI(GameObject* go) const override - { - return new go_tadpole_cageAI(go); - } -}; - -/*###### ## go_amberpine_outhouse ######*/ @@ -1528,10 +1484,18 @@ public: enum MidsummerPoleRibbon { - SPELL_POLE_DANCE = 29726, - SPELL_BLUE_FIRE_RING = 46842, - NPC_POLE_RIBBON_BUNNY = 17066, - ACTION_COSMETIC_FIRES = 0 + SPELL_TEST_RIBBON_POLE_1 = 29705, + SPELL_TEST_RIBBON_POLE_2 = 29726, + SPELL_TEST_RIBBON_POLE_3 = 29727, + NPC_POLE_RIBBON_BUNNY = 17066, + ACTION_COSMETIC_FIRES = 0 +}; + +uint32 const RibbonPoleSpells[3] = +{ + SPELL_TEST_RIBBON_POLE_1, + SPELL_TEST_RIBBON_POLE_2, + SPELL_TEST_RIBBON_POLE_3 }; class go_midsummer_ribbon_pole : public GameObjectScript @@ -1548,7 +1512,7 @@ public: if (Creature* creature = me->FindNearestCreature(NPC_POLE_RIBBON_BUNNY, 10.0f)) { creature->GetAI()->DoAction(ACTION_COSMETIC_FIRES); - player->CastSpell(creature, SPELL_POLE_DANCE, true); + player->CastSpell(player, RibbonPoleSpells[urand(0, 2)], true); } return true; } @@ -1679,43 +1643,99 @@ public: case EVENT_BM_START_MUSIC: if (!IsHolidayActive(HOLIDAY_BREWFEST)) // Check if Brewfest is active break; - // Check if gob is correct area, play music, set time of music - if (me->GetAreaId() == SILVERMOON || me->GetAreaId() == UNDERCITY || me->GetAreaId() == ORGRIMMAR_1 || me->GetAreaId() == ORGRIMMAR_2 || me->GetAreaId() == THUNDERBLUFF || me->GetAreaId() == SHATTRATH) - { - if (rnd == 0) - { - me->PlayDirectMusic(EVENT_BREWFESTGOBLIN01); - musicTime = EVENT_BREWFESTGOBLIN01_TIME; - } - else if (rnd == 1) - { - me->PlayDirectMusic(EVENT_BREWFESTGOBLIN02); - musicTime = EVENT_BREWFESTGOBLIN02_TIME; - } - else - { - me->PlayDirectMusic(EVENT_BREWFESTGOBLIN03); - musicTime = EVENT_BREWFESTGOBLIN03_TIME; - } - } - if (me->GetAreaId() == IRONFORGE_1 || me->GetAreaId() == IRONFORGE_2 || me->GetAreaId() == STORMWIND || me->GetAreaId() == EXODAR || me->GetAreaId() == DARNASSUS || me->GetAreaId() == SHATTRATH) + + switch (me->GetAreaId()) { - if (rnd == 0) - { - me->PlayDirectMusic(EVENT_BREWFESTDWARF01); - musicTime = EVENT_BREWFESTDWARF01_TIME; - } - else if (rnd == 1) - { - me->PlayDirectMusic(EVENT_BREWFESTDWARF02); - musicTime = EVENT_BREWFESTDWARF02_TIME; - } - else - { - me->PlayDirectMusic(EVENT_BREWFESTDWARF03); - musicTime = EVENT_BREWFESTDWARF03_TIME; - } + // Horde + case SILVERMOON: + case UNDERCITY: + case ORGRIMMAR_1: + case ORGRIMMAR_2: + case THUNDERBLUFF: + if (rnd == 0) + { + me->PlayDirectMusic(EVENT_BREWFESTGOBLIN01); + musicTime = EVENT_BREWFESTGOBLIN01_TIME; + } + else if (rnd == 1) + { + me->PlayDirectMusic(EVENT_BREWFESTGOBLIN02); + musicTime = EVENT_BREWFESTGOBLIN02_TIME; + } + else + { + me->PlayDirectMusic(EVENT_BREWFESTGOBLIN03); + musicTime = EVENT_BREWFESTGOBLIN03_TIME; + } + break; + // Alliance + case IRONFORGE_1: + case IRONFORGE_2: + case STORMWIND: + case EXODAR: + case DARNASSUS: + if (rnd == 0) + { + me->PlayDirectMusic(EVENT_BREWFESTDWARF01); + musicTime = EVENT_BREWFESTDWARF01_TIME; + } + else if (rnd == 1) + { + me->PlayDirectMusic(EVENT_BREWFESTDWARF02); + musicTime = EVENT_BREWFESTDWARF02_TIME; + } + else + { + me->PlayDirectMusic(EVENT_BREWFESTDWARF03); + musicTime = EVENT_BREWFESTDWARF03_TIME; + } + break; + // Neurtal + case SHATTRATH: + std::vector<Player*> playersNearby; + me->GetPlayerListInGrid(playersNearby, me->GetVisibilityRange()); + for (Player* player : playersNearby) + { + if (player->GetTeamId() == TEAM_HORDE) + { + if (rnd == 0) + { + me->PlayDirectMusic(EVENT_BREWFESTGOBLIN01); + musicTime = EVENT_BREWFESTGOBLIN01_TIME; + } + else if (rnd == 1) + { + me->PlayDirectMusic(EVENT_BREWFESTGOBLIN02); + musicTime = EVENT_BREWFESTGOBLIN02_TIME; + } + else + { + me->PlayDirectMusic(EVENT_BREWFESTGOBLIN03); + musicTime = EVENT_BREWFESTGOBLIN03_TIME; + } + } + else + { + if (rnd == 0) + { + me->PlayDirectMusic(EVENT_BREWFESTDWARF01); + musicTime = EVENT_BREWFESTDWARF01_TIME; + } + else if (rnd == 1) + { + me->PlayDirectMusic(EVENT_BREWFESTDWARF02); + musicTime = EVENT_BREWFESTDWARF02_TIME; + } + else + { + me->PlayDirectMusic(EVENT_BREWFESTDWARF03); + musicTime = EVENT_BREWFESTDWARF03_TIME; + } + } + } + break; } + _events.ScheduleEvent(EVENT_BM_START_MUSIC, 5000); // Every 5 second's SMSG_PLAY_MUSIC packet (PlayDirectMusic) is pushed to the client break; default: @@ -2045,7 +2065,6 @@ void AddSC_go_scripts() new go_table_theka(); new go_inconspicuous_landmark(); new go_soulwell(); - new go_tadpole_cage(); new go_dragonflayer_cage(); new go_amberpine_outhouse(); new go_hive_pod(); diff --git a/src/server/scripts/World/item_scripts.cpp b/src/server/scripts/World/item_scripts.cpp index e5b3735a22e..ac231434c83 100644 --- a/src/server/scripts/World/item_scripts.cpp +++ b/src/server/scripts/World/item_scripts.cpp @@ -363,33 +363,6 @@ public: } }; -enum TheEmissary -{ - QUEST_THE_EMISSARY = 11626, - NPC_LEVIROTH = 26452 -}; - -class item_trident_of_nazjan : public ItemScript -{ -public: - item_trident_of_nazjan() : ItemScript("item_Trident_of_Nazjan") { } - - bool OnUse(Player* player, Item* item, SpellCastTargets const& /*targets*/) override - { - if (player->GetQuestStatus(QUEST_THE_EMISSARY) == QUEST_STATUS_INCOMPLETE) - { - if (Creature* pLeviroth = player->FindNearestCreature(NPC_LEVIROTH, 10.0f)) // spell range - { - pLeviroth->AI()->AttackStart(player); - return false; - } else - player->SendEquipError(EQUIP_ERR_OUT_OF_RANGE, item, nullptr); - } else - player->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW, item, nullptr); - return true; - } -}; - enum CapturedFrog { QUEST_THE_PERFECT_SPIES = 25444, @@ -451,7 +424,6 @@ void AddSC_item_scripts() new item_pile_fake_furs(); new item_petrov_cluster_bombs(); new item_dehta_trap_smasher(); - new item_trident_of_nazjan(); new item_captured_frog(); new item_generic_limit_chance_above_60(); } diff --git a/src/server/scripts/World/npc_innkeeper.cpp b/src/server/scripts/World/npc_innkeeper.cpp index 7db733c7f78..dd59d2c0aa8 100644 --- a/src/server/scripts/World/npc_innkeeper.cpp +++ b/src/server/scripts/World/npc_innkeeper.cpp @@ -42,7 +42,14 @@ enum Spells #define LOCALE_TRICK_OR_TREAT_6 "¡Truco o trato!" #define LOCALE_INNKEEPER_0 "Make this inn my home." +#define LOCALE_INNKEEPER_2 "Faites de cette auberge votre foyer." #define LOCALE_INNKEEPER_3 "Ich möchte dieses Gasthaus zu meinem Heimatort machen." +#define LOCALE_INNKEEPER_6 "Fija tu hogar en esta taberna." + +#define LOCALE_VENDOR_0 "I want to browse your goods." +#define LOCALE_VENDOR_2 "Je voudrais regarder vos articles." +#define LOCALE_VENDOR_3 "Ich sehe mich nur mal um." +#define LOCALE_VENDOR_6 "Quiero ver tus mercancías." class npc_innkeeper : public CreatureScript { @@ -72,14 +79,26 @@ public: player->PrepareQuestMenu(me->GetGUID()); if (me->IsVendor()) - AddGossipItemFor(player, GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); + { + char const* localizedEntry; + switch (player->GetSession()->GetSessionDbcLocale()) + { + case LOCALE_frFR: localizedEntry = LOCALE_VENDOR_2; break; + case LOCALE_deDE: localizedEntry = LOCALE_VENDOR_3; break; + case LOCALE_esES: localizedEntry = LOCALE_VENDOR_6; break; + case LOCALE_enUS: default: localizedEntry = LOCALE_VENDOR_0; + } + AddGossipItemFor(player, GOSSIP_ICON_VENDOR, localizedEntry, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); + } if (me->IsInnkeeper()) { char const* localizedEntry; switch (player->GetSession()->GetSessionDbcLocale()) { + case LOCALE_frFR: localizedEntry = LOCALE_INNKEEPER_2; break; case LOCALE_deDE: localizedEntry = LOCALE_INNKEEPER_3; break; + case LOCALE_esES: localizedEntry = LOCALE_INNKEEPER_6; break; case LOCALE_enUS: default: localizedEntry = LOCALE_INNKEEPER_0; } AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, localizedEntry, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INN); diff --git a/src/server/scripts/World/npc_professions.cpp b/src/server/scripts/World/npc_professions.cpp index 9f1df957784..b68722b7ff8 100644 --- a/src/server/scripts/World/npc_professions.cpp +++ b/src/server/scripts/World/npc_professions.cpp @@ -64,15 +64,6 @@ A few notes for future developement: # gossip item and box texts ###*/ -#define GOSSIP_LEARN_POTION "Please teach me how to become a Master of Potions, Lauranna" -#define GOSSIP_UNLEARN_POTION "I wish to unlearn Potion Mastery" -#define GOSSIP_LEARN_TRANSMUTE "Please teach me how to become a Master of Transmutations, Zarevhi" -#define GOSSIP_UNLEARN_TRANSMUTE "I wish to unlearn Transmutation Mastery" -#define GOSSIP_LEARN_ELIXIR "Please teach me how to become a Master of Elixirs, Lorokeem" -#define GOSSIP_UNLEARN_ELIXIR "I wish to unlearn Elixir Mastery" - -#define BOX_UNLEARN_ALCHEMY_SPEC "Do you really want to unlearn your alchemy specialty and lose all associated recipes? \n Cost: " - #define GOSSIP_WEAPON_LEARN "Please teach me how to become a Weaponsmith" #define GOSSIP_WEAPON_UNLEARN "I wish to unlearn the art of Weaponsmithing" #define GOSSIP_ARMOR_LEARN "Please teach me how to become a Armorsmith" @@ -168,19 +159,7 @@ enum ProfessionSpells S_UNLEARN_SPELLFIRE = 41299, S_UNLEARN_MOONCLOTH = 41558, - S_UNLEARN_SHADOWEAVE = 41559, - - S_TRANSMUTE = 28672, - S_ELIXIR = 28677, - S_POTION = 28675, - - S_LEARN_TRANSMUTE = 28674, - S_LEARN_ELIXIR = 28678, - S_LEARN_POTION = 28676, - - S_UNLEARN_TRANSMUTE = 41565, - S_UNLEARN_ELIXIR = 41564, - S_UNLEARN_POTION = 41563, + S_UNLEARN_SHADOWEAVE = 41559 }; /*### @@ -188,11 +167,6 @@ enum ProfessionSpells ###*/ enum SpecializationTrainers { - /* Alchemy */ - N_TRAINER_TRANSMUTE = 22427, // Zarevhi - N_TRAINER_ELIXIR = 19052, // Lorokeem - N_TRAINER_POTION = 17909, // Lauranna Thar'well - /* Blacksmithing */ N_TRAINER_SMITHOMNI1 = 11145, // Myolor Sunderfury N_TRAINER_SMITHOMNI2 = 11176, // Krathok Moltenfist @@ -219,26 +193,15 @@ enum SpecializationTrainers }; /*### -# specialization quests -###*/ -enum SpecializationQuests -{ - /* Alchemy */ - Q_MASTER_TRANSMUTE = 10899, - Q_MASTER_ELIXIR = 10902, - Q_MASTER_POTION = 10897, -}; - -/*### # formulas to calculate unlearning cost ###*/ -int32 DoLearnCost(Player* /*player*/) //tailor, alchemy +int32 DoLearnCost(Player* /*player*/) //tailor { return 200000; } -int32 DoHighUnlearnCost(Player* /*player*/) //tailor, alchemy +int32 DoHighUnlearnCost(Player* /*player*/) //tailor { return 1500000; } @@ -441,183 +404,6 @@ void ProcessUnlearnAction(Player* player, Creature* creature, uint32 spellId, ui } /*### -# start menues alchemy -###*/ - -class npc_prof_alchemy : public CreatureScript -{ -public: - npc_prof_alchemy() : CreatureScript("npc_prof_alchemy") { } - - struct npc_prof_alchemyAI : public ScriptedAI - { - npc_prof_alchemyAI(Creature* creature) : ScriptedAI(creature) { } - - inline bool HasAlchemySpell(Player* player) - { - return (player->HasSpell(S_TRANSMUTE) || player->HasSpell(S_ELIXIR) || player->HasSpell(S_POTION)); - } - - bool GossipHello(Player* player) override - { - if (me->IsQuestGiver()) - player->PrepareQuestMenu(me->GetGUID()); - - if (me->IsVendor()) - AddGossipItemFor(player, GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); - - if (me->IsTrainer()) - AddGossipItemFor(player, GOSSIP_ICON_TRAINER, GOSSIP_TEXT_TRAIN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRAIN); - - if (player->HasSkill(SKILL_ALCHEMY) && player->GetBaseSkillValue(SKILL_ALCHEMY) >= 350 && player->getLevel() > 67) - { - if (player->GetQuestRewardStatus(Q_MASTER_TRANSMUTE) || player->GetQuestRewardStatus(Q_MASTER_ELIXIR) || player->GetQuestRewardStatus(Q_MASTER_POTION)) - { - switch (me->GetEntry()) - { - case N_TRAINER_TRANSMUTE: //Zarevhi - if (!HasAlchemySpell(player)) - AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_LEARN_TRANSMUTE, GOSSIP_SENDER_LEARN, GOSSIP_ACTION_INFO_DEF + 1); - if (player->HasSpell(S_TRANSMUTE)) - AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_UNLEARN_TRANSMUTE, GOSSIP_SENDER_UNLEARN, GOSSIP_ACTION_INFO_DEF + 4); - break; - case N_TRAINER_ELIXIR: //Lorokeem - if (!HasAlchemySpell(player)) - AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_LEARN_ELIXIR, GOSSIP_SENDER_LEARN, GOSSIP_ACTION_INFO_DEF + 2); - if (player->HasSpell(S_ELIXIR)) - AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_UNLEARN_ELIXIR, GOSSIP_SENDER_UNLEARN, GOSSIP_ACTION_INFO_DEF + 5); - break; - case N_TRAINER_POTION: //Lauranna Thar'well - if (!HasAlchemySpell(player)) - AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_LEARN_POTION, GOSSIP_SENDER_LEARN, GOSSIP_ACTION_INFO_DEF + 3); - if (player->HasSpell(S_POTION)) - AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_UNLEARN_POTION, GOSSIP_SENDER_UNLEARN, GOSSIP_ACTION_INFO_DEF + 6); - break; - } - } - } - - SendGossipMenuFor(player, player->GetGossipTextId(me), me->GetGUID()); - return true; - } - - void SendActionMenu(Player* player, uint32 action) - { - switch (action) - { - case GOSSIP_ACTION_TRADE: - player->GetSession()->SendListInventory(me->GetGUID()); - break; - case GOSSIP_ACTION_TRAIN: - player->GetSession()->SendTrainerList(me->GetGUID()); - break; - //Learn Alchemy - case GOSSIP_ACTION_INFO_DEF + 1: - ProcessCastaction(player, me, S_TRANSMUTE, S_LEARN_TRANSMUTE, DoLearnCost(player)); - break; - case GOSSIP_ACTION_INFO_DEF + 2: - ProcessCastaction(player, me, S_ELIXIR, S_LEARN_ELIXIR, DoLearnCost(player)); - break; - case GOSSIP_ACTION_INFO_DEF + 3: - ProcessCastaction(player, me, S_POTION, S_LEARN_POTION, DoLearnCost(player)); - break; - //Unlearn Alchemy - case GOSSIP_ACTION_INFO_DEF + 4: - ProcessCastaction(player, me, 0, S_UNLEARN_TRANSMUTE, DoHighUnlearnCost(player)); - break; - case GOSSIP_ACTION_INFO_DEF + 5: - ProcessCastaction(player, me, 0, S_UNLEARN_ELIXIR, DoHighUnlearnCost(player)); - break; - case GOSSIP_ACTION_INFO_DEF + 6: - ProcessCastaction(player, me, 0, S_UNLEARN_POTION, DoHighUnlearnCost(player)); - break; - } - } - - void SendConfirmLearn(Player* player, uint32 action) - { - if (action) - { - switch (me->GetEntry()) - { - case N_TRAINER_TRANSMUTE: - AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_LEARN_TRANSMUTE, GOSSIP_SENDER_CHECK, action); - //unknown textID () - SendGossipMenuFor(player, player->GetGossipTextId(me), me->GetGUID()); - break; - case N_TRAINER_ELIXIR: - AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_LEARN_ELIXIR, GOSSIP_SENDER_CHECK, action); - //unknown textID () - SendGossipMenuFor(player, player->GetGossipTextId(me), me->GetGUID()); - break; - case N_TRAINER_POTION: - AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_LEARN_POTION, GOSSIP_SENDER_CHECK, action); - //unknown textID () - SendGossipMenuFor(player, player->GetGossipTextId(me), me->GetGUID()); - break; - } - } - } - - void SendConfirmUnlearn(Player* player, uint32 action) - { - if (action) - { - switch (me->GetEntry()) - { - case N_TRAINER_TRANSMUTE: - AddGossipItemFor(player, 0, GOSSIP_UNLEARN_TRANSMUTE, GOSSIP_SENDER_CHECK, action, BOX_UNLEARN_ALCHEMY_SPEC, DoHighUnlearnCost(player), false); - //unknown textID () - SendGossipMenuFor(player, player->GetGossipTextId(me), me->GetGUID()); - break; - case N_TRAINER_ELIXIR: - AddGossipItemFor(player, 0, GOSSIP_UNLEARN_ELIXIR, GOSSIP_SENDER_CHECK, action, BOX_UNLEARN_ALCHEMY_SPEC, DoHighUnlearnCost(player), false); - //unknown textID () - SendGossipMenuFor(player, player->GetGossipTextId(me), me->GetGUID()); - break; - case N_TRAINER_POTION: - AddGossipItemFor(player, 0, GOSSIP_UNLEARN_POTION, GOSSIP_SENDER_CHECK, action, BOX_UNLEARN_ALCHEMY_SPEC, DoHighUnlearnCost(player), false); - //unknown textID () - SendGossipMenuFor(player, player->GetGossipTextId(me), me->GetGUID()); - break; - } - } - } - - bool GossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override - { - uint32 const sender = player->PlayerTalkClass->GetGossipOptionSender(gossipListId); - uint32 const action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId); - ClearGossipMenuFor(player); - switch (sender) - { - case GOSSIP_SENDER_MAIN: - SendActionMenu(player, action); - break; - - case GOSSIP_SENDER_LEARN: - SendConfirmLearn(player, action); - break; - - case GOSSIP_SENDER_UNLEARN: - SendConfirmUnlearn(player, action); - break; - - case GOSSIP_SENDER_CHECK: - SendActionMenu(player, action); - break; - } - return true; - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_prof_alchemyAI(creature); - } -}; - -/*### # start menues blacksmith ###*/ @@ -1365,7 +1151,6 @@ public: void AddSC_npc_professions() { - new npc_prof_alchemy(); new npc_prof_blacksmith(); new npc_engineering_tele_trinket(); new go_soothsaying_for_dummies(); diff --git a/src/server/scripts/World/npcs_special.cpp b/src/server/scripts/World/npcs_special.cpp index 03631c5b808..0e19b5f7bb4 100644 --- a/src/server/scripts/World/npcs_special.cpp +++ b/src/server/scripts/World/npcs_special.cpp @@ -457,8 +457,7 @@ public: enum TorchTossingTarget { - NPC_TORCH_TOSSING_TARGET_BUNNY = 25535, - SPELL_TARGET_INDICATOR = 45723 + SPELL_TORCH_TARGET_PICKER = 45907 }; class npc_torch_tossing_target_bunny_controller : public CreatureScript @@ -468,42 +467,28 @@ public: struct npc_torch_tossing_target_bunny_controllerAI : public ScriptedAI { - npc_torch_tossing_target_bunny_controllerAI(Creature* creature) : ScriptedAI(creature) - { - _targetTimer = 3000; - } + npc_torch_tossing_target_bunny_controllerAI(Creature* creature) : ScriptedAI(creature) { } - ObjectGuid DoSearchForTargets(ObjectGuid lastTargetGUID) + void Reset() override { - std::list<Creature*> targets; - me->GetCreatureListWithEntryInGrid(targets, NPC_TORCH_TOSSING_TARGET_BUNNY, 60.0f); - targets.remove_if([lastTargetGUID](Creature* creature) { return creature->GetGUID() == lastTargetGUID; }); - - if (!targets.empty()) + _scheduler.Schedule(Seconds(2), [this](TaskContext context) { - _lastTargetGUID = Trinity::Containers::SelectRandomContainerElement(targets)->GetGUID(); - - return _lastTargetGUID; - } - return ObjectGuid::Empty; + me->CastCustomSpell(SPELL_TORCH_TARGET_PICKER, SPELLVALUE_MAX_TARGETS, 1); + _scheduler.Schedule(Seconds(3), [this](TaskContext /*context*/) + { + me->CastCustomSpell(SPELL_TORCH_TARGET_PICKER, SPELLVALUE_MAX_TARGETS, 1); + }); + context.Repeat(Seconds(5)); + }); } void UpdateAI(uint32 diff) override { - if (_targetTimer < diff) - { - if (Unit* target = ObjectAccessor::GetUnit(*me, DoSearchForTargets(_lastTargetGUID))) - target->CastSpell(target, SPELL_TARGET_INDICATOR, true); - - _targetTimer = 3000; - } - else - _targetTimer -= diff; + _scheduler.Update(diff); } private: - uint32 _targetTimer; - ObjectGuid _lastTargetGUID; + TaskScheduler _scheduler; }; CreatureAI* GetAI(Creature* creature) const override @@ -1040,9 +1025,9 @@ class npc_garments_of_quests : public CreatureScript public: npc_garments_of_quests() : CreatureScript("npc_garments_of_quests") { } - struct npc_garments_of_questsAI : public npc_escortAI + struct npc_garments_of_questsAI : public EscortAI { - npc_garments_of_questsAI(Creature* creature) : npc_escortAI(creature) + npc_garments_of_questsAI(Creature* creature) : EscortAI(creature) { switch (me->GetEntry()) { @@ -1130,11 +1115,6 @@ public: } } - void WaypointReached(uint32 /*waypointId*/) override - { - - } - void UpdateAI(uint32 diff) override { if (CanRun && !me->IsInCombat()) @@ -1165,7 +1145,7 @@ public: RunAwayTimer -= diff; } - npc_escortAI::UpdateAI(diff); + EscortAI::UpdateAI(diff); } }; @@ -1603,7 +1583,7 @@ class npc_tournament_mount : public CreatureScript if (apply) { _pennantSpellId = GetPennantSpellId(player); - player->CastSpell((Unit*)nullptr, _pennantSpellId, true); + player->CastSpell(nullptr, _pennantSpellId, true); } else player->RemoveAurasDueToSpell(_pennantSpellId); |