diff options
Diffstat (limited to 'src/server/scripts')
139 files changed, 10715 insertions, 16390 deletions
diff --git a/src/server/scripts/CMakeLists.txt b/src/server/scripts/CMakeLists.txt index c1a9435de52..4ffa9925e0f 100644 --- a/src/server/scripts/CMakeLists.txt +++ b/src/server/scripts/CMakeLists.txt @@ -37,6 +37,7 @@ if(SCRIPTS) include(Kalimdor/CMakeLists.txt) include(Outland/CMakeLists.txt) include(Northrend/CMakeLists.txt) + include(Maelstrom/CMakeLists.txt) include(Events/CMakeLists.txt) include(Pet/CMakeLists.txt) endif() @@ -88,6 +89,7 @@ include_directories( ${CMAKE_SOURCE_DIR}/src/server/game/Combat ${CMAKE_SOURCE_DIR}/src/server/game/DataStores ${CMAKE_SOURCE_DIR}/src/server/game/DungeonFinding + ${CMAKE_SOURCE_DIR}/src/server/game/Entities/AreaTrigger ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Corpse ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Creature ${CMAKE_SOURCE_DIR}/src/server/game/Entities/DynamicObject diff --git a/src/server/scripts/Commands/cs_character.cpp b/src/server/scripts/Commands/cs_character.cpp index 7722c330e5f..ffdc9deeae3 100644 --- a/src/server/scripts/Commands/cs_character.cpp +++ b/src/server/scripts/Commands/cs_character.cpp @@ -277,7 +277,7 @@ public: if (titleInfo && target->HasTitle(titleInfo)) { - std::string name = target->getGender() == GENDER_MALE ? titleInfo->nameMale[loc] : titleInfo->nameFemale[loc]; + std::string name = target->getGender() == GENDER_MALE ? titleInfo->nameMale : titleInfo->nameFemale; if (name.empty()) continue; @@ -566,7 +566,7 @@ public: { FactionState const& faction = itr->second; FactionEntry const* factionEntry = sFactionStore.LookupEntry(faction.ID); - char const* factionName = factionEntry ? factionEntry->name[loc] : "#Not found#"; + char const* factionName = factionEntry ? factionEntry->name : "#Not found#"; ReputationRank rank = target->GetReputationMgr().GetRank(factionEntry); std::string rankName = handler->GetTrinityString(ReputationRankStrIndex[rank]); std::ostringstream ss; diff --git a/src/server/scripts/Commands/cs_cheat.cpp b/src/server/scripts/Commands/cs_cheat.cpp index b61cf2c54fe..1fe7c6adf5b 100644 --- a/src/server/scripts/Commands/cs_cheat.cpp +++ b/src/server/scripts/Commands/cs_cheat.cpp @@ -185,10 +185,11 @@ public: std::string argstr = (char*)args; + Player* target = handler->GetSession()->GetPlayer(); if (!*args) { - argstr = (handler->GetSession()->GetPlayer()->GetCommandStatus(CHEAT_WATERWALK)) ? "off" : "on"; - if (handler->GetSession()->GetPlayer()->GetCommandStatus(CHEAT_WATERWALK)) + argstr = (target->GetCommandStatus(CHEAT_WATERWALK)) ? "off" : "on"; + if (target->GetCommandStatus(CHEAT_WATERWALK)) argstr = "off"; else argstr = "on"; @@ -196,15 +197,15 @@ public: if (argstr == "off") { - handler->GetSession()->GetPlayer()->SetCommandStatusOff(CHEAT_WATERWALK); - handler->GetSession()->GetPlayer()->SetMovement(MOVE_LAND_WALK); // OFF + target->SetCommandStatusOff(CHEAT_WATERWALK); + target->SetWaterWalking(false); handler->SendSysMessage("Waterwalking is OFF. You can't walk on water."); return true; } else if (argstr == "on") { - handler->GetSession()->GetPlayer()->SetCommandStatusOn(CHEAT_WATERWALK); - handler->GetSession()->GetPlayer()->SetMovement(MOVE_WATER_WALK); // ON + target->SetCommandStatusOn(CHEAT_WATERWALK); + target->SetWaterWalking(true); handler->SendSysMessage("Waterwalking is ON. You can walk on water."); return true; } diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp index f18f9b4499c..d0a005f356e 100644 --- a/src/server/scripts/Commands/cs_debug.cpp +++ b/src/server/scripts/Commands/cs_debug.cpp @@ -93,6 +93,7 @@ public: { "los", rbac::RBAC_PERM_COMMAND_DEBUG_LOS, false, &HandleDebugLoSCommand, "", NULL }, { "moveflags", rbac::RBAC_PERM_COMMAND_DEBUG_MOVEFLAGS, false, &HandleDebugMoveflagsCommand, "", NULL }, { "transport", rbac::RBAC_PERM_COMMAND_DEBUG_TRANSPORT, false, &HandleDebugTransportCommand, "", NULL }, + { "phase", rbac::RBAC_PERM_COMMAND_DEBUG_PHASE, false, &HandleDebugPhaseCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; static ChatCommand commandTable[] = @@ -239,7 +240,7 @@ public: return false; SellResult msg = SellResult(atoi(args)); - handler->GetSession()->GetPlayer()->SendSellError(msg, 0, 0, 0); + handler->GetSession()->GetPlayer()->SendSellError(msg, 0, 0); return true; } @@ -313,7 +314,7 @@ public: uint32 opcode; parsedStream >> opcode; - WorldPacket data(opcode, 0); + WorldPacket data(Opcodes(opcode), 0); while (!parsedStream.eof()) { @@ -419,7 +420,7 @@ public: } TC_LOG_DEBUG("network", "Sending opcode %u", data.GetOpcode()); data.hexlike(); - player->GetSession()->SendPacket(&data); + player->GetSession()->SendPacket(&data, true); handler->PSendSysMessage(LANG_COMMAND_OPCODESENT, data.GetOpcode(), unit->GetName().c_str()); return true; } @@ -953,8 +954,21 @@ public: if (!*args) return false; - uint32 PhaseShift = atoi(args); - handler->GetSession()->SendSetPhaseShift(PhaseShift); + char* t = strtok((char*)args, " "); + char* p = strtok(NULL, " "); + + if (!t) + return false; + + std::set<uint32> terrainswap; + std::set<uint32> phaseId; + + terrainswap.insert((uint32)atoi(t)); + + if (p) + phaseId.insert((uint32)atoi(p)); + + handler->GetSession()->SendSetPhaseShift(phaseId, terrainswap); return true; } @@ -1311,35 +1325,9 @@ public: char* mask2 = strtok(NULL, " \n"); uint32 moveFlags = (uint32)atoi(mask1); + target->SetUnitMovementFlags(moveFlags); - static uint32 const FlagsWithHandlers = MOVEMENTFLAG_MASK_HAS_PLAYER_STATUS_OPCODE | - MOVEMENTFLAG_WALKING | MOVEMENTFLAG_SWIMMING | - MOVEMENTFLAG_SPLINE_ENABLED; - - bool unhandledFlag = (moveFlags ^ target->GetUnitMovementFlags()) & ~FlagsWithHandlers; - - target->SetWalk(moveFlags & MOVEMENTFLAG_WALKING); - target->SetDisableGravity(moveFlags & MOVEMENTFLAG_DISABLE_GRAVITY); - target->SetSwim(moveFlags & MOVEMENTFLAG_SWIMMING); - target->SetCanFly(moveFlags & MOVEMENTFLAG_CAN_FLY); - target->SetWaterWalking(moveFlags & MOVEMENTFLAG_WATERWALKING); - target->SetFeatherFall(moveFlags & MOVEMENTFLAG_FALLING_SLOW); - target->SetHover(moveFlags & MOVEMENTFLAG_HOVER); - - if (moveFlags & (MOVEMENTFLAG_DISABLE_GRAVITY | MOVEMENTFLAG_CAN_FLY)) - moveFlags &= ~MOVEMENTFLAG_FALLING; - - if (moveFlags & MOVEMENTFLAG_ROOT) - { - target->SetControlled(true, UNIT_STATE_ROOT); - moveFlags &= ~MOVEMENTFLAG_MASK_MOVING; - } - - if (target->HasUnitMovementFlag(MOVEMENTFLAG_SPLINE_ENABLED) && !(moveFlags & MOVEMENTFLAG_SPLINE_ENABLED)) - target->StopMoving(); - - if (unhandledFlag) - target->SetUnitMovementFlags(moveFlags); + /// @fixme: port master's HandleDebugMoveflagsCommand; flags need different handling if (mask2) { @@ -1347,8 +1335,14 @@ public: target->SetExtraUnitMovementFlags(moveFlagsExtra); } - if (mask2 || unhandledFlag) - target->SendMovementFlagUpdate(); + if (target->GetTypeId() != TYPEID_PLAYER) + target->DestroyForNearbyPlayers(); // Force new SMSG_UPDATE_OBJECT:CreateObject + else + { + WorldPacket data(SMSG_PLAYER_MOVE); + target->WriteMovementInfo(data); + target->SendMessageToSet(&data, true); + } handler->PSendSysMessage(LANG_MOVEFLAGS_SET, target->GetUnitMovementFlags(), target->GetExtraUnitMovementFlags()); } @@ -1391,6 +1385,17 @@ public: handler->PSendSysMessage("Transport %s %s", transport->GetName().c_str(), start ? "started" : "stopped"); return true; } + + static bool HandleDebugPhaseCommand(ChatHandler* handler, char const* /*args*/) + { + Unit* unit = handler->getSelectedUnit(); + Player* player = handler->GetSession()->GetPlayer(); + if (unit && unit->GetTypeId() == TYPEID_PLAYER) + player = unit->ToPlayer(); + + player->GetPhaseMgr().SendDebugReportToPlayer(handler->GetSession()->GetPlayer()); + return true; + } }; void AddSC_debug_commandscript() diff --git a/src/server/scripts/Commands/cs_gm.cpp b/src/server/scripts/Commands/cs_gm.cpp index a2c0861c113..eebb1b80002 100644 --- a/src/server/scripts/Commands/cs_gm.cpp +++ b/src/server/scripts/Commands/cs_gm.cpp @@ -101,19 +101,16 @@ public: if (!target) target = handler->GetSession()->GetPlayer(); - WorldPacket data(12); + WorldPacket data; if (strncmp(args, "on", 3) == 0) - data.SetOpcode(SMSG_MOVE_SET_CAN_FLY); + target->SetCanFly(true); else if (strncmp(args, "off", 4) == 0) - data.SetOpcode(SMSG_MOVE_UNSET_CAN_FLY); + target->SetCanFly(false); else { handler->SendSysMessage(LANG_USE_BOL); return false; } - data.append(target->GetPackGUID()); - data << uint32(0); // unknown - target->SendMessageToSet(&data, true); handler->PSendSysMessage(LANG_COMMAND_FLYMODE_STATUS, handler->GetNameLink(target).c_str(), args); return true; } diff --git a/src/server/scripts/Commands/cs_go.cpp b/src/server/scripts/Commands/cs_go.cpp index 3c1fa973cd8..f639fdbdd10 100644 --- a/src/server/scripts/Commands/cs_go.cpp +++ b/src/server/scripts/Commands/cs_go.cpp @@ -447,7 +447,7 @@ public: if (map->Instanceable()) { - handler->PSendSysMessage(LANG_INVALID_ZONE_MAP, areaEntry->ID, areaEntry->area_name[handler->GetSessionDbcLocale()], map->GetId(), map->GetMapName()); + handler->PSendSysMessage(LANG_INVALID_ZONE_MAP, areaEntry->ID, areaEntry->area_name, map->GetId(), map->GetMapName()); handler->SetSentErrorMessage(true); return false; } diff --git a/src/server/scripts/Commands/cs_gobject.cpp b/src/server/scripts/Commands/cs_gobject.cpp index ce0bee0d8c5..e556854c2ab 100644 --- a/src/server/scripts/Commands/cs_gobject.cpp +++ b/src/server/scripts/Commands/cs_gobject.cpp @@ -152,7 +152,7 @@ public: GameObject* object = new GameObject; uint32 guidLow = sObjectMgr->GenerateLowGuid(HIGHGUID_GAMEOBJECT); - if (!object->Create(guidLow, objectInfo->entry, map, player->GetPhaseMaskForSpawn(), x, y, z, o, 0.0f, 0.0f, 0.0f, 0.0f, 0, GO_STATE_READY)) + if (!object->Create(guidLow, objectInfo->entry, map, player->GetPhaseMgr().GetPhaseMaskForSpawn(), x, y, z, o, 0.0f, 0.0f, 0.0f, 0.0f, 0, GO_STATE_READY)) { delete object; return false; @@ -165,7 +165,7 @@ public: } // fill the gameobject data and save to the db - object->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), player->GetPhaseMaskForSpawn()); + object->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), player->GetPhaseMgr().GetPhaseMaskForSpawn()); // delete the old object and do a clean load from DB with a fresh new GameObject instance. // this is required to avoid weird behavior and memory leaks delete object; diff --git a/src/server/scripts/Commands/cs_guild.cpp b/src/server/scripts/Commands/cs_guild.cpp index 4627f6b022e..928e110e9a1 100644 --- a/src/server/scripts/Commands/cs_guild.cpp +++ b/src/server/scripts/Commands/cs_guild.cpp @@ -22,6 +22,7 @@ Comment: All guild related commands Category: commandscripts EndScriptData */ +#include "AchievementMgr.h" #include "Chat.h" #include "Language.h" #include "Guild.h" diff --git a/src/server/scripts/Commands/cs_learn.cpp b/src/server/scripts/Commands/cs_learn.cpp index 12721c61936..41d740de3c2 100644 --- a/src/server/scripts/Commands/cs_learn.cpp +++ b/src/server/scripts/Commands/cs_learn.cpp @@ -399,33 +399,14 @@ public: !skillInfo->canLink) // only prof with recipes have set continue; - int locale = handler->GetSessionDbcLocale(); - name = skillInfo->name[locale]; + name = skillInfo->name; if (name.empty()) continue; if (!Utf8FitTo(name, namePart)) - { - locale = 0; - for (; locale < TOTAL_LOCALES; ++locale) - { - if (locale == handler->GetSessionDbcLocale()) - continue; - - name = skillInfo->name[locale]; - if (name.empty()) - continue; - - if (Utf8FitTo(name, namePart)) - break; - } - } + continue; - if (locale < TOTAL_LOCALES) - { - targetSkillInfo = skillInfo; - break; - } + targetSkillInfo = skillInfo; } if (!targetSkillInfo) diff --git a/src/server/scripts/Commands/cs_list.cpp b/src/server/scripts/Commands/cs_list.cpp index 3c86d059ef5..d3f1e6bb092 100644 --- a/src/server/scripts/Commands/cs_list.cpp +++ b/src/server/scripts/Commands/cs_list.cpp @@ -439,7 +439,7 @@ public: AuraApplication const* aurApp = itr->second; Aura const* aura = aurApp->GetBase(); - char const* name = aura->GetSpellInfo()->SpellName[handler->GetSessionDbcLocale()]; + char const* name = aura->GetSpellInfo()->SpellName; std::ostringstream ss_name; ss_name << "|cffffffff|Hspell:" << aura->GetId() << "|h[" << name << "]|h|r"; diff --git a/src/server/scripts/Commands/cs_lookup.cpp b/src/server/scripts/Commands/cs_lookup.cpp index ee307a1d065..15d065f127e 100644 --- a/src/server/scripts/Commands/cs_lookup.cpp +++ b/src/server/scripts/Commands/cs_lookup.cpp @@ -106,48 +106,30 @@ public: AreaTableEntry const* areaEntry = sAreaStore.LookupEntry(areaflag); if (areaEntry) { - int locale = handler->GetSessionDbcLocale(); - std::string name = areaEntry->area_name[locale]; + std::string name = areaEntry->area_name; if (name.empty()) continue; if (!Utf8FitTo(name, wNamePart)) - { - locale = 0; - for (; locale < TOTAL_LOCALES; ++locale) - { - if (locale == handler->GetSessionDbcLocale()) - continue; - - name = areaEntry->area_name[locale]; - if (name.empty()) - continue; - - if (Utf8FitTo(name, wNamePart)) - break; - } - } + continue; - if (locale < TOTAL_LOCALES) + if (maxResults && count++ == maxResults) { - if (maxResults && count++ == maxResults) - { - handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults); - return true; - } + handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults); + return true; + } - // send area in "id - [name]" format - std::ostringstream ss; - if (handler->GetSession()) - ss << areaEntry->ID << " - |cffffffff|Harea:" << areaEntry->ID << "|h[" << name << ' ' << localeNames[locale]<< "]|h|r"; - else - ss << areaEntry->ID << " - " << name << ' ' << localeNames[locale]; + // send area in "id - [name]" format + std::ostringstream ss; + if (handler->GetSession()) + ss << areaEntry->ID << " - |cffffffff|Harea:" << areaEntry->ID << "|h[" << name<< "]|h|r"; + else + ss << areaEntry->ID << " - " << name; - handler->SendSysMessage(ss.str().c_str()); + handler->SendSysMessage(ss.str().c_str()); - if (!found) - found = true; - } + if (!found) + found = true; } } @@ -313,77 +295,58 @@ public: for (uint32 id = 0; id < sFactionStore.GetNumRows(); ++id) { - FactionEntry const* factionEntry = sFactionStore.LookupEntry(id); - if (factionEntry) + if (FactionEntry const* factionEntry = sFactionStore.LookupEntry(id)) { FactionState const* factionState = target ? target->GetReputationMgr().GetState(factionEntry) : NULL; - int locale = handler->GetSessionDbcLocale(); - std::string name = factionEntry->name[locale]; + std::string name = factionEntry->name; if (name.empty()) continue; if (!Utf8FitTo(name, wNamePart)) - { - locale = 0; - for (; locale < TOTAL_LOCALES; ++locale) - { - if (locale == handler->GetSessionDbcLocale()) - continue; - - name = factionEntry->name[locale]; - if (name.empty()) - continue; - - if (Utf8FitTo(name, wNamePart)) - break; - } - } + continue; - if (locale < TOTAL_LOCALES) + if (maxResults && count++ == maxResults) { - if (maxResults && count++ == maxResults) - { - handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults); - return true; - } + handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults); + return true; + } - // send faction in "id - [faction] rank reputation [visible] [at war] [own team] [unknown] [invisible] [inactive]" format - // or "id - [faction] [no reputation]" format - std::ostringstream ss; - if (handler->GetSession()) - ss << id << " - |cffffffff|Hfaction:" << id << "|h[" << name << ' ' << localeNames[locale] << "]|h|r"; - else - ss << id << " - " << name << ' ' << localeNames[locale]; + // send faction in "id - [faction] rank reputation [visible] [at war] [own team] [unknown] [invisible] [inactive]" format + // or "id - [faction] [no reputation]" format + std::ostringstream ss; + if (handler->GetSession()) + ss << id << " - |cffffffff|Hfaction:" << id << "|h[" << name << "]|h|r"; + else + ss << id << " - " << name; - if (factionState) // and then target != NULL also - { - uint32 index = target->GetReputationMgr().GetReputationRankStrIndex(factionEntry); - std::string rankName = handler->GetTrinityString(index); - - ss << ' ' << rankName << "|h|r (" << target->GetReputationMgr().GetReputation(factionEntry) << ')'; - - if (factionState->Flags & FACTION_FLAG_VISIBLE) - ss << handler->GetTrinityString(LANG_FACTION_VISIBLE); - if (factionState->Flags & FACTION_FLAG_AT_WAR) - ss << handler->GetTrinityString(LANG_FACTION_ATWAR); - if (factionState->Flags & FACTION_FLAG_PEACE_FORCED) - ss << handler->GetTrinityString(LANG_FACTION_PEACE_FORCED); - if (factionState->Flags & FACTION_FLAG_HIDDEN) - ss << handler->GetTrinityString(LANG_FACTION_HIDDEN); - if (factionState->Flags & FACTION_FLAG_INVISIBLE_FORCED) - ss << handler->GetTrinityString(LANG_FACTION_INVISIBLE_FORCED); - if (factionState->Flags & FACTION_FLAG_INACTIVE) - ss << handler->GetTrinityString(LANG_FACTION_INACTIVE); - } - else - ss << handler->GetTrinityString(LANG_FACTION_NOREPUTATION); + if (factionState) // and then target != NULL also + { + uint32 index = target->GetReputationMgr().GetReputationRankStrIndex(factionEntry); + std::string rankName = handler->GetTrinityString(index); + + ss << ' ' << rankName << "|h|r (" << target->GetReputationMgr().GetReputation(factionEntry) << ')'; + + if (factionState->Flags & FACTION_FLAG_VISIBLE) + ss << handler->GetTrinityString(LANG_FACTION_VISIBLE); + if (factionState->Flags & FACTION_FLAG_AT_WAR) + ss << handler->GetTrinityString(LANG_FACTION_ATWAR); + if (factionState->Flags & FACTION_FLAG_PEACE_FORCED) + ss << handler->GetTrinityString(LANG_FACTION_PEACE_FORCED); + if (factionState->Flags & FACTION_FLAG_HIDDEN) + ss << handler->GetTrinityString(LANG_FACTION_HIDDEN); + if (factionState->Flags & FACTION_FLAG_INVISIBLE_FORCED) + ss << handler->GetTrinityString(LANG_FACTION_INVISIBLE_FORCED); + if (factionState->Flags & FACTION_FLAG_INACTIVE) + ss << handler->GetTrinityString(LANG_FACTION_INACTIVE); + } + else + ss << handler->GetTrinityString(LANG_FACTION_NOREPUTATION); - handler->SendSysMessage(ss.str().c_str()); + handler->SendSysMessage(ss.str().c_str()); - if (!found) - found = true; - } + if (!found) + found = true; } } @@ -498,45 +461,27 @@ public: ItemSetEntry const* set = sItemSetStore.LookupEntry(id); if (set) { - int locale = handler->GetSessionDbcLocale(); - std::string name = set->name[locale]; + std::string name = set->name; if (name.empty()) continue; if (!Utf8FitTo(name, wNamePart)) - { - locale = 0; - for (; locale < TOTAL_LOCALES; ++locale) - { - if (locale == handler->GetSessionDbcLocale()) - continue; - - name = set->name[locale]; - if (name.empty()) - continue; - - if (Utf8FitTo(name, wNamePart)) - break; - } - } + continue; - if (locale < TOTAL_LOCALES) + if (maxResults && count++ == maxResults) { - if (maxResults && count++ == maxResults) - { - handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults); - return true; - } + handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults); + return true; + } - // send item set in "id - [namedlink locale]" format - if (handler->GetSession()) - handler->PSendSysMessage(LANG_ITEMSET_LIST_CHAT, id, id, name.c_str(), localeNames[locale]); - else - handler->PSendSysMessage(LANG_ITEMSET_LIST_CONSOLE, id, name.c_str(), localeNames[locale]); + // send item set in "id - [namedlink locale]" format + if (handler->GetSession()) + handler->PSendSysMessage(LANG_ITEMSET_LIST_CHAT, id, id, name.c_str(), ""); + else + handler->PSendSysMessage(LANG_ITEMSET_LIST_CONSOLE, id, name.c_str(), ""); - if (!found) - found = true; - } + if (!found) + found = true; } } if (!found) @@ -779,59 +724,41 @@ public: SkillLineEntry const* skillInfo = sSkillLineStore.LookupEntry(id); if (skillInfo) { - int locale = handler->GetSessionDbcLocale(); - std::string name = skillInfo->name[locale]; + std::string name = skillInfo->name; if (name.empty()) continue; if (!Utf8FitTo(name, wNamePart)) - { - locale = 0; - for (; locale < TOTAL_LOCALES; ++locale) - { - if (locale == handler->GetSessionDbcLocale()) - continue; - - name = skillInfo->name[locale]; - if (name.empty()) - continue; + continue; - if (Utf8FitTo(name, wNamePart)) - break; - } + if (maxResults && count++ == maxResults) + { + handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults); + return true; } - if (locale < TOTAL_LOCALES) + char valStr[50] = ""; + char const* knownStr = ""; + if (target && target->HasSkill(id)) { - if (maxResults && count++ == maxResults) - { - handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults); - return true; - } - - char valStr[50] = ""; - char const* knownStr = ""; - if (target && target->HasSkill(id)) - { - knownStr = handler->GetTrinityString(LANG_KNOWN); - uint32 curValue = target->GetPureSkillValue(id); - uint32 maxValue = target->GetPureMaxSkillValue(id); - uint32 permValue = target->GetSkillPermBonusValue(id); - uint32 tempValue = target->GetSkillTempBonusValue(id); - - char const* valFormat = handler->GetTrinityString(LANG_SKILL_VALUES); - snprintf(valStr, 50, valFormat, curValue, maxValue, permValue, tempValue); - } + knownStr = handler->GetTrinityString(LANG_KNOWN); + uint32 curValue = target->GetPureSkillValue(id); + uint32 maxValue = target->GetPureMaxSkillValue(id); + uint32 permValue = target->GetSkillPermBonusValue(id); + uint32 tempValue = target->GetSkillTempBonusValue(id); + + char const* valFormat = handler->GetTrinityString(LANG_SKILL_VALUES); + snprintf(valStr, 50, valFormat, curValue, maxValue, permValue, tempValue); + } - // send skill in "id - [namedlink locale]" format - if (handler->GetSession()) - handler->PSendSysMessage(LANG_SKILL_LIST_CHAT, id, id, name.c_str(), localeNames[locale], knownStr, valStr); - else - handler->PSendSysMessage(LANG_SKILL_LIST_CONSOLE, id, name.c_str(), localeNames[locale], knownStr, valStr); + // send skill in "id - [namedlink locale]" format + if (handler->GetSession()) + handler->PSendSysMessage(LANG_SKILL_LIST_CHAT, id, id, name.c_str(), "", knownStr, valStr); + else + handler->PSendSysMessage(LANG_SKILL_LIST_CONSOLE, id, name.c_str(), "", knownStr, valStr); - if (!found) - found = true; - } + if (!found) + found = true; } } if (!found) @@ -867,83 +794,63 @@ public: SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(id); if (spellInfo) { - int locale = handler->GetSessionDbcLocale(); - std::string name = spellInfo->SpellName[locale]; + std::string name = spellInfo->SpellName; if (name.empty()) continue; if (!Utf8FitTo(name, wNamePart)) + continue; + + if (maxResults && count++ == maxResults) { - locale = 0; - for (; locale < TOTAL_LOCALES; ++locale) - { - if (locale == handler->GetSessionDbcLocale()) - continue; + handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults); + return true; + } - name = spellInfo->SpellName[locale]; - if (name.empty()) - continue; + bool known = target && target->HasSpell(id); + bool learn = (spellInfo->Effects[0].Effect == SPELL_EFFECT_LEARN_SPELL); - if (Utf8FitTo(name, wNamePart)) - break; - } - } + SpellInfo const* learnSpellInfo = sSpellMgr->GetSpellInfo(spellInfo->Effects[0].TriggerSpell); - if (locale < TOTAL_LOCALES) - { - if (maxResults && count++ == maxResults) - { - handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults); - return true; - } + uint32 talentCost = GetTalentSpellCost(id); - bool known = target && target->HasSpell(id); - bool learn = (spellInfo->Effects[0].Effect == SPELL_EFFECT_LEARN_SPELL); + bool talent = (talentCost > 0); + bool passive = spellInfo->IsPassive(); + bool active = target && target->HasAura(id); - SpellInfo const* learnSpellInfo = sSpellMgr->GetSpellInfo(spellInfo->Effects[0].TriggerSpell); + // unit32 used to prevent interpreting uint8 as char at output + // find rank of learned spell for learning spell, or talent rank + uint32 rank = talentCost ? talentCost : learn && learnSpellInfo ? learnSpellInfo->GetRank() : spellInfo->GetRank(); - uint32 talentCost = GetTalentSpellCost(id); + // send spell in "id - [name, rank N] [talent] [passive] [learn] [known]" format + std::ostringstream ss; + if (handler->GetSession()) + ss << id << " - |cffffffff|Hspell:" << id << "|h[" << name; + else + ss << id << " - " << name; - bool talent = (talentCost > 0); - bool passive = spellInfo->IsPassive(); - bool active = target && target->HasAura(id); + // include rank in link name + if (rank) + ss << handler->GetTrinityString(LANG_SPELL_RANK) << rank; - // unit32 used to prevent interpreting uint8 as char at output - // find rank of learned spell for learning spell, or talent rank - uint32 rank = talentCost ? talentCost : learn && learnSpellInfo ? learnSpellInfo->GetRank() : spellInfo->GetRank(); + if (handler->GetSession()) + ss << "]|h|r"; - // send spell in "id - [name, rank N] [talent] [passive] [learn] [known]" format - std::ostringstream ss; - if (handler->GetSession()) - ss << id << " - |cffffffff|Hspell:" << id << "|h[" << name; - else - ss << id << " - " << name; - - // include rank in link name - if (rank) - ss << handler->GetTrinityString(LANG_SPELL_RANK) << rank; - - if (handler->GetSession()) - ss << ' ' << localeNames[locale] << "]|h|r"; - else - ss << ' ' << localeNames[locale]; - - if (talent) - ss << handler->GetTrinityString(LANG_TALENT); - if (passive) - ss << handler->GetTrinityString(LANG_PASSIVE); - if (learn) - ss << handler->GetTrinityString(LANG_LEARN); - if (known) - ss << handler->GetTrinityString(LANG_KNOWN); - if (active) - ss << handler->GetTrinityString(LANG_ACTIVE); + if (talent) + ss << handler->GetTrinityString(LANG_TALENT); + if (passive) + ss << handler->GetTrinityString(LANG_PASSIVE); + if (learn) + ss << handler->GetTrinityString(LANG_LEARN); + if (known) + ss << handler->GetTrinityString(LANG_KNOWN); + if (active) + ss << handler->GetTrinityString(LANG_ACTIVE); - handler->SendSysMessage(ss.str().c_str()); + handler->SendSysMessage(ss.str().c_str()); - if (!found) - found = true; - } + if (!found) + found = true; } } if (!found) @@ -965,7 +872,7 @@ public: if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(id)) { int locale = handler->GetSessionDbcLocale(); - std::string name = spellInfo->SpellName[locale]; + std::string name = spellInfo->SpellName; if (name.empty()) { handler->SendSysMessage(LANG_COMMAND_NOSPELLFOUND); @@ -1046,47 +953,29 @@ public: TaxiNodesEntry const* nodeEntry = sTaxiNodesStore.LookupEntry(id); if (nodeEntry) { - int locale = handler->GetSessionDbcLocale(); - std::string name = nodeEntry->name[locale]; + std::string name = nodeEntry->name; if (name.empty()) continue; if (!Utf8FitTo(name, wNamePart)) - { - locale = 0; - for (; locale < TOTAL_LOCALES; ++locale) - { - if (locale == handler->GetSessionDbcLocale()) - continue; - - name = nodeEntry->name[locale]; - if (name.empty()) - continue; - - if (Utf8FitTo(name, wNamePart)) - break; - } - } + continue; - if (locale < TOTAL_LOCALES) + if (maxResults && count++ == maxResults) { - if (maxResults && count++ == maxResults) - { - handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults); - return true; - } + handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults); + return true; + } - // send taxinode in "id - [name] (Map:m X:x Y:y Z:z)" format - if (handler->GetSession()) - handler->PSendSysMessage(LANG_TAXINODE_ENTRY_LIST_CHAT, id, id, name.c_str(), localeNames[locale], - nodeEntry->map_id, nodeEntry->x, nodeEntry->y, nodeEntry->z); - else - handler->PSendSysMessage(LANG_TAXINODE_ENTRY_LIST_CONSOLE, id, name.c_str(), localeNames[locale], - nodeEntry->map_id, nodeEntry->x, nodeEntry->y, nodeEntry->z); + // send taxinode in "id - [name] (Map:m X:x Y:y Z:z)" format + if (handler->GetSession()) + handler->PSendSysMessage(LANG_TAXINODE_ENTRY_LIST_CHAT, id, id, name.c_str(), "", + nodeEntry->map_id, nodeEntry->x, nodeEntry->y, nodeEntry->z); + else + handler->PSendSysMessage(LANG_TAXINODE_ENTRY_LIST_CONSOLE, id, name.c_str(), "", + nodeEntry->map_id, nodeEntry->x, nodeEntry->y, nodeEntry->z); - if (!found) - found = true; - } + if (!found) + found = true; } } if (!found) @@ -1183,54 +1072,36 @@ public: CharTitlesEntry const* titleInfo = sCharTitlesStore.LookupEntry(id); if (titleInfo) { - /// @todo: implement female support - int locale = handler->GetSessionDbcLocale(); - std::string name = titleInfo->nameMale[locale]; + std::string name = target->getGender() == GENDER_MALE ? titleInfo->nameMale : titleInfo->nameFemale; + if (name.empty()) continue; if (!Utf8FitTo(name, wNamePart)) - { - locale = 0; - for (; locale < TOTAL_LOCALES; ++locale) - { - if (locale == handler->GetSessionDbcLocale()) - continue; - - name = titleInfo->nameMale[locale]; - if (name.empty()) - continue; - - if (Utf8FitTo(name, wNamePart)) - break; - } - } + continue; - if (locale < TOTAL_LOCALES) + if (maxResults && counter == maxResults) { - if (maxResults && counter == maxResults) - { - handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults); - return true; - } + handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults); + return true; + } - char const* knownStr = target && target->HasTitle(titleInfo) ? handler->GetTrinityString(LANG_KNOWN) : ""; + char const* knownStr = target && target->HasTitle(titleInfo) ? handler->GetTrinityString(LANG_KNOWN) : ""; - char const* activeStr = target && target->GetUInt32Value(PLAYER_CHOSEN_TITLE) == titleInfo->bit_index - ? handler->GetTrinityString(LANG_ACTIVE) - : ""; + char const* activeStr = target && target->GetUInt32Value(PLAYER_CHOSEN_TITLE) == titleInfo->bit_index + ? handler->GetTrinityString(LANG_ACTIVE) + : ""; - char titleNameStr[80]; - snprintf(titleNameStr, 80, name.c_str(), targetName); + char titleNameStr[80]; + snprintf(titleNameStr, 80, name.c_str(), targetName); - // send title in "id (idx:idx) - [namedlink locale]" format - if (handler->GetSession()) - handler->PSendSysMessage(LANG_TITLE_LIST_CHAT, id, titleInfo->bit_index, id, titleNameStr, localeNames[locale], knownStr, activeStr); - else - handler->PSendSysMessage(LANG_TITLE_LIST_CONSOLE, id, titleInfo->bit_index, titleNameStr, localeNames[locale], knownStr, activeStr); + // send title in "id (idx:idx) - [namedlink locale]" format + if (handler->GetSession()) + handler->PSendSysMessage(LANG_TITLE_LIST_CHAT, id, titleInfo->bit_index, id, titleNameStr, "", knownStr, activeStr); + else + handler->PSendSysMessage(LANG_TITLE_LIST_CONSOLE, id, titleInfo->bit_index, titleNameStr, "", knownStr, activeStr); - ++counter; - } + ++counter; } } if (counter == 0) // if counter == 0 then we found nth @@ -1261,7 +1132,7 @@ public: { if (MapEntry const* mapInfo = sMapStore.LookupEntry(id)) { - std::string name = mapInfo->name[locale]; + std::string name = mapInfo->name; if (name.empty()) continue; diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index 458538936fd..bff12d4330e 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -61,7 +61,6 @@ public: { "die", rbac::RBAC_PERM_COMMAND_DIE, false, &HandleDieCommand, "", NULL }, { "dismount", rbac::RBAC_PERM_COMMAND_DISMOUNT, false, &HandleDismountCommand, "", NULL }, { "distance", rbac::RBAC_PERM_COMMAND_DISTANCE, false, &HandleGetDistanceCommand, "", NULL }, - { "flusharenapoints", rbac::RBAC_PERM_COMMAND_FLUSHARENAPOINTS, false, &HandleFlushArenaPointsCommand, "", NULL }, { "freeze", rbac::RBAC_PERM_COMMAND_FREEZE, false, &HandleFreezeCommand, "", NULL }, { "gps", rbac::RBAC_PERM_COMMAND_GPS, false, &HandleGPSCommand, "", NULL }, { "guid", rbac::RBAC_PERM_COMMAND_GUID, false, &HandleGUIDCommand, "", NULL }, @@ -201,9 +200,9 @@ public: handler->PSendSysMessage("no VMAP available for area info"); handler->PSendSysMessage(LANG_MAP_POSITION, - mapId, (mapEntry ? mapEntry->name[handler->GetSessionDbcLocale()] : "<unknown>"), - zoneId, (zoneEntry ? zoneEntry->area_name[handler->GetSessionDbcLocale()] : "<unknown>"), - areaId, (areaEntry ? areaEntry->area_name[handler->GetSessionDbcLocale()] : "<unknown>"), + mapId, (mapEntry ? mapEntry->name : "<unknown>"), + zoneId, (zoneEntry ? zoneEntry->area_name : "<unknown>"), + areaId, (areaEntry ? areaEntry->area_name : "<unknown>"), object->GetPhaseMask(), object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), object->GetOrientation(), cell.GridX(), cell.GridY(), cell.CellX(), cell.CellY(), object->GetInstanceId(), @@ -1346,7 +1345,7 @@ public: // If our target does not yet have the skill they are trying to add to them, the chosen level also becomes // the max level of the new profession. - uint16 max = maxPureSkill ? atol (maxPureSkill) : targetHasSkill ? target->GetPureMaxSkillValue(skill) : uint16(level); + uint16 max = maxPureSkill ? atol(maxPureSkill) : targetHasSkill ? target->GetPureMaxSkillValue(skill) : uint16(level); if (level <= 0 || level > max || max <= 0) return false; @@ -1355,7 +1354,7 @@ public: // add the skill to the player's book with step 1 (which is the first rank, in most cases something // like 'Apprentice <skill>'. target->SetSkill(skill, targetHasSkill ? target->GetSkillStep(skill) : 1, level, max); - handler->PSendSysMessage(LANG_SET_SKILL, skill, skillLine->name[handler->GetSessionDbcLocale()], handler->GetNameLink(target).c_str(), level, max); + handler->PSendSysMessage(LANG_SET_SKILL, skill, skillLine->name, handler->GetNameLink(target).c_str(), level, max); return true; } @@ -1711,15 +1710,15 @@ public: AreaTableEntry const* area = GetAreaEntryByAreaID(areaId); if (area) { - areaName = area->area_name[locale]; + areaName = area->area_name; AreaTableEntry const* zone = GetAreaEntryByAreaID(area->zone); if (zone) - zoneName = zone->area_name[locale]; + zoneName = zone->area_name; } if (target) - handler->PSendSysMessage(LANG_PINFO_CHR_MAP, map->name[locale], (!zoneName.empty() ? zoneName.c_str() : "<Unknown>"), (!areaName.empty() ? areaName.c_str() : "<Unknown>")); + handler->PSendSysMessage(LANG_PINFO_CHR_MAP, map->name, (!zoneName.empty() ? zoneName.c_str() : "<Unknown>"), (!areaName.empty() ? areaName.c_str() : "<Unknown>")); // Output XVII. - XVIX. if they are not empty if (!guildName.empty()) @@ -2231,12 +2230,6 @@ public: return true; } - static bool HandleFlushArenaPointsCommand(ChatHandler* /*handler*/, char const* /*args*/) - { - sArenaTeamMgr->DistributeArenaPoints(); - return true; - } - static bool HandleRepairitemsCommand(ChatHandler* handler, char const* args) { Player* target; diff --git a/src/server/scripts/Commands/cs_mmaps.cpp b/src/server/scripts/Commands/cs_mmaps.cpp index d89edd4d925..19a276fbbc0 100644 --- a/src/server/scripts/Commands/cs_mmaps.cpp +++ b/src/server/scripts/Commands/cs_mmaps.cpp @@ -1,19 +1,19 @@ /* - * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> - * - * 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/>. - */ +* Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> +* +* 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/>. +*/ /** * @file cs_mmaps.cpp @@ -46,17 +46,17 @@ public: static ChatCommand mmapCommandTable[] = { { "loadedtiles", rbac::RBAC_PERM_COMMAND_MMAP_LOADEDTILES, false, &HandleMmapLoadedTilesCommand, "", NULL }, - { "loc", rbac::RBAC_PERM_COMMAND_MMAP_LOC, false, &HandleMmapLocCommand, "", NULL }, - { "path", rbac::RBAC_PERM_COMMAND_MMAP_PATH, false, &HandleMmapPathCommand, "", NULL }, - { "stats", rbac::RBAC_PERM_COMMAND_MMAP_STATS, false, &HandleMmapStatsCommand, "", NULL }, - { "testarea", rbac::RBAC_PERM_COMMAND_MMAP_TESTAREA, false, &HandleMmapTestArea, "", NULL }, - { NULL, 0, false, NULL, "", NULL } + { "loc", rbac::RBAC_PERM_COMMAND_MMAP_LOC, false, &HandleMmapLocCommand, "", NULL }, + { "path", rbac::RBAC_PERM_COMMAND_MMAP_PATH, false, &HandleMmapPathCommand, "", NULL }, + { "stats", rbac::RBAC_PERM_COMMAND_MMAP_STATS, false, &HandleMmapStatsCommand, "", NULL }, + { "testarea", rbac::RBAC_PERM_COMMAND_MMAP_TESTAREA, false, &HandleMmapTestArea, "", NULL }, + { NULL, 0, false, NULL, "", NULL } }; static ChatCommand commandTable[] = { - { "mmap", rbac::RBAC_PERM_COMMAND_MMAP, true, NULL, "", mmapCommandTable }, - { NULL, 0, false, NULL, "", NULL } + { "mmap", rbac::RBAC_PERM_COMMAND_MMAP, true, NULL, "", mmapCommandTable }, + { NULL, 0, false, NULL, "", NULL } }; return commandTable; } @@ -142,8 +142,8 @@ public: float const* min = navmesh->getParams()->orig; float x, y, z; player->GetPosition(x, y, z); - float location[VERTEX_SIZE] = {y, z, x}; - float extents[VERTEX_SIZE] = {3.0f, 5.0f, 3.0f}; + float location[VERTEX_SIZE] = { y, z, x }; + float extents[VERTEX_SIZE] = { 3.0f, 5.0f, 3.0f }; int32 tilex = int32((y - min[0]) / SIZE_OF_GRIDS); int32 tiley = int32((x - min[2]) / SIZE_OF_GRIDS); diff --git a/src/server/scripts/Commands/cs_modify.cpp b/src/server/scripts/Commands/cs_modify.cpp index 5dbe95b3e54..d47ee20fac5 100644 --- a/src/server/scripts/Commands/cs_modify.cpp +++ b/src/server/scripts/Commands/cs_modify.cpp @@ -23,6 +23,7 @@ Category: commandscripts EndScriptData */ #include "Chat.h" +#include <stdlib.h> #include "ObjectMgr.h" #include "Opcodes.h" #include "Pet.h" @@ -50,7 +51,6 @@ public: }; static ChatCommand modifyCommandTable[] = { - { "arenapoints", rbac::RBAC_PERM_COMMAND_MODIFY_ARENAPOINTS, false, &HandleModifyArenaCommand, "", NULL }, { "bit", rbac::RBAC_PERM_COMMAND_MODIFY_BIT, false, &HandleModifyBitCommand, "", NULL }, { "drunk", rbac::RBAC_PERM_COMMAND_MODIFY_DRUNK, false, &HandleModifyDrunkCommand, "", NULL }, { "energy", rbac::RBAC_PERM_COMMAND_MODIFY_ENERGY, false, &HandleModifyEnergyCommand, "", NULL }, @@ -963,14 +963,14 @@ public: target->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP); target->Mount(mId); - WorldPacket data(SMSG_FORCE_RUN_SPEED_CHANGE, (8+4+1+4)); + WorldPacket data(SMSG_MOVE_SET_RUN_SPEED, (8+4+1+4)); data.append(target->GetPackGUID()); data << (uint32)0; data << (uint8)0; //new 2.1.0 data << float(speed); target->SendMessageToSet(&data, true); - data.Initialize(SMSG_FORCE_SWIM_SPEED_CHANGE, (8+4+4)); + data.Initialize(SMSG_MOVE_SET_SWIM_SPEED, (8+4+4)); data.append(target->GetPackGUID()); data << (uint32)0; data << float(speed); @@ -997,19 +997,19 @@ public: if (handler->HasLowerSecurity(target, 0)) return false; - int32 moneyToAdd = 0; + int64 moneyToAdd = 0; if (strchr(args, 'g') || strchr(args, 's') || strchr(args, 'c')) moneyToAdd = MoneyStringToMoney(std::string(args)); else - moneyToAdd = atoi(args); + moneyToAdd = atol(args); - uint32 targetMoney = target->GetMoney(); + uint64 targetMoney = target->GetMoney(); if (moneyToAdd < 0) { - int32 newmoney = int32(targetMoney) + moneyToAdd; + int64 newmoney = int64(targetMoney) + moneyToAdd; - TC_LOG_DEBUG("misc", handler->GetTrinityString(LANG_CURRENT_MONEY), targetMoney, moneyToAdd, newmoney); + TC_LOG_DEBUG("misc", handler->GetTrinityString(LANG_CURRENT_MONEY), uint32(targetMoney), int32(moneyToAdd), uint32(newmoney)); if (newmoney <= 0) { handler->PSendSysMessage(LANG_YOU_TAKE_ALL_MONEY, handler->GetNameLink(target).c_str()); @@ -1020,28 +1020,32 @@ public: } else { - if (newmoney > static_cast<int32>(MAX_MONEY_AMOUNT)) + uint64 moneyToAddMsg = moneyToAdd * -1; + if (newmoney > static_cast<int64>(MAX_MONEY_AMOUNT)) newmoney = MAX_MONEY_AMOUNT; - handler->PSendSysMessage(LANG_YOU_TAKE_MONEY, abs(moneyToAdd), handler->GetNameLink(target).c_str()); + handler->PSendSysMessage(LANG_YOU_TAKE_MONEY, moneyToAddMsg, handler->GetNameLink(target).c_str()); if (handler->needReportToTarget(target)) - ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOURS_MONEY_TAKEN, handler->GetNameLink().c_str(), abs(moneyToAdd)); + ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOURS_MONEY_TAKEN, handler->GetNameLink().c_str(), moneyToAddMsg); target->SetMoney(newmoney); } } else { - handler->PSendSysMessage(LANG_YOU_GIVE_MONEY, moneyToAdd, handler->GetNameLink(target).c_str()); + handler->PSendSysMessage(LANG_YOU_GIVE_MONEY, uint32(moneyToAdd), handler->GetNameLink(target).c_str()); if (handler->needReportToTarget(target)) - ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOURS_MONEY_GIVEN, handler->GetNameLink().c_str(), moneyToAdd); + ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOURS_MONEY_GIVEN, handler->GetNameLink().c_str(), uint32(moneyToAdd)); - if (targetMoney >= MAX_MONEY_AMOUNT - moneyToAdd) + if (moneyToAdd >= int64(MAX_MONEY_AMOUNT)) + moneyToAdd = MAX_MONEY_AMOUNT; + + if (targetMoney >= uint64(MAX_MONEY_AMOUNT) - moneyToAdd) moneyToAdd -= targetMoney; target->ModifyMoney(moneyToAdd); } - TC_LOG_DEBUG("misc", handler->GetTrinityString(LANG_NEW_MONEY), targetMoney, moneyToAdd, target->GetMoney()); + TC_LOG_DEBUG("misc", handler->GetTrinityString(LANG_NEW_MONEY), uint32(targetMoney), int32(moneyToAdd), uint32(target->GetMoney())); return true; } @@ -1101,7 +1105,7 @@ public: return true; } - static bool HandleModifyHonorCommand (ChatHandler* handler, const char* args) + static bool HandleModifyHonorCommand(ChatHandler* handler, const char* args) { if (!*args) return false; @@ -1120,9 +1124,9 @@ public: int32 amount = (uint32)atoi(args); - target->ModifyHonorPoints(amount); + target->ModifyCurrency(CURRENCY_TYPE_HONOR_POINTS, amount, true, true); - handler->PSendSysMessage(LANG_COMMAND_MODIFY_HONOR, handler->GetNameLink(target).c_str(), target->GetHonorPoints()); + handler->PSendSysMessage(LANG_COMMAND_MODIFY_HONOR, handler->GetNameLink(target).c_str(), target->GetCurrency(CURRENCY_TYPE_HONOR_POINTS, false)); return true; } @@ -1230,14 +1234,14 @@ public: if (factionEntry->reputationListID < 0) { - handler->PSendSysMessage(LANG_COMMAND_FACTION_NOREP_ERROR, factionEntry->name[handler->GetSessionDbcLocale()], factionId); + handler->PSendSysMessage(LANG_COMMAND_FACTION_NOREP_ERROR, factionEntry->name, factionId); handler->SetSentErrorMessage(true); return false; } target->GetReputationMgr().SetOneFactionReputation(factionEntry, amount, false); target->GetReputationMgr().SendState(target->GetReputationMgr().GetState(factionEntry)); - handler->PSendSysMessage(LANG_COMMAND_MODIFY_REP, factionEntry->name[handler->GetSessionDbcLocale()], factionId, + handler->PSendSysMessage(LANG_COMMAND_MODIFY_REP, factionEntry->name, factionId, handler->GetNameLink(target).c_str(), target->GetReputationMgr().GetReputation(factionEntry)); return true; } @@ -1272,14 +1276,15 @@ public: uint32 phasemask = (uint32)atoi((char*)args); Unit* target = handler->getSelectedUnit(); - if (!target) - target = handler->GetSession()->GetPlayer(); - - // check online security - else if (target->GetTypeId() == TYPEID_PLAYER && handler->HasLowerSecurity(target->ToPlayer(), 0)) - return false; - - target->SetPhaseMask(phasemask, true); + if (target) + { + if (target->GetTypeId() == TYPEID_PLAYER) + target->ToPlayer()->GetPhaseMgr().SetCustomPhase(phasemask); + else + target->SetPhaseMask(phasemask, true); + } + else + handler->GetSession()->GetPlayer()->GetPhaseMgr().SetCustomPhase(phasemask); return true; } @@ -1296,28 +1301,6 @@ public: return true; } - static bool HandleModifyArenaCommand(ChatHandler* handler, const char* args) - { - if (!*args) - return false; - - Player* target = handler->getSelectedPlayer(); - if (!target) - { - handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); - handler->SetSentErrorMessage(true); - return false; - } - - int32 amount = (uint32)atoi(args); - - target->ModifyArenaPoints(amount); - - handler->PSendSysMessage(LANG_COMMAND_MODIFY_ARENA, handler->GetNameLink(target).c_str(), target->GetArenaPoints()); - - return true; - } - static bool HandleModifyGenderCommand(ChatHandler* handler, const char* args) { if (!*args) @@ -1393,6 +1376,33 @@ public: return true; } + + static bool HandleModifyCurrencyCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + Player* target = handler->getSelectedPlayer(); + if (!target) + { + handler->PSendSysMessage(LANG_PLAYER_NOT_FOUND); + handler->SetSentErrorMessage(true); + return false; + } + + uint32 currencyId = atoi(strtok((char*)args, " ")); + const CurrencyTypesEntry* currencyType = sCurrencyTypesStore.LookupEntry(currencyId); + if (!currencyType) + return false; + + uint32 amount = atoi(strtok(NULL, " ")); + if (!amount) + return false; + + target->ModifyCurrency(currencyId, amount, true, true); + + return true; + } }; void AddSC_modify_commandscript() diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp index 28d49fe11aa..fb465aaca16 100644 --- a/src/server/scripts/Commands/cs_npc.cpp +++ b/src/server/scripts/Commands/cs_npc.cpp @@ -105,7 +105,8 @@ EnumName<Mechanics> const mechanicImmunes[MAX_MECHANIC] = CREATE_NAMED_ENUM(MECHANIC_DISCOVERY), CREATE_NAMED_ENUM(MECHANIC_IMMUNE_SHIELD), CREATE_NAMED_ENUM(MECHANIC_SAPPED), - CREATE_NAMED_ENUM(MECHANIC_ENRAGED) + CREATE_NAMED_ENUM(MECHANIC_ENRAGED), + CREATE_NAMED_ENUM(MECHANIC_WOUNDED) }; EnumName<UnitFlags> const unitFlags[MAX_UNIT_FLAGS] = @@ -242,7 +243,7 @@ public: uint32 guid = sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT); CreatureData& data = sObjectMgr->NewOrExistCreatureData(guid); data.id = id; - data.phaseMask = chr->GetPhaseMaskForSpawn(); + data.phaseMask = chr->GetPhaseMgr().GetPhaseMaskForSpawn(); data.posX = chr->GetTransOffsetX(); data.posY = chr->GetTransOffsetY(); data.posZ = chr->GetTransOffsetZ(); @@ -250,20 +251,20 @@ public: Creature* creature = trans->CreateNPCPassenger(guid, &data); - creature->SaveToDB(trans->GetGOInfo()->moTransport.mapID, 1 << map->GetSpawnMode(), chr->GetPhaseMaskForSpawn()); + creature->SaveToDB(trans->GetGOInfo()->moTransport.mapID, 1 << map->GetSpawnMode(), chr->GetPhaseMgr().GetPhaseMaskForSpawn()); sObjectMgr->AddCreatureToGrid(guid, &data); return true; } Creature* creature = new Creature(); - if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, x, y, z, o)) + if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMgr().GetPhaseMaskForSpawn(), id, x, y, z, o)) { delete creature; return false; } - creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn()); + creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMgr().GetPhaseMaskForSpawn()); uint32 db_guid = creature->GetDBTableGUIDLow(); @@ -288,6 +289,8 @@ public: if (!*args) return false; + const uint8 type = 1; // FIXME: make type (1 item, 2 currency) an argument + char* pitem = handler->extractKeyFromLink((char*)args, "Hitem"); if (!pitem) { @@ -324,13 +327,13 @@ public: uint32 vendor_entry = vendor->GetEntry(); - if (!sObjectMgr->IsVendorItemValid(vendor_entry, itemId, maxcount, incrtime, extendedcost, handler->GetSession()->GetPlayer())) + if (!sObjectMgr->IsVendorItemValid(vendor_entry, itemId, maxcount, incrtime, extendedcost, type, handler->GetSession()->GetPlayer())) { handler->SetSentErrorMessage(true); return false; } - sObjectMgr->AddVendorItem(vendor_entry, itemId, maxcount, incrtime, extendedcost); + sObjectMgr->AddVendorItem(vendor_entry, itemId, maxcount, incrtime, extendedcost, type); ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(itemId); @@ -545,7 +548,9 @@ public: } uint32 itemId = atol(pitem); - if (!sObjectMgr->RemoveVendorItem(vendor->GetEntry(), itemId)) + const uint8 type = 1; // FIXME: make type (1 item, 2 currency) an argument + + if (!sObjectMgr->RemoveVendorItem(vendor->GetEntry(), itemId, type)) { handler->PSendSysMessage(LANG_ITEM_NOT_IN_LIST, itemId); handler->SetSentErrorMessage(true); diff --git a/src/server/scripts/Commands/cs_reload.cpp b/src/server/scripts/Commands/cs_reload.cpp index 89dc08d5737..0274de02ae0 100644 --- a/src/server/scripts/Commands/cs_reload.cpp +++ b/src/server/scripts/Commands/cs_reload.cpp @@ -101,7 +101,6 @@ public: { "gossip_menu_option", rbac::RBAC_PERM_COMMAND_RELOAD_GOSSIP_MENU_OPTION, true, &HandleReloadGossipMenuOptionCommand, "", NULL }, { "item_enchantment_template", rbac::RBAC_PERM_COMMAND_RELOAD_ITEM_ENCHANTMENT_TEMPLATE, true, &HandleReloadItemEnchantementsCommand, "", NULL }, { "item_loot_template", rbac::RBAC_PERM_COMMAND_RELOAD_ITEM_LOOT_TEMPLATE, true, &HandleReloadLootTemplatesItemCommand, "", NULL }, - { "item_set_names", rbac::RBAC_PERM_COMMAND_RELOAD_ITEM_SET_NAMES, true, &HandleReloadItemSetNamesCommand, "", NULL }, { "lfg_dungeon_rewards", rbac::RBAC_PERM_COMMAND_RELOAD_LFG_DUNGEON_REWARDS, true, &HandleReloadLfgRewardsCommand, "", NULL }, { "locales_achievement_reward", rbac::RBAC_PERM_COMMAND_RELOAD_LOCALES_ACHIEVEMENT_REWARD, true, &HandleReloadLocalesAchievementRewardCommand, "", NULL }, { "locales_creature", rbac::RBAC_PERM_COMMAND_RELOAD_LOCALES_CRETURE, true, &HandleReloadLocalesCreatureCommand, "", NULL }, @@ -109,7 +108,6 @@ public: { "locales_gameobject", rbac::RBAC_PERM_COMMAND_RELOAD_LOCALES_GAMEOBJECT, true, &HandleReloadLocalesGameobjectCommand, "", NULL }, { "locales_gossip_menu_option", rbac::RBAC_PERM_COMMAND_RELOAD_LOCALES_GOSSIP_MENU_OPTION, true, &HandleReloadLocalesGossipMenuOptionCommand, "", NULL }, { "locales_item", rbac::RBAC_PERM_COMMAND_RELOAD_LOCALES_ITEM, true, &HandleReloadLocalesItemCommand, "", NULL }, - { "locales_item_set_name", rbac::RBAC_PERM_COMMAND_RELOAD_LOCALES_ITEM_SET_NAME, true, &HandleReloadLocalesItemSetNameCommand, "", NULL }, { "locales_npc_text", rbac::RBAC_PERM_COMMAND_RELOAD_LOCALES_NPC_TEXT, true, &HandleReloadLocalesNpcTextCommand, "", NULL }, { "locales_page_text", rbac::RBAC_PERM_COMMAND_RELOAD_LOCALES_PAGE_TEXT, true, &HandleReloadLocalesPageTextCommand, "", NULL }, { "locales_points_of_interest", rbac::RBAC_PERM_COMMAND_RELOAD_LOCALES_POINTS_OF_INTEREST, true, &HandleReloadLocalesPointsOfInterestCommand, "", NULL }, @@ -440,11 +438,12 @@ public: Field* fields = result->Fetch(); - cInfo->DifficultyEntry[0] = fields[0].GetUInt32(); - cInfo->DifficultyEntry[1] = fields[1].GetUInt32(); - cInfo->DifficultyEntry[2] = fields[2].GetUInt32(); - cInfo->KillCredit[0] = fields[3].GetUInt32(); - cInfo->KillCredit[1] = fields[4].GetUInt32(); + for (uint8 i = 0; i < MAX_DIFFICULTY - 1; ++i) + cInfo->DifficultyEntry[i] = fields[0 + i].GetUInt32(); + + for (uint8 i = 0; i < MAX_KILL_CREDIT; ++i) + cInfo->KillCredit[i] = fields[3 + i].GetUInt32(); + cInfo->Modelid1 = fields[5].GetUInt32(); cInfo->Modelid2 = fields[6].GetUInt32(); cInfo->Modelid3 = fields[7].GetUInt32(); @@ -456,26 +455,26 @@ public: cInfo->minlevel = fields[13].GetUInt8(); cInfo->maxlevel = fields[14].GetUInt8(); cInfo->expansion = fields[15].GetUInt16(); - cInfo->faction = fields[16].GetUInt16(); - cInfo->npcflag = fields[17].GetUInt32(); - cInfo->speed_walk = fields[18].GetFloat(); - cInfo->speed_run = fields[19].GetFloat(); - cInfo->scale = fields[20].GetFloat(); - cInfo->rank = fields[21].GetUInt8(); - cInfo->mindmg = fields[22].GetFloat(); - cInfo->maxdmg = fields[23].GetFloat(); - cInfo->dmgschool = fields[24].GetUInt8(); - cInfo->attackpower = fields[25].GetUInt32(); - cInfo->dmg_multiplier = fields[26].GetFloat(); - cInfo->baseattacktime = fields[27].GetUInt32(); - cInfo->rangeattacktime = fields[28].GetUInt32(); - cInfo->unit_class = fields[29].GetUInt8(); - cInfo->unit_flags = fields[30].GetUInt32(); - cInfo->unit_flags2 = fields[31].GetUInt32(); - cInfo->dynamicflags = fields[32].GetUInt32(); - cInfo->family = fields[33].GetUInt8(); - cInfo->trainer_type = fields[34].GetUInt8(); - cInfo->trainer_spell = fields[35].GetUInt32(); + cInfo->expansionUnknown = fields[16].GetUInt16(); + cInfo->faction = fields[17].GetUInt16(); + cInfo->npcflag = fields[18].GetUInt32(); + cInfo->speed_walk = fields[19].GetFloat(); + cInfo->speed_run = fields[20].GetFloat(); + cInfo->scale = fields[21].GetFloat(); + cInfo->rank = fields[22].GetUInt8(); + cInfo->mindmg = fields[23].GetFloat(); + cInfo->maxdmg = fields[24].GetFloat(); + cInfo->dmgschool = fields[25].GetUInt8(); + cInfo->attackpower = fields[26].GetUInt32(); + cInfo->dmg_multiplier = fields[27].GetFloat(); + cInfo->baseattacktime = fields[28].GetUInt32(); + cInfo->rangeattacktime = fields[29].GetUInt32(); + cInfo->unit_class = fields[30].GetUInt8(); + cInfo->unit_flags = fields[31].GetUInt32(); + cInfo->unit_flags2 = fields[32].GetUInt32(); + cInfo->dynamicflags = fields[33].GetUInt32(); + cInfo->family = fields[34].GetUInt8(); + cInfo->trainer_type = fields[35].GetUInt8(); cInfo->trainer_class = fields[36].GetUInt8(); cInfo->trainer_race = fields[37].GetUInt8(); cInfo->minrangedmg = fields[38].GetFloat(); @@ -483,44 +482,39 @@ public: cInfo->rangedattackpower = fields[40].GetUInt16(); cInfo->type = fields[41].GetUInt8(); cInfo->type_flags = fields[42].GetUInt32(); - cInfo->lootid = fields[43].GetUInt32(); - cInfo->pickpocketLootId = fields[44].GetUInt32(); - cInfo->SkinLootId = fields[45].GetUInt32(); + cInfo->type_flags2 = fields[43].GetUInt32(); + cInfo->lootid = fields[44].GetUInt32(); + cInfo->pickpocketLootId = fields[45].GetUInt32(); + cInfo->SkinLootId = fields[46].GetUInt32(); for (uint8 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i) - cInfo->resistance[i] = fields[46 + i -1].GetUInt16(); - - cInfo->spells[0] = fields[52].GetUInt32(); - cInfo->spells[1] = fields[53].GetUInt32(); - cInfo->spells[2] = fields[54].GetUInt32(); - cInfo->spells[3] = fields[55].GetUInt32(); - cInfo->spells[4] = fields[56].GetUInt32(); - cInfo->spells[5] = fields[57].GetUInt32(); - cInfo->spells[6] = fields[58].GetUInt32(); - cInfo->spells[7] = fields[59].GetUInt32(); - cInfo->PetSpellDataId = fields[60].GetUInt32(); - cInfo->VehicleId = fields[61].GetUInt32(); - cInfo->mingold = fields[62].GetUInt32(); - cInfo->maxgold = fields[63].GetUInt32(); - cInfo->AIName = fields[64].GetString(); - cInfo->MovementType = fields[65].GetUInt8(); - cInfo->InhabitType = fields[66].GetUInt8(); - cInfo->HoverHeight = fields[67].GetFloat(); - cInfo->ModHealth = fields[68].GetFloat(); - cInfo->ModMana = fields[69].GetFloat(); - cInfo->ModArmor = fields[70].GetFloat(); - cInfo->RacialLeader = fields[71].GetBool(); - cInfo->questItems[0] = fields[72].GetUInt32(); - cInfo->questItems[1] = fields[73].GetUInt32(); - cInfo->questItems[2] = fields[74].GetUInt32(); - cInfo->questItems[3] = fields[75].GetUInt32(); - cInfo->questItems[4] = fields[76].GetUInt32(); - cInfo->questItems[5] = fields[77].GetUInt32(); - cInfo->movementId = fields[78].GetUInt32(); - cInfo->RegenHealth = fields[79].GetBool(); - cInfo->MechanicImmuneMask = fields[80].GetUInt32(); - cInfo->flags_extra = fields[81].GetUInt32(); - cInfo->ScriptID = sObjectMgr->GetScriptId(fields[82].GetCString()); + cInfo->resistance[i] = fields[47 + i -1].GetUInt16(); + + for (uint8 i = 0; i < CREATURE_MAX_SPELLS; ++i) + cInfo->spells[i] = fields[53 + i].GetUInt32(); + + cInfo->PetSpellDataId = fields[61].GetUInt32(); + cInfo->VehicleId = fields[62].GetUInt32(); + cInfo->mingold = fields[63].GetUInt32(); + cInfo->maxgold = fields[64].GetUInt32(); + cInfo->AIName = fields[65].GetString(); + cInfo->MovementType = fields[66].GetUInt8(); + cInfo->InhabitType = fields[67].GetUInt8(); + cInfo->HoverHeight = fields[68].GetFloat(); + cInfo->ModHealth = fields[69].GetFloat(); + cInfo->ModMana = fields[70].GetFloat(); + cInfo->ModManaExtra = fields[71].GetFloat(); + cInfo->ModArmor = fields[72].GetFloat(); + cInfo->RacialLeader = fields[73].GetBool(); + + for (uint8 i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i) + cInfo->questItems[i] = fields[74 + i].GetUInt32(); + + cInfo->movementId = fields[80].GetUInt32(); + cInfo->RegenHealth = fields[81].GetBool(); + cInfo->MechanicImmuneMask = fields[82].GetUInt32(); + cInfo->flags_extra = fields[83].GetUInt32(); + cInfo->ScriptID = sObjectMgr->GetScriptId(fields[84].GetCString()); sObjectMgr->CheckCreatureTemplate(cInfo); } @@ -950,14 +944,6 @@ public: return true; } - static bool HandleReloadItemSetNamesCommand(ChatHandler* handler, const char* /*args*/) - { - TC_LOG_INFO("misc", "Re-Loading Item set names..."); - sObjectMgr->LoadItemSetNames(); - handler->SendGlobalGMSysMessage("DB table `item_set_names` reloaded."); - return true; - } - static bool HandleReloadEventScriptsCommand(ChatHandler* handler, const char* args) { if (sScriptMgr->IsScriptScheduled()) @@ -1127,14 +1113,6 @@ public: return true; } - static bool HandleReloadLocalesItemSetNameCommand(ChatHandler* handler, const char* /*args*/) - { - TC_LOG_INFO("misc", "Re-Loading Locales Item set name... "); - sObjectMgr->LoadItemSetNameLocales(); - handler->SendGlobalGMSysMessage("DB table `locales_item_set_name` reloaded."); - return true; - } - static bool HandleReloadLocalesNpcTextCommand(ChatHandler* handler, const char* /*args*/) { TC_LOG_INFO("misc", "Re-Loading Locales NPC Text ... "); @@ -1225,6 +1203,16 @@ public: return true; } + + static bool HandleReloadPhaseDefinitionsCommand(ChatHandler* handler, const char* /*args*/) + { + TC_LOG_INFO("misc", "Reloading phase_definitions table..."); + sObjectMgr->LoadPhaseDefinitions(); + sWorld->UpdatePhaseDefinitions(); + handler->SendGlobalGMSysMessage("Phase Definitions reloaded."); + return true; + } + static bool HandleReloadRBACCommand(ChatHandler* handler, const char* /*args*/) { TC_LOG_INFO("misc", "Reloading RBAC tables..."); diff --git a/src/server/scripts/Commands/cs_reset.cpp b/src/server/scripts/Commands/cs_reset.cpp index d61c36c887f..e23a9d81787 100644 --- a/src/server/scripts/Commands/cs_reset.cpp +++ b/src/server/scripts/Commands/cs_reset.cpp @@ -66,7 +66,7 @@ public: if (target) target->ResetAchievements(); else - AchievementMgr::DeleteFromDB(GUID_LOPART(targetGuid)); + AchievementMgr<Player>::DeleteFromDB(GUID_LOPART(targetGuid)); return true; } @@ -77,11 +77,8 @@ public: if (!handler->extractPlayerTarget((char*)args, &target)) return false; - target->SetHonorPoints(0); target->SetUInt32Value(PLAYER_FIELD_KILLS, 0); target->SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS, 0); - target->SetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, 0); - target->SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, 0); target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL); return true; @@ -233,7 +230,7 @@ public: if (target) { - target->resetTalents(true); + target->ResetTalents(true); target->SendTalentsInfoData(false); ChatHandler(target->GetSession()).SendSysMessage(LANG_RESET_TALENTS); if (!handler->GetSession() || handler->GetSession()->GetPlayer() != target) diff --git a/src/server/scripts/Commands/cs_titles.cpp b/src/server/scripts/Commands/cs_titles.cpp index dee9c33ae99..b1e5bd0ca98 100644 --- a/src/server/scripts/Commands/cs_titles.cpp +++ b/src/server/scripts/Commands/cs_titles.cpp @@ -96,8 +96,7 @@ public: target->SetTitle(titleInfo); // to be sure that title now known target->SetUInt32Value(PLAYER_CHOSEN_TITLE, titleInfo->bit_index); - handler->PSendSysMessage(LANG_TITLE_CURRENT_RES, id, target->getGender() == GENDER_MALE ? titleInfo->nameMale[handler->GetSessionDbcLocale()] : titleInfo->nameFemale[handler->GetSessionDbcLocale()], tNameLink.c_str()); - + handler->PSendSysMessage(LANG_TITLE_CURRENT_RES, id, target->getGender() == GENDER_MALE ? titleInfo->nameMale : titleInfo->nameFemale, tNameLink.c_str()); return true; } @@ -139,7 +138,7 @@ public: std::string tNameLink = handler->GetNameLink(target); char titleNameStr[80]; - snprintf(titleNameStr, 80, target->getGender() == GENDER_MALE ? titleInfo->nameMale[handler->GetSessionDbcLocale()] : titleInfo->nameFemale[handler->GetSessionDbcLocale()], target->GetName().c_str()); + snprintf(titleNameStr, 80, target->getGender() == GENDER_MALE ? titleInfo->nameMale : titleInfo->nameFemale, target->GetName().c_str()); target->SetTitle(titleInfo); handler->PSendSysMessage(LANG_TITLE_ADD_RES, id, titleNameStr, tNameLink.c_str()); @@ -187,7 +186,7 @@ public: std::string tNameLink = handler->GetNameLink(target); char titleNameStr[80]; - snprintf(titleNameStr, 80, target->getGender() == GENDER_MALE ? titleInfo->nameMale[handler->GetSessionDbcLocale()] : titleInfo->nameFemale[handler->GetSessionDbcLocale()], target->GetName().c_str()); + snprintf(titleNameStr, 80, target->getGender() == GENDER_MALE ? titleInfo->nameMale : titleInfo->nameFemale, target->GetName().c_str()); handler->PSendSysMessage(LANG_TITLE_REMOVE_RES, id, titleNameStr, tNameLink.c_str()); diff --git a/src/server/scripts/Commands/cs_wp.cpp b/src/server/scripts/Commands/cs_wp.cpp index 94f84aaf20a..5306e0e1d9e 100644 --- a/src/server/scripts/Commands/cs_wp.cpp +++ b/src/server/scripts/Commands/cs_wp.cpp @@ -241,40 +241,44 @@ public: if (!target) { - handler->PSendSysMessage("%s%s|r", "|cff33ffff", "You must select target."); + handler->PSendSysMessage("%s%s|r", "|cff33ffff", "You must select a target."); return true; } - uint32 guildLow = target->GetDBTableGUIDLow(); + uint32 guidLow = target->GetDBTableGUIDLow(); + if (guidLow == 0) + { + handler->PSendSysMessage("%s%s|r", "|cffff33ff", "Target is not saved to DB."); + return true; + } - if (target->GetCreatureAddon()) + CreatureAddon const* addon = sObjectMgr->GetCreatureAddon(guidLow); + if (!addon || addon->path_id == 0) { - if (target->GetCreatureAddon()->path_id != 0) - { - PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_CREATURE_ADDON); + handler->PSendSysMessage("%s%s|r", "|cffff33ff", "Target does not have a loaded path."); + return true; + } - stmt->setUInt32(0, guildLow); + PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_CREATURE_ADDON); - WorldDatabase.Execute(stmt); + stmt->setUInt32(0, guidLow); + + WorldDatabase.Execute(stmt); - target->UpdateWaypointID(0); + target->UpdateWaypointID(0); - stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_CREATURE_MOVEMENT_TYPE); + stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_CREATURE_MOVEMENT_TYPE); - stmt->setUInt8(0, uint8(IDLE_MOTION_TYPE)); - stmt->setUInt32(1, guildLow); + stmt->setUInt8(0, uint8(IDLE_MOTION_TYPE)); + stmt->setUInt32(1, guidLow); - WorldDatabase.Execute(stmt); + WorldDatabase.Execute(stmt); - target->LoadPath(0); - target->SetDefaultMovementType(IDLE_MOTION_TYPE); - target->GetMotionMaster()->MoveTargetedHome(); - target->GetMotionMaster()->Initialize(); - target->MonsterSay("Path unloaded.", LANG_UNIVERSAL, NULL); - return true; - } - handler->PSendSysMessage("%s%s|r", "|cffff33ff", "Target have no loaded path."); - } + target->LoadPath(0); + target->SetDefaultMovementType(IDLE_MOTION_TYPE); + target->GetMotionMaster()->MoveTargetedHome(); + target->GetMotionMaster()->Initialize(); + target->MonsterSay("Path unloaded.", LANG_UNIVERSAL, NULL); return true; } @@ -690,7 +694,7 @@ public: } // re-create Creature* wpCreature2 = new Creature(); - if (!wpCreature2->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), VISUAL_WAYPOINT, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation())) + if (!wpCreature2->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMgr().GetPhaseMaskForSpawn(), VISUAL_WAYPOINT, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation())) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT); delete wpCreature2; @@ -698,7 +702,7 @@ public: return false; } - wpCreature2->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn()); + wpCreature2->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMgr().GetPhaseMaskForSpawn()); // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells(); /// @todo Should we first use "Create" then use "LoadFromDB"? if (!wpCreature2->LoadCreatureFromDB(wpCreature2->GetDBTableGUIDLow(), map)) @@ -914,7 +918,7 @@ public: float o = chr->GetOrientation(); Creature* wpCreature = new Creature(); - if (!wpCreature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, x, y, z, o)) + if (!wpCreature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMgr().GetPhaseMaskForSpawn(), id, x, y, z, o)) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id); delete wpCreature; @@ -930,7 +934,7 @@ public: WorldDatabase.Execute(stmt); - wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn()); + wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMgr().GetPhaseMaskForSpawn()); // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells(); if (!wpCreature->LoadCreatureFromDB(wpCreature->GetDBTableGUIDLow(), map)) { @@ -978,14 +982,14 @@ public: Map* map = chr->GetMap(); Creature* creature = new Creature(); - if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, x, y, z, o)) + if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMgr().GetPhaseMaskForSpawn(), id, x, y, z, o)) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id); delete creature; return false; } - creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn()); + creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMgr().GetPhaseMaskForSpawn()); if (!creature->LoadCreatureFromDB(creature->GetDBTableGUIDLow(), map)) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id); @@ -1027,14 +1031,14 @@ public: Map* map = chr->GetMap(); Creature* creature = new Creature(); - if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, x, y, z, o)) + if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMgr().GetPhaseMaskForSpawn(), id, x, y, z, o)) { handler->PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id); delete creature; return false; } - creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn()); + creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMgr().GetPhaseMaskForSpawn()); if (!creature->LoadCreatureFromDB(creature->GetDBTableGUIDLow(), map)) { handler->PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id); diff --git a/src/server/scripts/EasternKingdoms/BaradinHold/baradin_hold.h b/src/server/scripts/EasternKingdoms/BaradinHold/baradin_hold.h new file mode 100644 index 00000000000..22df3858c43 --- /dev/null +++ b/src/server/scripts/EasternKingdoms/BaradinHold/baradin_hold.h @@ -0,0 +1,64 @@ +/* +* Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/> +* +* 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 3 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/>. +*/ + +#ifndef DEF_BARADIN_HOLD_H_ +#define DEF_BARADIN_HOLD_H_ + +#include "Map.h" +#include "Creature.h" +#include "ObjectMgr.h" + +#define BHScriptName "instance_baradin_hold" + +uint32 const EncounterCount = 3; + +enum DataTypes +{ + DATA_ARGALOTH = 0, + DATA_OCCUTHAR = 1, + DATA_ALIZABAL = 2 +}; + +enum CreatureIds +{ + BOSS_ARGALOTH = 47120, + BOSS_OCCUTHAR = 52363, + BOSS_ALIZABAL = 55869, + + NPC_EYE_OF_OCCUTHAR = 52389, + NPC_FOCUS_FIRE_DUMMY = 52369, + NPC_OCCUTHAR_EYE = 52368 +}; + +enum GameObjectIds +{ + GO_ARGALOTH_DOOR = 207619, + GO_OCCUTHAR_DOOR = 208953, + GO_ALIZABAL_DOOR = 209849 +}; + +template<class AI> +CreatureAI* GetBaradinHoldAI(Creature* creature) +{ + if (InstanceMap* instance = creature->GetMap()->ToInstanceMap()) + if (instance->GetInstanceScript()) + if (instance->GetScriptId() == sObjectMgr->GetScriptId(BHScriptName)) + return new AI(creature); + return NULL; +} + +#endif diff --git a/src/server/scripts/EasternKingdoms/BaradinHold/boss_alizabal.cpp b/src/server/scripts/EasternKingdoms/BaradinHold/boss_alizabal.cpp new file mode 100644 index 00000000000..52eac77cd46 --- /dev/null +++ b/src/server/scripts/EasternKingdoms/BaradinHold/boss_alizabal.cpp @@ -0,0 +1,270 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * 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/>. + */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "Player.h" +#include "ObjectAccessor.h" +#include "baradin_hold.h" + +enum Texts +{ + SAY_INTRO = 1, + SAY_AGGRO = 2, + SAY_HATE = 3, + SAY_SKEWER = 4, + SAY_SKEWER_ANNOUNCE = 5, + SAY_BLADE_STORM = 6, + SAY_SLAY = 10, + SAY_DEATH = 12 +}; + +enum Spells +{ + SPELL_BLADE_DANCE = 105784, + SPELL_BLADE_DANCE_DUMMY = 105828, + SPELL_SEETHING_HATE = 105067, + SPELL_SKEWER = 104936, + SPELL_BERSERK = 47008 +}; + +enum Actions +{ + ACTION_INTRO = 1 +}; + + enum Points +{ + POINT_STORM = 1 +}; + +enum Events +{ + EVENT_RANDOM_CAST = 1, + EVENT_STOP_STORM = 2, + EVENT_MOVE_STORM = 3, + EVENT_CAST_STORM = 4 +}; + +class at_alizabal_intro : public AreaTriggerScript +{ + public: + at_alizabal_intro() : AreaTriggerScript("at_alizabal_intro") { } + + bool OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/) + { + if (InstanceScript* instance = player->GetInstanceScript()) + if (Creature* alizabal = ObjectAccessor::GetCreature(*player, instance->GetData64(DATA_ALIZABAL))) + alizabal->AI()->DoAction(ACTION_INTRO); + return true; + } +}; + +class boss_alizabal : public CreatureScript +{ + public: + boss_alizabal() : CreatureScript("boss_alizabal") { } + + struct boss_alizabalAI : public BossAI + { + boss_alizabalAI(Creature* creature) : BossAI(creature, DATA_ALIZABAL) + { + _intro = false; + } + + void Reset() override + { + _Reset(); + _hate = false; + _skewer = false; + } + + void EnterCombat(Unit* /*who*/) override + { + _EnterCombat(); + Talk(SAY_AGGRO); + instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me); + events.ScheduleEvent(EVENT_RANDOM_CAST, 10000); + } + + void JustDied(Unit* /*killer*/) override + { + _JustDied(); + Talk(SAY_DEATH); + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); + } + + void KilledUnit(Unit* who) override + { + if (who->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_SLAY); + } + + void EnterEvadeMode() override + { + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); + me->GetMotionMaster()->MoveTargetedHome(); + _DespawnAtEvade(); + } + + void DoAction(int32 action) override + { + switch (action) + { + case ACTION_INTRO: + if (!_intro) + { + Talk(SAY_INTRO); + _intro = true; + } + break; + } + } + + void MovementInform(uint32 /*type*/, uint32 pointId) override + { + switch (pointId) + { + case POINT_STORM: + events.ScheduleEvent(EVENT_CAST_STORM, 1); + break; + } + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + events.Update(diff); + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_RANDOM_CAST: + switch (urand(0, 1)) + { + case 0: + if (!_skewer) + { + if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO, 0)) + { + DoCast(target, SPELL_SKEWER, true); + Talk(SAY_SKEWER); + Talk(SAY_SKEWER_ANNOUNCE, target); + } + _skewer = true; + events.ScheduleEvent(EVENT_RANDOM_CAST, urand(7000, 10000)); + } + else if (!_hate) + { + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, NonTankTargetSelector(me))) + { + DoCast(target, SPELL_SEETHING_HATE, true); + Talk(SAY_HATE); + } + _hate = true; + events.ScheduleEvent(EVENT_RANDOM_CAST, urand(7000, 10000)); + } + else if (_hate && _skewer) + { + Talk(SAY_BLADE_STORM); + DoCastAOE(SPELL_BLADE_DANCE_DUMMY); + DoCastAOE(SPELL_BLADE_DANCE); + events.ScheduleEvent(EVENT_RANDOM_CAST, 21000); + events.ScheduleEvent(EVENT_MOVE_STORM, 4050); + events.ScheduleEvent(EVENT_STOP_STORM, 13000); + } + break; + case 1: + if (!_hate) + { + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, NonTankTargetSelector(me))) + { + DoCast(target, SPELL_SEETHING_HATE, true); + Talk(SAY_HATE); + } + _hate = true; + events.ScheduleEvent(EVENT_RANDOM_CAST, urand(7000, 10000)); + } + else if (!_skewer) + { + if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO, 0)) + { + DoCast(target, SPELL_SKEWER, true); + Talk(SAY_SKEWER); + Talk(SAY_SKEWER_ANNOUNCE, target); + } + _skewer = true; + events.ScheduleEvent(EVENT_RANDOM_CAST, urand(7000, 10000)); + } + else if (_hate && _skewer) + { + Talk(SAY_BLADE_STORM); + DoCastAOE(SPELL_BLADE_DANCE_DUMMY); + DoCastAOE(SPELL_BLADE_DANCE); + events.ScheduleEvent(EVENT_RANDOM_CAST, 21000); + events.ScheduleEvent(EVENT_MOVE_STORM, 4050); + events.ScheduleEvent(EVENT_STOP_STORM, 13000); + } + break; + } + break; + case EVENT_MOVE_STORM: + me->SetSpeed(MOVE_RUN, 4.0f); + me->SetSpeed(MOVE_WALK, 4.0f); + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, NonTankTargetSelector(me))) + me->GetMotionMaster()->MovePoint(POINT_STORM, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()); + events.ScheduleEvent(EVENT_MOVE_STORM, 4050); + break; + case EVENT_STOP_STORM: + me->RemoveAura(SPELL_BLADE_DANCE); + me->RemoveAura(SPELL_BLADE_DANCE_DUMMY); + me->SetSpeed(MOVE_WALK, 1.0f); + me->SetSpeed(MOVE_RUN, 1.14f); + me->GetMotionMaster()->MoveChase(me->GetVictim()); + _hate = false; + _skewer = false; + break; + case EVENT_CAST_STORM: + DoCastAOE(SPELL_BLADE_DANCE); + break; + } + } + + DoMeleeAttackIfReady(); + } + + private: + bool _intro; + bool _hate; + bool _skewer; + + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetBaradinHoldAI<boss_alizabalAI>(creature); + } +}; + +void AddSC_boss_alizabal() +{ + new boss_alizabal(); + new at_alizabal_intro(); +} diff --git a/src/server/scripts/EasternKingdoms/BaradinHold/boss_occuthar.cpp b/src/server/scripts/EasternKingdoms/BaradinHold/boss_occuthar.cpp new file mode 100644 index 00000000000..ca2679b042a --- /dev/null +++ b/src/server/scripts/EasternKingdoms/BaradinHold/boss_occuthar.cpp @@ -0,0 +1,392 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * 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/>. + */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "Vehicle.h" +#include "SpellScript.h" +#include "SpellAuraEffects.h" +#include "baradin_hold.h" + +enum Spells +{ + SPELL_SEARING_SHADOWS = 96913, + SPELL_FOCUSED_FIRE_FIRST_DAMAGE = 97212, + SPELL_FOCUSED_FIRE_TRIGGER = 96872, + SPELL_FOCUSED_FIRE_VISUAL = 96886, + SPELL_FOCUSED_FIRE = 96884, + SPELL_EYES_OF_OCCUTHAR = 96920, + SPELL_GAZE_OF_OCCUTHAR = 96942, + SPELL_OCCUTHARS_DESTUCTION = 96968, + SPELL_BERSERK = 47008 +}; + +enum Events +{ + EVENT_SEARING_SHADOWS = 1, + EVENT_FOCUSED_FIRE = 2, + EVENT_EYES_OF_OCCUTHAR = 3, + EVENT_BERSERK = 4, + + EVENT_FOCUSED_FIRE_FIRST_DAMAGE = 1 +}; + +enum Misc +{ + MAX_OCCUTHAR_VEHICLE_SEATS = 7 +}; + +class boss_occuthar : public CreatureScript +{ + public: + boss_occuthar() : CreatureScript("boss_occuthar") { } + + struct boss_occutharAI : public BossAI + { + boss_occutharAI(Creature* creature) : BossAI(creature, DATA_OCCUTHAR), + _vehicle(me->GetVehicleKit()) + { + ASSERT(_vehicle); + } + + void EnterCombat(Unit* /*who*/) override + { + _EnterCombat(); + instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me); + events.ScheduleEvent(EVENT_SEARING_SHADOWS, 8 * IN_MILLISECONDS); + events.ScheduleEvent(EVENT_FOCUSED_FIRE, 15 * IN_MILLISECONDS); + events.ScheduleEvent(EVENT_EYES_OF_OCCUTHAR, 30 * IN_MILLISECONDS); + events.ScheduleEvent(EVENT_BERSERK, 5 * MINUTE * IN_MILLISECONDS); + } + + void EnterEvadeMode() override + { + BossAI::EnterEvadeMode(); + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); + _DespawnAtEvade(); + } + + void JustDied(Unit* /*killer*/) override + { + _JustDied(); + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); + } + + void JustSummoned(Creature* summon) override + { + summons.Summon(summon); + + if (summon->GetEntry() == NPC_FOCUS_FIRE_DUMMY) + { + DoCast(summon, SPELL_FOCUSED_FIRE); + + for (uint8 i = 0; i < MAX_OCCUTHAR_VEHICLE_SEATS; ++i) + { + if (Unit* vehicle = _vehicle->GetPassenger(i)) + vehicle->CastSpell(summon, SPELL_FOCUSED_FIRE_VISUAL); + } + } + } + + 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_SEARING_SHADOWS: + DoCastAOE(SPELL_SEARING_SHADOWS); + events.ScheduleEvent(EVENT_SEARING_SHADOWS, 25 * IN_MILLISECONDS); + break; + case EVENT_FOCUSED_FIRE: + DoCastAOE(SPELL_FOCUSED_FIRE_TRIGGER, true); + events.ScheduleEvent(EVENT_FOCUSED_FIRE, 15 * IN_MILLISECONDS); + break; + case EVENT_EYES_OF_OCCUTHAR: + DoCastAOE(SPELL_EYES_OF_OCCUTHAR); + events.RescheduleEvent(EVENT_FOCUSED_FIRE, 15 * IN_MILLISECONDS); + events.ScheduleEvent(EVENT_EYES_OF_OCCUTHAR, 60 * IN_MILLISECONDS); + break; + case EVENT_BERSERK: + DoCast(me, SPELL_BERSERK, true); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } + + private: + Vehicle* _vehicle; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetBaradinHoldAI<boss_occutharAI>(creature); + } +}; + +class npc_eyestalk : public CreatureScript +{ + public: + npc_eyestalk() : CreatureScript("npc_eyestalk") { } + + struct npc_eyestalkAI : public ScriptedAI + { + npc_eyestalkAI(Creature* creature) : ScriptedAI(creature), + _instance(creature->GetInstanceScript()) + { + _damageCount = 0; + } + + void IsSummonedBy(Unit* /*summoner*/) override + { + // player is the spellcaster so register summon manually + if (Creature* occuthar = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_OCCUTHAR))) + occuthar->AI()->JustSummoned(me); + } + + void Reset() override + { + _events.Reset(); + _events.ScheduleEvent(EVENT_FOCUSED_FIRE_FIRST_DAMAGE, 0); + } + + void UpdateAI(uint32 diff) override + { + _events.Update(diff); + + if (_events.ExecuteEvent() == EVENT_FOCUSED_FIRE_FIRST_DAMAGE) + { + DoCastAOE(SPELL_FOCUSED_FIRE_FIRST_DAMAGE); + if (++_damageCount < 2) + _events.ScheduleEvent(EVENT_FOCUSED_FIRE_FIRST_DAMAGE, 1 * IN_MILLISECONDS); + } + } + + void EnterEvadeMode() override { } // Never evade + + private: + InstanceScript* _instance; + EventMap _events; + uint8 _damageCount; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetBaradinHoldAI<npc_eyestalkAI>(creature); + } +}; + +class FocusedFireTargetSelector : public std::unary_function<Unit *, bool> +{ + public: + FocusedFireTargetSelector(Creature* me, const Unit* victim) : _me(me), _victim(victim) { } + + bool operator() (WorldObject* target) + { + if (target == _victim && _me->getThreatManager().getThreatList().size() > 1) + return true; + + if (target->GetTypeId() != TYPEID_PLAYER) + return true; + + return false; + } + + Creature* _me; + Unit const* _victim; +}; + +// 96872 - Focused Fire +class spell_occuthar_focused_fire : public SpellScriptLoader +{ + public: + spell_occuthar_focused_fire() : SpellScriptLoader("spell_occuthar_focused_fire") { } + + class spell_occuthar_focused_fire_SpellScript : public SpellScript + { + PrepareSpellScript(spell_occuthar_focused_fire_SpellScript); + + void FilterTargets(std::list<WorldObject*>& targets) + { + if (targets.empty()) + return; + + targets.remove_if(FocusedFireTargetSelector(GetCaster()->ToCreature(), GetCaster()->GetVictim())); + WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets); + targets.clear(); + targets.push_back(target); + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_occuthar_focused_fire_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_occuthar_focused_fire_SpellScript(); + } +}; + +// ID - 96931 Eyes of Occu'thar +class spell_occuthar_eyes_of_occuthar : public SpellScriptLoader +{ + public: + spell_occuthar_eyes_of_occuthar() : SpellScriptLoader("spell_occuthar_eyes_of_occuthar") { } + + class spell_occuthar_eyes_of_occuthar_SpellScript : public SpellScript + { + PrepareSpellScript(spell_occuthar_eyes_of_occuthar_SpellScript); + + bool Validate(SpellInfo const* spellInfo) override + { + if (!sSpellMgr->GetSpellInfo(spellInfo->Effects[EFFECT_0].CalcValue())) + return false; + return true; + } + + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } + + void FilterTargets(std::list<WorldObject*>& targets) + { + if (targets.empty()) + return; + + WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets); + targets.clear(); + targets.push_back(target); + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + GetHitUnit()->CastSpell(GetCaster(), GetEffectValue(), true); + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_occuthar_eyes_of_occuthar_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); + OnEffectHitTarget += SpellEffectFn(spell_occuthar_eyes_of_occuthar_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_occuthar_eyes_of_occuthar_SpellScript(); + } +}; + +// ID - 96932 Eyes of Occu'thar +class spell_occuthar_eyes_of_occuthar_vehicle : public SpellScriptLoader +{ + public: + spell_occuthar_eyes_of_occuthar_vehicle() : SpellScriptLoader("spell_occuthar_eyes_of_occuthar_vehicle") { } + + class spell_occuthar_eyes_of_occuthar_vehicle_SpellScript : public SpellScript + { + PrepareSpellScript(spell_occuthar_eyes_of_occuthar_vehicle_SpellScript); + + bool Load() override + { + return GetCaster()->GetInstanceScript() != NULL; + } + + void HandleScript() + { + Position pos = GetHitUnit()->GetPosition(); + + if (Creature* occuthar = ObjectAccessor::GetCreature(*GetCaster(), GetCaster()->GetInstanceScript()->GetData64(DATA_OCCUTHAR))) + { + if (Creature* creature = occuthar->SummonCreature(NPC_EYE_OF_OCCUTHAR, pos)) + creature->CastSpell(GetHitUnit(), SPELL_GAZE_OF_OCCUTHAR, false); + } + } + + void Register() override + { + AfterHit += SpellHitFn(spell_occuthar_eyes_of_occuthar_vehicle_SpellScript::HandleScript); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_occuthar_eyes_of_occuthar_vehicle_SpellScript(); + } +}; + +// 96942 / 101009 - Gaze of Occu'thar +class spell_occuthar_occuthars_destruction : public SpellScriptLoader +{ + public: + spell_occuthar_occuthars_destruction() : SpellScriptLoader("spell_occuthar_occuthars_destruction") { } + + class spell_occuthar_occuthars_destruction_AuraScript : public AuraScript + { + PrepareAuraScript(spell_occuthar_occuthars_destruction_AuraScript); + + bool Load() override + { + return GetCaster() && GetCaster()->GetTypeId() == TYPEID_UNIT; + } + + void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) + { + if (Unit* caster = GetCaster()) + { + if (IsExpired()) + caster->CastSpell((Unit*)NULL, SPELL_OCCUTHARS_DESTUCTION, true, NULL, aurEff); + + caster->ToCreature()->DespawnOrUnsummon(500); + } + } + + void Register() override + { + OnEffectRemove += AuraEffectRemoveFn(spell_occuthar_occuthars_destruction_AuraScript::OnRemove, EFFECT_2, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_occuthar_occuthars_destruction_AuraScript(); + } +}; + +void AddSC_boss_occuthar() +{ + new boss_occuthar(); + new npc_eyestalk(); + new spell_occuthar_focused_fire(); + new spell_occuthar_eyes_of_occuthar(); + new spell_occuthar_eyes_of_occuthar_vehicle(); + new spell_occuthar_occuthars_destruction(); +} diff --git a/src/server/scripts/EasternKingdoms/BaradinHold/boss_pit_lord_argaloth.cpp b/src/server/scripts/EasternKingdoms/BaradinHold/boss_pit_lord_argaloth.cpp new file mode 100644 index 00000000000..008803f9a52 --- /dev/null +++ b/src/server/scripts/EasternKingdoms/BaradinHold/boss_pit_lord_argaloth.cpp @@ -0,0 +1,200 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * 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/>. + */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "SpellScript.h" +#include "baradin_hold.h" + +/* TODO: +- Fel Firestorm need completion +- Need Correct timer +*/ + +enum Spells +{ + SPELL_METEOR_SLASH = 88942, + SPELL_CONSUMING_DARKNESS = 88954, + SPELL_FEL_FIRESTORM = 88972, + SPELL_BERSERK = 47008 +}; + +enum Events +{ + EVENT_METEOR_SLASH = 1, + EVENT_CONSUMING_DARKNESS = 2, + EVENT_BERSERK = 3 +}; + +class boss_pit_lord_argaloth : public CreatureScript +{ + public: + boss_pit_lord_argaloth() : CreatureScript("boss_pit_lord_argaloth") { } + + struct boss_pit_lord_argalothAI : public BossAI + { + boss_pit_lord_argalothAI(Creature* creature) : BossAI(creature, DATA_ARGALOTH) { } + + void EnterCombat(Unit* /*who*/) override + { + _EnterCombat(); + instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me); + events.ScheduleEvent(EVENT_METEOR_SLASH, urand(10 * IN_MILLISECONDS, 20 * IN_MILLISECONDS)); + events.ScheduleEvent(EVENT_CONSUMING_DARKNESS, urand(20 * IN_MILLISECONDS, 25 * IN_MILLISECONDS)); + events.ScheduleEvent(EVENT_BERSERK, 5 * MINUTE * IN_MILLISECONDS); + } + + void EnterEvadeMode() override + { + me->GetMotionMaster()->MoveTargetedHome(); + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); + _DespawnAtEvade(); + } + + void DamageTaken(Unit* /*attacker*/, uint32& damage) override + { + if (me->HealthBelowPctDamaged(33, damage) || + me->HealthBelowPctDamaged(66, damage)) + { + DoCastAOE(SPELL_FEL_FIRESTORM); + } + } + + void JustDied(Unit* /*killer*/) override + { + _JustDied(); + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); + } + + 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_METEOR_SLASH: + DoCastAOE(SPELL_METEOR_SLASH); + events.ScheduleEvent(EVENT_METEOR_SLASH, urand(15 * IN_MILLISECONDS, 20 * IN_MILLISECONDS)); + break; + case EVENT_CONSUMING_DARKNESS: + DoCastAOE(SPELL_CONSUMING_DARKNESS, true); + events.ScheduleEvent(EVENT_CONSUMING_DARKNESS, urand(20 * IN_MILLISECONDS, 25 * IN_MILLISECONDS)); + break; + case EVENT_BERSERK: + DoCast(me, SPELL_BERSERK, true); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetBaradinHoldAI<boss_pit_lord_argalothAI>(creature); + } +}; + +// 88954 / 95173 - Consuming Darkness +class spell_argaloth_consuming_darkness : public SpellScriptLoader +{ + public: + spell_argaloth_consuming_darkness() : SpellScriptLoader("spell_argaloth_consuming_darkness") { } + + class spell_argaloth_consuming_darkness_SpellScript : public SpellScript + { + PrepareSpellScript(spell_argaloth_consuming_darkness_SpellScript); + + void FilterTargets(std::list<WorldObject*>& targets) + { + Trinity::Containers::RandomResizeList(targets, GetCaster()->GetMap()->Is25ManRaid() ? 8 : 3); + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_argaloth_consuming_darkness_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_argaloth_consuming_darkness_SpellScript(); + } +}; + +// 88942 / 95172 - Meteor Slash +class spell_argaloth_meteor_slash : public SpellScriptLoader +{ + public: + spell_argaloth_meteor_slash() : SpellScriptLoader("spell_argaloth_meteor_slash") { } + + class spell_argaloth_meteor_slash_SpellScript : public SpellScript + { + PrepareSpellScript(spell_argaloth_meteor_slash_SpellScript); + + bool Load() override + { + _targetCount = 0; + return true; + } + + void CountTargets(std::list<WorldObject*>& targets) + { + _targetCount = targets.size(); + } + + void SplitDamage() + { + if (!_targetCount) + return; + + SetHitDamage(GetHitDamage() / _targetCount); + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_argaloth_meteor_slash_SpellScript::CountTargets, EFFECT_0, TARGET_UNIT_CONE_ENEMY_104); + OnHit += SpellHitFn(spell_argaloth_meteor_slash_SpellScript::SplitDamage); + } + + private: + uint32 _targetCount; + }; + + SpellScript* GetSpellScript() const override + { + return new spell_argaloth_meteor_slash_SpellScript(); + } +}; + +void AddSC_boss_pit_lord_argaloth() +{ + new boss_pit_lord_argaloth(); + new spell_argaloth_consuming_darkness(); + new spell_argaloth_meteor_slash(); +} diff --git a/src/server/scripts/EasternKingdoms/BaradinHold/instance_baradin_hold.cpp b/src/server/scripts/EasternKingdoms/BaradinHold/instance_baradin_hold.cpp new file mode 100644 index 00000000000..f1fec5f1453 --- /dev/null +++ b/src/server/scripts/EasternKingdoms/BaradinHold/instance_baradin_hold.cpp @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * 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 3 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/>. + */ + +#include "ScriptMgr.h" +#include "InstanceScript.h" +#include "baradin_hold.h" + +DoorData const doorData[] = +{ + { GO_ARGALOTH_DOOR, DATA_ARGALOTH, DOOR_TYPE_ROOM, BOUNDARY_NONE }, + { GO_OCCUTHAR_DOOR, DATA_OCCUTHAR, DOOR_TYPE_ROOM, BOUNDARY_NONE }, + { GO_ALIZABAL_DOOR, DATA_ALIZABAL, DOOR_TYPE_ROOM, BOUNDARY_NONE }, + { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END +}; + +class instance_baradin_hold: public InstanceMapScript +{ + public: + instance_baradin_hold() : InstanceMapScript(BHScriptName, 757) { } + + struct instance_baradin_hold_InstanceMapScript: public InstanceScript + { + instance_baradin_hold_InstanceMapScript(InstanceMap* map) : InstanceScript(map) + { + SetBossNumber(EncounterCount); + LoadDoorData(doorData); + + ArgalothGUID = 0; + OccutharGUID = 0; + AlizabalGUID = 0; + } + + void OnCreatureCreate(Creature* creature) override + { + switch(creature->GetEntry()) + { + case BOSS_ARGALOTH: + ArgalothGUID = creature->GetGUID(); + break; + case BOSS_OCCUTHAR: + OccutharGUID = creature->GetGUID(); + break; + case BOSS_ALIZABAL: + AlizabalGUID = creature->GetGUID(); + break; + } + } + + void OnGameObjectCreate(GameObject* go) override + { + switch(go->GetEntry()) + { + case GO_ARGALOTH_DOOR: + case GO_OCCUTHAR_DOOR: + case GO_ALIZABAL_DOOR: + AddDoor(go, true); + break; + } + } + + uint64 GetData64(uint32 data) const override + { + switch (data) + { + case DATA_ARGALOTH: + return ArgalothGUID; + case DATA_OCCUTHAR: + return OccutharGUID; + case DATA_ALIZABAL: + return AlizabalGUID; + default: + break; + } + + return 0; + } + + void OnGameObjectRemove(GameObject* go) override + { + switch(go->GetEntry()) + { + case GO_ARGALOTH_DOOR: + case GO_OCCUTHAR_DOOR: + case GO_ALIZABAL_DOOR: + AddDoor(go, false); + break; + } + } + + std::string GetSaveData() override + { + OUT_SAVE_INST_DATA; + + std::ostringstream saveStream; + saveStream << "B H " << GetBossSaveData(); + + OUT_SAVE_INST_DATA_COMPLETE; + return saveStream.str(); + } + + void Load(const char* in) override + { + if (!in) + { + OUT_LOAD_INST_DATA_FAIL; + return; + } + + OUT_LOAD_INST_DATA(in); + + char dataHead1, dataHead2; + + std::istringstream loadStream(in); + loadStream >> dataHead1 >> dataHead2; + + if (dataHead1 == 'B' && dataHead2 == 'H') + { + for (uint8 i = 0; i < EncounterCount; ++i) + { + uint32 tmpState; + loadStream >> tmpState; + if (tmpState == IN_PROGRESS || tmpState > SPECIAL) + tmpState = NOT_STARTED; + + SetBossState(i, EncounterState(tmpState)); + } + + } + else + OUT_LOAD_INST_DATA_FAIL; + + OUT_LOAD_INST_DATA_COMPLETE; + } + + protected: + uint64 ArgalothGUID; + uint64 OccutharGUID; + uint64 AlizabalGUID; + }; + + InstanceScript* GetInstanceScript(InstanceMap* map) const + { + return new instance_baradin_hold_InstanceMapScript(map); + } +}; + +void AddSC_instance_baradin_hold() +{ + new instance_baradin_hold(); +} diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp index 23a7cb10dd8..f7aedb42561 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp @@ -262,7 +262,7 @@ public: case EVENT_SUCCESS_1: if (Unit* player = me->SelectNearestPlayer(60.0f)) { - me->SetInFront(player); + me->SetFacingToObject(player); Talk(SAY_SUCCESS); if (GameObject* portcullis1 = me->FindNearestGameObject(GO_PORTCULLIS_ACTIVE, 65.0f)) portcullis1->SetGoState(GO_STATE_ACTIVE); diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_vaelastrasz.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_vaelastrasz.cpp index bbe70947901..5d7e7403686 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_vaelastrasz.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_vaelastrasz.cpp @@ -146,8 +146,8 @@ public: break; case EVENT_SPEECH_4: me->setFaction(103); - if (PlayerGUID && ObjectAccessor::GetUnit(*me, PlayerGUID)) - AttackStart(ObjectAccessor::GetUnit(*me, PlayerGUID));; + if (Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID)) + AttackStart(player); break; } } diff --git a/src/server/scripts/EasternKingdoms/CMakeLists.txt b/src/server/scripts/EasternKingdoms/CMakeLists.txt index 4adb087921b..1e0e05840c4 100644 --- a/src/server/scripts/EasternKingdoms/CMakeLists.txt +++ b/src/server/scripts/EasternKingdoms/CMakeLists.txt @@ -17,6 +17,10 @@ set(scripts_STAT_SRCS EasternKingdoms/AlteracValley/boss_drekthar.cpp EasternKingdoms/AlteracValley/boss_vanndar.cpp EasternKingdoms/AlteracValley/alterac_valley.cpp + EasternKingdoms/BaradinHold/boss_alizabal.cpp + EasternKingdoms/BaradinHold/boss_occuthar.cpp + EasternKingdoms/BaradinHold/boss_pit_lord_argaloth.cpp + EasternKingdoms/BaradinHold/instance_baradin_hold.cpp EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_high_interrogator_gerstahn.cpp EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_gorosh_the_dervish.cpp EasternKingdoms/BlackrockMountain/BlackrockDepths/blackrock_depths.cpp @@ -85,22 +89,17 @@ set(scripts_STAT_SRCS EasternKingdoms/Scholomance/boss_ras_frostwhisper.cpp EasternKingdoms/Scholomance/boss_kirtonos_the_herald.cpp EasternKingdoms/zone_isle_of_queldanas.cpp - EasternKingdoms/boss_kruul.cpp - EasternKingdoms/ZulGurub/boss_hakkar.cpp - EasternKingdoms/ZulGurub/boss_mandokir.cpp - EasternKingdoms/ZulGurub/boss_marli.cpp - EasternKingdoms/ZulGurub/boss_hazzarah.cpp - EasternKingdoms/ZulGurub/boss_jeklik.cpp EasternKingdoms/ZulGurub/boss_grilek.cpp - EasternKingdoms/ZulGurub/zulgurub.h + EasternKingdoms/ZulGurub/boss_hazzarah.cpp + EasternKingdoms/ZulGurub/boss_jindo_the_godbreaker.cpp + EasternKingdoms/ZulGurub/boss_kilnara.cpp + EasternKingdoms/ZulGurub/boss_mandokir.cpp EasternKingdoms/ZulGurub/boss_renataki.cpp - EasternKingdoms/ZulGurub/boss_arlokk.cpp - EasternKingdoms/ZulGurub/boss_gahzranka.cpp EasternKingdoms/ZulGurub/boss_venoxis.cpp - EasternKingdoms/ZulGurub/instance_zulgurub.cpp - EasternKingdoms/ZulGurub/boss_jindo.cpp EasternKingdoms/ZulGurub/boss_wushoolay.cpp - EasternKingdoms/ZulGurub/boss_thekal.cpp + EasternKingdoms/ZulGurub/boss_zanzil.cpp + EasternKingdoms/ZulGurub/instance_zulgurub.cpp + EasternKingdoms/ZulGurub/zulgurub.h EasternKingdoms/zone_wetlands.cpp EasternKingdoms/zone_arathi_highlands.cpp EasternKingdoms/Gnomeregan/instance_gnomeregan.cpp @@ -181,7 +180,7 @@ set(scripts_STAT_SRCS EasternKingdoms/zone_stormwind_city.cpp EasternKingdoms/ZulAman/boss_halazzi.cpp EasternKingdoms/ZulAman/boss_hexlord.cpp - EasternKingdoms/ZulAman/boss_zuljin.cpp + EasternKingdoms/ZulAman/boss_daakara.cpp EasternKingdoms/ZulAman/boss_akilzon.cpp EasternKingdoms/ZulAman/instance_zulaman.cpp EasternKingdoms/ZulAman/boss_janalai.cpp diff --git a/src/server/scripts/EasternKingdoms/Deadmines/deadmines.cpp b/src/server/scripts/EasternKingdoms/Deadmines/deadmines.cpp index 15d3f6225e1..59610b20015 100644 --- a/src/server/scripts/EasternKingdoms/Deadmines/deadmines.cpp +++ b/src/server/scripts/EasternKingdoms/Deadmines/deadmines.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2014 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,13 +15,6 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Deadmines -SD%Complete: 0 -SDComment: Placeholder -SDCategory: Deadmines -EndScriptData */ - #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "deadmines.h" @@ -30,37 +22,6 @@ EndScriptData */ #include "Player.h" #include "WorldSession.h" -/*##### -# item_Defias_Gunpowder -#####*/ - -class item_defias_gunpowder : public ItemScript -{ -public: - item_defias_gunpowder() : ItemScript("item_defias_gunpowder") { } - - bool OnUse(Player* player, Item* item, SpellCastTargets const& targets) override - { - InstanceScript* instance = player->GetInstanceScript(); - - if (!instance) - { - player->GetSession()->SendNotification("Instance script not initialized"); - return true; - } - - if (instance->GetData(EVENT_STATE) != CANNON_NOT_USED) - return false; - - if (targets.GetGOTarget() && targets.GetGOTarget()->GetEntry() == GO_DEFIAS_CANNON) - instance->SetData(EVENT_STATE, CANNON_GUNPOWDER_USED); - - player->DestroyItemCount(item->GetEntry(), 1, true); - return true; - } -}; - void AddSC_deadmines() { - new item_defias_gunpowder(); } diff --git a/src/server/scripts/EasternKingdoms/Deadmines/instance_deadmines.cpp b/src/server/scripts/EasternKingdoms/Deadmines/instance_deadmines.cpp index 050ef1eb642..2124e72d9ee 100644 --- a/src/server/scripts/EasternKingdoms/Deadmines/instance_deadmines.cpp +++ b/src/server/scripts/EasternKingdoms/Deadmines/instance_deadmines.cpp @@ -242,6 +242,7 @@ class instance_deadmines : public InstanceMapScript { WorldPacket data(SMSG_PLAY_SOUND, 4); data << uint32(sound); + data << uint64(unit->GetGUID()); unit->SendMessageToSet(&data, false); } }; diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_terestian_illhoof.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_terestian_illhoof.cpp index 3b499b649cf..2cdaf4b4e4a 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/boss_terestian_illhoof.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_terestian_illhoof.cpp @@ -64,7 +64,6 @@ enum Creatures NPC_KILREK = 17229 }; - class npc_kilrek : public CreatureScript { public: diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp index 46c566f62bd..fff8a92dfcd 100644 --- a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp @@ -1030,6 +1030,8 @@ class npc_scarlet_miner : public CreatureScript if (Unit* car = ObjectAccessor::GetCreature(*me, carGUID)) { me->SetFacingToObject(car); + car->Relocate(car->GetPositionX(), car->GetPositionY(), me->GetPositionZ() + 1); + car->StopMoving(); car->RemoveAura(SPELL_CART_DRAG); } Talk(SAY_SCARLET_MINER_1); diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/zone_the_scarlet_enclave.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/zone_the_scarlet_enclave.cpp index 43dee1338ef..cad51dd55e0 100644 --- a/src/server/scripts/EasternKingdoms/ScarletEnclave/zone_the_scarlet_enclave.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/zone_the_scarlet_enclave.cpp @@ -99,7 +99,7 @@ public: FlyBackTimer = 4500; break; case 2: - if (!player->isResurrectRequested()) + if (!player->IsResurrectRequested()) { me->HandleEmoteCommand(EMOTE_ONESHOT_CUSTOM_SPELL_01); DoCast(player, SPELL_REVIVE, true); diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp index 9810c42bdfb..f67e8d2712e 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2014 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,67 +15,19 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: boss_Akilzon -SD%Complete: 75% -SDComment: Missing timer for Call Lightning and Sound ID's -SQLUpdate: -#Temporary fix for Soaring Eagles - -EndScriptData */ - #include "ScriptMgr.h" #include "ScriptedCreature.h" -#include "GridNotifiers.h" -#include "GridNotifiersImpl.h" -#include "Cell.h" -#include "CellImpl.h" #include "zulaman.h" -#include "Weather.h" - -enum Spells -{ - SPELL_STATIC_DISRUPTION = 43622, - SPELL_STATIC_VISUAL = 45265, - SPELL_CALL_LIGHTNING = 43661, // Missing timer - SPELL_GUST_OF_WIND = 43621, - SPELL_ELECTRICAL_STORM = 43648, - SPELL_BERSERK = 45078, - SPELL_ELECTRICAL_OVERLOAD = 43658, - SPELL_EAGLE_SWOOP = 44732, - SPELL_ZAP = 43137, - SPELL_SAND_STORM = 25160 -}; enum Says { - SAY_AGGRO = 0, - SAY_SUMMON = 1, - SAY_INTRO = 2, // Not used in script - SAY_ENRAGE = 3, - SAY_KILL = 4, - SAY_DEATH = 5 -}; - -enum Misc -{ - NPC_SOARING_EAGLE = 24858, - SE_LOC_X_MAX = 400, - SE_LOC_X_MIN = 335, - SE_LOC_Y_MAX = 1435, - SE_LOC_Y_MIN = 1370 -}; - -enum Events -{ - EVENT_STATIC_DISRUPTION = 1, - EVENT_GUST_OF_WIND = 2, - EVENT_CALL_LIGHTNING = 3, - EVENT_ELECTRICAL_STORM = 4, - EVENT_RAIN = 5, - EVENT_SUMMON_EAGLES = 6, - EVENT_STORM_SEQUENCE = 7, - EVENT_ENRAGE = 8 + SAY_AGGRO = 0, + SAY_PLAYER_KILL = 1, + EMOTE_ELECTRICAL_STORM = 2, + SAY_SUMMON_EAGLE = 3, + SAY_SUMMON_BIRDS = 4, + SAY_BERSERK = 5, + SAY_DEATH = 6 }; class boss_akilzon : public CreatureScript @@ -86,37 +37,17 @@ class boss_akilzon : public CreatureScript struct boss_akilzonAI : public BossAI { - boss_akilzonAI(Creature* creature) : BossAI(creature, DATA_AKILZONEVENT) - { - memset(BirdGUIDs, 0, sizeof(BirdGUIDs)); - } + boss_akilzonAI(Creature* creature) : BossAI(creature, DATA_AKILZON) { } void Reset() override { _Reset(); - - TargetGUID = 0; - CloudGUID = 0; - CycloneGUID = 0; - memset(BirdGUIDs, 0, sizeof(BirdGUIDs)); - StormCount = 0; - isRaining = false; - - SetWeather(WEATHER_STATE_FINE, 0.0f); } void EnterCombat(Unit* /*who*/) override { - events.ScheduleEvent(EVENT_STATIC_DISRUPTION, urand(10000, 20000)); // 10 to 20 seconds (bosskillers) - events.ScheduleEvent(EVENT_GUST_OF_WIND, urand(20000, 30000)); // 20 to 30 seconds(bosskillers) - events.ScheduleEvent(EVENT_CALL_LIGHTNING, urand(10000, 20000)); // totaly random timer. can't find any info on this - events.ScheduleEvent(EVENT_ELECTRICAL_STORM, 60000); // 60 seconds(bosskillers) - events.ScheduleEvent(EVENT_RAIN, urand(47000, 52000)); - events.ScheduleEvent(EVENT_ENRAGE, 10*MINUTE*IN_MILLISECONDS); // 10 minutes till enrage(bosskillers) - Talk(SAY_AGGRO); - //DoZoneInCombat(); - instance->SetData(DATA_AKILZONEVENT, IN_PROGRESS); + _EnterCombat(); } void JustDied(Unit* /*killer*/) override @@ -128,90 +59,7 @@ class boss_akilzon : public CreatureScript void KilledUnit(Unit* who) override { if (who->GetTypeId() == TYPEID_PLAYER) - Talk(SAY_KILL); - } - - void SetWeather(uint32 weather, float grade) - { - Map* map = me->GetMap(); - if (!map->IsDungeon()) - return; - - WorldPacket data(SMSG_WEATHER, (4+4+4)); - data << uint32(weather) << float(grade) << uint8(0); - - map->SendToPlayers(&data); - } - - void HandleStormSequence(Unit* Cloud) // 1: begin, 2-9: tick, 10: end - { - if (StormCount < 10 && StormCount > 1) - { - // deal damage - int32 bp0 = 800; - for (uint8 i = 2; i < StormCount; ++i) - bp0 *= 2; - - CellCoord p(Trinity::ComputeCellCoord(me->GetPositionX(), me->GetPositionY())); - Cell cell(p); - cell.SetNoCreate(); - - std::list<Unit*> tempUnitMap; - - { - Trinity::AnyAoETargetUnitInObjectRangeCheck u_check(me, me, SIZE_OF_GRIDS); - Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck> searcher(me, tempUnitMap, u_check); - - TypeContainerVisitor<Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck>, WorldTypeMapContainer > world_unit_searcher(searcher); - TypeContainerVisitor<Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck>, GridTypeMapContainer > grid_unit_searcher(searcher); - - cell.Visit(p, world_unit_searcher, *me->GetMap(), *me, SIZE_OF_GRIDS); - cell.Visit(p, grid_unit_searcher, *me->GetMap(), *me, SIZE_OF_GRIDS); - } - - // deal damage - for (std::list<Unit*>::const_iterator i = tempUnitMap.begin(); i != tempUnitMap.end(); ++i) - { - if (Unit* target = (*i)) - { - if (Cloud && !Cloud->IsWithinDist(target, 6, false)) - Cloud->CastCustomSpell(target, SPELL_ZAP, &bp0, NULL, NULL, true, 0, 0, me->GetGUID()); - } - } - - // visual - float x, y, z; - z = me->GetPositionZ(); - for (uint8 i = 0; i < 5+rand()%5; ++i) - { - x = 343.0f+rand()%60; - y = 1380.0f+rand()%60; - if (Unit* trigger = me->SummonTrigger(x, y, z, 0, 2000)) - { - trigger->setFaction(35); - trigger->SetMaxHealth(100000); - trigger->SetHealth(100000); - trigger->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - if (Cloud) - Cloud->CastCustomSpell(trigger, /*43661*/SPELL_ZAP, &bp0, NULL, NULL, true, 0, 0, Cloud->GetGUID()); - } - } - } - - ++StormCount; - - if (StormCount > 10) - { - StormCount = 0; // finish - events.ScheduleEvent(EVENT_SUMMON_EAGLES, 5000); - me->InterruptNonMeleeSpells(false); - CloudGUID = 0; - if (Cloud) - Cloud->DealDamage(Cloud, Cloud->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); - SetWeather(WEATHER_STATE_FINE, 0.0f); - isRaining = false; - } - events.ScheduleEvent(EVENT_STORM_SEQUENCE, 1000); + Talk(SAY_PLAYER_KILL); } void UpdateAI(uint32 diff) override @@ -221,149 +69,21 @@ class boss_akilzon : public CreatureScript events.Update(diff); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + /* while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { - case EVENT_STATIC_DISRUPTION: - { - Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1); - if (!target) - target = me->GetVictim(); - if (target) - { - TargetGUID = target->GetGUID(); - DoCast(target, SPELL_STATIC_DISRUPTION, false); - me->SetInFront(me->GetVictim()); - } - /*if (float dist = me->IsWithinDist3d(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 5.0f) dist = 5.0f; - SDisruptAOEVisual_Timer = 1000 + floor(dist / 30 * 1000.0f);*/ - events.ScheduleEvent(EVENT_STATIC_DISRUPTION, urand(10000, 18000)); - break; - } - case EVENT_GUST_OF_WIND: - { - Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1); - if (!target) - target = me->GetVictim(); - if (target) - DoCast(target, SPELL_GUST_OF_WIND); - events.ScheduleEvent(EVENT_GUST_OF_WIND, urand(20000, 30000)); - break; - } - case EVENT_CALL_LIGHTNING: - DoCastVictim(SPELL_CALL_LIGHTNING); - events.ScheduleEvent(EVENT_CALL_LIGHTNING, urand(12000, 17000)); // totaly random timer. can't find any info on this - break; - case EVENT_ELECTRICAL_STORM: - { - Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 50, true); - if (!target) - { - EnterEvadeMode(); - return; - } - target->CastSpell(target, 44007, true); // cloud visual - DoCast(target, SPELL_ELECTRICAL_STORM, false); // storm cyclon + visual - float x, y, z; - target->GetPosition(x, y, z); - /// @todo: fix it in correct way, that causes player to can fly until logout - /* - if (target) - { - target->SetDisableGravity(true); - target->MonsterMoveWithSpeed(x, y, me->GetPositionZ()+15, 0); - } - */ - - Unit* Cloud = me->SummonTrigger(x, y, me->GetPositionZ()+16, 0, 15000); - if (Cloud) - { - CloudGUID = Cloud->GetGUID(); - Cloud->SetDisableGravity(true); - Cloud->StopMoving(); - Cloud->SetObjectScale(1.0f); - Cloud->setFaction(35); - Cloud->SetMaxHealth(9999999); - Cloud->SetHealth(9999999); - Cloud->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - } - StormCount = 1; - events.ScheduleEvent(EVENT_ELECTRICAL_STORM, 60000); // 60 seconds(bosskillers) - events.ScheduleEvent(EVENT_RAIN, urand(47000, 52000)); - break; - } - case EVENT_RAIN: - if (!isRaining) - { - SetWeather(WEATHER_STATE_HEAVY_RAIN, 0.9999f); - isRaining = true; - } - else - events.ScheduleEvent(EVENT_RAIN, 1000); - break; - case EVENT_STORM_SEQUENCE: - { - Unit* target = ObjectAccessor::GetUnit(*me, CloudGUID); - if (!target || !target->IsAlive()) - { - EnterEvadeMode(); - return; - } - else if (Unit* Cyclone = ObjectAccessor::GetUnit(*me, CycloneGUID)) - Cyclone->CastSpell(target, SPELL_SAND_STORM, true); // keep casting or... - HandleStormSequence(target); - break; - } - case EVENT_SUMMON_EAGLES: - Talk(SAY_SUMMON); - - float x, y, z; - me->GetPosition(x, y, z); - - for (uint8 i = 0; i < 8; ++i) - { - Unit* bird = ObjectAccessor::GetUnit(*me, BirdGUIDs[i]); - if (!bird) //they despawned on die - { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - { - x = target->GetPositionX() + irand(-10, 10); - y = target->GetPositionY() + irand(-10, 10); - z = target->GetPositionZ() + urand(16, 20); - if (z > 95) - z = 95.0f - urand(0, 5); - } - Creature* creature = me->SummonCreature(NPC_SOARING_EAGLE, x, y, z, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); - if (creature) - { - creature->AddThreat(me->GetVictim(), 1.0f); - creature->AI()->AttackStart(me->GetVictim()); - BirdGUIDs[i] = creature->GetGUID(); - } - } - } - break; - case EVENT_ENRAGE: - Talk(SAY_ENRAGE); - DoCast(me, SPELL_BERSERK, true); - events.ScheduleEvent(EVENT_ENRAGE, 600000); - break; default: break; } } + */ DoMeleeAttackIfReady(); } - - private: - uint64 BirdGUIDs[8]; - uint64 TargetGUID; - uint64 CycloneGUID; - uint64 CloudGUID; - uint8 StormCount; - bool isRaining; }; CreatureAI* GetAI(Creature* creature) const override @@ -372,91 +92,7 @@ class boss_akilzon : public CreatureScript } }; -class npc_akilzon_eagle : public CreatureScript -{ - public: - npc_akilzon_eagle() : CreatureScript("npc_akilzon_eagle") { } - - struct npc_akilzon_eagleAI : public ScriptedAI - { - npc_akilzon_eagleAI(Creature* creature) : ScriptedAI(creature) { } - - uint32 EagleSwoop_Timer; - bool arrived; - uint64 TargetGUID; - - void Reset() override - { - EagleSwoop_Timer = urand(5000, 10000); - arrived = true; - TargetGUID = 0; - me->SetDisableGravity(true); - } - - void EnterCombat(Unit* /*who*/) override - { - DoZoneInCombat(); - } - - void MoveInLineOfSight(Unit* /*who*/) override { } - - - void MovementInform(uint32, uint32) override - { - arrived = true; - if (TargetGUID) - { - if (Unit* target = ObjectAccessor::GetUnit(*me, TargetGUID)) - DoCast(target, SPELL_EAGLE_SWOOP, true); - TargetGUID = 0; - me->SetSpeed(MOVE_RUN, 1.2f); - EagleSwoop_Timer = urand(5000, 10000); - } - } - - void UpdateAI(uint32 diff) override - { - if (EagleSwoop_Timer <= diff) - EagleSwoop_Timer = 0; - else - EagleSwoop_Timer -= diff; - - if (arrived) - { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - { - float x, y, z; - if (EagleSwoop_Timer) - { - x = target->GetPositionX() + irand(-10, 10); - y = target->GetPositionY() + irand(-10, 10); - z = target->GetPositionZ() + urand(10, 15); - if (z > 95) - z = 95.0f - urand(0, 5); - } - else - { - target->GetContactPoint(me, x, y, z); - z += 2; - me->SetSpeed(MOVE_RUN, 5.0f); - TargetGUID = target->GetGUID(); - } - me->GetMotionMaster()->MovePoint(0, x, y, z); - arrived = false; - } - } - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_akilzon_eagleAI(creature); - } -}; - void AddSC_boss_akilzon() { new boss_akilzon(); - new npc_akilzon_eagle(); } - diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_daakara.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_daakara.cpp new file mode 100644 index 00000000000..dd5fdf989fd --- /dev/null +++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_daakara.cpp @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * 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/>. + */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "zulaman.h" + +enum Says +{ + SAY_INTRO = 0, + SAY_AGGRO = 1, + SAY_PLAYER_KILL = 2, + SAY_FIRE_BREATH = 3, + SAY_TRANSFORMS_BEAR = 4, + SAY_TRANSFORMS_EAGLE = 5, + SAY_TRANSFORMS_LYNX = 6, + SAY_TRANSFORMS_DRAGONHAWK = 7, + SAY_ABSORBS_BEAR_SPIRIT = 8, + SAY_ABSORBS_EAGLE_SPIRIT = 9, + SAY_ABSORBS_LYNX_SPIRIT = 10, + SAY_ABSORBS_DRAGONHAWK_SPIRIT = 11, + SAY_DEATH = 12 +}; + +enum Spells +{ +}; + +enum Events +{ +}; + +class boss_daakara : public CreatureScript +{ + public: + + boss_daakara() : CreatureScript("boss_daakara") { } + + struct boss_daakaraAI : public BossAI + { + boss_daakaraAI(Creature* creature) : BossAI(creature, DATA_DAAKARA) { } + + void Reset() override + { + _Reset(); + } + + void EnterCombat(Unit* /*who*/) override + { + Talk(SAY_AGGRO); + _EnterCombat(); + } + + void JustDied(Unit* /*killer*/) override + { + Talk(SAY_DEATH); + _JustDied(); + } + + void KilledUnit(Unit* victim) override + { + if (victim->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_PLAYER_KILL); + } + + 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) + { + default: + break; + } + } + */ + + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetZulAmanAI<boss_daakaraAI>(creature); + } +}; + +void AddSC_boss_daakara() +{ + new boss_daakara(); +} diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_halazzi.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_halazzi.cpp index 74ce267441f..d10d749be81 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/boss_halazzi.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_halazzi.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2014 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 @@ -19,176 +18,56 @@ #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "zulaman.h" -#include "SpellInfo.h" -enum Spells -{ - SPELL_DUAL_WIELD = 29651, - SPELL_SABER_LASH = 43267, - SPELL_FRENZY = 43139, - SPELL_FLAMESHOCK = 43303, - SPELL_EARTHSHOCK = 43305, - SPELL_TRANSFORM_SPLIT = 43142, - SPELL_TRANSFORM_SPLIT2 = 43573, - SPELL_TRANSFORM_MERGE = 43271, - SPELL_SUMMON_LYNX = 43143, - SPELL_SUMMON_TOTEM = 43302, - SPELL_BERSERK = 45078, - SPELL_LYNX_FRENZY = 43290, // Used by Spirit Lynx - SPELL_SHRED_ARMOR = 43243 // Used by Spirit Lynx -}; - -enum Hal_CreatureIds +enum Says { - NPC_SPIRIT_LYNX = 24143, - NPC_TOTEM = 24224 + SAY_AGGRO = 0, + SAY_PLAYER_KILL = 1, + SAY_MELEE = 2, + SAY_SPLIT = 3, + SAY_COMBINE = 4, + SAY_DEATH = 5 }; -enum PhaseHalazzi +enum Spells { - PHASE_NONE = 0, - PHASE_LYNX = 1, - PHASE_SPLIT = 2, - PHASE_HUMAN = 3, - PHASE_MERGE = 4, - PHASE_ENRAGE = 5 }; -enum Yells +enum Events { - SAY_AGGRO = 0, - SAY_SABER = 1, - SAY_SPLIT = 2, - SAY_MERGE = 3, - SAY_KILL = 4, - SAY_DEATH = 5, - SAY_BERSERK = 6 }; class boss_halazzi : public CreatureScript { public: + boss_halazzi() : CreatureScript("boss_halazzi") { } - struct boss_halazziAI : public ScriptedAI + struct boss_halazziAI : public BossAI { - boss_halazziAI(Creature* creature) : ScriptedAI(creature), summons(me) - { - instance = creature->GetInstanceScript(); - } - - InstanceScript* instance; - SummonList summons; - PhaseHalazzi Phase; - - uint32 FrenzyTimer; - uint32 SaberlashTimer; - uint32 ShockTimer; - uint32 TotemTimer; - uint32 CheckTimer; - uint32 BerserkTimer; - uint32 TransformCount; - - uint64 LynxGUID; + boss_halazziAI(Creature* creature) : BossAI(creature, DATA_HALAZZI) { } void Reset() override { - instance->SetData(DATA_HALAZZIEVENT, NOT_STARTED); - summons.DespawnAll(); - - LynxGUID = 0; - TransformCount = 0; - BerserkTimer = 600000; - CheckTimer = 1000; - - DoCast(me, SPELL_DUAL_WIELD, true); - - Phase = PHASE_NONE; - EnterPhase(PHASE_LYNX); + _Reset(); } void EnterCombat(Unit* /*who*/) override { - instance->SetData(DATA_HALAZZIEVENT, IN_PROGRESS); Talk(SAY_AGGRO); - EnterPhase(PHASE_LYNX); - } - - void JustSummoned(Creature* summon) override - { - summon->AI()->AttackStart(me->GetVictim()); - if (summon->GetEntry() == NPC_SPIRIT_LYNX) - LynxGUID = summon->GetGUID(); - summons.Summon(summon); - } - - void DamageTaken(Unit* /*done_by*/, uint32 &damage) override - { - if (damage >= me->GetHealth() && Phase != PHASE_ENRAGE) - damage = 0; - } - - void SpellHit(Unit*, const SpellInfo* spell) override - { - if (spell->Id == SPELL_TRANSFORM_SPLIT2) - EnterPhase(PHASE_HUMAN); + _EnterCombat(); } - void AttackStart(Unit* who) override + void JustDied(Unit* /*killer*/) override { - if (Phase != PHASE_MERGE) - ScriptedAI::AttackStart(who); + Talk(SAY_DEATH); + _JustDied(); } - void EnterPhase(PhaseHalazzi NextPhase) + void KilledUnit(Unit* victim) override { - switch (NextPhase) - { - case PHASE_LYNX: - case PHASE_ENRAGE: - if (Phase == PHASE_MERGE) - { - DoCast(me, SPELL_TRANSFORM_MERGE, true); - me->Attack(me->GetVictim(), true); - me->GetMotionMaster()->MoveChase(me->GetVictim()); - } - if (Creature* Lynx = ObjectAccessor::GetCreature(*me, LynxGUID)) - Lynx->DisappearAndDie(); - me->SetMaxHealth(600000); - me->SetHealth(600000 - 150000 * TransformCount); - FrenzyTimer = 16000; - SaberlashTimer = 20000; - ShockTimer = 10000; - TotemTimer = 12000; - break; - case PHASE_SPLIT: - Talk(SAY_SPLIT); - DoCast(me, SPELL_TRANSFORM_SPLIT, true); - break; - case PHASE_HUMAN: - //DoCast(me, SPELL_SUMMON_LYNX, true); - DoSpawnCreature(NPC_SPIRIT_LYNX, 5, 5, 0, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); - me->SetMaxHealth(400000); - me->SetHealth(400000); - ShockTimer = 10000; - TotemTimer = 12000; - break; - case PHASE_MERGE: - if (Unit* pLynx = ObjectAccessor::GetUnit(*me, LynxGUID)) - { - Talk(SAY_MERGE); - pLynx->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - pLynx->GetMotionMaster()->Clear(); - pLynx->GetMotionMaster()->MoveFollow(me, 0, 0); - me->GetMotionMaster()->Clear(); - me->GetMotionMaster()->MoveFollow(pLynx, 0, 0); - ++TransformCount; - } - break; - default: - break; - } - Phase = NextPhase; + if (victim->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_PLAYER_KILL); } void UpdateAI(uint32 diff) override @@ -196,186 +75,32 @@ class boss_halazzi : public CreatureScript if (!UpdateVictim()) return; - if (BerserkTimer <= diff) - { - Talk(SAY_BERSERK); - DoCast(me, SPELL_BERSERK, true); - BerserkTimer = 60000; - } else BerserkTimer -= diff; - - if (Phase == PHASE_LYNX || Phase == PHASE_ENRAGE) - { - if (SaberlashTimer <= diff) - { - // A tank with more than 490 defense skills should receive no critical hit - //DoCast(me, 41296, true); - DoCastVictim(SPELL_SABER_LASH, true); - //me->RemoveAurasDueToSpell(41296); - SaberlashTimer = 30000; - } else SaberlashTimer -= diff; - - if (FrenzyTimer <= diff) - { - DoCast(me, SPELL_FRENZY); - FrenzyTimer = urand(10000, 15000); - } else FrenzyTimer -= diff; - - if (Phase == PHASE_LYNX) - { - if (CheckTimer <= diff) - { - if (HealthBelowPct(25 * (3 - TransformCount))) - EnterPhase(PHASE_SPLIT); - CheckTimer = 1000; - } else CheckTimer -= diff; - } - } + events.Update(diff); - if (Phase == PHASE_HUMAN || Phase == PHASE_ENRAGE) + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + /* + while (uint32 eventId = events.ExecuteEvent()) { - if (TotemTimer <= diff) + switch (eventId) { - DoCast(me, SPELL_SUMMON_TOTEM); - TotemTimer = 20000; - } else TotemTimer -= diff; - - if (ShockTimer <= diff) - { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - { - if (target->IsNonMeleeSpellCast(false)) - DoCast(target, SPELL_EARTHSHOCK); - else - DoCast(target, SPELL_FLAMESHOCK); - ShockTimer = urand(10000, 15000); - } - } else ShockTimer -= diff; - - if (Phase == PHASE_HUMAN) - { - if (CheckTimer <= diff) - { - if (!HealthAbovePct(20) /*HealthBelowPct(10)*/) - EnterPhase(PHASE_MERGE); - else - { - Unit* Lynx = ObjectAccessor::GetUnit(*me, LynxGUID); - if (Lynx && !Lynx->HealthAbovePct(20) /*Lynx->HealthBelowPct(10)*/) - EnterPhase(PHASE_MERGE); - } - CheckTimer = 1000; - } else CheckTimer -= diff; + default: + break; } } - - if (Phase == PHASE_MERGE) - { - if (CheckTimer <= diff) - { - Unit* Lynx = ObjectAccessor::GetUnit(*me, LynxGUID); - if (Lynx) - { - Lynx->GetMotionMaster()->MoveFollow(me, 0, 0); - me->GetMotionMaster()->MoveFollow(Lynx, 0, 0); - if (me->IsWithinDistInMap(Lynx, 6.0f)) - { - if (TransformCount < 3) - EnterPhase(PHASE_LYNX); - else - EnterPhase(PHASE_ENRAGE); - } - } - CheckTimer = 1000; - } else CheckTimer -= diff; - } + */ DoMeleeAttackIfReady(); } - - void KilledUnit(Unit* victim) override - { - if (victim->GetTypeId() != TYPEID_PLAYER) - return; - - Talk(SAY_KILL); - } - - void JustDied(Unit* /*killer*/) override - { - instance->SetData(DATA_HALAZZIEVENT, DONE); - Talk(SAY_DEATH); - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetInstanceAI<boss_halazziAI>(creature); - } -}; - -// Spirits Lynx AI -class npc_halazzi_lynx : public CreatureScript -{ - public: - npc_halazzi_lynx() : CreatureScript("npc_halazzi_lynx") { } - - struct npc_halazzi_lynxAI : public ScriptedAI - { - npc_halazzi_lynxAI(Creature* creature) : ScriptedAI(creature) { } - - uint32 FrenzyTimer; - uint32 shredder_timer; - - void Reset() override - { - FrenzyTimer = urand(30000, 50000); //frenzy every 30-50 seconds - shredder_timer = 4000; - } - - void DamageTaken(Unit* /*done_by*/, uint32 &damage) override - { - if (damage >= me->GetHealth()) - damage = 0; - } - - void AttackStart(Unit* who) override - { - if (!me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE)) - ScriptedAI::AttackStart(who); - } - - void EnterCombat(Unit* /*who*/) override {/*DoZoneInCombat();*/ } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - if (FrenzyTimer <= diff) - { - DoCast(me, SPELL_LYNX_FRENZY); - FrenzyTimer = urand(30000, 50000); //frenzy every 30-50 seconds - } else FrenzyTimer -= diff; - - if (shredder_timer <= diff) - { - DoCastVictim(SPELL_SHRED_ARMOR); - shredder_timer = 4000; - } else shredder_timer -= diff; - - DoMeleeAttackIfReady(); - } - }; CreatureAI* GetAI(Creature* creature) const override { - return new npc_halazzi_lynxAI(creature); + return GetZulAmanAI<boss_halazziAI>(creature); } }; void AddSC_boss_halazzi() { new boss_halazzi(); - new npc_halazzi_lynx(); } diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp index 6e5517e82a6..7219d6e5f9e 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2006-2007 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,939 +15,92 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Boss_Hex_Lord_Malacrass -SD%Complete: -SDComment: -SDCategory: Zul'Aman -EndScriptData */ - #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "SpellScript.h" #include "SpellAuraEffects.h" #include "zulaman.h" -#define YELL_AGGRO "Da shadow gonna fall on you... " -#define SOUND_YELL_AGGRO 12041 -#define YELL_SPIRIT_BOLTS "Your soul gonna bleed!" -#define SOUND_YELL_SPIRIT_BOLTS 12047 -#define YELL_DRAIN_POWER "Darkness comin\' for you" -#define SOUND_YELL_DRAIN_POWER 12046 -#define YELL_KILL_ONE "Dis a nightmare ya don\' wake up from!" -#define SOUND_YELL_KILL_ONE 12043 -#define YELL_KILL_TWO "Azzaga choogo zinn!" -#define SOUND_YELL_KILL_TWO 12044 -#define YELL_DEATH "Dis not... da end of me..." -#define SOUND_YELL_DEATH 12051 - - -enum Creatures +enum Says { - NPC_TEMP_TRIGGER = 23920 + SAY_AGGRO = 0, + SAY_PLAYER_KILL = 1, + SAY_SPIRIT_BOLTS = 2, + SAY_SIPHON_SOUL = 3, + SAY_PET_DEATH = 4, + SAY_DEATH = 5 }; enum Spells { - SPELL_SPIRIT_BOLTS = 43383, - SPELL_DRAIN_POWER = 44131, - SPELL_SIPHON_SOUL = 43501, - - // Druid - SPELL_DR_THORNS = 43420, - SPELL_DR_LIFEBLOOM = 43421, - SPELL_DR_MOONFIRE = 43545, - - // Hunter - SPELL_HU_EXPLOSIVE_TRAP = 43444, - SPELL_HU_FREEZING_TRAP = 43447, - SPELL_HU_SNAKE_TRAP = 43449, - - // Mage - SPELL_MG_FIREBALL = 41383, - SPELL_MG_FROST_NOVA = 43426, - SPELL_MG_ICE_LANCE = 43427, - SPELL_MG_FROSTBOLT = 43428, - - // Paladin - SPELL_PA_CONSECRATION = 43429, - SPELL_PA_AVENGING_WRATH = 43430, - SPELL_PA_HOLY_LIGHT = 43451, - - // Priest - SPELL_PR_HEAL = 41372, - SPELL_PR_MIND_BLAST = 41374, - SPELL_PR_SW_DEATH = 41375, - SPELL_PR_PSYCHIC_SCREAM = 43432, - SPELL_PR_MIND_CONTROL = 43550, - SPELL_PR_PAIN_SUPP = 44416, - - // Rogue - SPELL_RO_BLIND = 43433, - SPELL_RO_SLICE_DICE = 43457, - SPELL_RO_WOUND_POISON = 43461, - - // Shaman - SPELL_SH_CHAIN_LIGHT = 43435, - SPELL_SH_FIRE_NOVA = 43436, - SPELL_SH_HEALING_WAVE = 43548, - - // Warlock - SPELL_WL_CURSE_OF_DOOM = 43439, - SPELL_WL_RAIN_OF_FIRE = 43440, SPELL_WL_UNSTABLE_AFFL = 43522, SPELL_WL_UNSTABLE_AFFL_DISPEL = 43523, - - // Warrior - SPELL_WR_MORTAL_STRIKE = 43441, - SPELL_WR_WHIRLWIND = 43442, - SPELL_WR_SPELL_REFLECT = 43443, - - // Thurg - SPELL_BLOODLUST = 43578, - SPELL_CLEAVE = 15496, - - // Gazakroth - SPELL_FIREBOLT = 43584, - - // Alyson Antille - SPELL_FLASH_HEAL = 43575, - SPELL_DISPEL_MAGIC = 43577, - - // Lord Raadan - SPELL_FLAME_BREATH = 43582, - SPELL_THUNDERCLAP = 43583, - - // Darkheart - SPELL_PSYCHIC_WAIL = 43590, - - // Slither - SPELL_VENOM_SPIT = 43579, - - // Fenstalker - SPELL_VOLATILE_INFECTION = 43586, - - // Koragg - SPELL_COLD_STARE = 43593, - SPELL_MIGHTY_BLOW = 43592 - -}; - -#define ORIENT 1.5696f -#define POS_Y 921.2795f -#define POS_Z 33.8883f - -static float Pos_X[4] = {112.8827f, 107.8827f, 122.8827f, 127.8827f}; - -static uint32 AddEntryList[8]= -{ - 24240, //Alyson Antille - 24241, //Thurg - 24242, //Slither - 24243, //Lord Raadan - 24244, //Gazakroth - 24245, //Fenstalker - 24246, //Darkheart - 24247 //Koragg -}; - -enum AbilityTarget -{ - ABILITY_TARGET_SELF = 0, - ABILITY_TARGET_VICTIM = 1, - ABILITY_TARGET_ENEMY = 2, - ABILITY_TARGET_HEAL = 3, - ABILITY_TARGET_BUFF = 4, - ABILITY_TARGET_SPECIAL = 5 }; -struct PlayerAbilityStruct +enum Events { - uint32 spell; - AbilityTarget target; - uint32 cooldown; //FIXME - it's never used -}; - -static PlayerAbilityStruct PlayerAbility[][3] = -{ - // 1 warrior - {{SPELL_WR_SPELL_REFLECT, ABILITY_TARGET_SELF, 10000}, - {SPELL_WR_WHIRLWIND, ABILITY_TARGET_SELF, 10000}, - {SPELL_WR_MORTAL_STRIKE, ABILITY_TARGET_VICTIM, 6000}}, - // 2 paladin - {{SPELL_PA_CONSECRATION, ABILITY_TARGET_SELF, 10000}, - {SPELL_PA_HOLY_LIGHT, ABILITY_TARGET_HEAL, 10000}, - {SPELL_PA_AVENGING_WRATH, ABILITY_TARGET_SELF, 10000}}, - // 3 hunter - {{SPELL_HU_EXPLOSIVE_TRAP, ABILITY_TARGET_SELF, 10000}, - {SPELL_HU_FREEZING_TRAP, ABILITY_TARGET_SELF, 10000}, - {SPELL_HU_SNAKE_TRAP, ABILITY_TARGET_SELF, 10000}}, - // 4 rogue - {{SPELL_RO_WOUND_POISON, ABILITY_TARGET_VICTIM, 3000}, - {SPELL_RO_SLICE_DICE, ABILITY_TARGET_SELF, 10000}, - {SPELL_RO_BLIND, ABILITY_TARGET_ENEMY, 10000}}, - // 5 priest - {{SPELL_PR_PAIN_SUPP, ABILITY_TARGET_HEAL, 10000}, - {SPELL_PR_HEAL, ABILITY_TARGET_HEAL, 10000}, - {SPELL_PR_PSYCHIC_SCREAM, ABILITY_TARGET_SELF, 10000}}, - // 5* shadow priest - {{SPELL_PR_MIND_CONTROL, ABILITY_TARGET_ENEMY, 15000}, - {SPELL_PR_MIND_BLAST, ABILITY_TARGET_ENEMY, 5000}, - {SPELL_PR_SW_DEATH, ABILITY_TARGET_ENEMY, 10000}}, - // 7 shaman - {{SPELL_SH_FIRE_NOVA, ABILITY_TARGET_SELF, 10000}, - {SPELL_SH_HEALING_WAVE, ABILITY_TARGET_HEAL, 10000}, - {SPELL_SH_CHAIN_LIGHT, ABILITY_TARGET_ENEMY, 8000}}, - // 8 mage - {{SPELL_MG_FIREBALL, ABILITY_TARGET_ENEMY, 5000}, - {SPELL_MG_FROSTBOLT, ABILITY_TARGET_ENEMY, 5000}, - {SPELL_MG_ICE_LANCE, ABILITY_TARGET_SPECIAL, 2000}}, - // 9 warlock - {{SPELL_WL_CURSE_OF_DOOM, ABILITY_TARGET_ENEMY, 10000}, - {SPELL_WL_RAIN_OF_FIRE, ABILITY_TARGET_ENEMY, 10000}, - {SPELL_WL_UNSTABLE_AFFL, ABILITY_TARGET_ENEMY, 10000}}, - // 11 druid - {{SPELL_DR_LIFEBLOOM, ABILITY_TARGET_HEAL, 10000}, - {SPELL_DR_THORNS, ABILITY_TARGET_SELF, 10000}, - {SPELL_DR_MOONFIRE, ABILITY_TARGET_ENEMY, 8000}} -}; - -struct boss_hexlord_addAI : public ScriptedAI -{ - InstanceScript* instance; - - boss_hexlord_addAI(Creature* creature) : ScriptedAI(creature) - { - instance = creature->GetInstanceScript(); - } - - void Reset() override { } - - void EnterCombat(Unit* /*who*/) override - { - DoZoneInCombat(); - } - - void UpdateAI(uint32 /*diff*/) override - { - if (instance->GetData(DATA_HEXLORDEVENT) != IN_PROGRESS) - { - EnterEvadeMode(); - return; - } - - DoMeleeAttackIfReady(); - } }; class boss_hexlord_malacrass : public CreatureScript { public: - boss_hexlord_malacrass() - : CreatureScript("boss_hexlord_malacrass") - { - } + boss_hexlord_malacrass() : CreatureScript("boss_hexlord_malacrass") { } - struct boss_hex_lord_malacrassAI : public ScriptedAI + struct boss_hex_lord_malacrassAI : public BossAI { - boss_hex_lord_malacrassAI(Creature* creature) : ScriptedAI(creature) - { - instance = creature->GetInstanceScript(); - SelectAddEntry(); - for (uint8 i = 0; i < 4; ++i) - AddGUID[i] = 0; - } - - InstanceScript* instance; - - uint64 AddGUID[4]; - uint32 AddEntry[4]; - - uint64 PlayerGUID; - - uint32 SpiritBolts_Timer; - uint32 DrainPower_Timer; - uint32 SiphonSoul_Timer; - uint32 PlayerAbility_Timer; - uint32 CheckAddState_Timer; - uint32 ResetTimer; - - uint32 PlayerClass; + boss_hex_lord_malacrassAI(Creature* creature) : BossAI(creature, DATA_HEXLORD) { } void Reset() override { - instance->SetData(DATA_HEXLORDEVENT, NOT_STARTED); - - SpiritBolts_Timer = 20000; - DrainPower_Timer = 60000; - SiphonSoul_Timer = 100000; - PlayerAbility_Timer = 99999; - CheckAddState_Timer = 5000; - ResetTimer = 5000; - - SpawnAdds(); - - me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 46916); - me->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE); + _Reset(); } void EnterCombat(Unit* /*who*/) override { - instance->SetData(DATA_HEXLORDEVENT, IN_PROGRESS); - - DoZoneInCombat(); - me->MonsterYell(YELL_AGGRO, LANG_UNIVERSAL, NULL); - DoPlaySoundToSet(me, SOUND_YELL_AGGRO); - - for (uint8 i = 0; i < 4; ++i) - { - Creature* creature = ObjectAccessor::GetCreature(*me, AddGUID[i]); - if (creature && creature->IsAlive()) - creature->AI()->AttackStart(me->GetVictim()); - else - { - EnterEvadeMode(); - break; - } - } - } - - void KilledUnit(Unit* /*victim*/) override - { - switch (urand(0, 1)) - { - case 0: - me->MonsterYell(YELL_KILL_ONE, LANG_UNIVERSAL, NULL); - DoPlaySoundToSet(me, SOUND_YELL_KILL_ONE); - break; - case 1: - me->MonsterYell(YELL_KILL_TWO, LANG_UNIVERSAL, NULL); - DoPlaySoundToSet(me, SOUND_YELL_KILL_TWO); - break; - } + Talk(SAY_AGGRO); + _EnterCombat(); } void JustDied(Unit* /*killer*/) override { - instance->SetData(DATA_HEXLORDEVENT, DONE); - - me->MonsterYell(YELL_DEATH, LANG_UNIVERSAL, NULL); - DoPlaySoundToSet(me, SOUND_YELL_DEATH); - - for (uint8 i = 0; i < 4; ++i) - { - Unit* Temp = ObjectAccessor::GetUnit(*me, AddGUID[i]); - if (Temp && Temp->IsAlive()) - Temp->DealDamage(Temp, Temp->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); - } - } - - void SelectAddEntry() - { - std::vector<uint32> AddList; - - for (uint8 i = 0; i < 8; ++i) - AddList.push_back(AddEntryList[i]); - - while (AddList.size() > 4) - AddList.erase(AddList.begin()+rand()%AddList.size()); - - uint8 i = 0; - for (std::vector<uint32>::const_iterator itr = AddList.begin(); itr != AddList.end(); ++itr, ++i) - AddEntry[i] = *itr; - } - - void SpawnAdds() - { - for (uint8 i = 0; i < 4; ++i) - { - Creature* creature = (ObjectAccessor::GetCreature((*me), AddGUID[i])); - if (!creature || !creature->IsAlive()) - { - if (creature) creature->setDeathState(DEAD); - creature = me->SummonCreature(AddEntry[i], Pos_X[i], POS_Y, POS_Z, ORIENT, TEMPSUMMON_DEAD_DESPAWN, 0); - if (creature) AddGUID[i] = creature->GetGUID(); - } - else - { - creature->AI()->EnterEvadeMode(); - creature->SetPosition(Pos_X[i], POS_Y, POS_Z, ORIENT); - creature->StopMoving(); - } - } - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - if (ResetTimer <= diff) - { - if (me->IsWithinDist3d(119.223f, 1035.45f, 29.4481f, 10)) - { - EnterEvadeMode(); - return; - } - ResetTimer = 5000; - } else ResetTimer -= diff; - - if (CheckAddState_Timer <= diff) - { - for (uint8 i = 0; i < 4; ++i) - if (Creature* temp = ObjectAccessor::GetCreature(*me, AddGUID[i])) - if (temp->IsAlive() && !temp->GetVictim()) - temp->AI()->AttackStart(me->GetVictim()); - - CheckAddState_Timer = 5000; - } else CheckAddState_Timer -= diff; - - if (DrainPower_Timer <= diff) - { - DoCast(me, SPELL_DRAIN_POWER, true); - me->MonsterYell(YELL_DRAIN_POWER, LANG_UNIVERSAL, NULL); - DoPlaySoundToSet(me, SOUND_YELL_DRAIN_POWER); - DrainPower_Timer = urand(40000, 55000); // must cast in 60 sec, or buff/debuff will disappear - } else DrainPower_Timer -= diff; - - if (SpiritBolts_Timer <= diff) - { - if (DrainPower_Timer < 12000) // channel 10 sec - SpiritBolts_Timer = 13000; // cast drain power first - else - { - DoCast(me, SPELL_SPIRIT_BOLTS, false); - me->MonsterYell(YELL_SPIRIT_BOLTS, LANG_UNIVERSAL, NULL); - DoPlaySoundToSet(me, SOUND_YELL_SPIRIT_BOLTS); - SpiritBolts_Timer = 40000; - SiphonSoul_Timer = 10000; // ready to drain - PlayerAbility_Timer = 99999; - } - } else SpiritBolts_Timer -= diff; - - if (SiphonSoul_Timer <= diff) - { - Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 70, true); - Unit* trigger = DoSpawnCreature(NPC_TEMP_TRIGGER, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN, 30000); - if (!target || !trigger) - { - EnterEvadeMode(); - return; - } - else - { - trigger->SetDisplayId(11686); - trigger->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - trigger->CastSpell(target, SPELL_SIPHON_SOUL, true); - trigger->GetMotionMaster()->MoveChase(me); - - //DoCast(target, SPELL_SIPHON_SOUL, true); - //me->SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT, target->GetGUID()); - //me->SetUInt32Value(UNIT_CHANNEL_SPELL, SPELL_SIPHON_SOUL); - - PlayerGUID = target->GetGUID(); - PlayerAbility_Timer = urand(8000, 10000); - PlayerClass = target->getClass() - 1; - - if (PlayerClass == CLASS_DRUID-1) - PlayerClass = CLASS_DRUID; - else if (PlayerClass == CLASS_PRIEST-1 && target->HasSpell(15473)) - PlayerClass = CLASS_PRIEST; // shadow priest - - SiphonSoul_Timer = 99999; // buff lasts 30 sec - } - } else SiphonSoul_Timer -= diff; - - if (PlayerAbility_Timer <= diff) - { - //Unit* target = ObjectAccessor::GetUnit(*me, PlayerGUID); - //if (target && target->IsAlive()) - //{ - UseAbility(); - PlayerAbility_Timer = urand(8000, 10000); - //} - } else PlayerAbility_Timer -= diff; - - DoMeleeAttackIfReady(); - } - - void UseAbility() - { - uint8 random = urand(0, 2); - Unit* target = NULL; - switch (PlayerAbility[PlayerClass][random].target) - { - case ABILITY_TARGET_SELF: - target = me; - break; - case ABILITY_TARGET_VICTIM: - target = me->GetVictim(); - break; - case ABILITY_TARGET_ENEMY: - default: - target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true); - break; - case ABILITY_TARGET_HEAL: - target = DoSelectLowestHpFriendly(50, 0); - break; - case ABILITY_TARGET_BUFF: - { - std::list<Creature*> templist = DoFindFriendlyMissingBuff(50, PlayerAbility[PlayerClass][random].spell); - if (!templist.empty()) - target = *(templist.begin()); - } - break; - } - if (target) - DoCast(target, PlayerAbility[PlayerClass][random].spell, false); - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetInstanceAI<boss_hex_lord_malacrassAI>(creature); - } -}; - -class boss_thurg : public CreatureScript -{ - public: - - boss_thurg() - : CreatureScript("boss_thurg") - { - } - - struct boss_thurgAI : public boss_hexlord_addAI - { - - boss_thurgAI(Creature* creature) : boss_hexlord_addAI(creature) { } - - uint32 bloodlust_timer; - uint32 cleave_timer; - - void Reset() override - { - bloodlust_timer = 15000; - cleave_timer = 10000; - - boss_hexlord_addAI::Reset(); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - if (bloodlust_timer <= diff) - { - std::list<Creature*> templist = DoFindFriendlyMissingBuff(50, SPELL_BLOODLUST); - if (!templist.empty()) - { - if (Unit* target = *(templist.begin())) - DoCast(target, SPELL_BLOODLUST, false); - } - bloodlust_timer = 12000; - } else bloodlust_timer -= diff; - - if (cleave_timer <= diff) - { - DoCastVictim(SPELL_CLEAVE, false); - cleave_timer = 12000; //3 sec cast - } else cleave_timer -= diff; - - boss_hexlord_addAI::UpdateAI(diff); - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetInstanceAI<boss_thurgAI>(creature); - } -}; - -class boss_alyson_antille : public CreatureScript -{ - public: - - boss_alyson_antille() - : CreatureScript("boss_alyson_antille") - { - } - - struct boss_alyson_antilleAI : public boss_hexlord_addAI - { - //Holy Priest - boss_alyson_antilleAI(Creature* creature) : boss_hexlord_addAI(creature) { } - - uint32 flashheal_timer; - uint32 dispelmagic_timer; - - void Reset() override - { - flashheal_timer = 2500; - dispelmagic_timer = 10000; - - //AcquireGUID(); - - boss_hexlord_addAI::Reset(); - } - - void AttackStart(Unit* who) override - { - if (!who) - return; - - if (who->isTargetableForAttack()) - { - if (me->Attack(who, false)) - { - me->GetMotionMaster()->MoveChase(who, 20); - me->AddThreat(who, 0.0f); - } - } - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - if (flashheal_timer <= diff) - { - Unit* target = DoSelectLowestHpFriendly(99, 30000); - if (target) - { - if (target->IsWithinDistInMap(me, 50)) - DoCast(target, SPELL_FLASH_HEAL, false); - else - { - // bugged - //me->GetMotionMaster()->Clear(); - //me->GetMotionMaster()->MoveChase(target, 20); - } - } - else - { - if (urand(0, 1)) - target = DoSelectLowestHpFriendly(50, 0); - else - target = SelectTarget(SELECT_TARGET_RANDOM, 0); - if (target) - DoCast(target, SPELL_DISPEL_MAGIC, false); - } - flashheal_timer = 2500; - } else flashheal_timer -= diff; - - /*if (dispelmagic_timer <= diff) - { - if (urand(0, 1)) - { - Unit* target = SelectTarget(); - - DoCast(target, SPELL_DISPEL_MAGIC, false); - } - else - me->CastSpell(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_DISPEL_MAGIC, false); - - dispelmagic_timer = 12000; - } else dispelmagic_timer -= diff;*/ - - boss_hexlord_addAI::UpdateAI(diff); + Talk(SAY_DEATH); + _JustDied(); } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetInstanceAI<boss_alyson_antilleAI>(creature); - } -}; - -struct boss_gazakrothAI : public boss_hexlord_addAI -{ - boss_gazakrothAI(Creature* creature) : boss_hexlord_addAI(creature) { } - - uint32 firebolt_timer; - - void Reset() override - { - firebolt_timer = 2000; - boss_hexlord_addAI::Reset(); - } - void AttackStart(Unit* who) override - { - if (!who) - return; - - if (who->isTargetableForAttack()) - { - if (me->Attack(who, false)) + void KilledUnit(Unit* victim) override { - me->GetMotionMaster()->MoveChase(who, 20); - me->AddThreat(who, 0.0f); + if (victim->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_PLAYER_KILL); } - } - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - if (firebolt_timer <= diff) - { - DoCastVictim(SPELL_FIREBOLT, false); - firebolt_timer = 700; - } else firebolt_timer -= diff; - - boss_hexlord_addAI::UpdateAI(diff); - } -}; - -class boss_lord_raadan : public CreatureScript -{ - public: - boss_lord_raadan() - : CreatureScript("boss_lord_raadan") - { - } - - struct boss_lord_raadanAI : public boss_hexlord_addAI - { - boss_lord_raadanAI(Creature* creature) : boss_hexlord_addAI(creature) { } - - uint32 flamebreath_timer; - uint32 thunderclap_timer; - - void Reset() override - { - flamebreath_timer = 8000; - thunderclap_timer = 13000; - - boss_hexlord_addAI::Reset(); - - } void UpdateAI(uint32 diff) override { if (!UpdateVictim()) return; - if (thunderclap_timer <= diff) - { - DoCastVictim(SPELL_THUNDERCLAP, false); - thunderclap_timer = 12000; - } else thunderclap_timer -= diff; + events.Update(diff); - if (flamebreath_timer <= diff) - { - DoCastVictim(SPELL_FLAME_BREATH, false); - flamebreath_timer = 12000; - } else flamebreath_timer -= diff; - - boss_hexlord_addAI::UpdateAI(diff); - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetInstanceAI<boss_lord_raadanAI>(creature); - } -}; - -class boss_darkheart : public CreatureScript -{ - public: - - boss_darkheart() - : CreatureScript("boss_darkheart") - { - } - - struct boss_darkheartAI : public boss_hexlord_addAI - { - boss_darkheartAI(Creature* creature) : boss_hexlord_addAI(creature) { } - - uint32 psychicwail_timer; - - void Reset() override - { - psychicwail_timer = 8000; - boss_hexlord_addAI::Reset(); - } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) + if (me->HasUnitState(UNIT_STATE_CASTING)) return; - - if (psychicwail_timer <= diff) + /* + while (uint32 eventId = events.ExecuteEvent()) { - DoCastVictim(SPELL_PSYCHIC_WAIL, false); - psychicwail_timer = 12000; - } else psychicwail_timer -= diff; - - boss_hexlord_addAI::UpdateAI(diff); - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetInstanceAI<boss_darkheartAI>(creature); - } -}; - - -class boss_slither : public CreatureScript -{ - public: - - boss_slither() - : CreatureScript("boss_slither") - { - } - - struct boss_slitherAI : public boss_hexlord_addAI - { - boss_slitherAI(Creature* creature) : boss_hexlord_addAI(creature) { } - - uint32 venomspit_timer; - - void Reset() override - { - venomspit_timer = 5000; - boss_hexlord_addAI::Reset(); - } - - void AttackStart(Unit* who) override - { - if (!who) - return; - - if (who->isTargetableForAttack()) - { - if (me->Attack(who, false)) + switch (eventId) { - me->GetMotionMaster()->MoveChase(who, 20); - me->AddThreat(who, 0.0f); + default: + break; } } - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - if (venomspit_timer <= diff) - { - if (Unit* victim = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) - DoCast(victim, SPELL_VENOM_SPIT, false); - venomspit_timer = 2500; - } else venomspit_timer -= diff; - - boss_hexlord_addAI::UpdateAI(diff); - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetInstanceAI<boss_slitherAI>(creature); - } -}; - -class boss_fenstalker : public CreatureScript -{ - public: - - boss_fenstalker() - : CreatureScript("boss_fenstalker") - { - } - - struct boss_fenstalkerAI : public boss_hexlord_addAI - { - boss_fenstalkerAI(Creature* creature) : boss_hexlord_addAI(creature) { } - - uint32 volatileinf_timer; - - void Reset() override - { - volatileinf_timer = 15000; - boss_hexlord_addAI::Reset(); - - } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - if (volatileinf_timer <= diff) - { - // core bug - if (me->GetVictim()) - me->EnsureVictim()->CastSpell(me->GetVictim(), SPELL_VOLATILE_INFECTION, false); - volatileinf_timer = 12000; - } else volatileinf_timer -= diff; - - boss_hexlord_addAI::UpdateAI(diff); - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetInstanceAI<boss_fenstalkerAI>(creature); - } -}; - -class boss_koragg : public CreatureScript -{ - public: - - boss_koragg() - : CreatureScript("boss_koragg") - { - } - - struct boss_koraggAI : public boss_hexlord_addAI - { - boss_koraggAI(Creature* creature) : boss_hexlord_addAI(creature) { } - - uint32 coldstare_timer; - uint32 mightyblow_timer; - - void Reset() override - { - coldstare_timer = 15000; - mightyblow_timer = 10000; - boss_hexlord_addAI::Reset(); - - } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - if (mightyblow_timer <= diff) - { - DoCastVictim(SPELL_MIGHTY_BLOW, false); - mightyblow_timer = 12000; - } - if (coldstare_timer <= diff) - { - if (Unit* victim = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) - DoCast(victim, SPELL_COLD_STARE, false); - coldstare_timer = 12000; - } + */ - boss_hexlord_addAI::UpdateAI(diff); + DoMeleeAttackIfReady(); } }; CreatureAI* GetAI(Creature* creature) const override { - return GetInstanceAI<boss_koraggAI>(creature); + return GetInstanceAI<boss_hex_lord_malacrassAI>(creature); } }; @@ -989,14 +141,5 @@ class spell_hexlord_unstable_affliction : public SpellScriptLoader void AddSC_boss_hex_lord_malacrass() { new boss_hexlord_malacrass(); - new boss_thurg(); - // new boss_gazakroth(); - new boss_lord_raadan(); - new boss_darkheart(); - new boss_slither(); - new boss_fenstalker(); - new boss_koragg(); - new boss_alyson_antille(); new spell_hexlord_unstable_affliction(); } - diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_janalai.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_janalai.cpp index f264b12ca23..61955d7ae5a 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/boss_janalai.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_janalai.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2014 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,424 +15,83 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Boss_Janalai -SD%Complete: 100 -SDComment: -SDCategory: Zul'Aman -EndScriptData */ - #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "zulaman.h" -#include "GridNotifiers.h" -#include "CellImpl.h" -enum Yells +enum Says { - SAY_AGGRO = 0, - SAY_FIRE_BOMBS = 1, - SAY_SUMMON_HATCHER = 2, - SAY_ALL_EGGS = 3, - SAY_BERSERK = 4, - SAY_SLAY = 5, - SAY_DEATH = 6, - SAY_EVENT_STRANGERS = 7, - SAY_EVENT_FRIENDS = 8 + SAY_AGGRO = 0, + SAY_PLAYER_KILL = 1, + SAY_SUMMON_HATCHER = 2, + SAY_FIRE_BOMB = 3, + SAY_HATCH_ALL_EGGS = 4, + EMOTE_FRENZY = 5, + SAY_DEATH = 6 }; enum Spells { - // Jan'alai - SPELL_FLAME_BREATH = 43140, - SPELL_FIRE_WALL = 43113, - SPELL_ENRAGE = 44779, - SPELL_SUMMON_PLAYERS = 43097, - SPELL_TELE_TO_CENTER = 43098, // coord - SPELL_HATCH_ALL = 43144, - SPELL_BERSERK = 45078, - - // Fire Bob Spells - SPELL_FIRE_BOMB_CHANNEL = 42621, // last forever - SPELL_FIRE_BOMB_THROW = 42628, // throw visual - SPELL_FIRE_BOMB_DUMMY = 42629, // bomb visual - SPELL_FIRE_BOMB_DAMAGE = 42630, - - // Hatcher Spells - SPELL_HATCH_EGG = 42471, // 43734 - SPELL_SUMMON_HATCHLING = 42493, - - // Hatchling Spells - SPELL_FLAMEBUFFET = 43299 -}; - -enum Creatures -{ - NPC_AMANI_HATCHER = 23818, - NPC_HATCHLING = 23598, // 42493 - NPC_EGG = 23817, - NPC_FIRE_BOMB = 23920 -}; - -const int area_dx = 44; -const int area_dy = 51; - -float JanalainPos[1][3] = -{ - {-33.93f, 1149.27f, 19} }; -float FireWallCoords[4][4] = +enum Events { - {-10.13f, 1149.27f, 19, 3.1415f}, - {-33.93f, 1123.90f, 19, 0.5f*3.1415f}, - {-54.80f, 1150.08f, 19, 0}, - {-33.93f, 1175.68f, 19, 1.5f*3.1415f} }; -float hatcherway[2][5][3] = -{ - { - {-87.46f, 1170.09f, 6}, - {-74.41f, 1154.75f, 6}, - {-52.74f, 1153.32f, 19}, - {-33.37f, 1172.46f, 19}, - {-33.09f, 1203.87f, 19} - }, - { - {-86.57f, 1132.85f, 6}, - {-73.94f, 1146.00f, 6}, - {-52.29f, 1146.51f, 19}, - {-33.57f, 1125.72f, 19}, - {-34.29f, 1095.22f, 19} - } -}; class boss_janalai : public CreatureScript { public: - boss_janalai() - : CreatureScript("boss_janalai") - { - } + boss_janalai() : CreatureScript("boss_janalai") { } - struct boss_janalaiAI : public ScriptedAI + struct boss_janalaiAI : public BossAI { - boss_janalaiAI(Creature* creature) : ScriptedAI(creature) - { - instance = creature->GetInstanceScript(); - } - - InstanceScript* instance; - - uint32 FireBreathTimer; - uint32 BombTimer; - uint32 BombSequenceTimer; - uint32 BombCount; - uint32 HatcherTimer; - uint32 EnrageTimer; - - bool noeggs; - bool enraged; - bool isBombing; - - bool isFlameBreathing; - - uint64 FireBombGUIDs[40]; + boss_janalaiAI(Creature* creature) : BossAI(creature, DATA_JANALAI) { } void Reset() override { - instance->SetData(DATA_JANALAIEVENT, NOT_STARTED); - - FireBreathTimer = 8000; - BombTimer = 30000; - BombSequenceTimer = 1000; - BombCount = 0; - HatcherTimer = 10000; - EnrageTimer = MINUTE*5*IN_MILLISECONDS; - - noeggs = false; - isBombing =false; - enraged = false; - - isFlameBreathing = false; - - for (uint8 i = 0; i < 40; ++i) - FireBombGUIDs[i] = 0; - - HatchAllEggs(1); - } - - void JustDied(Unit* /*killer*/) override - { - Talk(SAY_DEATH); - - instance->SetData(DATA_JANALAIEVENT, DONE); - } - - void KilledUnit(Unit* /*victim*/) override - { - Talk(SAY_SLAY); + _Reset(); } void EnterCombat(Unit* /*who*/) override { - instance->SetData(DATA_JANALAIEVENT, IN_PROGRESS); - Talk(SAY_AGGRO); - // DoZoneInCombat(); - } - - void DamageDealt(Unit* target, uint32 &damage, DamageEffectType /*damagetype*/) override - { - if (isFlameBreathing) - { - if (!me->HasInArc(M_PI/6, target)) - damage = 0; - } + _EnterCombat(); } - void FireWall() - { - uint8 WallNum; - Creature* wall = NULL; - for (uint8 i = 0; i < 4; ++i) - { - if (i == 0 || i == 2) - WallNum = 3; - else - WallNum = 2; - - for (uint8 j = 0; j < WallNum; j++) - { - if (WallNum == 3) - wall = me->SummonCreature(NPC_FIRE_BOMB, FireWallCoords[i][0], FireWallCoords[i][1]+5*(j-1), FireWallCoords[i][2], FireWallCoords[i][3], TEMPSUMMON_TIMED_DESPAWN, 15000); - else - wall = me->SummonCreature(NPC_FIRE_BOMB, FireWallCoords[i][0]-2+4*j, FireWallCoords[i][1], FireWallCoords[i][2], FireWallCoords[i][3], TEMPSUMMON_TIMED_DESPAWN, 15000); - if (wall) wall->CastSpell(wall, SPELL_FIRE_WALL, true); - } - } - } - - void SpawnBombs() - { - float dx, dy; - for (int i(0); i < 40; ++i) - { - dx = float(irand(-area_dx/2, area_dx/2)); - dy = float(irand(-area_dy/2, area_dy/2)); - - Creature* bomb = DoSpawnCreature(NPC_FIRE_BOMB, dx, dy, 0, 0, TEMPSUMMON_TIMED_DESPAWN, 15000); - if (bomb) - FireBombGUIDs[i] = bomb->GetGUID(); - } - BombCount = 0; - } - - bool HatchAllEggs(uint32 action) //1: reset, 2: isHatching all - { - std::list<Creature*> templist; - float x, y, z; - me->GetPosition(x, y, z); - - { - CellCoord pair(Trinity::ComputeCellCoord(x, y)); - Cell cell(pair); - cell.SetNoCreate(); - - Trinity::AllCreaturesOfEntryInRange check(me, NPC_EGG, 100); - Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(me, templist, check); - - TypeContainerVisitor<Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange>, GridTypeMapContainer> cSearcher(searcher); - - cell.Visit(pair, cSearcher, *me->GetMap(), *me, me->GetGridActivationRange()); - } - - //TC_LOG_ERROR("scripts", "Eggs %d at middle", templist.size()); - if (templist.empty()) - return false; - - for (std::list<Creature*>::const_iterator i = templist.begin(); i != templist.end(); ++i) - { - if (action == 1) - (*i)->SetDisplayId(10056); - else if (action == 2 &&(*i)->GetDisplayId() != 11686) - (*i)->CastSpell(*i, SPELL_HATCH_EGG, false); - } - return true; - } - - void Boom() + void JustDied(Unit* /*killer*/) override { - std::list<Creature*> templist; - float x, y, z; - me->GetPosition(x, y, z); - - { - CellCoord pair(Trinity::ComputeCellCoord(x, y)); - Cell cell(pair); - cell.SetNoCreate(); - - Trinity::AllCreaturesOfEntryInRange check(me, NPC_FIRE_BOMB, 100); - Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(me, templist, check); - - TypeContainerVisitor<Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange>, GridTypeMapContainer> cSearcher(searcher); - - cell.Visit(pair, cSearcher, *me->GetMap(), *me, me->GetGridActivationRange()); - } - for (std::list<Creature*>::const_iterator i = templist.begin(); i != templist.end(); ++i) - { - (*i)->CastSpell(*i, SPELL_FIRE_BOMB_DAMAGE, true); - (*i)->RemoveAllAuras(); - } + Talk(SAY_DEATH); + _JustDied(); } - void HandleBombSequence() + void KilledUnit(Unit* victim) override { - if (BombCount < 40) - { - if (Unit* FireBomb = ObjectAccessor::GetUnit(*me, FireBombGUIDs[BombCount])) - { - FireBomb->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - DoCast(FireBomb, SPELL_FIRE_BOMB_THROW, true); - FireBomb->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - } - ++BombCount; - if (BombCount == 40) - { - BombSequenceTimer = 5000; - } else BombSequenceTimer = 100; - } - else - { - Boom(); - isBombing = false; - BombTimer = urand(20000, 40000); - me->RemoveAurasDueToSpell(SPELL_FIRE_BOMB_CHANNEL); - if (EnrageTimer <= 10000) - EnrageTimer = 0; - else - EnrageTimer -= 10000; - } + if (victim->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_PLAYER_KILL); } void UpdateAI(uint32 diff) override { - if (isFlameBreathing) - { - if (!me->IsNonMeleeSpellCast(false)) - isFlameBreathing = false; - else - return; - } - - if (isBombing) - { - if (BombSequenceTimer <= diff) - HandleBombSequence(); - else - BombSequenceTimer -= diff; - return; - } - if (!UpdateVictim()) return; - //enrage if under 25% hp before 5 min. - if (!enraged && HealthBelowPct(25)) - EnrageTimer = 0; + events.Update(diff); - if (EnrageTimer <= diff) - { - if (!enraged) - { - DoCast(me, SPELL_ENRAGE, true); - enraged = true; - EnrageTimer = 300000; - } - else - { - Talk(SAY_BERSERK); - DoCast(me, SPELL_BERSERK, true); - EnrageTimer = 300000; - } - } else EnrageTimer -= diff; - - if (BombTimer <= diff) - { - Talk(SAY_FIRE_BOMBS); - - me->AttackStop(); - me->GetMotionMaster()->Clear(); - DoTeleportTo(JanalainPos[0][0], JanalainPos[0][1], JanalainPos[0][2]); - me->StopMoving(); - DoCast(me, SPELL_FIRE_BOMB_CHANNEL, false); - //DoTeleportPlayer(me, JanalainPos[0][0], JanalainPos[0][1], JanalainPos[0][2], 0); - //DoCast(me, SPELL_TELE_TO_CENTER, true); - - FireWall(); - SpawnBombs(); - isBombing = true; - BombSequenceTimer = 100; - - //Teleport every Player into the middle - Map* map = me->GetMap(); - if (!map->IsDungeon()) - return; - - Map::PlayerList const &PlayerList = map->GetPlayers(); - for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) - if (Player* i_pl = i->GetSource()) - if (i_pl->IsAlive()) - DoTeleportPlayer(i_pl, JanalainPos[0][0]-5+rand()%10, JanalainPos[0][1]-5+rand()%10, JanalainPos[0][2], 0); - //DoCast(Temp, SPELL_SUMMON_PLAYERS, true) // core bug, spell does not work if too far + if (me->HasUnitState(UNIT_STATE_CASTING)) return; - } else BombTimer -= diff; - - if (!noeggs) + /* + while (uint32 eventId = events.ExecuteEvent()) { - if (HealthBelowPct(35)) + switch (eventId) { - Talk(SAY_ALL_EGGS); - - me->AttackStop(); - me->GetMotionMaster()->Clear(); - DoTeleportTo(JanalainPos[0][0], JanalainPos[0][1], JanalainPos[0][2]); - me->StopMoving(); - DoCast(me, SPELL_HATCH_ALL, false); - HatchAllEggs(2); - noeggs = true; + default: + break; } - else if (HatcherTimer <= diff) - { - if (HatchAllEggs(0)) - { - Talk(SAY_SUMMON_HATCHER); - me->SummonCreature(NPC_AMANI_HATCHER, hatcherway[0][0][0], hatcherway[0][0][1], hatcherway[0][0][2], 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); - me->SummonCreature(NPC_AMANI_HATCHER, hatcherway[1][0][0], hatcherway[1][0][1], hatcherway[1][0][2], 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); - HatcherTimer = 90000; - } - else - noeggs = true; - } else HatcherTimer -= diff; } - - EnterEvadeIfOutOfCombatArea(diff); + */ DoMeleeAttackIfReady(); - - if (FireBreathTimer <= diff) - { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - { - me->AttackStop(); - me->GetMotionMaster()->Clear(); - DoCast(target, SPELL_FLAME_BREATH, false); - me->StopMoving(); - isFlameBreathing = true; - } - FireBreathTimer = 8000; - } else FireBreathTimer -= diff; } }; @@ -443,270 +101,7 @@ class boss_janalai : public CreatureScript } }; -class npc_janalai_firebomb : public CreatureScript -{ - public: - - npc_janalai_firebomb() - : CreatureScript("npc_janalai_firebomb") - { - } - - struct npc_janalai_firebombAI : public ScriptedAI - { - npc_janalai_firebombAI(Creature* creature) : ScriptedAI(creature){ } - - void Reset() override { } - - void SpellHit(Unit* /*caster*/, const SpellInfo* spell) override - { - if (spell->Id == SPELL_FIRE_BOMB_THROW) - DoCast(me, SPELL_FIRE_BOMB_DUMMY, true); - } - - void EnterCombat(Unit* /*who*/) override { } - - void AttackStart(Unit* /*who*/) override { } - - void MoveInLineOfSight(Unit* /*who*/) override { } - - - void UpdateAI(uint32 /*diff*/) override { } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_janalai_firebombAI(creature); - } -}; - -class npc_janalai_hatcher : public CreatureScript -{ - public: - - npc_janalai_hatcher() - : CreatureScript("npc_janalai_hatcher") - { - } - - struct npc_janalai_hatcherAI : public ScriptedAI - { - npc_janalai_hatcherAI(Creature* creature) : ScriptedAI(creature) - { - instance = creature->GetInstanceScript(); - } - - InstanceScript* instance; - - uint32 waypoint; - uint32 HatchNum; - uint32 WaitTimer; - - bool side; - bool hasChangedSide; - bool isHatching; - - void Reset() override - { - me->SetWalk(true); - side =(me->GetPositionY() < 1150); - waypoint = 0; - isHatching = false; - hasChangedSide = false; - WaitTimer = 1; - HatchNum = 0; - } - - bool HatchEggs(uint32 num) - { - std::list<Creature*> templist; - float x, y, z; - me->GetPosition(x, y, z); - - { - CellCoord pair(Trinity::ComputeCellCoord(x, y)); - Cell cell(pair); - cell.SetNoCreate(); - - Trinity::AllCreaturesOfEntryInRange check(me, 23817, 50); - Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(me, templist, check); - - TypeContainerVisitor<Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange>, GridTypeMapContainer> cSearcher(searcher); - - cell.Visit(pair, cSearcher, *(me->GetMap()), *me, me->GetGridActivationRange()); - } - - //TC_LOG_ERROR("scripts", "Eggs %d at %d", templist.size(), side); - - for (std::list<Creature*>::const_iterator i = templist.begin(); i != templist.end() && num > 0; ++i) - if ((*i)->GetDisplayId() != 11686) - { - (*i)->CastSpell(*i, SPELL_HATCH_EGG, false); - num--; - } - - return num == 0; // if num == 0, no more templist - } - - void EnterCombat(Unit* /*who*/) override { } - void AttackStart(Unit* /*who*/) override { } - void MoveInLineOfSight(Unit* /*who*/) override { } - - void MovementInform(uint32, uint32) override - { - if (waypoint == 5) - { - isHatching = true; - HatchNum = 1; - WaitTimer = 5000; - } - else - WaitTimer = 1; - } - - void UpdateAI(uint32 diff) override - { - if (!instance || !(instance->GetData(DATA_JANALAIEVENT) == IN_PROGRESS)) - { - me->DisappearAndDie(); - return; - } - - if (!isHatching) - { - if (WaitTimer) - { - me->GetMotionMaster()->Clear(); - me->GetMotionMaster()->MovePoint(0, hatcherway[side][waypoint][0], hatcherway[side][waypoint][1], hatcherway[side][waypoint][2]); - ++waypoint; - WaitTimer = 0; - } - } - else - { - if (WaitTimer <= diff) - { - if (HatchEggs(HatchNum)) - { - ++HatchNum; - WaitTimer = 10000; - } - else if (!hasChangedSide) - { - side = side ? 0 : 1; - isHatching = false; - waypoint = 3; - WaitTimer = 1; - hasChangedSide = true; - } - else - me->DisappearAndDie(); - - } else WaitTimer -= diff; - } - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetInstanceAI<npc_janalai_hatcherAI>(creature); - } -}; - -class npc_janalai_hatchling : public CreatureScript -{ - public: - - npc_janalai_hatchling() - : CreatureScript("npc_janalai_hatchling") - { - } - - struct npc_janalai_hatchlingAI : public ScriptedAI - { - npc_janalai_hatchlingAI(Creature* creature) : ScriptedAI(creature) - { - instance = creature->GetInstanceScript(); - } - - InstanceScript* instance; - uint32 BuffetTimer; - - void Reset() override - { - BuffetTimer = 7000; - if (me->GetPositionY() > 1150) - me->GetMotionMaster()->MovePoint(0, hatcherway[0][3][0]+rand()%4-2, 1150.0f+rand()%4-2, hatcherway[0][3][2]); - else - me->GetMotionMaster()->MovePoint(0, hatcherway[1][3][0]+rand()%4-2, 1150.0f+rand()%4-2, hatcherway[1][3][2]); - - me->SetDisableGravity(true); - } - - void EnterCombat(Unit* /*who*/) override {/*DoZoneInCombat();*/ } - - void UpdateAI(uint32 diff) override - { - if (!instance || !(instance->GetData(DATA_JANALAIEVENT) == IN_PROGRESS)) - { - me->DisappearAndDie(); - return; - } - - if (!UpdateVictim()) - return; - - if (BuffetTimer <= diff) - { - DoCastVictim(SPELL_FLAMEBUFFET, false); - BuffetTimer = 10000; - } else BuffetTimer -= diff; - - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetInstanceAI<npc_janalai_hatchlingAI>(creature); - } -}; - -class npc_janalai_egg : public CreatureScript -{ -public: - npc_janalai_egg(): CreatureScript("npc_janalai_egg") { } - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_janalai_eggAI(creature); - } - - struct npc_janalai_eggAI : public ScriptedAI - { - npc_janalai_eggAI(Creature* creature) : ScriptedAI(creature){ } - - void Reset() override { } - - void UpdateAI(uint32 /*diff*/) override { } - - void SpellHit(Unit* /*caster*/, const SpellInfo* spell) override - { - if (spell->Id == SPELL_HATCH_EGG) - { - DoCast(SPELL_SUMMON_HATCHLING); - } - } - }; - -}; - void AddSC_boss_janalai() { new boss_janalai(); - new npc_janalai_firebomb(); - new npc_janalai_hatcher(); - new npc_janalai_hatchling(); - new npc_janalai_egg(); } - diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp index 4909074b059..89ee0cfd8d4 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2014 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,433 +15,86 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Boss_Nalorakk -SD%Complete: 100 -SDComment: -SDCategory: Zul'Aman -EndScriptData */ - #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "zulaman.h" -#include "GridNotifiers.h" -#include "GridNotifiersImpl.h" -#include "CellImpl.h" -enum Spells +enum Says { - SPELL_BERSERK = 45078, - - // Troll form - SPELL_BRUTALSWIPE = 42384, - SPELL_MANGLE = 42389, - SPELL_MANGLEEFFECT = 44955, - SPELL_SURGE = 42402, - SPELL_BEARFORM = 42377, - - // Bear form - SPELL_LACERATINGSLASH = 42395, - SPELL_RENDFLESH = 42397, - SPELL_DEAFENINGROAR = 42398 + SAY_WAVE_1 = 0, + SAY_WAVE_2 = 1, + SAY_WAVE_3 = 2, + SAY_WAVE_4 = 3, + SAY_AGGRO = 4, + SAY_PLAYER_KILL = 5, + SAY_SURGE = 6, + EMOTE_SURGE = 7, + EMOTE_BEAR = 8, + SAY_BEAR = 9, + SAY_TROLL = 10, + SAY_DEATH = 11 }; -// Trash Waves -float NalorakkWay[8][3] = +enum Spells { - { 18.569f, 1414.512f, 11.42f}, // waypoint 1 - {-17.264f, 1419.551f, 12.62f}, - {-52.642f, 1419.357f, 27.31f}, // waypoint 2 - {-69.908f, 1419.721f, 27.31f}, - {-79.929f, 1395.958f, 27.31f}, - {-80.072f, 1374.555f, 40.87f}, // waypoint 3 - {-80.072f, 1314.398f, 40.87f}, - {-80.072f, 1295.775f, 48.60f} // waypoint 4 }; -#define YELL_NALORAKK_WAVE1 "Get da move on, guards! It be killin' time!" -#define SOUND_NALORAKK_WAVE1 12066 -#define YELL_NALORAKK_WAVE2 "Guards, go already! Who you more afraid of, dem... or me?" -#define SOUND_NALORAKK_WAVE2 12067 -#define YELL_NALORAKK_WAVE3 "Ride now! Ride out dere and bring me back some heads!" -#define SOUND_NALORAKK_WAVE3 12068 -#define YELL_NALORAKK_WAVE4 "I be losin' me patience! Go on: make dem wish dey was never born!" -#define SOUND_NALORAKK_WAVE4 12069 - -//Unimplemented SoundIDs -/* -#define SOUND_NALORAKK_EVENT1 12078 -#define SOUND_NALORAKK_EVENT2 12079 -*/ - -//General defines -#define YELL_AGGRO "You be dead soon enough!" -#define SOUND_YELL_AGGRO 12070 -#define YELL_KILL_ONE "Mua-ha-ha! Now whatchoo got to say?" -#define SOUND_YELL_KILL_ONE 12075 -#define YELL_KILL_TWO "Da Amani gonna rule again!" -#define SOUND_YELL_KILL_TWO 12076 -#define YELL_DEATH "I... be waitin' on da udda side...." -#define SOUND_YELL_DEATH 12077 -#define YELL_BERSERK "You had your chance, now it be too late!" //Never seen this being used, so just guessing from what I hear. -#define SOUND_YELL_BERSERK 12074 -#define YELL_SURGE "I bring da pain!" -#define SOUND_YELL_SURGE 12071 - -#define YELL_SHIFTEDTOTROLL "Make way for Nalorakk!" -#define SOUND_YELL_TOTROLL 12073 - - -#define YELL_SHIFTEDTOBEAR "You call on da beast, you gonna get more dan you bargain for!" -#define SOUND_YELL_TOBEAR 12072 +enum Events +{ +}; class boss_nalorakk : public CreatureScript { public: - boss_nalorakk() - : CreatureScript("boss_nalorakk") - { - } + boss_nalorakk() : CreatureScript("boss_nalorakk") { } - struct boss_nalorakkAI : public ScriptedAI + struct boss_nalorakkAI : public BossAI { - boss_nalorakkAI(Creature* creature) : ScriptedAI(creature) - { - MoveEvent = true; - MovePhase = 0; - instance = creature->GetInstanceScript(); - } - - InstanceScript* instance; - - uint32 BrutalSwipe_Timer; - uint32 Mangle_Timer; - uint32 Surge_Timer; - - uint32 LaceratingSlash_Timer; - uint32 RendFlesh_Timer; - uint32 DeafeningRoar_Timer; - - uint32 ShapeShift_Timer; - uint32 Berserk_Timer; - - bool inBearForm; - bool MoveEvent; - bool inMove; - uint32 MovePhase; - uint32 waitTimer; + boss_nalorakkAI(Creature* creature) : BossAI(creature, DATA_NALORAKK) { } void Reset() override { - if (MoveEvent) - { - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - inMove = false; - waitTimer = 0; - me->SetSpeed(MOVE_RUN, 2); - me->SetWalk(false); - }else - { - (*me).GetMotionMaster()->MovePoint(0, NalorakkWay[7][0], NalorakkWay[7][1], NalorakkWay[7][2]); - } - - instance->SetData(DATA_NALORAKKEVENT, NOT_STARTED); - - Surge_Timer = urand(15000, 20000); - BrutalSwipe_Timer = urand(7000, 12000); - Mangle_Timer = urand(10000, 15000); - ShapeShift_Timer = urand(45000, 50000); - Berserk_Timer = 600000; - - inBearForm = false; - // me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, 5122); /// @todo find the correct equipment id - } - - void SendAttacker(Unit* target) - { - std::list<Creature*> templist; - float x, y, z; - me->GetPosition(x, y, z); - - { - CellCoord pair(Trinity::ComputeCellCoord(x, y)); - Cell cell(pair); - cell.SetNoCreate(); - - Trinity::AllFriendlyCreaturesInGrid check(me); - Trinity::CreatureListSearcher<Trinity::AllFriendlyCreaturesInGrid> searcher(me, templist, check); - - TypeContainerVisitor<Trinity::CreatureListSearcher<Trinity::AllFriendlyCreaturesInGrid>, GridTypeMapContainer> cSearcher(searcher); - - cell.Visit(pair, cSearcher, *(me->GetMap()), *me, me->GetGridActivationRange()); - } - - if (templist.empty()) - return; - - for (std::list<Creature*>::const_iterator i = templist.begin(); i != templist.end(); ++i) - { - if ((*i) && me->IsWithinDistInMap((*i), 25)) - { - (*i)->SetNoCallAssistance(true); - (*i)->AI()->AttackStart(target); - } - } - } - - void AttackStart(Unit* who) override - { - if (!MoveEvent) - ScriptedAI::AttackStart(who); - } - - void MoveInLineOfSight(Unit* who) override - - { - if (!MoveEvent) - { - ScriptedAI::MoveInLineOfSight(who); - } - else - { - if (me->IsHostileTo(who)) - { - if (!inMove) - { - switch (MovePhase) - { - case 0: - if (me->IsWithinDistInMap(who, 50)) - { - me->MonsterYell(YELL_NALORAKK_WAVE1, LANG_UNIVERSAL, NULL); - DoPlaySoundToSet(me, SOUND_NALORAKK_WAVE1); - - (*me).GetMotionMaster()->MovePoint(1, NalorakkWay[1][0], NalorakkWay[1][1], NalorakkWay[1][2]); - MovePhase ++; - inMove = true; - - SendAttacker(who); - } - break; - case 2: - if (me->IsWithinDistInMap(who, 40)) - { - me->MonsterYell(YELL_NALORAKK_WAVE2, LANG_UNIVERSAL, NULL); - DoPlaySoundToSet(me, SOUND_NALORAKK_WAVE2); - - (*me).GetMotionMaster()->MovePoint(3, NalorakkWay[3][0], NalorakkWay[3][1], NalorakkWay[3][2]); - MovePhase ++; - inMove = true; - - SendAttacker(who); - } - break; - case 5: - if (me->IsWithinDistInMap(who, 40)) - { - me->MonsterYell(YELL_NALORAKK_WAVE3, LANG_UNIVERSAL, NULL); - DoPlaySoundToSet(me, SOUND_NALORAKK_WAVE3); - - (*me).GetMotionMaster()->MovePoint(6, NalorakkWay[6][0], NalorakkWay[6][1], NalorakkWay[6][2]); - MovePhase ++; - inMove = true; - - SendAttacker(who); - } - break; - case 7: - if (me->IsWithinDistInMap(who, 50)) - { - SendAttacker(who); - - me->MonsterYell(YELL_NALORAKK_WAVE4, LANG_UNIVERSAL, NULL); - DoPlaySoundToSet(me, SOUND_NALORAKK_WAVE4); - - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - - MoveEvent = false; - } - break; - } - } - } - } + _Reset(); } void EnterCombat(Unit* /*who*/) override { - instance->SetData(DATA_NALORAKKEVENT, IN_PROGRESS); - - me->MonsterYell(YELL_AGGRO, LANG_UNIVERSAL, NULL); - DoPlaySoundToSet(me, SOUND_YELL_AGGRO); - DoZoneInCombat(); + Talk(SAY_AGGRO); + _EnterCombat(); } void JustDied(Unit* /*killer*/) override { - instance->SetData(DATA_NALORAKKEVENT, DONE); - - me->MonsterYell(YELL_DEATH, LANG_UNIVERSAL, NULL); - DoPlaySoundToSet(me, SOUND_YELL_DEATH); + Talk(SAY_DEATH); + _JustDied(); } - void KilledUnit(Unit* /*victim*/) override + void KilledUnit(Unit* victim) override { - switch (urand(0, 1)) - { - case 0: - me->MonsterYell(YELL_KILL_ONE, LANG_UNIVERSAL, NULL); - DoPlaySoundToSet(me, SOUND_YELL_KILL_ONE); - break; - case 1: - me->MonsterYell(YELL_KILL_TWO, LANG_UNIVERSAL, NULL); - DoPlaySoundToSet(me, SOUND_YELL_KILL_TWO); - break; - } - } - - void MovementInform(uint32 type, uint32 id) override - { - if (MoveEvent) - { - if (type != POINT_MOTION_TYPE) - return; - - if (!inMove) - return; - - if (MovePhase != id) - return; - - switch (MovePhase) - { - case 2: - me->SetOrientation(3.1415f*2); - inMove = false; - return; - case 1: - case 3: - case 4: - case 6: - MovePhase ++; - waitTimer = 1; - inMove = true; - return; - case 5: - me->SetOrientation(3.1415f*0.5f); - inMove = false; - return; - case 7: - me->SetOrientation(3.1415f*0.5f); - inMove = false; - return; - } - - } + if (victim->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_PLAYER_KILL); } void UpdateAI(uint32 diff) override { - if (waitTimer && inMove) - { - if (waitTimer <= diff) - { - (*me).GetMotionMaster()->MovementExpired(); - (*me).GetMotionMaster()->MovePoint(MovePhase, NalorakkWay[MovePhase][0], NalorakkWay[MovePhase][1], NalorakkWay[MovePhase][2]); - waitTimer = 0; - } else waitTimer -= diff; - } - if (!UpdateVictim()) return; - if (Berserk_Timer <= diff) - { - DoCast(me, SPELL_BERSERK, true); - me->MonsterYell(YELL_BERSERK, LANG_UNIVERSAL, NULL); - DoPlaySoundToSet(me, SOUND_YELL_BERSERK); - Berserk_Timer = 600000; - } else Berserk_Timer -= diff; + events.Update(diff); - if (ShapeShift_Timer <= diff) + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + /* + while (uint32 eventId = events.ExecuteEvent()) { - if (inBearForm) - { - // me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, 5122); - me->MonsterYell(YELL_SHIFTEDTOTROLL, LANG_UNIVERSAL, NULL); - DoPlaySoundToSet(me, SOUND_YELL_TOTROLL); - me->RemoveAurasDueToSpell(SPELL_BEARFORM); - Surge_Timer = urand(15000, 20000); - BrutalSwipe_Timer = urand(7000, 12000); - Mangle_Timer = urand(10000, 15000); - ShapeShift_Timer = urand(45000, 50000); - inBearForm = false; - } - else + switch (eventId) { - // me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, 0); - me->MonsterYell(YELL_SHIFTEDTOBEAR, LANG_UNIVERSAL, NULL); - DoPlaySoundToSet(me, SOUND_YELL_TOBEAR); - DoCast(me, SPELL_BEARFORM, true); - LaceratingSlash_Timer = 2000; // dur 18s - RendFlesh_Timer = 3000; // dur 5s - DeafeningRoar_Timer = urand(5000, 10000); // dur 2s - ShapeShift_Timer = urand(20000, 25000); // dur 30s - inBearForm = true; + default: + break; } - } else ShapeShift_Timer -= diff; - - if (!inBearForm) - { - if (BrutalSwipe_Timer <= diff) - { - DoCastVictim(SPELL_BRUTALSWIPE); - BrutalSwipe_Timer = urand(7000, 12000); - } else BrutalSwipe_Timer -= diff; - - if (Mangle_Timer <= diff) - { - if (me->GetVictim() && !me->EnsureVictim()->HasAura(SPELL_MANGLEEFFECT)) - { - DoCastVictim(SPELL_MANGLE); - Mangle_Timer = 1000; - } - else Mangle_Timer = urand(10000, 15000); - } else Mangle_Timer -= diff; - - if (Surge_Timer <= diff) - { - me->MonsterYell(YELL_SURGE, LANG_UNIVERSAL, NULL); - DoPlaySoundToSet(me, SOUND_YELL_SURGE); - Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 45, true); - if (target) - DoCast(target, SPELL_SURGE); - Surge_Timer = urand(15000, 20000); - } else Surge_Timer -= diff; - } - else - { - if (LaceratingSlash_Timer <= diff) - { - DoCastVictim(SPELL_LACERATINGSLASH); - LaceratingSlash_Timer = urand(18000, 23000); - } else LaceratingSlash_Timer -= diff; - - if (RendFlesh_Timer <= diff) - { - DoCastVictim(SPELL_RENDFLESH); - RendFlesh_Timer = urand(5000, 10000); - } else RendFlesh_Timer -= diff; - - if (DeafeningRoar_Timer <= diff) - { - DoCastVictim(SPELL_DEAFENINGROAR); - DeafeningRoar_Timer = urand(15000, 20000); - } else DeafeningRoar_Timer -= diff; } + */ DoMeleeAttackIfReady(); } @@ -458,4 +110,3 @@ void AddSC_boss_nalorakk() { new boss_nalorakk(); } - diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_zuljin.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_zuljin.cpp deleted file mode 100644 index 6b0fc05ba3d..00000000000 --- a/src/server/scripts/EasternKingdoms/ZulAman/boss_zuljin.cpp +++ /dev/null @@ -1,602 +0,0 @@ -/* - * Copyright (C) 2008-2014 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: Boss_ZulJin -SD%Complete: 85% -SDComment: -EndScriptData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "zulaman.h" -#include "SpellInfo.h" - -enum Says -{ - YELL_INTRO = 0, - YELL_AGGRO = 1, - YELL_TRANSFORM_TO_BEAR = 2, - YELL_TRANSFORM_TO_EAGLE = 3, - YELL_TRANSFORM_TO_LYNX = 4, - YELL_TRANSFORM_TO_DRAGONHAWK = 5, - YELL_FIRE_BREATH = 6, - YELL_BERSERK = 7, - YELL_KILL = 8, - YELL_DEATH = 9 -}; - -enum Spells -{ - // Troll Form - SPELL_WHIRLWIND = 17207, - SPELL_GRIEVOUS_THROW = 43093, // remove debuff after full healed - // Bear Form - SPELL_CREEPING_PARALYSIS = 43095, // should cast on the whole raid - SPELL_OVERPOWER = 43456, // use after melee attack dodged - // Eagle Form - SPELL_ENERGY_STORM = 43983, // enemy area aura, trigger 42577 - SPELL_ZAP_INFORM = 42577, - SPELL_ZAP_DAMAGE = 43137, // 1250 damage - SPELL_SUMMON_CYCLONE = 43112, // summon four feather vortex - CREATURE_FEATHER_VORTEX = 24136, - SPELL_CYCLONE_VISUAL = 43119, // trigger 43147 visual - SPELL_CYCLONE_PASSIVE = 43120, // trigger 43121 (4y aoe) every second - // Lynx Form - SPELL_CLAW_RAGE_HASTE = 42583, - SPELL_CLAW_RAGE_TRIGGER = 43149, - SPELL_CLAW_RAGE_DAMAGE = 43150, - SPELL_LYNX_RUSH_HASTE = 43152, - SPELL_LYNX_RUSH_DAMAGE = 43153, - // Dragonhawk Form - SPELL_FLAME_WHIRL = 43213, // trigger two spells - SPELL_FLAME_BREATH = 43215, - SPELL_SUMMON_PILLAR = 43216, // summon 24187 - CREATURE_COLUMN_OF_FIRE = 24187, - SPELL_PILLAR_TRIGGER = 43218, // trigger 43217 - // Cosmetic - SPELL_SPIRIT_AURA = 42466, - SPELL_SIPHON_SOUL = 43501, - // Transforms: - SPELL_SHAPE_OF_THE_BEAR = 42594, // 15% dmg - SPELL_SHAPE_OF_THE_EAGLE = 42606, - SPELL_SHAPE_OF_THE_LYNX = 42607, // haste melee 30% - SPELL_SHAPE_OF_THE_DRAGONHAWK = 42608, - - SPELL_BERSERK = 45078 -}; - -enum Phase -{ - PHASE_BEAR = 0, - PHASE_EAGLE = 1, - PHASE_LYNX = 2, - PHASE_DRAGONHAWK = 3, - PHASE_TROLL = 4 -}; - -//coords for going for changing form -#define CENTER_X 120.148811f -#define CENTER_Y 703.713684f -#define CENTER_Z 45.111477f - -struct SpiritInfoStruct -{ - uint32 entry; - float x, y, z, orient; -}; - -static SpiritInfoStruct SpiritInfo[4] = -{ - {23878, 147.87f, 706.51f, 45.11f, 3.04f}, - {23880, 88.95f, 705.49f, 45.11f, 6.11f}, - {23877, 137.23f, 725.98f, 45.11f, 3.71f}, - {23879, 104.29f, 726.43f, 45.11f, 5.43f} -}; - -struct TransformStruct -{ - uint8 text; - uint32 spell, unaura; -}; - -static TransformStruct Transform[4] = -{ - {YELL_TRANSFORM_TO_BEAR, SPELL_SHAPE_OF_THE_BEAR, SPELL_WHIRLWIND}, - {YELL_TRANSFORM_TO_EAGLE, SPELL_SHAPE_OF_THE_EAGLE, SPELL_SHAPE_OF_THE_BEAR}, - {YELL_TRANSFORM_TO_LYNX, SPELL_SHAPE_OF_THE_LYNX, SPELL_SHAPE_OF_THE_EAGLE}, - {YELL_TRANSFORM_TO_DRAGONHAWK, SPELL_SHAPE_OF_THE_DRAGONHAWK, SPELL_SHAPE_OF_THE_LYNX} -}; - -class boss_zuljin : public CreatureScript -{ - public: - - boss_zuljin() - : CreatureScript("boss_zuljin") - { - } - - struct boss_zuljinAI : public ScriptedAI - { - boss_zuljinAI(Creature* creature) : ScriptedAI(creature), Summons(me) - { - instance = creature->GetInstanceScript(); - } - InstanceScript* instance; - - uint64 SpiritGUID[4]; - uint64 ClawTargetGUID; - uint64 TankGUID; - - uint32 Phase; - uint32 health_20; - - uint32 Intro_Timer; - uint32 Berserk_Timer; - - uint32 Whirlwind_Timer; - uint32 Grievous_Throw_Timer; - - uint32 Creeping_Paralysis_Timer; - uint32 Overpower_Timer; - - uint32 Claw_Rage_Timer; - uint32 Lynx_Rush_Timer; - uint32 Claw_Counter; - uint32 Claw_Loop_Timer; - - uint32 Flame_Whirl_Timer; - uint32 Flame_Breath_Timer; - uint32 Pillar_Of_Fire_Timer; - - SummonList Summons; - - void Reset() override - { - instance->SetData(DATA_ZULJINEVENT, NOT_STARTED); - - Phase = 0; - - health_20 = me->CountPctFromMaxHealth(20); - - Intro_Timer = 37000; - Berserk_Timer = 600000; - - Whirlwind_Timer = 7000; - Grievous_Throw_Timer = 8000; - - Creeping_Paralysis_Timer = 7000; - Overpower_Timer = 0; - - Claw_Rage_Timer = 5000; - Lynx_Rush_Timer = 14000; - Claw_Loop_Timer = 0; - Claw_Counter = 0; - - Flame_Whirl_Timer = 5000; - Flame_Breath_Timer = 6000; - Pillar_Of_Fire_Timer = 7000; - - ClawTargetGUID = 0; - TankGUID = 0; - - Summons.DespawnAll(); - - me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 33975); - //me->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, 218172674); - //me->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE); - } - - void EnterCombat(Unit* /*who*/) override - { - instance->SetData(DATA_ZULJINEVENT, IN_PROGRESS); - - DoZoneInCombat(); - - Talk(YELL_INTRO); - SpawnAdds(); - EnterPhase(0); - } - - void KilledUnit(Unit* /*victim*/) override - { - if (Intro_Timer) - return; - - Talk(YELL_KILL); - } - - void JustDied(Unit* /*killer*/) override - { - instance->SetData(DATA_ZULJINEVENT, DONE); - - Talk(YELL_DEATH); - Summons.DespawnEntry(CREATURE_COLUMN_OF_FIRE); - - if (Unit* Temp = ObjectAccessor::GetUnit(*me, SpiritGUID[3])) - Temp->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_DEAD); - } - - void AttackStart(Unit* who) override - { - if (Phase == 2) - AttackStartNoMove(who); - else - ScriptedAI::AttackStart(who); - } - - void DoMeleeAttackIfReady() - { - if (!me->IsNonMeleeSpellCast(false)) - { - if (me->isAttackReady() && me->IsWithinMeleeRange(me->GetVictim())) - { - if (Phase == 1 && !Overpower_Timer) - { - uint32 health = me->EnsureVictim()->GetHealth(); - me->AttackerStateUpdate(me->GetVictim()); - if (me->GetVictim() && health == me->EnsureVictim()->GetHealth()) - { - DoCastVictim(SPELL_OVERPOWER, false); - Overpower_Timer = 5000; - } - } else me->AttackerStateUpdate(me->GetVictim()); - me->resetAttackTimer(); - } - } - } - - void SpawnAdds() - { - Creature* creature = NULL; - for (uint8 i = 0; i < 4; ++i) - { - creature = me->SummonCreature(SpiritInfo[i].entry, SpiritInfo[i].x, SpiritInfo[i].y, SpiritInfo[i].z, SpiritInfo[i].orient, TEMPSUMMON_DEAD_DESPAWN, 0); - if (creature) - { - creature->CastSpell(creature, SPELL_SPIRIT_AURA, true); - creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - SpiritGUID[i] = creature->GetGUID(); - } - } - } - - void DespawnAdds() - { - for (uint8 i = 0; i < 4; ++i) - { - if (SpiritGUID[i]) - { - if (Unit* temp = ObjectAccessor::GetUnit(*me, SpiritGUID[i])) - { - temp->SetVisible(false); - temp->setDeathState(DEAD); - } - } - SpiritGUID[i] = 0; - } - } - - void JustSummoned(Creature* summon) override - { - Summons.Summon(summon); - } - - void SummonedCreatureDespawn(Creature* summon) override - { - Summons.Despawn(summon); - } - - void EnterPhase(uint32 NextPhase) - { - switch (NextPhase) - { - case 0: - break; - case 1: - case 2: - case 3: - case 4: - DoTeleportTo(CENTER_X, CENTER_Y, CENTER_Z, 100); - DoResetThreat(); - me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 0); - me->RemoveAurasDueToSpell(Transform[Phase].unaura); - DoCast(me, Transform[Phase].spell); - Talk(Transform[Phase].text); - if (Phase > 0) - { - if (Unit* Temp = ObjectAccessor::GetUnit(*me, SpiritGUID[Phase - 1])) - Temp->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_DEAD); - } - if (Unit* Temp = ObjectAccessor::GetUnit(*me, SpiritGUID[NextPhase - 1])) - Temp->CastSpell(me, SPELL_SIPHON_SOUL, false); // should m cast on temp - if (NextPhase == 2) - { - me->GetMotionMaster()->Clear(); - DoCast(me, SPELL_ENERGY_STORM, true); // enemy aura - for (uint8 i = 0; i < 4; ++i) - { - Creature* Vortex = DoSpawnCreature(CREATURE_FEATHER_VORTEX, 0, 0, 0, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); - if (Vortex) - { - Vortex->CastSpell(Vortex, SPELL_CYCLONE_PASSIVE, true); - Vortex->CastSpell(Vortex, SPELL_CYCLONE_VISUAL, true); - Vortex->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - Vortex->SetSpeed(MOVE_RUN, 1.0f); - Vortex->AI()->AttackStart(SelectTarget(SELECT_TARGET_RANDOM, 0)); - DoZoneInCombat(Vortex); - } - } - } - else - AttackStart(me->GetVictim()); - if (NextPhase == 3) - { - me->RemoveAurasDueToSpell(SPELL_ENERGY_STORM); - Summons.DespawnEntry(CREATURE_FEATHER_VORTEX); - me->GetMotionMaster()->MoveChase(me->GetVictim()); - } - break; - default: - break; - } - Phase = NextPhase; - } - - void UpdateAI(uint32 diff) override - { - if (!TankGUID) - { - if (!UpdateVictim()) - return; - - if (me->GetHealth() < health_20 * (4 - Phase)) - EnterPhase(Phase + 1); - } - - if (Berserk_Timer <= diff) - { - DoCast(me, SPELL_BERSERK, true); - Talk(YELL_BERSERK); - Berserk_Timer = 60000; - } else Berserk_Timer -= diff; - - switch (Phase) - { - case 0: - if (Intro_Timer) - { - if (Intro_Timer <= diff) - { - Talk(YELL_AGGRO); - Intro_Timer = 0; - } else Intro_Timer -= diff; - } - - if (Whirlwind_Timer <= diff) - { - DoCast(me, SPELL_WHIRLWIND); - Whirlwind_Timer = urand(15000, 20000); - } else Whirlwind_Timer -= diff; - - if (Grievous_Throw_Timer <= diff) - { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) - DoCast(target, SPELL_GRIEVOUS_THROW, false); - Grievous_Throw_Timer = 10000; - } else Grievous_Throw_Timer -= diff; - break; - - case 1: - if (Creeping_Paralysis_Timer <= diff) - { - DoCast(me, SPELL_CREEPING_PARALYSIS); - Creeping_Paralysis_Timer = 20000; - } else Creeping_Paralysis_Timer -= diff; - - if (Overpower_Timer <= diff) - { - // implemented in DoMeleeAttackIfReady() - Overpower_Timer = 0; - } else Overpower_Timer -= diff; - break; - - case 2: - return; - - case 3: - if (Claw_Rage_Timer <= diff) - { - if (!TankGUID) - { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - { - if (me->GetVictim()) - TankGUID = me->EnsureVictim()->GetGUID(); - me->SetSpeed(MOVE_RUN, 5.0f); - AttackStart(target); // change victim - Claw_Rage_Timer = 0; - Claw_Loop_Timer = 500; - Claw_Counter = 0; - } - } - else if (!Claw_Rage_Timer) // do not do this when Lynx_Rush - { - if (Claw_Loop_Timer <= diff) - { - Unit* target = me->GetVictim(); - if (!target || !target->isTargetableForAttack()) target = ObjectAccessor::GetUnit(*me, TankGUID); - if (!target || !target->isTargetableForAttack()) target = SelectTarget(SELECT_TARGET_RANDOM, 0); - if (target) - { - AttackStart(target); - if (me->IsWithinMeleeRange(target)) - { - DoCast(target, SPELL_CLAW_RAGE_DAMAGE, true); - ++Claw_Counter; - if (Claw_Counter == 12) - { - Claw_Rage_Timer = urand(15000, 20000); - me->SetSpeed(MOVE_RUN, 1.2f); - AttackStart(ObjectAccessor::GetUnit(*me, TankGUID)); - TankGUID = 0; - return; - } - else - Claw_Loop_Timer = 500; - } - } - else - { - EnterEvadeMode(); // if (target) - return; - } - } else Claw_Loop_Timer -= diff; - } //if (TankGUID) - } else Claw_Rage_Timer -= diff; - - if (Lynx_Rush_Timer <= diff) - { - if (!TankGUID) - { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - { - TankGUID = me->EnsureVictim()->GetGUID(); - me->SetSpeed(MOVE_RUN, 5.0f); - AttackStart(target); // change victim - Lynx_Rush_Timer = 0; - Claw_Counter = 0; - } - } - else if (!Lynx_Rush_Timer) - { - Unit* target = me->GetVictim(); - if (!target || !target->isTargetableForAttack()) - { - target = SelectTarget(SELECT_TARGET_RANDOM, 0); - AttackStart(target); - } - if (target) - { - if (me->IsWithinMeleeRange(target)) - { - DoCast(target, SPELL_LYNX_RUSH_DAMAGE, true); - ++Claw_Counter; - if (Claw_Counter == 9) - { - Lynx_Rush_Timer = urand(15000, 20000); - me->SetSpeed(MOVE_RUN, 1.2f); - AttackStart(ObjectAccessor::GetUnit(*me, TankGUID)); - TankGUID = 0; - } - else - AttackStart(SelectTarget(SELECT_TARGET_RANDOM, 0)); - } - } - else - { - EnterEvadeMode(); // if (target) - return; - } - } //if (TankGUID) - } else Lynx_Rush_Timer -= diff; - - break; - case 4: - if (Flame_Whirl_Timer <= diff) - { - DoCast(me, SPELL_FLAME_WHIRL); - Flame_Whirl_Timer = 12000; - }Flame_Whirl_Timer -= diff; - - if (Pillar_Of_Fire_Timer <= diff) - { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(target, SPELL_SUMMON_PILLAR); - Pillar_Of_Fire_Timer = 10000; - } else Pillar_Of_Fire_Timer -= diff; - - if (Flame_Breath_Timer <= diff) - { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - me->SetInFront(target); - DoCast(me, SPELL_FLAME_BREATH); - Flame_Breath_Timer = 10000; - } else Flame_Breath_Timer -= diff; - break; - - default: - break; - } - - if (!TankGUID) - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetInstanceAI<boss_zuljinAI>(creature); - } -}; - -class npc_zuljin_vortex : public CreatureScript -{ - public: - - npc_zuljin_vortex() - : CreatureScript("npc_zuljin_vortex") - { - } - - struct npc_zuljin_vortexAI : public ScriptedAI - { - npc_zuljin_vortexAI(Creature* creature) : ScriptedAI(creature) { } - - void Reset() override { } - - void EnterCombat(Unit* /*target*/) override { } - - void SpellHit(Unit* caster, const SpellInfo* spell) override - { - if (spell->Id == SPELL_ZAP_INFORM) - DoCast(caster, SPELL_ZAP_DAMAGE, true); - } - - void UpdateAI(uint32 /*diff*/) override - { - //if the vortex reach the target, it change his target to another player - if (me->IsWithinMeleeRange(me->GetVictim())) - AttackStart(SelectTarget(SELECT_TARGET_RANDOM, 0)); - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_zuljin_vortexAI(creature); - } -}; - -void AddSC_boss_zuljin() -{ - new boss_zuljin(); - new npc_zuljin_vortex(); -} - diff --git a/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp b/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp index 64ffddbbb6e..d5cfb7b4851 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp @@ -1,6 +1,5 @@ - /* +/* * Copyright (C) 2008-2014 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,136 +15,69 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: instance_zulaman -SD%Complete: 80 -SDComment: -SDCategory: Zul'Aman -EndScriptData */ - #include "ScriptMgr.h" #include "InstanceScript.h" +#include "ScriptedCreature.h" #include "zulaman.h" -#include "Player.h" -#include "TemporarySummon.h" - -enum Misc -{ - MAX_ENCOUNTER = 7, - RAND_VENDOR = 2, - WORLDSTATE_SHOW_TIMER = 3104, - WORLDSTATE_TIME_TO_SACRIFICE = 3106 -}; - -// Chests spawn at bear/eagle/dragonhawk/lynx bosses -// The loots depend on how many bosses have been killed, but not the entries of the chests -// But we cannot add loots to gameobject, so we have to use the fixed loot_template -struct SHostageInfo -{ - uint32 npc, go; // FIXME go Not used - float x, y, z, o; -}; - -static SHostageInfo HostageInfo[] = -{ - {23790, 186648, -57, 1343, 40.77f, 3.2f}, // bear - {23999, 187021, 400, 1414, 74.36f, 3.3f}, // eagle - {24001, 186672, -35, 1134, 18.71f, 1.9f}, // dragonhawk - {24024, 186667, 413, 1117, 6.32f, 3.1f} // lynx -}; - -Position const HarrisonJonesLoc = {120.687f, 1674.0f, 42.0217f, 1.59044f}; class instance_zulaman : public InstanceMapScript { public: - instance_zulaman() - : InstanceMapScript("instance_zulaman", 568) - { - } + instance_zulaman() : InstanceMapScript(ZulAmanScriptName, 568) { } - struct instance_zulaman_InstanceMapScript : public InstanceScript + struct instance_zulaman_InstanceScript : public InstanceScript { - instance_zulaman_InstanceMapScript(Map* map) : InstanceScript(map) { } - - uint64 HarkorsSatchelGUID; - uint64 TanzarsTrunkGUID; - uint64 AshlisBagGUID; - uint64 KrazsPackageGUID; - uint64 StrangeGongGUID; - uint64 HarrisonJonesGUID; - - uint64 HexLordGateGUID; - uint64 ZulJinGateGUID; - uint64 MassiveGateGUID; - uint64 AkilzonDoorGUID; - uint64 ZulJinDoorGUID; - uint64 HalazziDoorGUID; - - uint32 QuestTimer; - uint16 BossKilled; - uint16 QuestMinute; - uint16 ChestLooted; - - uint32 m_auiEncounter[MAX_ENCOUNTER]; - uint32 RandVendor[RAND_VENDOR]; - - void Initialize() override + instance_zulaman_InstanceScript(InstanceMap* map) : InstanceScript(map) { - memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); - - HarkorsSatchelGUID = 0; - TanzarsTrunkGUID = 0; - AshlisBagGUID = 0; - KrazsPackageGUID = 0; - StrangeGongGUID = 0; - HexLordGateGUID = 0; - ZulJinGateGUID = 0; - MassiveGateGUID = 0; - AkilzonDoorGUID = 0; - HalazziDoorGUID = 0; - ZulJinDoorGUID = 0; - - HarrisonJonesGUID = 0; - - QuestTimer = 0; - QuestMinute = 0; - BossKilled = 0; - ChestLooted = 0; - - for (uint8 i = 0; i < RAND_VENDOR; ++i) - RandVendor[i] = NOT_STARTED; - - m_auiEncounter[DATA_GONGEVENT] = NOT_STARTED; - } - - bool IsEncounterInProgress() const override - { - for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) - if (m_auiEncounter[i] == IN_PROGRESS) - return true; - - return false; + SetBossNumber(EncounterCount); + + AkilzonGUID = 0; + NalorakkGUID = 0; + JanalaiGUID = 0; + HalazziGUID = 0; + HexLordMalacrassGUID = 0; + DaakaraGUID = 0; + VoljinGUID = 0; + HexLordTriggerGUID = 0; + SpeedRunTimer = 16; + ZulAmanState = NOT_STARTED; + ZulAmanBossCount = 0; } - void OnPlayerEnter(Player* /*player*/) + void FillInitialWorldStates(WorldPacket& packet) override { - if (!HarrisonJonesGUID) - instance->SummonCreature(NPC_HARRISON_JONES, HarrisonJonesLoc); + packet << uint32(WORLD_STATE_ZULAMAN_TIMER_ENABLED) << uint32(ZulAmanState ? 1 : 0); + packet << uint32(WORLD_STATE_ZULAMAN_TIMER) << uint32(SpeedRunTimer); } void OnCreatureCreate(Creature* creature) override { switch (creature->GetEntry()) { - case NPC_HARRISON_JONES: - HarrisonJonesGUID = creature->GetGUID(); + case NPC_AKILZON: + AkilzonGUID = creature->GetGUID(); + break; + case NPC_NALORAKK: + NalorakkGUID = creature->GetGUID(); break; case NPC_JANALAI: - case NPC_ZULJIN: - case NPC_HEXLORD: + JanalaiGUID = creature->GetGUID(); + break; case NPC_HALAZZI: - case NPC_NALORAKK: + HalazziGUID = creature->GetGUID(); + break; + case NPC_HEXLORD: + HexLordMalacrassGUID = creature->GetGUID(); + break; + case NPC_DAAKARA: + DaakaraGUID = creature->GetGUID(); + break; + case NPC_VOLJIN: + VoljinGUID = creature->GetGUID(); + break; + case NPC_HEXLORD_TRIGGER: + HexLordTriggerGUID = creature->GetGUID(); + break; default: break; } @@ -155,219 +87,261 @@ class instance_zulaman : public InstanceMapScript { switch (go->GetEntry()) { - case GO_DOOR_HALAZZI: HalazziDoorGUID = go->GetGUID(); break; - case GO_GATE_ZULJIN: ZulJinGateGUID = go->GetGUID(); break; - case GO_GATE_HEXLORD: HexLordGateGUID = go->GetGUID(); break; - case GO_MASSIVE_GATE: MassiveGateGUID = go->GetGUID(); break; - case GO_DOOR_AKILZON: AkilzonDoorGUID = go->GetGUID(); break; - case GO_DOOR_ZULJIN: ZulJinDoorGUID = go->GetGUID(); break; - - case GO_HARKORS_SATCHEL: HarkorsSatchelGUID = go->GetGUID(); break; - case GO_TANZARS_TRUNK: TanzarsTrunkGUID = go->GetGUID(); break; - case GO_ASHLIS_BAG: AshlisBagGUID = go->GetGUID(); break; - case GO_KRAZS_PACKAGE: KrazsPackageGUID = go->GetGUID(); break; - case GO_STRANGE_GONG: StrangeGongGUID = go->GetGUID(); break; - default: break; + case GO_STRANGE_GONG: + StrangeGongGUID = go->GetGUID(); + break; + case GO_MASSIVE_GATE: + MasiveGateGUID = go->GetGUID(); + AddDoor(go, true); + if (ZulAmanState != NOT_STARTED) + go->SetGoState(GO_STATE_ACTIVE); + break; + default: + break; } - CheckInstanceStatus(); } - void SummonHostage(uint8 num) + void OnGameObjectRemove(GameObject* go) override { - if (!QuestMinute) - return; - - Map::PlayerList const &PlayerList = instance->GetPlayers(); - if (PlayerList.isEmpty()) - return; - - Map::PlayerList::const_iterator i = PlayerList.begin(); - if (Player* i_pl = i->GetSource()) + switch (go->GetEntry()) { - if (Unit* Hostage = i_pl->SummonCreature(HostageInfo[num].npc, HostageInfo[num].x, HostageInfo[num].y, HostageInfo[num].z, HostageInfo[num].o, TEMPSUMMON_DEAD_DESPAWN, 0)) - { - Hostage->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - Hostage->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - } + case GO_MASSIVE_GATE: + AddDoor(go, false); + break; + default: + break; } } - void CheckInstanceStatus() + uint64 GetData64(uint32 type) const override { - if (BossKilled >= DATA_HALAZZIEVENT) - HandleGameObject(HexLordGateGUID, true); + switch (type) + { + case DATA_AKILZON: + return AkilzonGUID; + case DATA_NALORAKK: + return NalorakkGUID; + case DATA_JANALAI: + return JanalaiGUID; + case DATA_HALAZZI: + return HalazziGUID; + case DATA_HEXLORD: + return HexLordMalacrassGUID; + case DATA_DAAKARA: + return DaakaraGUID; + case DATA_HEXLORD_TRIGGER: + return HexLordTriggerGUID; + case DATA_STRANGE_GONG: + return StrangeGongGUID; + case DATA_MASSIVE_GATE: + return MasiveGateGUID; + default: + break; + } - if (BossKilled >= DATA_HEXLORDEVENT) - HandleGameObject(ZulJinGateGUID, true); + return 0; } - std::string GetSaveData() override + void SetData(uint32 type, uint32 data) override { - OUT_SAVE_INST_DATA; - - std::ostringstream ss; - ss << "S " << BossKilled << ' ' << ChestLooted << ' ' << QuestMinute; - - OUT_SAVE_INST_DATA_COMPLETE; - return ss.str(); + switch (type) + { + case DATA_ZULAMAN_STATE: + { + if (data == IN_PROGRESS) + { + DoUpdateWorldState(WORLD_STATE_ZULAMAN_TIMER_ENABLED, 1); + DoUpdateWorldState(WORLD_STATE_ZULAMAN_TIMER, 15); + events.ScheduleEvent(EVENT_UPDATE_ZULAMAN_TIMER, 60000); + SpeedRunTimer = 15; + ZulAmanState = data; + SaveToDB(); + } + break; + } + default: + break; + } } - void Load(const char* load) + uint32 GetData(uint32 type) const override { - if (!load) - return; - - std::istringstream ss(load); - //TC_LOG_ERROR("scripts", "Zul'aman loaded, %s.", ss.str().c_str()); - char dataHead; // S - uint16 data1, data2, data3; - ss >> dataHead >> data1 >> data2 >> data3; - //TC_LOG_ERROR("scripts", "Zul'aman loaded, %d %d %d.", data1, data2, data3); - if (dataHead == 'S') + switch (type) { - BossKilled = data1; - ChestLooted = data2; - QuestMinute = data3; - } else TC_LOG_ERROR("scripts", "Zul'aman: corrupted save data."); + case DATA_ZULAMAN_STATE: + return ZulAmanState; + default: + break; + } + + return 0; } - void SetData(uint32 type, uint32 data) override + bool SetBossState(uint32 type, EncounterState state) override { - switch (type) + if (!InstanceScript::SetBossState(type, state)) + return false; + + if (state == DONE) { - case DATA_GONGEVENT: - m_auiEncounter[DATA_GONGEVENT] = data; - if (data == IN_PROGRESS) - SaveToDB(); - else if (data == DONE) - QuestMinute = 21; - break; - case DATA_NALORAKKEVENT: - m_auiEncounter[DATA_NALORAKKEVENT] = data; - if (data == DONE) + if (ZulAmanState == IN_PROGRESS && SpeedRunTimer) { - if (QuestMinute) + ++ZulAmanBossCount; + + if (ZulAmanBossCount < 2) { - QuestMinute += 15; - DoUpdateWorldState(WORLDSTATE_TIME_TO_SACRIFICE, QuestMinute); + SpeedRunTimer = SpeedRunTimer + 5; + DoUpdateWorldState(WORLD_STATE_ZULAMAN_TIMER, SpeedRunTimer); } - SummonHostage(0); - } - break; - case DATA_AKILZONEVENT: - m_auiEncounter[DATA_AKILZONEVENT] = data; - HandleGameObject(AkilzonDoorGUID, data != IN_PROGRESS); - if (data == DONE) - { - if (QuestMinute) + else if (ZulAmanBossCount == 4) { - QuestMinute += 10; - DoUpdateWorldState(WORLDSTATE_TIME_TO_SACRIFICE, QuestMinute); + DoUpdateWorldState(WORLD_STATE_ZULAMAN_TIMER_ENABLED, 0); + events.CancelEvent(EVENT_UPDATE_ZULAMAN_TIMER); + ZulAmanState = DONE; } - SummonHostage(1); } - break; - case DATA_JANALAIEVENT: - m_auiEncounter[DATA_JANALAIEVENT] = data; - if (data == DONE) - SummonHostage(2); - break; - case DATA_HALAZZIEVENT: - m_auiEncounter[DATA_HALAZZIEVENT] = data; - HandleGameObject(HalazziDoorGUID, data != IN_PROGRESS); - if (data == DONE) SummonHostage(3); - break; - case DATA_HEXLORDEVENT: - m_auiEncounter[DATA_HEXLORDEVENT] = data; - if (data == IN_PROGRESS) - HandleGameObject(HexLordGateGUID, false); - else if (data == NOT_STARTED) - CheckInstanceStatus(); - break; - case DATA_ZULJINEVENT: - m_auiEncounter[DATA_ZULJINEVENT] = data; - HandleGameObject(ZulJinDoorGUID, data != IN_PROGRESS); - break; - case DATA_CHESTLOOTED: - ++ChestLooted; - SaveToDB(); - break; - case TYPE_RAND_VENDOR_1: - RandVendor[0] = data; - break; - case TYPE_RAND_VENDOR_2: - RandVendor[1] = data; - break; } - if (data == DONE) + switch (type) { - ++BossKilled; - if (QuestMinute && BossKilled >= DATA_HALAZZIEVENT) - { - QuestMinute = 0; - DoUpdateWorldState(WORLDSTATE_SHOW_TIMER, 0); - } - CheckInstanceStatus(); - SaveToDB(); + case DATA_AKILZON: + break; + case DATA_NALORAKK: + break; + case DATA_JANALAI: + break; + case DATA_HALAZZI: + case DATA_HEXLORD: + case DATA_DAAKARA: + break; + default: + break; } + + return true; } - uint32 GetData(uint32 type) const override + void ProcessEvent(WorldObject* /*obj*/, uint32 eventId) override { - switch (type) + switch (eventId) { - case DATA_GONGEVENT: return m_auiEncounter[DATA_GONGEVENT]; - case DATA_NALORAKKEVENT: return m_auiEncounter[DATA_NALORAKKEVENT]; - case DATA_AKILZONEVENT: return m_auiEncounter[DATA_AKILZONEVENT]; - case DATA_JANALAIEVENT: return m_auiEncounter[DATA_JANALAIEVENT]; - case DATA_HALAZZIEVENT: return m_auiEncounter[DATA_HALAZZIEVENT]; - case DATA_HEXLORDEVENT: return m_auiEncounter[DATA_HEXLORDEVENT]; - case DATA_ZULJINEVENT: return m_auiEncounter[DATA_ZULJINEVENT]; - case DATA_CHESTLOOTED: return ChestLooted; - case TYPE_RAND_VENDOR_1: return RandVendor[0]; - case TYPE_RAND_VENDOR_2: return RandVendor[1]; - default: return 0; + case EVENT_START_ZULAMAN: + if (Creature* voljin = instance->GetCreature(VoljinGUID)) + { + if (voljin->IsAIEnabled) + voljin->AI()->DoAction(ACTION_START_ZULAMAN); + } + break; + default: + break; } } - void Update(uint32 diff) override + void Update(uint32 diff) { - if (QuestMinute) + if (events.Empty()) + return; + + events.Update(diff); + + while (uint32 eventId = events.ExecuteEvent()) { - if (QuestTimer <= diff) + switch (eventId) { - QuestMinute--; - SaveToDB(); - QuestTimer += 60000; - if (QuestMinute) - { - DoUpdateWorldState(WORLDSTATE_SHOW_TIMER, 1); - DoUpdateWorldState(WORLDSTATE_TIME_TO_SACRIFICE, QuestMinute); - } else DoUpdateWorldState(WORLDSTATE_SHOW_TIMER, 0); + case EVENT_UPDATE_ZULAMAN_TIMER: + SaveToDB(); + DoUpdateWorldState(WORLD_STATE_ZULAMAN_TIMER, --SpeedRunTimer); + if (SpeedRunTimer) + events.ScheduleEvent(EVENT_UPDATE_ZULAMAN_TIMER, 60000); + else + { + DoUpdateWorldState(WORLD_STATE_ZULAMAN_TIMER_ENABLED, 0); + events.CancelEvent(EVENT_UPDATE_ZULAMAN_TIMER); + ZulAmanState = FAIL; + } + break; + default: + break; } - QuestTimer -= diff; } } - uint64 GetData64(uint32 type) const override + std::string GetSaveData() override { - switch (type) + OUT_SAVE_INST_DATA; + + std::ostringstream saveStream; + saveStream << "Z A " << GetBossSaveData() << ZulAmanState + << ' ' << SpeedRunTimer << ' ' << ZulAmanBossCount; + + OUT_SAVE_INST_DATA_COMPLETE; + return saveStream.str(); + } + + void Load(char const* str) override + { + if (!str) { - case GO_STRANGE_GONG: - return StrangeGongGUID; - case GO_MASSIVE_GATE: - return MassiveGateGUID; + OUT_LOAD_INST_DATA_FAIL; + return; } - return 0; + OUT_LOAD_INST_DATA(str); + + char dataHead1, dataHead2; + + std::istringstream loadStream(str); + loadStream >> dataHead1 >> dataHead2; + + if (dataHead1 == 'Z' && dataHead2 == 'A') + { + for (uint8 i = 0; i < EncounterCount; ++i) + { + uint32 tmpState; + loadStream >> tmpState; + if (tmpState == IN_PROGRESS || tmpState > SPECIAL) + tmpState = NOT_STARTED; + + SetBossState(i, EncounterState(tmpState)); + } + + loadStream >> ZulAmanState; + loadStream >> SpeedRunTimer; + loadStream >> ZulAmanBossCount; + + if (ZulAmanState == IN_PROGRESS && SpeedRunTimer && SpeedRunTimer <= 15) + { + events.ScheduleEvent(EVENT_UPDATE_ZULAMAN_TIMER, 60000); + DoUpdateWorldState(WORLD_STATE_ZULAMAN_TIMER_ENABLED, 1); + DoUpdateWorldState(WORLD_STATE_ZULAMAN_TIMER, SpeedRunTimer); + } + } + else + OUT_LOAD_INST_DATA_FAIL; + + OUT_LOAD_INST_DATA_COMPLETE; } + protected: + EventMap events; + uint64 AkilzonGUID; + uint64 NalorakkGUID; + uint64 JanalaiGUID; + uint64 HalazziGUID; + uint64 HexLordMalacrassGUID; + uint64 DaakaraGUID; + uint64 VoljinGUID; + uint64 HexLordTriggerGUID; + uint64 StrangeGongGUID; + uint64 MasiveGateGUID; + uint32 SpeedRunTimer; + uint32 ZulAmanState; + uint32 ZulAmanBossCount; }; InstanceScript* GetInstanceScript(InstanceMap* map) const override { - return new instance_zulaman_InstanceMapScript(map); + return new instance_zulaman_InstanceScript(map); } }; @@ -375,4 +349,3 @@ void AddSC_instance_zulaman() { new instance_zulaman(); } - diff --git a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp index b2eec0574f3..d4b4cb3ea6b 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2014 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,447 +15,209 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Zulaman -SD%Complete: 90 -SDComment: Forest Frog will turn into different NPC's. Workaround to prevent new entry from running this script -SDCategory: Zul'Aman -EndScriptData */ - -/* ContentData -npc_forest_frog -EndContentData */ - #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "ScriptedGossip.h" -#include "zulaman.h" #include "Player.h" -#include "SpellInfo.h" +#include "CreatureTextMgr.h" #include "SpellScript.h" - -/*###### -## npc_forest_frog -######*/ - -enum ForestFrog -{ - // Spells - SPELL_REMOVE_AMANI_CURSE = 43732, - SPELL_PUSH_MOJO = 43923, - - // Creatures - NPC_FOREST_FROG = 24396 - -}; - -class npc_forest_frog : public CreatureScript -{ - public: - - npc_forest_frog() - : CreatureScript("npc_forest_frog") - { - } - - struct npc_forest_frogAI : public ScriptedAI - { - npc_forest_frogAI(Creature* creature) : ScriptedAI(creature) - { - instance = creature->GetInstanceScript(); - } - - InstanceScript* instance; - - void Reset() override { } - - void EnterCombat(Unit* /*who*/) override { } - - void DoSpawnRandom() - { - uint32 cEntry = 0; - switch (rand()%10) - { - case 0: cEntry = 24397; break; //Mannuth - case 1: cEntry = 24403; break; //Deez - case 2: cEntry = 24404; break; //Galathryn - case 3: cEntry = 24405; break; //Adarrah - case 4: cEntry = 24406; break; //Fudgerick - case 5: cEntry = 24407; break; //Darwen - case 6: cEntry = 24445; break; //Mitzi - case 7: cEntry = 24448; break; //Christian - case 8: cEntry = 24453; break; //Brennan - case 9: cEntry = 24455; break; //Hollee - } - - if (!instance->GetData(TYPE_RAND_VENDOR_1)) - if (rand()%10 == 1) cEntry = 24408; //Gunter - if (!instance->GetData(TYPE_RAND_VENDOR_2)) - if (rand()%10 == 1) cEntry = 24409; //Kyren - - if (cEntry) me->UpdateEntry(cEntry); - - if (cEntry == 24408) instance->SetData(TYPE_RAND_VENDOR_1, DONE); - if (cEntry == 24409) instance->SetData(TYPE_RAND_VENDOR_2, DONE); - } - - void SpellHit(Unit* caster, const SpellInfo* spell) override - { - if (spell->Id == SPELL_REMOVE_AMANI_CURSE && caster->GetTypeId() == TYPEID_PLAYER && me->GetEntry() == NPC_FOREST_FROG) - { - //increase or decrease chance of mojo? - if (rand()%99 == 50) DoCast(caster, SPELL_PUSH_MOJO, true); - else DoSpawnRandom(); - } - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetInstanceAI<npc_forest_frogAI>(creature); - } -}; - -/*###### -## npc_zulaman_hostage -######*/ - -#define GOSSIP_HOSTAGE1 "I am glad to help you." - -static uint32 HostageEntry[] = {23790, 23999, 24024, 24001}; -static uint32 ChestEntry[] = {186648, 187021, 186672, 186667}; - -class npc_zulaman_hostage : public CreatureScript -{ - public: - npc_zulaman_hostage() : CreatureScript("npc_zulaman_hostage") { } - - struct npc_zulaman_hostageAI : public ScriptedAI - { - npc_zulaman_hostageAI(Creature* creature) : ScriptedAI(creature) - { - IsLoot = false; - } - - bool IsLoot; - uint64 PlayerGUID; - - void Reset() override { } - - void EnterCombat(Unit* /*who*/) override { } - - void JustDied(Unit* /*killer*/) override - { - if (Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID)) - player->SendLoot(me->GetGUID(), LOOT_CORPSE); - } - - void UpdateAI(uint32 /*diff*/) override - { - if (IsLoot) - DoCast(me, 7, false); - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_zulaman_hostageAI(creature); - } - - bool OnGossipHello(Player* player, Creature* creature) override - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HOSTAGE1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - return true; - } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override - { - player->PlayerTalkClass->ClearMenus(); - - if (action == GOSSIP_ACTION_INFO_DEF + 1) - player->CLOSE_GOSSIP_MENU(); - - if (!creature->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP)) - return true; - - creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - - InstanceScript* instance = creature->GetInstanceScript(); - if (instance) - { - //uint8 progress = instance->GetData(DATA_CHESTLOOTED); - instance->SetData(DATA_CHESTLOOTED, 0); - float x, y, z; - creature->GetPosition(x, y, z); - uint32 entry = creature->GetEntry(); - for (uint8 i = 0; i < 4; ++i) - { - if (HostageEntry[i] == entry) - { - creature->SummonGameObject(ChestEntry[i], x-2, y, z, 0, 0, 0, 0, 0, 0); - break; - } - } - } - return true; - } -}; - -/*###### -## npc_harrison_jones -######*/ +#include "zulaman.h" enum Says { - SAY_HARRISON_0 = 0, - SAY_HARRISON_1 = 1, - SAY_HARRISON_2 = 0, - SAY_HARRISON_3 = 1 + // Vol'jin + SAY_INTRO_1 = 0, + SAY_INTRO_2 = 1, + SAY_INTRO_3 = 2, + SAY_INTRO_4 = 3, + SAY_INTRO_FAIL = 4, + + // Hex Lord Malacrass + SAY_HEXLOR_INTRO = 0 }; enum Spells { - SPELL_BANGING_THE_GONG = 45225, - SPELL_STEALTH = 34189, - SPELL_COSMETIC_SPEAR_THROW = 43647 + // Vol'jin + SPELL_BANGING_THE_GONG = 45225 }; enum Events { - GONG_EVENT_1 = 1, - GONG_EVENT_2 = 2, - GONG_EVENT_3 = 3, - GONG_EVENT_4 = 4, - GONG_EVENT_5 = 5, - GONG_EVENT_6 = 6, - GONG_EVENT_7 = 7, - GONG_EVENT_8 = 8, - GONG_EVENT_9 = 9, - GONG_EVENT_10 = 10, - GONG_EVENT_11 = 11 + EVENT_INTRO_MOVEPOINT_1 = 1, + EVENT_INTRO_MOVEPOINT_2 = 2, + EVENT_INTRO_MOVEPOINT_3 = 3, + EVENT_BANGING_THE_GONG = 4, + EVENT_START_DOOR_OPENING_1 = 5, + EVENT_START_DOOR_OPENING_2 = 6, + EVENT_START_DOOR_OPENING_3 = 7, + EVENT_START_DOOR_OPENING_4 = 8, + EVENT_START_DOOR_OPENING_5 = 9, + EVENT_START_DOOR_OPENING_6 = 10, + EVENT_START_DOOR_OPENING_7 = 11 }; -enum Waypoints +enum Points { - HARRISON_MOVE_1 = 860440, - HARRISON_MOVE_2 = 860441, - HARRISON_MOVE_3 = 860442 + POINT_INTRO = 1, + POINT_STRANGE_GONG = 2, + POINT_START_DOOR_OPENING_1 = 3, + POINT_START_DOOR_OPENING_2 = 4 }; -enum DisplayIds +enum Misc { - MODEL_HARRISON_JONES_0 = 22340, - MODEL_HARRISON_JONES_1 = 22354, - MODEL_HARRISON_JONES_2 = 22347 + ITEM_VIRTUAL_ITEM = 5301 }; -enum EntryIds +Position const VoljinIntroWaypoint[4] = { - NPC_HARRISON_JONES_1 = 24375, - NPC_HARRISON_JONES_2 = 24365, - NPC_AMANISHI_GUARDIAN = 23597, + { 117.7349f, 1662.77f, 42.02156f, 0.0f }, + { 132.14f, 1645.143f, 42.02158f, 0.0f }, + { 121.8901f, 1639.118f, 42.23253f, 0.0f }, + { 122.618f, 1639.546f, 42.11659f, 0.0f }, }; -enum Weapons -{ - WEAPON_MACE = 5301, - WEAPON_SPEAR = 13631 -}; - -class npc_harrison_jones : public CreatureScript +class npc_voljin_zulaman : public CreatureScript { public: + npc_voljin_zulaman() : CreatureScript("npc_voljin_zulaman") { } - npc_harrison_jones() : CreatureScript("npc_harrison_jones") - { - } - - struct npc_harrison_jonesAI : public ScriptedAI + struct npc_voljin_zulamanAI : public ScriptedAI { - npc_harrison_jonesAI(Creature* creature) : ScriptedAI(creature) + npc_voljin_zulamanAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { - instance = creature->GetInstanceScript(); + me->SetDisplayId(me->GetCreatureTemplate()->Modelid1); + if (_instance->GetData(DATA_ZULAMAN_STATE) == NOT_STARTED) + me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); } - InstanceScript* instance; - - uint8 _gongEvent; - uint32 _gongTimer; - uint64 uiTargetGUID; - void Reset() override { - _gongEvent = 0; - _gongTimer = 0; - uiTargetGUID = 0; + _gongCount = 0; } - void EnterCombat(Unit* /*who*/) override { } - void sGossipSelect(Player* player, uint32 sender, uint32 action) override { - if (me->GetCreatureTemplate()->GossipMenuId == sender && !action) - { - player->CLOSE_GOSSIP_MENU(); - me->SetFacingToObject(player); + if (_instance->GetData(DATA_ZULAMAN_STATE) != NOT_STARTED) + return; + + if (me->GetCreatureTemplate()->GossipMenuId == sender && !action) + { + _events.Reset(); + me->SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID, 0); me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - Talk(SAY_HARRISON_0); - _gongEvent = GONG_EVENT_1; - _gongTimer = 4000; - } + me->SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_NONE); + _events.ScheduleEvent(EVENT_INTRO_MOVEPOINT_1, 1000); + Talk(SAY_INTRO_1, player); + me->SetWalk(true); + } } - void SpellHit(Unit*, const SpellInfo* spell) override + void DoAction(int32 action) override { - if (spell->Id == SPELL_COSMETIC_SPEAR_THROW) + if (action == ACTION_START_ZULAMAN) { - me->RemoveAllAuras(); - me->SetEntry(NPC_HARRISON_JONES_2); - me->SetDisplayId(MODEL_HARRISON_JONES_2); - me->SetTarget(0); - me->SetByteValue(UNIT_FIELD_BYTES_1, 0, UNIT_STAND_STATE_DEAD); - me->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD); - instance->SetData(DATA_GONGEVENT, DONE); + if (++_gongCount == 10) + _events.ScheduleEvent(EVENT_START_DOOR_OPENING_1, 500); } } void UpdateAI(uint32 diff) override { - if (_gongEvent) + _events.Update(diff); + while (uint32 eventId = _events.ExecuteEvent()) { - if (_gongTimer <= diff) + switch (eventId) { - switch (_gongEvent) - { - case GONG_EVENT_1: - me->GetMotionMaster()->MovePath(HARRISON_MOVE_1, false); - _gongEvent = GONG_EVENT_2; - _gongTimer = 12000; - break; - case GONG_EVENT_2: - me->SetFacingTo(6.235659f); - Talk(SAY_HARRISON_1); - DoCast(me, SPELL_BANGING_THE_GONG); - me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, uint32(WEAPON_MACE)); - me->SetSheath(SHEATH_STATE_MELEE); - _gongEvent = GONG_EVENT_3; - _gongTimer = 4000; - break; - case GONG_EVENT_3: - if (GameObject* gong = me->GetMap()->GetGameObject(instance->GetData64(GO_STRANGE_GONG))) - gong->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - _gongEvent = GONG_EVENT_4; - _gongTimer = 105000; - break; - case GONG_EVENT_4: - me->RemoveAura(SPELL_BANGING_THE_GONG); - if (GameObject* gong = me->GetMap()->GetGameObject(instance->GetData64(GO_STRANGE_GONG))) - gong->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - - // trigger or gong will need to be scripted to set IN_PROGRESS after enough hits. - // This is temp workaround. - instance->SetData(DATA_GONGEVENT, IN_PROGRESS); // to be removed. - - if (instance->GetData(DATA_GONGEVENT) == IN_PROGRESS) - { - // Players are Now Saved to instance at SPECIAL (Player should be notified?) - me->GetMotionMaster()->MovePath(HARRISON_MOVE_2, false); - _gongEvent = GONG_EVENT_5; - _gongTimer = 5000; - } - else - { - _gongTimer = 1000; - _gongEvent = GONG_EVENT_9; - } - break; - case GONG_EVENT_5: - me->SetEntry(NPC_HARRISON_JONES_1); - me->SetDisplayId(MODEL_HARRISON_JONES_1); - Talk(SAY_HARRISON_2); - _gongTimer = 12000; - _gongEvent = GONG_EVENT_6; - break; - case GONG_EVENT_6: - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_USE_STANDING); - Talk(SAY_HARRISON_3); - _gongTimer = 7000; - _gongEvent = GONG_EVENT_7; - break; - case GONG_EVENT_7: - if (!uiTargetGUID) - { - std::list<Creature*> targetList; - GetCreatureListWithEntryInGrid(targetList, me, NPC_AMANISHI_GUARDIAN, 26.0f); - if (!targetList.empty()) - { - for (std::list<Creature*>::const_iterator itr = targetList.begin(); itr != targetList.end(); ++itr) - { - if (Creature* ptarget = *itr) - { - if (ptarget->GetPositionX() > 120) - { - ptarget->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, uint32(WEAPON_SPEAR)); - ptarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); - ptarget->SetReactState(REACT_PASSIVE); - ptarget->AI()->SetData(0, 1); - } - else - { - ptarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); - ptarget->SetReactState(REACT_PASSIVE); - ptarget->AI()->SetData(0, 2); - } - } - } - } - } + case EVENT_INTRO_MOVEPOINT_1: + me->GetMotionMaster()->MovePoint(POINT_INTRO, VoljinIntroWaypoint[0]); + _events.ScheduleEvent(EVENT_INTRO_MOVEPOINT_2, 1000); + break; + case EVENT_INTRO_MOVEPOINT_2: + me->GetMotionMaster()->MovePoint(POINT_STRANGE_GONG, VoljinIntroWaypoint[1]); + _events.ScheduleEvent(EVENT_INTRO_MOVEPOINT_3, 4000); + break; + case EVENT_INTRO_MOVEPOINT_3: + Talk(SAY_INTRO_2); + _events.ScheduleEvent(EVENT_BANGING_THE_GONG, 3000); + case EVENT_BANGING_THE_GONG: + DoCast(me, SPELL_BANGING_THE_GONG); + if (GameObject* strangeGong = ObjectAccessor::GetGameObject(*me, _instance->GetData64(DATA_STRANGE_GONG))) + strangeGong->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, uint32(ITEM_VIRTUAL_ITEM)); + break; + case EVENT_START_DOOR_OPENING_1: + me->RemoveAura(SPELL_BANGING_THE_GONG); + _events.ScheduleEvent(EVENT_START_DOOR_OPENING_2, 500); + break; + case EVENT_START_DOOR_OPENING_2: + me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, uint32(0)); + if (GameObject* strangeGong = ObjectAccessor::GetGameObject(*me, _instance->GetData64(DATA_STRANGE_GONG))) + strangeGong->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + _events.ScheduleEvent(EVENT_START_DOOR_OPENING_3, 500); + break; + case EVENT_START_DOOR_OPENING_3: + me->GetMotionMaster()->MovePoint(POINT_START_DOOR_OPENING_1, VoljinIntroWaypoint[2]); + break; + case EVENT_START_DOOR_OPENING_4: + _instance->SetData(DATA_ZULAMAN_STATE, IN_PROGRESS); + if (GameObject* masiveGate = ObjectAccessor::GetGameObject(*me, _instance->GetData64(DATA_MASSIVE_GATE))) + masiveGate->SetGoState(GO_STATE_ACTIVE); + _events.ScheduleEvent(EVENT_START_DOOR_OPENING_5, 3000); + break; + case EVENT_START_DOOR_OPENING_5: + Talk(SAY_INTRO_4); + _events.ScheduleEvent(EVENT_START_DOOR_OPENING_6, 6000); + break; + case EVENT_START_DOOR_OPENING_6: + _events.ScheduleEvent(EVENT_START_DOOR_OPENING_7, 6000); + break; + case EVENT_START_DOOR_OPENING_7: + if (Creature* hexLordTrigger = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_HEXLORD_TRIGGER))) + sCreatureTextMgr->SendChat(hexLordTrigger, SAY_HEXLOR_INTRO, 0, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_MAP); + break; + default: + break; + } + } + } - if (GameObject* gate = me->GetMap()->GetGameObject(instance->GetData64(GO_MASSIVE_GATE))) - gate->SetGoState(GO_STATE_ACTIVE); - _gongTimer = 2000; - _gongEvent = GONG_EVENT_8; - break; - case GONG_EVENT_8: - DoCast(me, SPELL_STEALTH); - me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, uint32(0)); - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); - me->GetMotionMaster()->MovePath(HARRISON_MOVE_3, false); - _gongTimer = 1000; - _gongEvent = 0; - break; - case GONG_EVENT_9: - me->GetMotionMaster()->MovePoint(0, 120.687f, 1674.0f, 42.0217f); - _gongTimer = 12000; - _gongEvent = GONG_EVENT_10; - break; - case GONG_EVENT_10: - me->SetFacingTo(1.59044f); - _gongEvent = 11; - _gongTimer = 6000; - break; - case GONG_EVENT_11: - me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + void MovementInform(uint32 movementType, uint32 pointId) override + { + if (movementType != POINT_MOTION_TYPE) + return; - instance->SetData(DATA_GONGEVENT, NOT_STARTED); - _gongEvent = 0; - _gongTimer = 1000; - break; - } - } - else - _gongTimer -= diff; + switch (pointId) + { + case POINT_STRANGE_GONG: + if (GameObject* strangeGong = ObjectAccessor::GetGameObject(*me, _instance->GetData64(DATA_STRANGE_GONG))) + me->SetFacingToObject(strangeGong); // setInFront + break; + case POINT_START_DOOR_OPENING_1: + me->SetFacingTo(4.747295f); + me->GetMotionMaster()->MovePoint(POINT_START_DOOR_OPENING_2, VoljinIntroWaypoint[3]); + Talk(SAY_INTRO_3); + _events.ScheduleEvent(EVENT_START_DOOR_OPENING_4, 4500); + break; + default: + break; } } + + private: + InstanceScript* _instance; + EventMap _events; + uint8 _gongCount; }; CreatureAI* GetAI(Creature* creature) const override { - return GetInstanceAI<npc_harrison_jonesAI>(creature); + return GetInstanceAI<npc_voljin_zulamanAI>(creature); } }; +// 45226 - Banging the Gong class spell_banging_the_gong : public SpellScriptLoader { public: @@ -484,11 +245,8 @@ class spell_banging_the_gong : public SpellScriptLoader } }; - void AddSC_zulaman() { - new npc_forest_frog(); - new npc_zulaman_hostage(); - new npc_harrison_jones(); + new npc_voljin_zulaman(); new spell_banging_the_gong(); } diff --git a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h index 4d5938d7253..a9a1aaecd05 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h +++ b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2014 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 @@ -19,43 +18,73 @@ #ifndef DEF_ZULAMAN_H #define DEF_ZULAMAN_H +uint32 const EncounterCount = 6; +#define ZulAmanScriptName "instance_zulaman" + enum DataTypes { - DATA_GONGEVENT = 0, - DATA_NALORAKKEVENT = 1, - DATA_AKILZONEVENT = 2, - DATA_JANALAIEVENT = 3, - DATA_HALAZZIEVENT = 4, - DATA_HEXLORDEVENT = 5, - DATA_ZULJINEVENT = 6, - DATA_CHESTLOOTED = 7, - TYPE_RAND_VENDOR_1 = 8, - TYPE_RAND_VENDOR_2 = 9 + // BossState + DATA_AKILZON = 0, + DATA_NALORAKK = 1, + DATA_JANALAI = 2, + DATA_HALAZZI = 3, + DATA_HEXLORD = 4, + DATA_DAAKARA = 5, + + // Data64 + DATA_HEXLORD_TRIGGER, + + DATA_STRANGE_GONG, + DATA_MASSIVE_GATE, + + // SetData + DATA_ZULAMAN_STATE }; enum CreatureIds { - NPC_HARRISON_JONES = 24358, - NPC_JANALAI = 23578, - NPC_ZULJIN = 23863, - NPC_HEXLORD = 24239, - NPC_HALAZZI = 23577, - NPC_NALORAKK = 23576 + NPC_AKILZON = 23574, + NPC_NALORAKK = 23576, + NPC_JANALAI = 23578, + NPC_HALAZZI = 23577, + NPC_HEXLORD = 24239, + NPC_DAAKARA = 23863, + + NPC_VOLJIN = 52924, + NPC_HEXLORD_TRIGGER = 24363 +}; + +enum GameObjectIds +{ + GO_STRANGE_GONG = 187359, + GO_MASSIVE_GATE = 186728, }; -enum GameobjectIds +enum ZulAmanEvents { - GO_DOOR_HALAZZI = 186303, - GO_GATE_ZULJIN = 186304, - GO_GATE_HEXLORD = 186305, - GO_MASSIVE_GATE = 186728, - GO_DOOR_AKILZON = 186858, - GO_DOOR_ZULJIN = 186859, - GO_HARKORS_SATCHEL = 187021, - GO_TANZARS_TRUNK = 186648, - GO_ASHLIS_BAG = 186672, - GO_KRAZS_PACKAGE = 186667, - GO_STRANGE_GONG = 187359 + EVENT_START_ZULAMAN = 15897, + EVENT_UPDATE_ZULAMAN_TIMER = 1, }; +enum ZulAmanAction +{ + ACTION_START_ZULAMAN = 1 +}; + +enum ZulAmanWorldStates +{ + WORLD_STATE_ZULAMAN_TIMER_ENABLED = 3104, + WORLD_STATE_ZULAMAN_TIMER = 3106, +}; + +template<class AI> +CreatureAI* GetZulAmanAI(Creature* creature) +{ + if (InstanceMap* instance = creature->GetMap()->ToInstanceMap()) + if (instance->GetInstanceScript()) + if (instance->GetScriptId() == sObjectMgr->GetScriptId(ZulAmanScriptName)) + return new AI(creature); + return NULL; +} + #endif diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp deleted file mode 100644 index 4ac34615498..00000000000 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp +++ /dev/null @@ -1,441 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> - * - * 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 -TCName: Boss_Arlokk -TC%Complete: 95 -TCComment: Wrong cleave and red aura is missing not yet added. -TCComment: Prowlers moving through wall hopefully mmaps will fix. -TCComment: Can't test LOS until mmaps. -TCCategory: Zul'Gurub -EndScriptData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "SpellInfo.h" -#include "zulgurub.h" - -enum Says -{ - SAY_AGGRO = 0, - SAY_FEAST_PROWLER = 1, - SAY_DEATH = 2 -}; - -enum Spells -{ - SPELL_SHADOW_WORD_PAIN = 24212, // Corrected - SPELL_GOUGE = 12540, // Corrected - SPELL_MARK_OF_ARLOKK = 24210, // triggered spell 24211 Added to spell_dbc - SPELL_RAVAGE = 24213, // Corrected - SPELL_CLEAVE = 25174, // Searching for right spell - SPELL_PANTHER_TRANSFORM = 24190, // Transform to panther now used - SPELL_SUMMON_PROWLER = 24246, // Added to Spell_dbc - SPELL_VANISH_VISUAL = 24222, // Added - SPELL_VANISH = 24223, // Added - SPELL_SUPER_INVIS = 24235 // Added to Spell_dbc -}; - -enum Events -{ - EVENT_SHADOW_WORD_PAIN = 1, - EVENT_GOUGE = 2, - EVENT_MARK_OF_ARLOKK = 3, - EVENT_RAVAGE = 4, - EVENT_TRANSFORM = 5, - EVENT_VANISH = 6, - EVENT_VANISH_2 = 7, - EVENT_TRANSFORM_BACK = 8, - EVENT_VISIBLE = 9, - EVENT_SUMMON_PROWLERS = 10 -}; - -enum Phases -{ - PHASE_ALL = 0, - PHASE_ONE = 1, - PHASE_TWO = 2 -}; - -enum Weapon -{ - WEAPON_DAGGER = 10616 -}; - -enum Misc -{ - MAX_PROWLERS_PER_SIDE = 15 -}; - -Position const PosMoveOnSpawn[1] = -{ - { -11561.9f, -1627.868f, 41.29941f, 0.0f } -}; - -class boss_arlokk : public CreatureScript -{ - public: boss_arlokk() : CreatureScript("boss_arlokk") { } - - struct boss_arlokkAI : public BossAI - { - boss_arlokkAI(Creature* creature) : BossAI(creature, DATA_ARLOKK) { } - - void Reset() override - { - if (events.IsInPhase(PHASE_TWO)) - me->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, 35.0f, false); // hack - _Reset(); - _summonCountA = 0; - _summonCountB = 0; - me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, uint32(WEAPON_DAGGER)); - me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, uint32(WEAPON_DAGGER)); - me->SetWalk(false); - me->GetMotionMaster()->MovePoint(0, PosMoveOnSpawn[0]); - } - - void JustDied(Unit* /*killer*/) override - { - _JustDied(); - Talk(SAY_DEATH); - } - - void EnterCombat(Unit* /*who*/) override - { - _EnterCombat(); - events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, urand(7000, 9000), 0, PHASE_ONE); - events.ScheduleEvent(EVENT_GOUGE, urand(12000, 15000), 0, PHASE_ONE); - events.ScheduleEvent(EVENT_SUMMON_PROWLERS, 6000, 0, PHASE_ALL); - events.ScheduleEvent(EVENT_MARK_OF_ARLOKK, urand(9000, 11000), 0, PHASE_ALL); - events.ScheduleEvent(EVENT_TRANSFORM, urand(15000, 20000), 0, PHASE_ONE); - Talk(SAY_AGGRO); - - // Sets up list of Panther spawners to cast on - std::list<Creature*> triggerList; - GetCreatureListWithEntryInGrid(triggerList, me, NPC_PANTHER_TRIGGER, 100.0f); - if (!triggerList.empty()) - { - uint8 sideA = 0; - uint8 sideB = 0; - for (std::list<Creature*>::const_iterator itr = triggerList.begin(); itr != triggerList.end(); ++itr) - { - if (Creature* trigger = *itr) - { - if (trigger->GetPositionY() < -1625.0f) - { - _triggersSideAGUID[sideA] = trigger->GetGUID(); - ++sideA; - } - else - { - _triggersSideBGUID[sideB] = trigger->GetGUID(); - ++sideB; - } - } - } - } - } - - void EnterEvadeMode() override - { - BossAI::EnterEvadeMode(); - if (GameObject* object = ObjectAccessor::GetGameObject(*me, instance->GetData64(GO_GONG_OF_BETHEKK))) - object->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - me->DespawnOrUnsummon(4000); - } - - void SetData(uint32 id, uint32 /*value*/) override - { - if (id == 1) - --_summonCountA; - else if (id == 2) - --_summonCountB; - } - - 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_SHADOW_WORD_PAIN: - DoCastVictim(SPELL_SHADOW_WORD_PAIN, true); - events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, urand(5000, 7000), 0, PHASE_ONE); - break; - case EVENT_GOUGE: - DoCastVictim(SPELL_GOUGE, true); - break; - case EVENT_SUMMON_PROWLERS: - if (_summonCountA < MAX_PROWLERS_PER_SIDE) - { - if (Unit* trigger = ObjectAccessor::GetUnit(*me, _triggersSideAGUID[urand(0, 4)])) - { - trigger->CastSpell(trigger, SPELL_SUMMON_PROWLER); - ++_summonCountA; - } - } - if (_summonCountB < MAX_PROWLERS_PER_SIDE) - { - if (Unit* trigger = ObjectAccessor::GetUnit(*me, _triggersSideBGUID[urand(0, 4)])) - { - trigger->CastSpell(trigger, SPELL_SUMMON_PROWLER); - ++_summonCountB; - } - } - events.ScheduleEvent(EVENT_SUMMON_PROWLERS, 6000, 0, PHASE_ALL); - break; - case EVENT_MARK_OF_ARLOKK: - { - Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO, urand(1, 3), 0.0f, false, -SPELL_MARK_OF_ARLOKK); - if (!target) - target = me->GetVictim(); - if (target) - { - DoCast(target, SPELL_MARK_OF_ARLOKK, true); - Talk(SAY_FEAST_PROWLER, target); - } - events.ScheduleEvent(EVENT_MARK_OF_ARLOKK, urand(120000, 130000)); - break; - } - case EVENT_TRANSFORM: - { - DoCast(me, SPELL_PANTHER_TRANSFORM); // SPELL_AURA_TRANSFORM - me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, uint32(EQUIP_UNEQUIP)); - me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, uint32(EQUIP_UNEQUIP)); - /* - const CreatureTemplate* cinfo = me->GetCreatureTemplate(); - me->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg +((cinfo->mindmg/100) * 35))); - me->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg +((cinfo->maxdmg/100) * 35))); - me->UpdateDamagePhysical(BASE_ATTACK); - */ - me->AttackStop(); - DoResetThreat(); - me->SetReactState(REACT_PASSIVE); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE); - DoCast(me, SPELL_VANISH_VISUAL); - DoCast(me, SPELL_VANISH); - events.ScheduleEvent(EVENT_VANISH, 1000, 0, PHASE_ONE); - break; - } - case EVENT_VANISH: - DoCast(me, SPELL_SUPER_INVIS); - me->SetWalk(false); - me->GetMotionMaster()->MovePoint(0, frand(-11551.0f, -11508.0f), frand(-1638.0f, -1617.0f), me->GetPositionZ()); - events.ScheduleEvent(EVENT_VANISH_2, 9000, 0, PHASE_ONE); - break; - case EVENT_VANISH_2: - DoCast(me, SPELL_VANISH); - DoCast(me, SPELL_SUPER_INVIS); - events.ScheduleEvent(EVENT_VISIBLE, urand(7000, 10000), 0, PHASE_ONE); - break; - case EVENT_VISIBLE: - me->SetReactState(REACT_AGGRESSIVE); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE); - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - AttackStart(target); - me->RemoveAura(SPELL_SUPER_INVIS); - me->RemoveAura(SPELL_VANISH); - events.ScheduleEvent(EVENT_RAVAGE, urand(10000, 14000), 0, PHASE_TWO); - events.ScheduleEvent(EVENT_TRANSFORM_BACK, urand(15000, 18000), 0, PHASE_TWO); - events.SetPhase(PHASE_TWO); - me->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, 35.0f, true); // hack - break; - case EVENT_RAVAGE: - DoCastVictim(SPELL_RAVAGE, true); - events.ScheduleEvent(EVENT_RAVAGE, urand(10000, 14000), 0, PHASE_TWO); - break; - case EVENT_TRANSFORM_BACK: - { - me->RemoveAura(SPELL_PANTHER_TRANSFORM); // SPELL_AURA_TRANSFORM - DoCast(me, SPELL_VANISH_VISUAL); - me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, uint32(WEAPON_DAGGER)); - me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, uint32(WEAPON_DAGGER)); - /* - const CreatureTemplate* cinfo = me->GetCreatureTemplate(); - me->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg)); - me->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg)); - me->UpdateDamagePhysical(BASE_ATTACK); - */ - me->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, 35.0f, false); // hack - events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, urand(4000, 7000), 0, PHASE_ONE); - events.ScheduleEvent(EVENT_GOUGE, urand(12000, 15000), 0, PHASE_ONE); - events.ScheduleEvent(EVENT_TRANSFORM, urand(16000, 20000), 0, PHASE_ONE); - events.SetPhase(PHASE_ONE); - break; - } - default: - break; - } - } - - DoMeleeAttackIfReady(); - } - - private: - uint8 _summonCountA; - uint8 _summonCountB; - uint64 _triggersSideAGUID[5]; - uint64 _triggersSideBGUID[5]; - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetZulGurubAI<boss_arlokkAI>(creature); - } -}; - -/*###### -## npc_zulian_prowler -######*/ - -enum ZulianProwlerSpells -{ - SPELL_SNEAK_RANK_1_1 = 22766, - SPELL_SNEAK_RANK_1_2 = 7939, // Added to Spell_dbc - SPELL_MARK_OF_ARLOKK_TRIGGER = 24211 // Added to Spell_dbc -}; - -enum ZulianProwlerEvents -{ - EVENT_ATTACK = 1 -}; - -Position const PosProwlerCenter[1] = -{ - { -11556.7f, -1631.344f, 41.2994f, 0.0f } -}; - -class npc_zulian_prowler : public CreatureScript -{ - public: npc_zulian_prowler() : CreatureScript("npc_zulian_prowler") { } - - struct npc_zulian_prowlerAI : public ScriptedAI - { - npc_zulian_prowlerAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { } - - void Reset() override - { - if (me->GetPositionY() < -1625.0f) - _sideData = 1; - else - _sideData = 2; - - DoCast(me, SPELL_SNEAK_RANK_1_1); - DoCast(me, SPELL_SNEAK_RANK_1_2); - - if (Unit* arlokk = ObjectAccessor::GetUnit(*me, _instance->GetData64(NPC_ARLOKK))) - me->GetMotionMaster()->MovePoint(0, arlokk->GetPositionX(), arlokk->GetPositionY(), arlokk->GetPositionZ()); - _events.ScheduleEvent(EVENT_ATTACK, 6000); - } - - void EnterCombat(Unit* /*who*/) override - { - me->GetMotionMaster()->Clear(false); - me->RemoveAura(SPELL_SNEAK_RANK_1_1); - me->RemoveAura(SPELL_SNEAK_RANK_1_2); - } - - void SpellHit(Unit* caster, SpellInfo const* spell) override - { - if (spell->Id == SPELL_MARK_OF_ARLOKK_TRIGGER) // Should only hit if line of sight - me->Attack(caster, true); - } - - void JustDied(Unit* /*killer*/) override - { - if (Unit* arlokk = ObjectAccessor::GetUnit(*me, _instance->GetData64(NPC_ARLOKK))) - { - if (arlokk->IsAlive()) - arlokk->GetAI()->SetData(_sideData, 0); - } - me->DespawnOrUnsummon(4000); - } - - void UpdateAI(uint32 diff) override - { - if (UpdateVictim()) - { - DoMeleeAttackIfReady(); - return; - } - - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_ATTACK: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0.0f, 100, false)) - me->Attack(target, true); - break; - default: - break; - } - } - } - - private: - int32 _sideData; - EventMap _events; - InstanceScript* _instance; - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetZulGurubAI<npc_zulian_prowlerAI>(creature); - } -}; - -/*###### -## go_gong_of_bethekk -######*/ - -Position const PosSummonArlokk[1] = -{ - { -11507.22f, -1628.062f, 41.38264f, 3.159046f } -}; - -class go_gong_of_bethekk : public GameObjectScript -{ - public: go_gong_of_bethekk() : GameObjectScript("go_gong_of_bethekk") { } - - bool OnGossipHello(Player* /*player*/, GameObject* go) override - { - if (go->GetInstanceScript()) - { - go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - go->SendCustomAnim(0); - go->SummonCreature(NPC_ARLOKK, PosSummonArlokk[0], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 600000); - } - return true; - } -}; - -void AddSC_boss_arlokk() -{ - new boss_arlokk(); - new npc_zulian_prowler(); - new go_gong_of_bethekk(); -} diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_grilek.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_grilek.cpp index 4ffe7b35240..fccaf768704 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_grilek.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_grilek.cpp @@ -16,53 +16,44 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Boss_Grilek -SD%Complete: 100 -SDComment: -SDCategory: Zul'Gurub -EndScriptData */ - +#include "ObjectMgr.h" #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "zulgurub.h" +enum Yells +{ +}; + enum Spells { - SPELL_AVATAR = 24646, // Enrage Spell - SPELL_GROUND_TREMOR = 6524 }; enum Events { - EVENT_AVATAR = 1, - EVENT_GROUND_TREMOR = 2 }; -class boss_grilek : public CreatureScript // grilek +class boss_grilek : public CreatureScript { public: boss_grilek() : CreatureScript("boss_grilek") { } struct boss_grilekAI : public BossAI { - boss_grilekAI(Creature* creature) : BossAI(creature, DATA_EDGE_OF_MADNESS) { } + boss_grilekAI(Creature* creature) : BossAI(creature, DATA_GRILEK) + { + } void Reset() override { - _Reset(); } - void JustDied(Unit* /*killer*/) override + void EnterCombat(Unit* /*who*/) override { - _JustDied(); } - void EnterCombat(Unit* /*who*/) override + void JustDied(Unit* /*killer*/) override { - _EnterCombat(); - events.ScheduleEvent(EVENT_AVATAR, urand(15000, 25000)); - events.ScheduleEvent(EVENT_GROUND_TREMOR, urand(15000, 25000)); } void UpdateAI(uint32 diff) override @@ -74,31 +65,16 @@ class boss_grilek : public CreatureScript // grilek if (me->HasUnitState(UNIT_STATE_CASTING)) return; - + /* while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { - case EVENT_AVATAR: - DoCast(me, SPELL_AVATAR); - if (Unit* victim = me->GetVictim()) - { - if (DoGetThreat(victim)) - DoModifyThreatPercent(victim, -50); - } - - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1)) - AttackStart(target); - events.ScheduleEvent(EVENT_AVATAR, urand(25000, 35000)); - break; - case EVENT_GROUND_TREMOR: - DoCastVictim(SPELL_GROUND_TREMOR, true); - events.ScheduleEvent(EVENT_GROUND_TREMOR, urand(12000, 16000)); - break; default: break; } } + */ DoMeleeAttackIfReady(); } @@ -114,4 +90,3 @@ void AddSC_boss_grilek() { new boss_grilek(); } - diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_hakkar.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_hakkar.cpp deleted file mode 100644 index 2d4a424476d..00000000000 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_hakkar.cpp +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> - * - * 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/>. - */ - -/* -Name: Boss_Hakkar -%Complete: 95 -Comment: Blood siphon spell buggy cause of Core Issue. -Category: Zul'Gurub -*/ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "zulgurub.h" - -enum Says -{ - SAY_AGGRO = 0, - SAY_FLEEING = 1, - SAY_MINION_DESTROY = 2, // Where does it belong? - SAY_PROTECT_ALTAR = 3 // Where does it belong? -}; - -enum Spells -{ - SPELL_BLOOD_SIPHON = 24322, // Buggy ? - SPELL_CORRUPTED_BLOOD = 24328, - SPELL_CAUSE_INSANITY = 24327, // Spell needs scripting. - SPELL_WILL_OF_HAKKAR = 24178, - SPELL_ENRAGE = 24318, - // The Aspects of all High Priests spells - SPELL_ASPECT_OF_JEKLIK = 24687, - SPELL_ASPECT_OF_VENOXIS = 24688, - SPELL_ASPECT_OF_MARLI = 24686, - SPELL_ASPECT_OF_THEKAL = 24689, - SPELL_ASPECT_OF_ARLOKK = 24690 -}; - -enum Events -{ - EVENT_BLOOD_SIPHON = 1, - EVENT_CORRUPTED_BLOOD = 2, - EVENT_CAUSE_INSANITY = 3, // Spell needs scripting. Event disabled - EVENT_WILL_OF_HAKKAR = 4, - EVENT_ENRAGE = 5, - // The Aspects of all High Priests events - EVENT_ASPECT_OF_JEKLIK = 6, - EVENT_ASPECT_OF_VENOXIS = 7, - EVENT_ASPECT_OF_MARLI = 8, - EVENT_ASPECT_OF_THEKAL = 9, - EVENT_ASPECT_OF_ARLOKK = 10 -}; - -class boss_hakkar : public CreatureScript -{ - public: - boss_hakkar() : CreatureScript("boss_hakkar") { } - - struct boss_hakkarAI : public BossAI - { - boss_hakkarAI(Creature* creature) : BossAI(creature, DATA_HAKKAR) { } - - void Reset() override - { - _Reset(); - } - - void JustDied(Unit* /*killer*/) override - { - _JustDied(); - } - - void EnterCombat(Unit* /*who*/) override - { - _EnterCombat(); - events.ScheduleEvent(EVENT_BLOOD_SIPHON, 90000); - events.ScheduleEvent(EVENT_CORRUPTED_BLOOD, 25000); - events.ScheduleEvent(EVENT_CAUSE_INSANITY, 17000); - events.ScheduleEvent(EVENT_WILL_OF_HAKKAR, 17000); - events.ScheduleEvent(EVENT_ENRAGE, 600000); - if (instance->GetBossState(DATA_JEKLIK) != DONE) - events.ScheduleEvent(EVENT_ASPECT_OF_JEKLIK, 4000); - if (instance->GetBossState(DATA_VENOXIS) != DONE) - events.ScheduleEvent(EVENT_ASPECT_OF_VENOXIS, 7000); - if (instance->GetBossState(DATA_MARLI) != DONE) - events.ScheduleEvent(EVENT_ASPECT_OF_MARLI, 12000); - if (instance->GetBossState(DATA_THEKAL) != DONE) - events.ScheduleEvent(EVENT_ASPECT_OF_THEKAL, 8000); - if (instance->GetBossState(DATA_ARLOKK) != DONE) - events.ScheduleEvent(EVENT_ASPECT_OF_ARLOKK, 18000); - Talk(SAY_AGGRO); - } - - 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_BLOOD_SIPHON: - DoCastVictim(SPELL_BLOOD_SIPHON, true); - events.ScheduleEvent(EVENT_BLOOD_SIPHON, 90000); - break; - case EVENT_CORRUPTED_BLOOD: - DoCastVictim(SPELL_CORRUPTED_BLOOD, true); - events.ScheduleEvent(EVENT_CORRUPTED_BLOOD, urand(30000, 45000)); - break; - case EVENT_CAUSE_INSANITY: - // DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true), SPELL_CAUSE_INSANITY); - // events.ScheduleEvent(EVENT_CAUSE_INSANITY, urand(35000, 45000)); - break; - case EVENT_WILL_OF_HAKKAR: - DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true), SPELL_WILL_OF_HAKKAR); - events.ScheduleEvent(EVENT_WILL_OF_HAKKAR, urand(25000, 35000)); - break; - case EVENT_ENRAGE: - if (!me->HasAura(SPELL_ENRAGE)) - DoCast(me, SPELL_ENRAGE); - events.ScheduleEvent(EVENT_ENRAGE, 90000); - break; - case EVENT_ASPECT_OF_JEKLIK: - DoCastVictim(SPELL_ASPECT_OF_JEKLIK, true); - events.ScheduleEvent(EVENT_ASPECT_OF_JEKLIK, urand(10000, 14000)); - break; - case EVENT_ASPECT_OF_VENOXIS: - DoCastVictim(SPELL_ASPECT_OF_VENOXIS, true); - events.ScheduleEvent(EVENT_ASPECT_OF_VENOXIS, 8000); - break; - case EVENT_ASPECT_OF_MARLI: - DoCastVictim(SPELL_ASPECT_OF_MARLI, true); - events.ScheduleEvent(EVENT_ASPECT_OF_MARLI, 10000); - break; - case EVENT_ASPECT_OF_THEKAL: - DoCastVictim(SPELL_ASPECT_OF_THEKAL, true); - events.ScheduleEvent(EVENT_ASPECT_OF_THEKAL, 15000); - break; - case EVENT_ASPECT_OF_ARLOKK: - DoCastVictim(SPELL_ASPECT_OF_ARLOKK, true); - events.ScheduleEvent(EVENT_ASPECT_OF_ARLOKK, urand(10000, 15000)); - break; - default: - break; - } - } - - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetInstanceAI<boss_hakkarAI>(creature); - } -}; - -void AddSC_boss_hakkar() -{ - new boss_hakkar(); -} - diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_hazzarah.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_hazzarah.cpp index 6b964d8825f..14d5f301241 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_hazzarah.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_hazzarah.cpp @@ -16,28 +16,21 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Boss_Hazzarah -SD%Complete: 100 -SDComment: -SDCategory: Zul'Gurub -EndScriptData */ - +#include "ObjectMgr.h" #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "zulgurub.h" +enum Yells +{ +}; + enum Spells { - SPELL_MANABURN = 26046, - SPELL_SLEEP = 24664 }; enum Events { - EVENT_MANABURN = 1, - EVENT_SLEEP = 2, - EVENT_ILLUSIONS = 3 }; class boss_hazzarah : public CreatureScript @@ -47,24 +40,20 @@ class boss_hazzarah : public CreatureScript struct boss_hazzarahAI : public BossAI { - boss_hazzarahAI(Creature* creature) : BossAI(creature, DATA_EDGE_OF_MADNESS) { } + boss_hazzarahAI(Creature* creature) : BossAI(creature, DATA_HAZZARAH) + { + } void Reset() override { - _Reset(); } - void JustDied(Unit* /*killer*/) override + void EnterCombat(Unit* /*who*/) override { - _JustDied(); } - void EnterCombat(Unit* /*who*/) override + void JustDied(Unit* /*killer*/) override { - _EnterCombat(); - events.ScheduleEvent(EVENT_MANABURN, urand(4000, 10000)); - events.ScheduleEvent(EVENT_SLEEP, urand(10000, 18000)); - events.ScheduleEvent(EVENT_ILLUSIONS, urand(10000, 18000)); } void UpdateAI(uint32 diff) override @@ -76,34 +65,16 @@ class boss_hazzarah : public CreatureScript if (me->HasUnitState(UNIT_STATE_CASTING)) return; - + /* while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { - case EVENT_MANABURN: - DoCastVictim(SPELL_MANABURN, true); - events.ScheduleEvent(EVENT_MANABURN, urand(8000, 16000)); - break; - case EVENT_SLEEP: - DoCastVictim(SPELL_SLEEP, true); - events.ScheduleEvent(EVENT_SLEEP, urand(12000, 20000)); - break; - case EVENT_ILLUSIONS: - // We will summon 3 illusions that will spawn on a random gamer and attack this gamer - // We will just use one model for the beginning - for (uint8 i = 0; i < 3; ++i) - { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - if (Creature* Illusion = me->SummonCreature(NPC_NIGHTMARE_ILLUSION, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000)) - Illusion->AI()->AttackStart(target); - } - events.ScheduleEvent(EVENT_ILLUSIONS, urand(15000, 25000)); - break; default: break; } } + */ DoMeleeAttackIfReady(); } diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_jeklik.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_jeklik.cpp deleted file mode 100644 index 7a16f670afe..00000000000 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_jeklik.cpp +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> - * - * 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/>. - */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "zulgurub.h" - -enum Says -{ - SAY_AGGRO = 0, - SAY_RAIN_FIRE = 1, - SAY_DEATH = 2 -}; - -enum Spells -{ - SPELL_CHARGE = 22911, - SPELL_SONICBURST = 23918, - SPELL_SCREECH = 6605, - SPELL_SHADOW_WORD_PAIN = 23952, - SPELL_MIND_FLAY = 23953, - SPELL_CHAIN_MIND_FLAY = 26044, // Right ID unknown. So disabled - SPELL_GREATERHEAL = 23954, - SPELL_BAT_FORM = 23966, - - // Batriders Spell - SPELL_BOMB = 40332 // Wrong ID but Magmadars bomb is not working... -}; - -enum BatIds -{ - NPC_BLOODSEEKER_BAT = 11368, - NPC_FRENZIED_BAT = 14965 -}; - -enum Events -{ - EVENT_CHARGE_JEKLIK = 1, - EVENT_SONIC_BURST, - EVENT_SCREECH, - EVENT_SPAWN_BATS, - EVENT_SHADOW_WORD_PAIN, - EVENT_MIND_FLAY, - EVENT_CHAIN_MIND_FLAY, - EVENT_GREATER_HEAL, - EVENT_SPAWN_FLYING_BATS -}; - -enum Phase -{ - PHASE_ONE = 1, - PHASE_TWO = 2 -}; - -Position const SpawnBat[6] = -{ - { -12291.6220f, -1380.2640f, 144.8304f, 5.483f }, - { -12289.6220f, -1380.2640f, 144.8304f, 5.483f }, - { -12293.6220f, -1380.2640f, 144.8304f, 5.483f }, - { -12291.6220f, -1380.2640f, 144.8304f, 5.483f }, - { -12289.6220f, -1380.2640f, 144.8304f, 5.483f }, - { -12293.6220f, -1380.2640f, 144.8304f, 5.483f } -}; - -class boss_jeklik : public CreatureScript -{ - public: boss_jeklik() : CreatureScript("boss_jeklik") { } - - struct boss_jeklikAI : public BossAI - { - boss_jeklikAI(Creature* creature) : BossAI(creature, DATA_JEKLIK) { } - - void Reset() override - { - _Reset(); - } - - void JustDied(Unit* /*killer*/) override - { - _JustDied(); - Talk(SAY_DEATH); - } - - void EnterCombat(Unit* /*who*/) override - { - _EnterCombat(); - Talk(SAY_AGGRO); - events.SetPhase(PHASE_ONE); - - events.ScheduleEvent(EVENT_CHARGE_JEKLIK, 20000, 0, PHASE_ONE); - events.ScheduleEvent(EVENT_SONIC_BURST, 8000, 0, PHASE_ONE); - events.ScheduleEvent(EVENT_SCREECH, 13000, 0, PHASE_ONE); - events.ScheduleEvent(EVENT_SPAWN_BATS, 60000, 0, PHASE_ONE); - - me->SetCanFly(true); - DoCast(me, SPELL_BAT_FORM); - } - - void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/) override - { - if (events.IsInPhase(PHASE_ONE) && !HealthAbovePct(50)) - { - me->RemoveAurasDueToSpell(SPELL_BAT_FORM); - me->SetCanFly(false); - DoResetThreat(); - events.SetPhase(PHASE_TWO); - events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, 6000, 0, PHASE_TWO); - events.ScheduleEvent(EVENT_MIND_FLAY, 11000, 0, PHASE_TWO); - events.ScheduleEvent(EVENT_CHAIN_MIND_FLAY, 26000, 0, PHASE_TWO); - events.ScheduleEvent(EVENT_GREATER_HEAL, 50000, 0, PHASE_TWO); - events.ScheduleEvent(EVENT_SPAWN_FLYING_BATS, 10000, 0, PHASE_TWO); - return; - } - } - - 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_CHARGE_JEKLIK: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - { - DoCast(target, SPELL_CHARGE); - AttackStart(target); - } - events.ScheduleEvent(EVENT_CHARGE_JEKLIK, urand(15000, 30000), 0, PHASE_ONE); - break; - case EVENT_SONIC_BURST: - DoCastVictim(SPELL_SONICBURST); - events.ScheduleEvent(EVENT_SONIC_BURST, urand(8000, 13000), 0, PHASE_ONE); - break; - case EVENT_SCREECH: - DoCastVictim(SPELL_SCREECH); - events.ScheduleEvent(EVENT_SCREECH, urand(18000, 26000), 0, PHASE_ONE); - break; - case EVENT_SPAWN_BATS: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - for (uint8 i = 0; i < 6; ++i) - if (Creature* bat = me->SummonCreature(NPC_BLOODSEEKER_BAT, SpawnBat[i], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000)) - bat->AI()->AttackStart(target); - events.ScheduleEvent(EVENT_SPAWN_BATS, 60000, 0, PHASE_ONE); - break; - case EVENT_SHADOW_WORD_PAIN: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(target, SPELL_SHADOW_WORD_PAIN); - events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, urand(12000, 18000), 0, PHASE_TWO); - break; - case EVENT_MIND_FLAY: - DoCastVictim(SPELL_MIND_FLAY); - events.ScheduleEvent(EVENT_MIND_FLAY, 16000, 0, PHASE_TWO); - break; - case EVENT_CHAIN_MIND_FLAY: - me->InterruptNonMeleeSpells(false); - DoCastVictim(SPELL_CHAIN_MIND_FLAY); - events.ScheduleEvent(EVENT_CHAIN_MIND_FLAY, urand(15000, 30000), 0, PHASE_TWO); - break; - case EVENT_GREATER_HEAL: - me->InterruptNonMeleeSpells(false); - DoCast(me, SPELL_GREATERHEAL); - events.ScheduleEvent(EVENT_GREATER_HEAL, urand(25000, 35000), 0, PHASE_TWO); - break; - case EVENT_SPAWN_FLYING_BATS: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - if (Creature* flyingBat = me->SummonCreature(NPC_FRENZIED_BAT, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ() + 15.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000)) - flyingBat->AI()->AttackStart(target); - events.ScheduleEvent(EVENT_SPAWN_FLYING_BATS, urand(10000, 15000), 0, PHASE_TWO); - break; - default: - break; - } - } - - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetZulGurubAI<boss_jeklikAI>(creature); - } -}; - -// Flying Bat -class npc_batrider : public CreatureScript -{ - public: - npc_batrider() : CreatureScript("npc_batrider") { } - - struct npc_batriderAI : public ScriptedAI - { - npc_batriderAI(Creature* creature) : ScriptedAI(creature) { } - - uint32 Bomb_Timer; - - void Reset() override - { - Bomb_Timer = 2000; - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - } - - void EnterCombat(Unit* /*who*/) override { } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - if (Bomb_Timer <= diff) - { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - { - DoCast(target, SPELL_BOMB); - Bomb_Timer = 5000; - } - } - else - Bomb_Timer -= diff; - - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_batriderAI(creature); - } -}; - -void AddSC_boss_jeklik() -{ - new boss_jeklik(); - new npc_batrider(); -} diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_jindo.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_jindo.cpp deleted file mode 100644 index f766a795658..00000000000 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_jindo.cpp +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Copyright (C) 2008-2014 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/>. - */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "zulgurub.h" - -enum Say -{ - SAY_AGGRO = 1 -}; - -enum Spells -{ - SPELL_BRAIN_WASH_TOTEM = 24262, - SPELL_POWERFULL_HEALING_WARD = 24309, - SPELL_HEX = 24053, - SPELL_DELUSIONS_OF_JINDO = 24306, - SPELL_SHADE_OF_JINDO = 24308, - // Healing Ward Spell - SPELL_HEAL = 24311, - // Shade of Jindo Spell - SPELL_SHADOWSHOCK = 19460, - SPELL_INVISIBLE = 24307 -}; - -enum Events -{ - EVENT_BRAIN_WASH_TOTEM = 1, - EVENT_POWERFULL_HEALING_WARD = 2, - EVENT_HEX = 3, - EVENT_DELUSIONS_OF_JINDO = 4, - EVENT_TELEPORT = 5 -}; - -Position const TeleportLoc = { -11583.7783f, -1249.4278f, 77.5471f, 4.745f }; - -// Formation of summoned trolls -Position const Formation[] = -{ - { -11582.2998f, -1247.8599f, 77.6298f, 0.0f }, - { -11585.0996f, -1248.7600f, 77.6298f, 0.0f }, - { -11586.5996f, -1250.7199f, 77.6298f, 0.0f }, - { -11586.4003f, -1253.9200f, 77.6298f, 0.0f }, - { -11584.2001f, -1252.2099f, 77.6298f, 0.0f }, - { -11582.5000f, -1250.3199f, 77.6298f, 0.0f }, - { -11583.2001f, -1254.8299f, 77.6298f, 0.0f }, - { -11581.5000f, -1252.5400f, 77.6298f, 0.0f }, - { -11580.2001f, -1250.5999f, 77.6298f, 0.0f }, - { -11580.5996f, -1254.7900f, 77.6298f, 0.0f } -}; - -class boss_jindo : public CreatureScript -{ - public: - boss_jindo() : CreatureScript("boss_jindo") { } - - struct boss_jindoAI : public BossAI - { - boss_jindoAI(Creature* creature) : BossAI(creature, DATA_JINDO) { } - - void Reset() override - { - _Reset(); - } - - void JustDied(Unit* /*killer*/) override - { - _JustDied(); - } - - void EnterCombat(Unit* /*who*/) override - { - _EnterCombat(); - events.ScheduleEvent(EVENT_BRAIN_WASH_TOTEM, 20000); - events.ScheduleEvent(EVENT_POWERFULL_HEALING_WARD, 16000); - events.ScheduleEvent(EVENT_HEX, 8000); - events.ScheduleEvent(EVENT_DELUSIONS_OF_JINDO, 10000); - events.ScheduleEvent(EVENT_TELEPORT, 5000); - Talk(SAY_AGGRO); - } - - 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_BRAIN_WASH_TOTEM: - DoCast(me, SPELL_BRAIN_WASH_TOTEM); - events.ScheduleEvent(EVENT_BRAIN_WASH_TOTEM, urand(18000, 26000)); - break; - case EVENT_POWERFULL_HEALING_WARD: - DoCast(me, SPELL_POWERFULL_HEALING_WARD); - events.ScheduleEvent(EVENT_POWERFULL_HEALING_WARD, urand(14000, 20000)); - break; - case EVENT_HEX: - if (Unit* target = me->GetVictim()) - { - DoCast(target, SPELL_HEX, true); - if (DoGetThreat(target)) - DoModifyThreatPercent(target, -80); - } - events.ScheduleEvent(EVENT_HEX, urand(12000, 20000)); - break; - case EVENT_DELUSIONS_OF_JINDO: - // Casting the delusion curse with a shade so shade will attack the same target with the curse. - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true)) - { - DoCast(target, SPELL_SHADE_OF_JINDO, true); - DoCast(target, SPELL_DELUSIONS_OF_JINDO); - } - events.ScheduleEvent(EVENT_DELUSIONS_OF_JINDO, urand(4000, 12000)); - break; - case EVENT_TELEPORT: - // Teleports a random player and spawns 9 Sacrificed Trolls to attack player - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true)) - { - DoTeleportPlayer(target, TeleportLoc.GetPositionX(), TeleportLoc.GetPositionY(), TeleportLoc.GetPositionZ(), TeleportLoc.GetOrientation()); - if (DoGetThreat(me->GetVictim())) - DoModifyThreatPercent(target, -100); - - // Summon a formation of trolls - for (uint8 i = 0; i < 10; ++i) - if (Creature* SacrificedTroll = me->SummonCreature(NPC_SACRIFICED_TROLL, Formation[i].GetPositionX(), Formation[i].GetPositionY(), Formation[i].GetPositionZ(), Formation[i].GetOrientation(), TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000)) - SacrificedTroll->AI()->AttackStart(target); - } - events.ScheduleEvent(EVENT_TELEPORT, urand(15000, 23000)); - break; - default: - break; - } - } - - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new boss_jindoAI(creature); - } -}; - -// Healing Ward -class npc_healing_ward : public CreatureScript -{ - public: - npc_healing_ward() : CreatureScript("npc_healing_ward") { } - - struct npc_healing_wardAI : public ScriptedAI - { - npc_healing_wardAI(Creature* creature) : ScriptedAI(creature) - { - instance = creature->GetInstanceScript(); - } - - uint32 Heal_Timer; - InstanceScript* instance; - - void Reset() override - { - Heal_Timer = 2000; - } - - void EnterCombat(Unit* /*who*/) override { } - - void UpdateAI(uint32 diff) override - { - // Heal_Timer - if (Heal_Timer <= diff) - { - if (Unit* jindo = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_JINDO))) - DoCast(jindo, SPELL_HEAL); - Heal_Timer = 3000; - } else Heal_Timer -= diff; - - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetInstanceAI<npc_healing_wardAI>(creature); - } -}; - -//Shade of Jindo -class npc_shade_of_jindo : public CreatureScript -{ - public: - npc_shade_of_jindo() : CreatureScript("npc_shade_of_jindo") { } - - struct npc_shade_of_jindoAI : public ScriptedAI - { - npc_shade_of_jindoAI(Creature* creature) : ScriptedAI(creature) { } - - uint32 ShadowShock_Timer; - - void Reset() override - { - ShadowShock_Timer = 1000; - DoCast(me, SPELL_INVISIBLE, true); - } - - void EnterCombat(Unit* /*who*/) override { } - - void UpdateAI(uint32 diff) override - { - // ShadowShock_Timer - if (ShadowShock_Timer <= diff) - { - DoCastVictim(SPELL_SHADOWSHOCK); - ShadowShock_Timer = 2000; - } else ShadowShock_Timer -= diff; - - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_shade_of_jindoAI(creature); - } -}; - -void AddSC_boss_jindo() -{ - new boss_jindo(); - new npc_healing_ward(); - new npc_shade_of_jindo(); -} diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_jindo_the_godbreaker.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_jindo_the_godbreaker.cpp new file mode 100644 index 00000000000..d06fdb2840e --- /dev/null +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_jindo_the_godbreaker.cpp @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * 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/>. + */ + +#include "ObjectMgr.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "zulgurub.h" + +enum Yells +{ + // Jin'do the Godbreaker + SAY_INTRO = 0, + SAY_AGGRO = 1, + EMOTE_SHADOWS_OF_HAKKAR = 2, // ID - 97172 Shadows of Hakkar + SAY_JINDO_SPIRIT_PHASE = 3, + //SAY_PLAYER_KILL = 4, // missing data + + // Spirit of Hakkar + SAY_SPIRIT_SPIRIT_PHASE = 0, + SAY_SPIRIT_DEFEATED = 1, + + // Jin'do the Godbreaker - Trigger + SAY_JINDO_DEFEATED = 0, + + // Shadow of Hakkar + SAY_SHADOW_DEFEATED = 0, +}; + +enum Spells +{ +}; + +enum Events +{ +}; + +class boss_jindo_the_godbreaker : public CreatureScript +{ + public: + boss_jindo_the_godbreaker() : CreatureScript("boss_jindo_the_godbreaker") { } + + struct boss_jindo_the_godbreakerAI : public BossAI + { + boss_jindo_the_godbreakerAI(Creature* creature) : BossAI(creature, DATA_JINDO) { } + + void Reset() override + { + _Reset(); + } + + void EnterCombat(Unit* /*who*/) override + { + _EnterCombat(); + Talk(SAY_AGGRO); + } + + void JustDied(Unit* /*killer*/) override + { + } + + 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) + { + default: + break; + } + } + */ + + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetZulGurubAI<boss_jindo_the_godbreakerAI>(creature); + } +}; + +void AddSC_boss_jindo_the_godbreaker() +{ + new boss_jindo_the_godbreaker(); +} diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_gahzranka.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_kilnara.cpp index 51b00e39fed..b42b6d29731 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_gahzranka.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_kilnara.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2014 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,56 +15,60 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Boss_Gahz'ranka -SD%Complete: 85 -SDComment: Massive Geyser with knockback not working. Spell buggy. -SDCategory: Zul'Gurub -EndScriptData */ - +#include "ObjectMgr.h" #include "ScriptMgr.h" #include "ScriptedCreature.h" +#include "Spell.h" #include "zulgurub.h" +enum Yells +{ + SAY_AGGRO = 0, + SAY_WAVE_OF_AGONY = 1, // ID - 96457 Wave of Agony + SAY_TRANSFROM_1 = 2, + SAY_TRANSFROM_2 = 3, + SAY_PLAYER_KILL = 4, + SAY_DEATH = 5 +}; + enum Spells { - SPELL_FROSTBREATH = 16099, - SPELL_MASSIVEGEYSER = 22421, // Not working. (summon) - SPELL_SLAM = 24326 }; enum Events { - EVENT_FROSTBREATH = 1, - EVENT_MASSIVEGEYSER = 2, - EVENT_SLAM = 3 }; -class boss_gahzranka : public CreatureScript // gahzranka +class boss_kilnara : public CreatureScript { public: - boss_gahzranka() : CreatureScript("boss_gahzranka") { } + boss_kilnara() : CreatureScript("boss_kilnara") { } - struct boss_gahzrankaAI : public BossAI + struct boss_kilnaraAI : public BossAI { - boss_gahzrankaAI(Creature* creature) : BossAI(creature, DATA_GAHZRANKA) { } + boss_kilnaraAI(Creature* creature) : BossAI(creature, DATA_KILNARA) { } void Reset() override { _Reset(); } + void EnterCombat(Unit* /*who*/) override + { + _EnterCombat(); + Talk(SAY_AGGRO); + } + void JustDied(Unit* /*killer*/) override { _JustDied(); + Talk(SAY_DEATH); } - void EnterCombat(Unit* /*who*/) override + void KilledUnit(Unit* victim) override { - _EnterCombat(); - events.ScheduleEvent(EVENT_FROSTBREATH, 8000); - events.ScheduleEvent(EVENT_MASSIVEGEYSER, 25000); - events.ScheduleEvent(EVENT_SLAM, 17000); + if (victim->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_PLAYER_KILL); } void UpdateAI(uint32 diff) override @@ -77,27 +80,16 @@ class boss_gahzranka : public CreatureScript // gahzranka if (me->HasUnitState(UNIT_STATE_CASTING)) return; - + /* while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { - case EVENT_FROSTBREATH: - DoCastVictim(SPELL_FROSTBREATH, true); - events.ScheduleEvent(EVENT_FROSTBREATH, urand(7000, 11000)); - break; - case EVENT_MASSIVEGEYSER: - DoCastVictim(SPELL_MASSIVEGEYSER, true); - events.ScheduleEvent(EVENT_MASSIVEGEYSER, urand(22000, 32000)); - break; - case EVENT_SLAM: - DoCastVictim(SPELL_SLAM, true); - events.ScheduleEvent(EVENT_SLAM, urand(12000, 20000)); - break; default: break; } } + */ DoMeleeAttackIfReady(); } @@ -105,11 +97,11 @@ class boss_gahzranka : public CreatureScript // gahzranka CreatureAI* GetAI(Creature* creature) const override { - return new boss_gahzrankaAI(creature); + return GetZulGurubAI<boss_kilnaraAI>(creature); } }; -void AddSC_boss_gahzranka() +void AddSC_boss_kilnara() { - new boss_gahzranka(); + new boss_kilnara(); } diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp index 72ba9db3637..bb355be52a9 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp @@ -16,98 +16,93 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Boss_Mandokir -SD%Complete: 90 -SDComment: Ohgan function needs improvements. -SDCategory: Zul'Gurub -EndScriptData */ - #include "ScriptMgr.h" #include "ScriptedCreature.h" -#include "Spell.h" -#include "SpellAuras.h" #include "SpellScript.h" +#include "SpellAuraEffects.h" +#include "Player.h" +#include "GridNotifiers.h" #include "zulgurub.h" -enum Says +enum Yells { - SAY_AGGRO = 0, - SAY_DING_KILL = 1, - SAY_WATCH = 2, - SAY_WATCH_WHISPER = 3, - SAY_OHGAN_DEAD = 4, - - SAY_GRATS_JINDO = 0 + SAY_AGGRO = 0, + SAY_PLAYER_KILL = 1, + SAY_DISMOUNT_OHGAN = 2, + EMOTE_DEVASTATING_SLAM = 3, + SAY_REANIMATE_OHGAN = 4, + EMOTE_FRENZY = 5, + SAY_FRENZY = 6, + SAY_DEATH = 7 }; enum Spells { - SPELL_CHARGE = 24408, // seen - SPELL_OVERPOWER = 24407, // Seen - SPELL_FEAR = 29321, - SPELL_WHIRLWIND = 13736, // Triggers 15589 - SPELL_MORTAL_STRIKE = 16856, // Seen - SPELL_FRENZY = 24318, // seen - SPELL_WATCH = 24314, // seen 24315, 24316 - SPELL_WATCH_CHARGE = 24315, // Triggers 24316 - SPELL_LEVEL_UP = 24312 // + // Bloodlord Mandokir + SPELL_BLOODLORD_AURA = 96480, + SPELL_SUMMON_OHGAN = 96717, + SPELL_REANIMATE_OHGAN = 96724, + SPELL_DECAPITATE = 96682, + SPELL_BLOODLETTING = 96776, + SPELL_BLOODLETTING_DAMAGE = 96777, + SPELL_BLOODLETTING_HEAL = 96778, + SPELL_FRENZY = 96800, + SPELL_LEVEL_UP = 96662, + SPELL_DEVASTATING_SLAM = 96740, + SPELL_DEVASTATING_SLAM_TRIGGER = 96761, + SPELL_DEVASTATING_SLAM_DAMAGE = 97385, + SPELL_SPIRIT_VENGEANCE_CANCEL = 96821, + + // Chained Spirit + SPELL_REVIVE = 96484, + + // Ohgan + SPELL_OHGAN_HEART_VISUAL = 96727, + SPELL_PERMANENT_FEIGN_DEATH = 96733, + SPELL_CLEAR_ALL = 28471, + SPELL_OHGAN_ORDERS = 96721, + SPELL_OHGAN_ORDERS_TRIGGER = 96722 }; enum Events { - EVENT_CHECK_SPEAKER = 1, - EVENT_CHECK_START = 2, - EVENT_STARTED = 3, - EVENT_OVERPOWER = 4, - EVENT_MORTAL_STRIKE = 5, - EVENT_WHIRLWIND = 6, - EVENT_CHECK_OHGAN = 7, - EVENT_WATCH_PLAYER = 8, - EVENT_CHARGE_PLAYER = 9 + // Bloodlord Mandokir + EVENT_SUMMON_OHGAN = 1, + EVENT_DECAPITATE = 2, + EVENT_BLOODLETTING = 3, + EVENT_REANIMATE_OHGAN = 4, + EVENT_REANIMATE_OHGAN_COOLDOWN = 5, + EVENT_DEVASTATING_SLAM = 6 }; -enum Misc +enum Action { - MODEL_OHGAN_MOUNT = 15271, - PATH_MANDOKIR = 492861, - POINT_MANDOKIR_END = 24, - CHAINED_SPIRT_COUNT = 20 + // Bloodlord Mandokir + ACTION_OHGAN_IS_DEATH = 1, + ACTION_START_REVIVE = 2, + + // Chained Spirit + ACTION_REVIVE = 1 }; -Position const PosSummonChainedSpirits[CHAINED_SPIRT_COUNT] = +enum Misc { - { -12167.17f, -1979.330f, 133.0992f, 2.268928f }, - { -12262.74f, -1953.394f, 133.5496f, 0.593412f }, - { -12176.89f, -1983.068f, 133.7841f, 2.129302f }, - { -12226.45f, -1977.933f, 132.7982f, 1.466077f }, - { -12204.74f, -1890.431f, 135.7569f, 4.415683f }, - { -12216.70f, -1891.806f, 136.3496f, 4.677482f }, - { -12236.19f, -1892.034f, 134.1041f, 5.044002f }, - { -12248.24f, -1893.424f, 134.1182f, 5.270895f }, - { -12257.36f, -1897.663f, 133.1484f, 5.462881f }, - { -12265.84f, -1903.077f, 133.1649f, 5.654867f }, - { -12158.69f, -1972.707f, 133.8751f, 2.408554f }, - { -12178.82f, -1891.974f, 134.1786f, 3.944444f }, - { -12193.36f, -1890.039f, 135.1441f, 4.188790f }, - { -12275.59f, -1932.845f, 134.9017f, 0.174533f }, - { -12273.51f, -1941.539f, 136.1262f, 0.314159f }, - { -12247.02f, -1963.497f, 133.9476f, 0.872665f }, - { -12238.68f, -1969.574f, 133.6273f, 1.134464f }, - { -12192.78f, -1982.116f, 132.6966f, 1.919862f }, - { -12210.81f, -1979.316f, 133.8700f, 1.797689f }, - { -12283.51f, -1924.839f, 133.5170f, 0.069813f } + POINT_START_REVIVE = 1, + + DATA_OHGANOT_SO_FAST = 5762, + + FACTION_NONE = 1665 }; -Position const PosMandokir[2] = +enum SummonGroups { - { -12167.8f, -1927.25f, 153.73f, 3.76991f }, - { -12197.86f, -1949.392f, 130.2745f, 0.0f } + SUMMON_GROUP_CHAINED_SPIRIT = 0 }; class boss_mandokir : public CreatureScript { public: + boss_mandokir() : CreatureScript("boss_mandokir") { } struct boss_mandokirAI : public BossAI @@ -116,115 +111,121 @@ class boss_mandokir : public CreatureScript void Reset() override { - if (me->GetPositionZ() > 140.0f) - { - _Reset(); - killCount = 0; - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC); - events.ScheduleEvent(EVENT_CHECK_START, 1000); - if (Creature* speaker = ObjectAccessor::GetCreature(*me, instance->GetData64(NPC_VILEBRANCH_SPEAKER))) - if (!speaker->IsAlive()) - speaker->Respawn(true); - } - summons.DespawnAll(); - me->Mount(MODEL_OHGAN_MOUNT); - } + DoCastAOE(SPELL_SPIRIT_VENGEANCE_CANCEL); - void JustDied(Unit* /*killer*/) override - { - // Do not want to unsummon Ohgan - for (int i = 0; i < CHAINED_SPIRT_COUNT; ++i) - if (Creature* unsummon = ObjectAccessor::GetCreature(*me, chainedSpirtGUIDs[i])) - unsummon->DespawnOrUnsummon(); - instance->SetBossState(DATA_MANDOKIR, DONE); - instance->SaveToDB(); + _Reset(); + + me->SummonCreatureGroup(SUMMON_GROUP_CHAINED_SPIRIT); + _ohganotSoFast = true; + _reanimateOhganCooldown = false; + _reviveGUID = 0; } void EnterCombat(Unit* /*who*/) override { _EnterCombat(); - events.ScheduleEvent(EVENT_OVERPOWER, urand(7000, 9000)); - events.ScheduleEvent(EVENT_MORTAL_STRIKE, urand(12000, 18000)); - events.ScheduleEvent(EVENT_WHIRLWIND, urand(24000, 30000)); - events.ScheduleEvent(EVENT_CHECK_OHGAN, 1000); - events.ScheduleEvent(EVENT_WATCH_PLAYER, urand(13000, 15000)); - events.ScheduleEvent(EVENT_CHARGE_PLAYER, urand(33000, 38000)); - me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation()); Talk(SAY_AGGRO); - me->Dismount(); - // Summon Ohgan (Spell missing) TEMP HACK - me->SummonCreature(NPC_OHGAN, me->GetPositionX()-3, me->GetPositionY(), me->GetPositionZ(), me->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 35000); - // Summon Chained Spirits - for (int i = 0; i < CHAINED_SPIRT_COUNT; ++i) + + DoCastAOE(SPELL_BLOODLORD_AURA); + + if (!summons.empty()) { - Creature* chainedSpirt = me->SummonCreature(NPC_CHAINED_SPIRT, PosSummonChainedSpirits[i], TEMPSUMMON_CORPSE_DESPAWN); - chainedSpirtGUIDs[i] = chainedSpirt->GetGUID(); + for (std::list<uint64>::const_iterator itr = summons.begin(); itr != summons.end(); ++itr) + { + if (Creature* chainedSpirit = ObjectAccessor::GetCreature(*me, *itr)) + if (chainedSpirit->GetEntry() == NPC_CHAINED_SPIRIT && chainedSpirit->AI()) + chainedSpirit->setFaction(FACTION_NONE); + } } - DoZoneInCombat(); + + events.ScheduleEvent(EVENT_DECAPITATE, 10000); + events.ScheduleEvent(EVENT_BLOODLETTING, 15000); + events.ScheduleEvent(EVENT_SUMMON_OHGAN, 20000); + events.ScheduleEvent(EVENT_DEVASTATING_SLAM, 25000); } - void KilledUnit(Unit* victim) override + void JustDied(Unit* /*killer*/) override { - if (victim->GetTypeId() != TYPEID_PLAYER) - return; + DoCastAOE(SPELL_SPIRIT_VENGEANCE_CANCEL); + _JustDied(); + Talk(SAY_DEATH); + } - if (++killCount == 3) + void KilledUnit(Unit* victim) override + { + if (victim->GetTypeId() == TYPEID_PLAYER) { - Talk(SAY_DING_KILL); - if (Creature* jindo = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_JINDO))) - if (jindo->IsAlive()) - jindo->AI()->Talk(SAY_GRATS_JINDO); - DoCast(me, SPELL_LEVEL_UP, true); - killCount = 0; + Talk(SAY_PLAYER_KILL); + DoCast(SPELL_LEVEL_UP); + _reviveGUID = victim->GetGUID(); + DoAction(ACTION_START_REVIVE); } } - void MovementInform(uint32 type, uint32 id) override + void DamageTaken(Unit* /*attacker*/, uint32& damage) override { - if (type == WAYPOINT_MOTION_TYPE) + if (me->HealthBelowPctDamaged(20, damage) && !me->HasAura(SPELL_FRENZY)) { - me->SetWalk(false); - if (id == POINT_MANDOKIR_END) - { - me->SetHomePosition(PosMandokir[0]); - instance->SetBossState(DATA_MANDOKIR, NOT_STARTED); - me->DespawnOrUnsummon(6000); // No idea how to respawn on wipe. - } + DoCast(me, SPELL_FRENZY, true); + Talk(SAY_FRENZY); + Talk(EMOTE_FRENZY); } } - void UpdateAI(uint32 diff) override + void DoAction(int32 action) override { - events.Update(diff); - - if (!UpdateVictim()) + switch (action) { - if (instance->GetBossState(DATA_MANDOKIR) == NOT_STARTED || instance->GetBossState(DATA_MANDOKIR) == SPECIAL) + case ACTION_OHGAN_IS_DEATH: + events.ScheduleEvent(EVENT_REANIMATE_OHGAN, 4000); + _ohganotSoFast = false; + break; + case ACTION_START_REVIVE: { - while (uint32 eventId = events.ExecuteEvent()) + std::list<Creature*> creatures; + GetCreatureListWithEntryInGrid(creatures, me, NPC_CHAINED_SPIRIT, 200.0f); + creatures.remove_if(Trinity::AnyDeadUnitCheck()); + creatures.remove_if(Trinity::UnitAuraCheck(true, SPELL_OHGAN_ORDERS_TRIGGER)); + Trinity::Containers::RandomResizeList(creatures, 1); + if (creatures.empty()) + return; + + for (std::list<Creature*>::iterator itr = creatures.begin(); itr != creatures.end(); ++itr) { - switch (eventId) + if (Creature* chainedSpirit = ObjectAccessor::GetCreature(*me, (*itr)->GetGUID())) { - case EVENT_CHECK_START: - if (instance->GetBossState(DATA_MANDOKIR) == SPECIAL) - { - me->GetMotionMaster()->MovePoint(0, PosMandokir[1].m_positionX, PosMandokir[1].m_positionY, PosMandokir[1].m_positionZ); - events.ScheduleEvent(EVENT_STARTED, 6000); - } - else - events.ScheduleEvent(EVENT_CHECK_START, 1000); - break; - case EVENT_STARTED: - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC); - me->GetMotionMaster()->MovePath(PATH_MANDOKIR, false); - break; - default: - break; + chainedSpirit->AI()->SetGUID(_reviveGUID); + chainedSpirit->AI()->DoAction(ACTION_REVIVE); + _reviveGUID = 0; } } + break; } - return; + default: + break; + } + } + + uint32 GetData(uint32 type) const override + { + if (type == DATA_OHGANOT_SO_FAST) + return _ohganotSoFast; + + return 0; + } + + void SetGUID(uint64 guid, int32 /*type = 0 */) override + { + _reviveGUID = guid; + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) return; @@ -233,39 +234,40 @@ class boss_mandokir : public CreatureScript { switch (eventId) { - case EVENT_OVERPOWER: - DoCastVictim(SPELL_OVERPOWER, true); - events.ScheduleEvent(EVENT_OVERPOWER, urand(6000, 12000)); + case EVENT_SUMMON_OHGAN: + me->SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID, 0); + DoCast(me, SPELL_SUMMON_OHGAN, true); break; - case EVENT_MORTAL_STRIKE: - if (me->GetVictim() && me->EnsureVictim()->HealthBelowPct(50)) - DoCastVictim(SPELL_MORTAL_STRIKE, true); - events.ScheduleEvent(EVENT_MORTAL_STRIKE, urand(12000, 18000)); + case EVENT_DECAPITATE: + DoCastAOE(SPELL_DECAPITATE); + events.ScheduleEvent(EVENT_DECAPITATE, me->HasAura(SPELL_FRENZY) ? 17500 : 35000); break; - case EVENT_WHIRLWIND: - DoCast(me, SPELL_WHIRLWIND); - events.ScheduleEvent(EVENT_WHIRLWIND, urand(22000, 26000)); - break; - case EVENT_CHECK_OHGAN: - if (instance->GetBossState(DATA_OHGAN) == DONE) + case EVENT_BLOODLETTING: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true)) { - DoCast(me, SPELL_FRENZY); - Talk(SAY_OHGAN_DEAD); + DoCast(target, SPELL_BLOODLETTING, true); + me->ClearUnitState(UNIT_STATE_CASTING); } - else - events.ScheduleEvent(EVENT_CHECK_OHGAN, 1000); + events.ScheduleEvent(EVENT_BLOODLETTING, 25000); break; - case EVENT_WATCH_PLAYER: - if (Unit* player = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) + case EVENT_REANIMATE_OHGAN: + if (_reanimateOhganCooldown) + events.ScheduleEvent(EVENT_REANIMATE_OHGAN, 1000); + else { - DoCast(player, SPELL_WATCH); - Talk(SAY_WATCH, player); + DoCastAOE(SPELL_REANIMATE_OHGAN); + Talk(SAY_REANIMATE_OHGAN); + // Cooldown + _reanimateOhganCooldown = true; + events.ScheduleEvent(EVENT_REANIMATE_OHGAN_COOLDOWN, 20000); } - events.ScheduleEvent(EVENT_WATCH_PLAYER, urand(12000, 15000)); break; - case EVENT_CHARGE_PLAYER: - DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0, 40, true), SPELL_CHARGE); - events.ScheduleEvent(EVENT_CHARGE_PLAYER, urand(22000, 30000)); + case EVENT_REANIMATE_OHGAN_COOLDOWN: + _reanimateOhganCooldown = false; + break; + case EVENT_DEVASTATING_SLAM: + DoCastAOE(SPELL_DEVASTATING_SLAM_TRIGGER); + events.ScheduleEvent(EVENT_DEVASTATING_SLAM, 30000); break; default: break; @@ -276,8 +278,9 @@ class boss_mandokir : public CreatureScript } private: - uint8 killCount; - uint64 chainedSpirtGUIDs[CHAINED_SPIRT_COUNT]; + bool _ohganotSoFast; + bool _reanimateOhganCooldown; + uint64 _reviveGUID; }; CreatureAI* GetAI(Creature* creature) const override @@ -286,13 +289,6 @@ class boss_mandokir : public CreatureScript } }; -// Ohgan - -enum OhganSpells -{ - SPELL_SUNDERARMOR = 24317 -}; - class npc_ohgan : public CreatureScript { public: @@ -300,38 +296,51 @@ class npc_ohgan : public CreatureScript struct npc_ohganAI : public ScriptedAI { - npc_ohganAI(Creature* creature) : ScriptedAI(creature), instance(creature->GetInstanceScript()) { } + npc_ohganAI(Creature* creature) : ScriptedAI(creature) + { + _instance = me->GetInstanceScript(); + } - void Reset() override + void EnterCombat(Unit* /*who*/) override { - SunderArmor_Timer = 5000; + DoCastAOE(SPELL_OHGAN_ORDERS, true); } - void EnterCombat(Unit* /*who*/) override { } + void DamageTaken(Unit* /*attacker*/, uint32& damage) override + { + if (damage >= me->GetHealth()) + { + damage = 0; + me->AttackStop(); + me->SetHealth(0); + me->SetTarget(0); + DoCast(me, SPELL_CLEAR_ALL, true); + DoCast(me, SPELL_PERMANENT_FEIGN_DEATH); + + if (Creature* mandokir = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_MANDOKIR))) + mandokir->AI()->DoAction(ACTION_OHGAN_IS_DEATH); + } + } - void JustDied(Unit* /*killer*/) override + void KilledUnit(Unit* victim) override { - instance->SetBossState(DATA_OHGAN, DONE); + if (Creature* creature = victim->ToCreature()) + { + if (creature->GetEntry() == NPC_CHAINED_SPIRIT) + DoCastAOE(SPELL_OHGAN_ORDERS, true); + } } - void UpdateAI(uint32 diff) override + void UpdateAI(uint32 /*diff*/) override { - // Return since we have no target if (!UpdateVictim()) return; - if (SunderArmor_Timer <= diff) - { - DoCastVictim(SPELL_SUNDERARMOR, true); - SunderArmor_Timer = urand(10000, 15000); - } else SunderArmor_Timer -= diff; - DoMeleeAttackIfReady(); } private: - uint32 SunderArmor_Timer; - InstanceScript* instance; + InstanceScript* _instance; }; CreatureAI* GetAI(Creature* creature) const override @@ -340,100 +349,428 @@ class npc_ohgan : public CreatureScript } }; -enum VilebranchSpells -{ - SPELL_DEMORALIZING_SHOUT = 13730, - SPELL_CLEAVE = 15284 -}; - -class npc_vilebranch_speaker : public CreatureScript +class npc_chained_spirit : public CreatureScript { public: - npc_vilebranch_speaker() : CreatureScript("npc_vilebranch_speaker") { } + npc_chained_spirit() : CreatureScript("npc_chained_spirit") { } - struct npc_vilebranch_speakerAI : public ScriptedAI + struct npc_chained_spiritAI : public ScriptedAI { - npc_vilebranch_speakerAI(Creature* creature) : ScriptedAI(creature), instance(creature->GetInstanceScript()) { } + npc_chained_spiritAI(Creature* creature) : ScriptedAI(creature) + { + _instance = me->GetInstanceScript(); + me->AddUnitMovementFlag(MOVEMENTFLAG_HOVER); + me->SetReactState(REACT_PASSIVE); // correct? + } void Reset() override { - demoralizing_Shout_Timer = urand(2000, 4000); - cleave_Timer = urand(5000, 8000); + _revivePlayerGUID = 0; } - void EnterCombat(Unit* /*who*/) override { } + void SetGUID(uint64 guid, int32 /*type = 0 */) override + { + _revivePlayerGUID = guid; + } - void JustDied(Unit* /*killer*/) override + void DoAction(int32 action) override { - instance->SetBossState(DATA_MANDOKIR, SPECIAL); + if (action == ACTION_REVIVE) + { + Position pos; + if (Player* target = ObjectAccessor::GetPlayer(*me, _revivePlayerGUID)) + { + target->GetNearPoint(me, pos.m_positionX, pos.m_positionY, pos.m_positionZ, 0.0f, 5.0f, target->GetAngle(me)); + me->GetMotionMaster()->MovePoint(POINT_START_REVIVE, pos); + } + } } - void UpdateAI(uint32 diff) override + void MovementInform(uint32 type, uint32 pointId) override { - // Return since we have no target - if (!UpdateVictim()) + if (type != POINT_MOTION_TYPE || !_revivePlayerGUID) return; - if (demoralizing_Shout_Timer <= diff) + if (pointId == POINT_START_REVIVE) { - DoCast(me, SPELL_DEMORALIZING_SHOUT); - demoralizing_Shout_Timer = urand(22000, 30000); - } else demoralizing_Shout_Timer -= diff; + if (Player* target = ObjectAccessor::GetPlayer(*me, _revivePlayerGUID)) + DoCast(target, SPELL_REVIVE); + + me->DespawnOrUnsummon(2000); + } + } + + void JustDied(Unit* /*killer*/) override + { + Player* target = ObjectAccessor::GetPlayer(*me, _revivePlayerGUID); + if (!target || target->IsAlive()) + return; - if (cleave_Timer <= diff) + if (Creature* mandokir = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_MANDOKIR))) { - DoCastVictim(SPELL_CLEAVE, true); - cleave_Timer = urand(6000, 9000); - } else cleave_Timer -= diff; + mandokir->GetAI()->SetGUID(target->GetGUID()); + mandokir->GetAI()->DoAction(ACTION_START_REVIVE); + } - DoMeleeAttackIfReady(); + me->DespawnOrUnsummon(); } + void UpdateAI(uint32 /*diff*/) override { } + private: - uint32 demoralizing_Shout_Timer; - uint32 cleave_Timer; - InstanceScript* instance; + InstanceScript* _instance; + uint64 _revivePlayerGUID; }; CreatureAI* GetAI(Creature* creature) const override { - return GetInstanceAI<npc_vilebranch_speakerAI>(creature); + return GetZulGurubAI<npc_chained_spiritAI>(creature); + } +}; + +class spell_mandokir_decapitate : public SpellScriptLoader +{ + public: + spell_mandokir_decapitate() : SpellScriptLoader("spell_mandokir_decapitate") { } + + class spell_mandokir_decapitate_SpellScript : public SpellScript + { + PrepareSpellScript(spell_mandokir_decapitate_SpellScript); + + void FilterTargets(std::list<WorldObject*>& targets) + { + if (targets.empty()) + return; + + WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets); + targets.clear(); + targets.push_back(target); + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + if (Player* target = GetHitPlayer()) + caster->CastSpell(target, uint32(GetEffectValue()), true); + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mandokir_decapitate_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + OnEffectHitTarget += SpellEffectFn(spell_mandokir_decapitate_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_mandokir_decapitate_SpellScript(); + } +}; + +class spell_mandokir_bloodletting : public SpellScriptLoader +{ + public: + spell_mandokir_bloodletting() : SpellScriptLoader("spell_mandokir_bloodletting") { } + + class spell_mandokir_bloodletting_AuraScript : public AuraScript + { + PrepareAuraScript(spell_mandokir_bloodletting_AuraScript); + + bool Validate(SpellInfo const* /*spell*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_BLOODLETTING_DAMAGE)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_BLOODLETTING_HEAL)) + return false; + return true; + } + + void HandleEffectPeriodic(AuraEffect const* aurEff) + { + Unit* target = GetTarget(); + Unit* caster = GetCaster(); + if (!caster) + return; + + int32 damage = std::max<int32>(7500, target->CountPctFromCurHealth(aurEff->GetAmount())); + + caster->CastCustomSpell(target, SPELL_BLOODLETTING_DAMAGE, &damage, 0, 0, true); + target->CastCustomSpell(caster, SPELL_BLOODLETTING_HEAL, &damage, 0, 0, true); + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_mandokir_bloodletting_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_mandokir_bloodletting_AuraScript(); + } +}; + +class spell_mandokir_spirit_vengeance_cancel : public SpellScriptLoader +{ + public: + spell_mandokir_spirit_vengeance_cancel() : SpellScriptLoader("spell_mandokir_spirit_vengeance_cancel") { } + + class spell_mandokir_spirit_vengeance_cancel_SpellScript : public SpellScript + { + PrepareSpellScript(spell_mandokir_spirit_vengeance_cancel_SpellScript); + + void HandleScript(SpellEffIndex /*effIndex*/) + { + if (Player* target = GetHitPlayer()) + target->RemoveAura(uint32(GetEffectValue())); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_mandokir_spirit_vengeance_cancel_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_mandokir_spirit_vengeance_cancel_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_mandokir_spirit_vengeance_cancel_SpellScript(); + } +}; + +class DevastatingSlamTargetSelector : public std::unary_function<Unit *, bool> +{ + public: + DevastatingSlamTargetSelector(Creature* me, const Unit* victim) : _me(me), _victim(victim) {} + + bool operator() (WorldObject* target) + { + if (target == _victim && _me->getThreatManager().getThreatList().size() > 1) + return true; + + if (target->GetTypeId() != TYPEID_PLAYER) + return true; + + return false; } + + Creature* _me; + Unit const* _victim; }; -class spell_threatening_gaze : public SpellScriptLoader +class spell_mandokir_devastating_slam : public SpellScriptLoader { public: - spell_threatening_gaze() : SpellScriptLoader("spell_threatening_gaze") { } + spell_mandokir_devastating_slam() : SpellScriptLoader("spell_mandokir_devastating_slam") { } - class spell_threatening_gaze_AuraScript : public AuraScript + class spell_mandokir_devastating_slam_SpellScript : public SpellScript { - PrepareAuraScript(spell_threatening_gaze_AuraScript); + PrepareSpellScript(spell_mandokir_devastating_slam_SpellScript); + + void FilterTargets(std::list<WorldObject*>& targets) + { + targets.remove_if(DevastatingSlamTargetSelector(GetCaster()->ToCreature(), GetCaster()->GetVictim())); + if (targets.empty()) + return; + + WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets); + targets.clear(); + targets.push_back(target); + } - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + void HandleScript(SpellEffIndex /*effIndex*/) { + Unit* caster = GetCaster(); + float angle = 0.0f; + float x, y, z; + + if (Player* target = GetHitPlayer()) + { + caster->AttackStop(); + caster->SetOrientation(caster->GetAngle(target)); + caster->SetFacingTo(caster->GetAngle(target)); + + caster->CastSpell(caster, SPELL_DEVASTATING_SLAM, false); + + // HACK: Need better way for pos calculation + for (uint8 i = 0; i <= 50; ++i) + { + angle = float(rand_norm()) * static_cast<float>(M_PI * 35.0f / 180.0f) - static_cast<float>(M_PI * 17.5f / 180.0f); + caster->GetClosePoint(x, y, z, 4.0f, frand(-2.5f, 50.0f), angle); + + caster->CastSpell(x, y, z, SPELL_DEVASTATING_SLAM_DAMAGE, true); + } + } + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mandokir_devastating_slam_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + OnEffectHitTarget += SpellEffectFn(spell_mandokir_devastating_slam_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_FORCE_CAST); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_mandokir_devastating_slam_SpellScript(); + } +}; + +class spell_mandokir_ohgan_orders : public SpellScriptLoader +{ + public: + spell_mandokir_ohgan_orders() : SpellScriptLoader("spell_mandokir_ohgan_orders") { } + + class spell_mandokir_ohgan_orders_SpellScript : public SpellScript + { + PrepareSpellScript(spell_mandokir_ohgan_orders_SpellScript); + + void FilterTargets(std::list<WorldObject*>& targets) + { + if (targets.empty()) + return; + + WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets); + targets.clear(); + targets.push_back(target); + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + if (Unit* target = GetHitUnit()) + caster->CastSpell(target, uint32(GetEffectValue()), true); + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mandokir_ohgan_orders_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); + OnEffectHitTarget += SpellEffectFn(spell_mandokir_ohgan_orders_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_mandokir_ohgan_orders_SpellScript(); + } +}; + +class spell_mandokir_ohgan_orders_trigger : public SpellScriptLoader +{ + public: + spell_mandokir_ohgan_orders_trigger() : SpellScriptLoader("spell_mandokir_ohgan_orders_trigger") { } + + class spell_mandokir_ohgan_orders_trigger_AuraScript : public AuraScript + { + PrepareAuraScript(spell_mandokir_ohgan_orders_trigger_AuraScript); + + void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); if (Unit* caster = GetCaster()) - if (Unit* target = GetTarget()) - if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE && GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_DEATH) - caster->CastSpell(target, SPELL_WATCH_CHARGE); + { + // HACK: research better way + caster->ClearUnitState(UNIT_STATE_CASTING); + caster->GetMotionMaster()->Clear(); + caster->DeleteThreatList(); + caster->AddThreat(target, 50000000.0f); + caster->TauntApply(target); + } } void Register() override { - OnEffectRemove += AuraEffectRemoveFn(spell_threatening_gaze_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + AfterEffectApply += AuraEffectApplyFn(spell_mandokir_ohgan_orders_trigger_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); } }; AuraScript* GetAuraScript() const override { - return new spell_threatening_gaze_AuraScript(); + return new spell_mandokir_ohgan_orders_trigger_AuraScript(); } }; +class spell_mandokir_reanimate_ohgan : public SpellScriptLoader +{ + public: + spell_mandokir_reanimate_ohgan() : SpellScriptLoader("spell_mandokir_reanimate_ohgan") { } + + class spell_mandokir_reanimate_ohgan_SpellScript : public SpellScript + { + PrepareSpellScript(spell_mandokir_reanimate_ohgan_SpellScript); + + void HandleScript(SpellEffIndex /*effIndex*/) + { + if (Unit* target = GetHitUnit()) + { + target->RemoveAura(SPELL_PERMANENT_FEIGN_DEATH); + target->CastSpell(target, SPELL_OHGAN_HEART_VISUAL, true); + target->CastSpell((Unit*)NULL, SPELL_OHGAN_ORDERS, true); + } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_mandokir_reanimate_ohgan_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_mandokir_reanimate_ohgan_SpellScript(); + } +}; + +class spell_clear_all : public SpellScriptLoader +{ + public: + spell_clear_all() : SpellScriptLoader("spell_clear_all") { } + + class spell_clear_all_SpellScript : public SpellScript + { + PrepareSpellScript(spell_clear_all_SpellScript); + + void HandleScript(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + caster->RemoveAllAurasOnDeath(); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_clear_all_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_clear_all_SpellScript(); + } +}; + +class achievement_ohganot_so_fast : public AchievementCriteriaScript +{ + public: + achievement_ohganot_so_fast() : AchievementCriteriaScript("achievement_ohganot_so_fast") { } + + bool OnCheck(Player* /*player*/, Unit* target) + { + return target && target->GetAI()->GetData(DATA_OHGANOT_SO_FAST); + } +}; + void AddSC_boss_mandokir() { new boss_mandokir(); new npc_ohgan(); - new npc_vilebranch_speaker(); - new spell_threatening_gaze(); + new npc_chained_spirit(); + new spell_mandokir_decapitate(); + new spell_mandokir_bloodletting(); + new spell_mandokir_spirit_vengeance_cancel(); + new spell_mandokir_devastating_slam(); + new spell_mandokir_ohgan_orders(); + new spell_mandokir_ohgan_orders_trigger(); + new spell_mandokir_reanimate_ohgan(); + new spell_clear_all(); + new achievement_ohganot_so_fast(); } diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_marli.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_marli.cpp deleted file mode 100644 index bbc1fb6c90e..00000000000 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_marli.cpp +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright (C) 2008-2014 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: Boss_Marli -SD%Complete: 80 -SDComment: Charging healers and casters not working. Perhaps wrong Spell Timers. -SDCategory: Zul'Gurub -EndScriptData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "zulgurub.h" - -enum Says -{ - SAY_AGGRO = 0, - SAY_TRANSFORM = 1, - SAY_SPIDER_SPAWN = 2, - SAY_DEATH = 3 -}; - -enum Spells -{ - SPELL_CHARGE = 22911, - SPELL_ASPECT_OF_MARLI = 24686, // A stun spell - SPELL_ENVOLWINGWEB = 24110, - SPELL_POISON_VOLLEY = 24099, - SPELL_SPIDER_FORM = 24084, - // The Spider Spell - SPELL_LEVELUP = 24312 // Not right Spell. -}; - -enum Events -{ - EVENT_SPAWN_START_SPIDERS = 1, // Phase 1 - EVENT_POISON_VOLLEY = 2, // Phase All - EVENT_SPAWN_SPIDER = 3, // Phase All - EVENT_CHARGE_PLAYER = 4, // Phase 3 - EVENT_ASPECT_OF_MARLI = 5, // Phase 2 - EVENT_TRANSFORM = 6, // Phase 2 - EVENT_TRANSFORM_BACK = 7 // Phase 3 -}; - -enum Phases -{ - PHASE_ONE = 1, - PHASE_TWO = 2, - PHASE_THREE = 3 -}; - -enum Misc -{ - NPC_SPIDER = 15041 -}; - -class boss_marli : public CreatureScript -{ - public: boss_marli() : CreatureScript("boss_marli") { } - - struct boss_marliAI : public BossAI - { - boss_marliAI(Creature* creature) : BossAI(creature, DATA_MARLI) { } - - void Reset() override - { - if (events.IsInPhase(PHASE_THREE)) - me->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, 35.0f, false); // hack - _Reset(); - } - - void JustDied(Unit* /*killer*/) override - { - _JustDied(); - Talk(SAY_DEATH); - } - - void EnterCombat(Unit* /*who*/) override - { - _EnterCombat(); - events.ScheduleEvent(EVENT_SPAWN_START_SPIDERS, 1000, 0, PHASE_ONE); - Talk(SAY_AGGRO); - } - - 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_SPAWN_START_SPIDERS: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - { - Talk(SAY_SPIDER_SPAWN); - for (uint8 i = 0; i < 4; ++i) - if (Creature* spider = me->SummonCreature(NPC_SPIDER, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000)) - spider->AI()->AttackStart(target); - } - events.ScheduleEvent(EVENT_ASPECT_OF_MARLI, 12000, 0, PHASE_TWO); - events.ScheduleEvent(EVENT_TRANSFORM, 45000, 0, PHASE_TWO); - events.ScheduleEvent(EVENT_POISON_VOLLEY, 15000); - events.ScheduleEvent(EVENT_SPAWN_SPIDER, 30000); - events.ScheduleEvent(EVENT_TRANSFORM, 45000, 0, PHASE_TWO); - events.SetPhase(PHASE_TWO); - break; - case EVENT_POISON_VOLLEY: - DoCastVictim(SPELL_POISON_VOLLEY, true); - events.ScheduleEvent(EVENT_POISON_VOLLEY, urand(10000, 20000)); - break; - case EVENT_ASPECT_OF_MARLI: - DoCastVictim(SPELL_ASPECT_OF_MARLI, true); - events.ScheduleEvent(EVENT_ASPECT_OF_MARLI, urand(13000, 18000), 0, PHASE_TWO); - break; - case EVENT_SPAWN_SPIDER: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - if (Creature* spider = me->SummonCreature(NPC_SPIDER, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000)) - spider->AI()->AttackStart(target); - events.ScheduleEvent(EVENT_SPAWN_SPIDER, urand(12000, 17000)); - break; - case EVENT_TRANSFORM: - { - Talk(SAY_TRANSFORM); - DoCast(me, SPELL_SPIDER_FORM); // SPELL_AURA_TRANSFORM - /* - CreatureTemplate const* cinfo = me->GetCreatureTemplate(); - me->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg +((cinfo->mindmg/100) * 35))); - me->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg +((cinfo->maxdmg/100) * 35))); - me->UpdateDamagePhysical(BASE_ATTACK); - */ - me->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, 35.0f, true); // hack - DoCastVictim(SPELL_ENVOLWINGWEB); - if (DoGetThreat(me->GetVictim())) - DoModifyThreatPercent(me->GetVictim(), -100); - events.ScheduleEvent(EVENT_CHARGE_PLAYER, 1500, 0, PHASE_THREE); - events.ScheduleEvent(EVENT_TRANSFORM_BACK, 25000, 0, PHASE_THREE); - events.SetPhase(PHASE_THREE); - break; - } - case EVENT_CHARGE_PLAYER: - { - Unit* target = NULL; - int i = 0; - while (i++ < 3) // max 3 tries to get a random target with power_mana - { - target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100, true); // not aggro leader - if (target && target->getPowerType() == POWER_MANA) - break; - } - if (target) - { - DoCast(target, SPELL_CHARGE); - AttackStart(target); - } - events.ScheduleEvent(EVENT_CHARGE_PLAYER, 8000, 0, PHASE_THREE); - break; - } - case EVENT_TRANSFORM_BACK: - { - me->RemoveAura(SPELL_SPIDER_FORM); - /* - CreatureTemplate const* cinfo = me->GetCreatureTemplate(); - me->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg +((cinfo->mindmg/100) * 1))); - me->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg +((cinfo->maxdmg/100) * 1))); - me->UpdateDamagePhysical(BASE_ATTACK); - */ - me->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, 35.0f, false); // hack - events.ScheduleEvent(EVENT_ASPECT_OF_MARLI, 12000, 0, PHASE_TWO); - events.ScheduleEvent(EVENT_TRANSFORM, 45000, 0, PHASE_TWO); - events.ScheduleEvent(EVENT_POISON_VOLLEY, 15000); - events.ScheduleEvent(EVENT_SPAWN_SPIDER, 30000); - events.ScheduleEvent(EVENT_TRANSFORM, urand(35000, 60000), 0, PHASE_TWO); - events.SetPhase(PHASE_TWO); - break; - } - default: - break; - } - } - - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new boss_marliAI(creature); - } -}; - -// Spawn of Marli -class npc_spawn_of_marli : public CreatureScript -{ - public: npc_spawn_of_marli() : CreatureScript("npc_spawn_of_marli") { } - - struct npc_spawn_of_marliAI : public ScriptedAI - { - npc_spawn_of_marliAI(Creature* creature) : ScriptedAI(creature) { } - - uint32 LevelUp_Timer; - - void Reset() override - { - LevelUp_Timer = 3000; - } - - void EnterCombat(Unit* /*who*/) override { } - - void UpdateAI(uint32 diff) override - { - //Return since we have no target - if (!UpdateVictim()) - return; - - //LevelUp_Timer - if (LevelUp_Timer <= diff) - { - DoCast(me, SPELL_LEVELUP); - LevelUp_Timer = 3000; - } else LevelUp_Timer -= diff; - - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_spawn_of_marliAI(creature); - } -}; - -void AddSC_boss_marli() -{ - new boss_marli(); - new npc_spawn_of_marli(); -} diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_renataki.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_renataki.cpp index 015a2840a9c..66955db8163 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_renataki.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_renataki.cpp @@ -16,26 +16,21 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Boss_Renataki -SD%Complete: 100 -SDComment: -SDCategory: Zul'Gurub -EndScriptData */ - +#include "ObjectMgr.h" #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "zulgurub.h" +enum Yells +{ +}; + enum Spells { - SPELL_AMBUSH = 34794, - SPELL_THOUSANDBLADES = 34799 }; -enum Misc +enum Events { - EQUIP_ID_MAIN_HAND = 0 //was item display id 31818, but this id does not exist }; class boss_renataki : public CreatureScript @@ -45,38 +40,20 @@ class boss_renataki : public CreatureScript struct boss_renatakiAI : public BossAI { - boss_renatakiAI(Creature* creature) : BossAI(creature, DATA_EDGE_OF_MADNESS) { } - - uint32 Invisible_Timer; - uint32 Ambush_Timer; - uint32 Visible_Timer; - uint32 Aggro_Timer; - uint32 ThousandBlades_Timer; - - bool Invisible; - bool Ambushed; + boss_renatakiAI(Creature* creature) : BossAI(creature, DATA_RENATAKI) + { + } void Reset() override { - _Reset(); - Invisible_Timer = urand(8000, 18000); - Ambush_Timer = 3000; - Visible_Timer = 4000; - Aggro_Timer = urand(15000, 25000); - ThousandBlades_Timer = urand(4000, 8000); - - Invisible = false; - Ambushed = false; } - void JustDied(Unit* /*killer*/) override + void EnterCombat(Unit* /*who*/) override { - _JustDied(); } - void EnterCombat(Unit* /*who*/) override + void JustDied(Unit* /*killer*/) override { - _EnterCombat(); } void UpdateAI(uint32 diff) override @@ -84,72 +61,20 @@ class boss_renataki : public CreatureScript if (!UpdateVictim()) return; - //Invisible_Timer - if (Invisible_Timer <= diff) - { - me->InterruptSpell(CURRENT_GENERIC_SPELL); - - SetEquipmentSlots(false, EQUIP_UNEQUIP, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE); - me->SetDisplayId(11686); - - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - Invisible = true; - - Invisible_Timer = urand(15000, 30000); - } else Invisible_Timer -= diff; + events.Update(diff); - if (Invisible) - { - if (Ambush_Timer <= diff) - { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true)) - { - DoTeleportTo(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()); - DoCast(target, SPELL_AMBUSH); - } - - Ambushed = true; - Ambush_Timer = 3000; - } else Ambush_Timer -= diff; - } - - if (Ambushed) - { - if (Visible_Timer <= diff) - { - me->InterruptSpell(CURRENT_GENERIC_SPELL); - - me->SetDisplayId(15268); - SetEquipmentSlots(false, EQUIP_ID_MAIN_HAND, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE); - - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - Invisible = false; - - Visible_Timer = 4000; - } else Visible_Timer -= diff; - } - - //Resetting some aggro so he attacks other gamers - if (!Invisible) + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + /* + while (uint32 eventId = events.ExecuteEvent()) { - if (Aggro_Timer <= diff) + switch (eventId) { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true)) - { - if (DoGetThreat(me->GetVictim())) - DoModifyThreatPercent(me->GetVictim(), -50); - AttackStart(target); - } - - Aggro_Timer = urand(7000, 20000); - } else Aggro_Timer -= diff; - - if (ThousandBlades_Timer <= diff) - { - DoCastVictim(SPELL_THOUSANDBLADES); - ThousandBlades_Timer = urand(7000, 12000); - } else ThousandBlades_Timer -= diff; + default: + break; + } } + */ DoMeleeAttackIfReady(); } @@ -165,4 +90,3 @@ void AddSC_boss_renataki() { new boss_renataki(); } - diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_thekal.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_thekal.cpp deleted file mode 100644 index 52fbcaba003..00000000000 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_thekal.cpp +++ /dev/null @@ -1,554 +0,0 @@ -/* - * Copyright (C) 2008-2014 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: Boss_Thekal -SD%Complete: 95 -SDComment: Almost finished. -SDCategory: Zul'Gurub -EndScriptData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "zulgurub.h" - -enum Says -{ - SAY_AGGRO = 0, - SAY_DEATH = 1 -}; - -enum Spells -{ - SPELL_MORTALCLEAVE = 22859, // Phase 1 - SPELL_SILENCE = 22666, // Phase 1 - SPELL_TIGER_FORM = 24169, // Phase 1 - SPELL_RESURRECT = 24173, // Phase 1 // Not used in script. - SPELL_FRENZY = 8269, // Phase 2 - SPELL_FORCEPUNCH = 24189, // Phase 2 - SPELL_CHARGE = 24193, // Phase 2 - SPELL_ENRAGE = 8269, // Phase 2 - SPELL_SUMMONTIGERS = 24183, // Phase 2 - // Zealot Lor'Khan Spells - SPELL_SHIELD = 20545, - SPELL_BLOODLUST = 24185, - SPELL_GREATERHEAL = 24208, - SPELL_DISARM = 6713, - // Zealot Zath Spells - SPELL_SWEEPINGSTRIKES = 18765, - SPELL_SINISTERSTRIKE = 15581, - SPELL_GOUGE = 12540, - SPELL_KICK = 15614, - SPELL_BLIND = 21060 -}; - -enum Events -{ - EVENT_MORTALCLEAVE = 1, // Phase 1 - EVENT_SILENCE = 2, // Phase 1 - EVENT_CHECK_TIMER = 3, // Phase 1 - EVENT_RESURRECT_TIMER = 4, // Phase 1 - EVENT_FRENZY = 5, // Phase 2 - EVENT_FORCEPUNCH = 6, // Phase 2 - EVENT_SPELL_CHARGE = 7, // Phase 2 - EVENT_ENRAGE = 8, // Phase 2 - EVENT_SUMMONTIGERS = 9 // Phase 2 -}; - -enum Phases -{ - PHASE_ONE = 1, - PHASE_TWO = 2 -}; - -class boss_thekal : public CreatureScript -{ - public: - boss_thekal() : CreatureScript("boss_thekal") { } - - struct boss_thekalAI : public BossAI - { - boss_thekalAI(Creature* creature) : BossAI(creature, DATA_THEKAL) { } - - bool Enraged; - bool WasDead; - - void Reset() override - { - if (events.IsInPhase(PHASE_TWO)) - me->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, 35.0f, false); // hack - _Reset(); - Enraged = false; - WasDead = false; - } - - void JustDied(Unit* /*killer*/) override - { - _JustDied(); - Talk(SAY_DEATH); - } - - void EnterCombat(Unit* /*who*/) override - { - _EnterCombat(); - events.ScheduleEvent(EVENT_MORTALCLEAVE, 4000, 0, PHASE_ONE); // Phase 1 - events.ScheduleEvent(EVENT_SILENCE, 9000, 0, PHASE_ONE); // Phase 1 - events.ScheduleEvent(EVENT_CHECK_TIMER, 10000, 0, PHASE_ONE); // Phase 1 - events.ScheduleEvent(EVENT_RESURRECT_TIMER, 10000, 0, PHASE_ONE); // Phase 1 - Talk(SAY_AGGRO); - } - - void JustReachedHome() override - { - instance->SetBossState(DATA_THEKAL, NOT_STARTED); - } - - 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_MORTALCLEAVE: - DoCastVictim(SPELL_MORTALCLEAVE, true); - events.ScheduleEvent(EVENT_MORTALCLEAVE, urand(15000, 20000), 0, PHASE_ONE); - break; - case EVENT_SILENCE: - DoCastVictim(SPELL_SILENCE, true); - events.ScheduleEvent(EVENT_SILENCE, urand(20000, 25000), 0, PHASE_ONE); - break; - case EVENT_RESURRECT_TIMER: - //Thekal will transform to Tiger if he died and was not resurrected after 10 seconds. - if (WasDead) - { - DoCast(me, SPELL_TIGER_FORM); // SPELL_AURA_TRANSFORM - me->SetObjectScale(2.00f); - me->SetStandState(UNIT_STAND_STATE_STAND); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - /* - const CreatureTemplate* cinfo = me->GetCreatureTemplate(); - me->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg +((cinfo->mindmg/100) * 40))); - me->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg +((cinfo->maxdmg/100) * 40))); - me->UpdateDamagePhysical(BASE_ATTACK); - */ - me->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, 40.0f, true); // hack - DoResetThreat(); - events.ScheduleEvent(EVENT_FRENZY, 30000, 0, PHASE_TWO); // Phase 2 - events.ScheduleEvent(EVENT_FORCEPUNCH, 4000, 0, PHASE_TWO); // Phase 2 - events.ScheduleEvent(EVENT_SPELL_CHARGE, 12000, 0, PHASE_TWO); // Phase 2 - events.ScheduleEvent(EVENT_ENRAGE, 32000, 0, PHASE_TWO); // Phase 2 - events.ScheduleEvent(EVENT_SUMMONTIGERS, 25000, 0, PHASE_TWO); // Phase 2 - events.SetPhase(PHASE_TWO); - } - events.ScheduleEvent(EVENT_RESURRECT_TIMER, 10000, 0, PHASE_ONE); - break; - case EVENT_CHECK_TIMER: - //Check_Timer for the death of LorKhan and Zath. - if (!WasDead) - { - if (instance->GetBossState(DATA_LORKHAN) == SPECIAL) - { - //Resurrect LorKhan - if (Unit* pLorKhan = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_LORKHAN))) - { - pLorKhan->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); - pLorKhan->setFaction(14); - pLorKhan->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - pLorKhan->SetFullHealth(); - instance->SetData(DATA_LORKHAN, DONE); - } - } - - if (instance->GetBossState(DATA_ZATH) == SPECIAL) - { - //Resurrect Zath - if (Unit* pZath = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_ZATH))) - { - pZath->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); - pZath->setFaction(14); - pZath->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - pZath->SetFullHealth(); - instance->SetBossState(DATA_ZATH, DONE); - } - } - } - events.ScheduleEvent(EVENT_CHECK_TIMER, 5000, 0, PHASE_ONE); - break; - case EVENT_FRENZY: - DoCast(me, SPELL_FRENZY); - events.ScheduleEvent(EVENT_FRENZY, 30000, 0, PHASE_TWO); - break; - case EVENT_FORCEPUNCH: - DoCastVictim(SPELL_FORCEPUNCH, true); - events.ScheduleEvent(EVENT_FORCEPUNCH, urand(16000, 21000), 0, PHASE_TWO); - break; - case EVENT_CHARGE: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - { - DoCast(target, SPELL_CHARGE); - DoResetThreat(); - AttackStart(target); - } - events.ScheduleEvent(EVENT_CHARGE, urand(15000, 22000), 0, PHASE_TWO); - break; - case EVENT_ENRAGE: - if (HealthBelowPct(11) && !Enraged) - { - DoCast(me, SPELL_ENRAGE); - Enraged = true; - } - events.ScheduleEvent(EVENT_ENRAGE, 30000); - break; - case EVENT_SUMMONTIGERS: - DoCastVictim(SPELL_SUMMONTIGERS, true); - events.ScheduleEvent(EVENT_SUMMONTIGERS, urand(10000, 14000), 0, PHASE_TWO); - break; - default: - break; - } - - if (me->IsFullHealth() && WasDead) - WasDead = false; - - if ((events.IsInPhase(PHASE_ONE)) && !WasDead && !HealthAbovePct(5)) - { - me->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE_PERCENT); - me->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE); - me->RemoveAurasByType(SPELL_AURA_PERIODIC_LEECH); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->SetStandState(UNIT_STAND_STATE_SLEEP); - me->AttackStop(); - instance->SetBossState(DATA_THEKAL, SPECIAL); - WasDead=true; - } - } - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetInstanceAI<boss_thekalAI>(creature); - } -}; - -//Zealot Lor'Khan -class npc_zealot_lorkhan : public CreatureScript -{ - public: npc_zealot_lorkhan() : CreatureScript("npc_zealot_lorkhan") { } - - struct npc_zealot_lorkhanAI : public ScriptedAI - { - npc_zealot_lorkhanAI(Creature* creature) : ScriptedAI(creature) - { - instance = creature->GetInstanceScript(); - } - - uint32 Shield_Timer; - uint32 BloodLust_Timer; - uint32 GreaterHeal_Timer; - uint32 Disarm_Timer; - uint32 Check_Timer; - - bool FakeDeath; - - InstanceScript* instance; - - void Reset() override - { - Shield_Timer = 1000; - BloodLust_Timer = 16000; - GreaterHeal_Timer = 32000; - Disarm_Timer = 6000; - Check_Timer = 10000; - - FakeDeath = false; - - instance->SetBossState(DATA_LORKHAN, NOT_STARTED); - - me->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - } - - void EnterCombat(Unit* /*who*/) override - { - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - //Shield_Timer - if (Shield_Timer <= diff) - { - DoCast(me, SPELL_SHIELD); - Shield_Timer = 61000; - } else Shield_Timer -= diff; - - //BloodLust_Timer - if (BloodLust_Timer <= diff) - { - DoCast(me, SPELL_BLOODLUST); - BloodLust_Timer = 20000+rand()%8000; - } else BloodLust_Timer -= diff; - - //Casting Greaterheal to Thekal or Zath if they are in meele range. - if (GreaterHeal_Timer <= diff) - { - Unit* pThekal = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_THEKAL)); - Unit* pZath = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_ZATH)); - - if (!pThekal || !pZath) - return; - - switch (urand(0, 1)) - { - case 0: - if (me->IsWithinMeleeRange(pThekal)) - DoCast(pThekal, SPELL_GREATERHEAL); - break; - case 1: - if (me->IsWithinMeleeRange(pZath)) - DoCast(pZath, SPELL_GREATERHEAL); - break; - } - - GreaterHeal_Timer = 15000+rand()%5000; - } else GreaterHeal_Timer -= diff; - - //Disarm_Timer - if (Disarm_Timer <= diff) - { - DoCastVictim(SPELL_DISARM); - Disarm_Timer = 15000+rand()%10000; - } else Disarm_Timer -= diff; - - //Check_Timer for the death of LorKhan and Zath. - if (!FakeDeath && Check_Timer <= diff) - { - if (instance->GetBossState(DATA_THEKAL) == SPECIAL) - { - //Resurrect Thekal - if (Unit* pThekal = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_THEKAL))) - { - pThekal->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); - pThekal->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - pThekal->setFaction(14); - pThekal->SetFullHealth(); - } - } - - if (instance->GetBossState(DATA_ZATH) == SPECIAL) - { - //Resurrect Zath - if (Unit* pZath = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_ZATH))) - { - pZath->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); - pZath->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - pZath->setFaction(14); - pZath->SetFullHealth(); - } - } - - Check_Timer = 5000; - } else Check_Timer -= diff; - - if (!HealthAbovePct(5)) - { - me->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE_PERCENT); - me->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE); - me->RemoveAurasByType(SPELL_AURA_PERIODIC_LEECH); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->SetStandState(UNIT_STAND_STATE_SLEEP); - me->setFaction(35); - me->AttackStop(); - - instance->SetBossState(DATA_LORKHAN, SPECIAL); - - FakeDeath = true; - } - - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetInstanceAI<npc_zealot_lorkhanAI>(creature); - } -}; - -//Zealot Zath -class npc_zealot_zath : public CreatureScript -{ - public: - npc_zealot_zath() : CreatureScript("npc_zealot_zath") { } - - struct npc_zealot_zathAI : public ScriptedAI - { - npc_zealot_zathAI(Creature* creature) : ScriptedAI(creature) - { - instance = creature->GetInstanceScript(); - } - - uint32 SweepingStrikes_Timer; - uint32 SinisterStrike_Timer; - uint32 Gouge_Timer; - uint32 Kick_Timer; - uint32 Blind_Timer; - uint32 Check_Timer; - - bool FakeDeath; - - InstanceScript* instance; - - void Reset() override - { - SweepingStrikes_Timer = 13000; - SinisterStrike_Timer = 8000; - Gouge_Timer = 25000; - Kick_Timer = 18000; - Blind_Timer = 5000; - Check_Timer = 10000; - - FakeDeath = false; - - instance->SetBossState(DATA_ZATH, NOT_STARTED); - - me->SetStandState(UNIT_STAND_STATE_STAND); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - } - - void EnterCombat(Unit* /*who*/) override - { - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - //SweepingStrikes_Timer - if (SweepingStrikes_Timer <= diff) - { - DoCastVictim(SPELL_SWEEPINGSTRIKES); - SweepingStrikes_Timer = 22000+rand()%4000; - } else SweepingStrikes_Timer -= diff; - - //SinisterStrike_Timer - if (SinisterStrike_Timer <= diff) - { - DoCastVictim(SPELL_SINISTERSTRIKE); - SinisterStrike_Timer = 8000+rand()%8000; - } else SinisterStrike_Timer -= diff; - - //Gouge_Timer - if (Gouge_Timer <= diff) - { - DoCastVictim(SPELL_GOUGE); - - if (DoGetThreat(me->GetVictim())) - DoModifyThreatPercent(me->GetVictim(), -100); - - Gouge_Timer = 17000+rand()%10000; - } else Gouge_Timer -= diff; - - //Kick_Timer - if (Kick_Timer <= diff) - { - DoCastVictim(SPELL_KICK); - Kick_Timer = 15000+rand()%10000; - } else Kick_Timer -= diff; - - //Blind_Timer - if (Blind_Timer <= diff) - { - DoCastVictim(SPELL_BLIND); - Blind_Timer = 10000+rand()%10000; - } else Blind_Timer -= diff; - - //Check_Timer for the death of LorKhan and Zath. - if (!FakeDeath && Check_Timer <= diff) - { - if (instance->GetBossState(DATA_LORKHAN) == SPECIAL) - { - //Resurrect LorKhan - if (Unit* pLorKhan = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_LORKHAN))) - { - pLorKhan->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); - pLorKhan->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - pLorKhan->setFaction(14); - pLorKhan->SetFullHealth(); - } - } - - if (instance->GetBossState(DATA_THEKAL) == SPECIAL) - { - //Resurrect Thekal - if (Unit* pThekal = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_THEKAL))) - { - pThekal->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); - pThekal->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - pThekal->setFaction(14); - pThekal->SetFullHealth(); - } - } - - Check_Timer = 5000; - } else Check_Timer -= diff; - - if (!HealthAbovePct(5)) - { - me->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE_PERCENT); - me->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE); - me->RemoveAurasByType(SPELL_AURA_PERIODIC_LEECH); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->SetStandState(UNIT_STAND_STATE_SLEEP); - me->setFaction(35); - me->AttackStop(); - - instance->SetBossState(DATA_ZATH, SPECIAL); - - FakeDeath = true; - } - - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetInstanceAI<npc_zealot_zathAI>(creature); - } -}; - -void AddSC_boss_thekal() -{ - new boss_thekal(); - new npc_zealot_lorkhan(); - new npc_zealot_zath(); -} diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_venoxis.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_venoxis.cpp index 7047d22c970..b334c611528 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_venoxis.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_venoxis.cpp @@ -22,65 +22,24 @@ #include "Spell.h" #include "zulgurub.h" -/* - * @todo - * - Fix timers (research some more) - */ - -enum Says +enum Yells { - SAY_VENOXIS_TRANSFORM = 1, // Let the coils of hate unfurl! - SAY_VENOXIS_DEATH = 2 // Ssserenity.. at lassst! + SAY_AGGRO = 0, + SAY_BLOODVENOM = 1, // ID - 96842 Venomous Effusion + SAY_TRANSFROM = 2, // ID - 97354 Blessing of the Snake God + SAY_WORD_OF_HETHISS = 3, // ID - 96560 Word of Hethiss + EMOTE_BLOODVENOM = 4, // ID - 96842 Bloodvenom + EMOTE_VENOM_WITHDRAWAL = 5, // ID - 96653 Venom Withdrawal + SAY_PLAYER_KILL = 6, + SAY_DEATH = 7 }; enum Spells { - // troll form - SPELL_THRASH = 3391, - SPELL_DISPEL_MAGIC = 23859, - SPELL_RENEW = 23895, - SPELL_HOLY_NOVA = 23858, - SPELL_HOLY_FIRE = 23860, - SPELL_HOLY_WRATH = 23979, - // snake form - SPELL_POISON_CLOUD = 23861, - SPELL_VENOM_SPIT = 23862, - - SPELL_PARASITIC_SERPENT = 23865, - SPELL_SUMMON_PARASITIC_SERPENT = 23866, - SPELL_PARASITIC_SERPENT_TRIGGER = 23867, - // used when swapping event-stages - SPELL_VENOXIS_TRANSFORM = 23849, // 50% health - shapechange to cobra - SPELL_FRENZY = 8269 // 20% health - frenzy }; enum Events { - // troll form - EVENT_THRASH = 1, - EVENT_DISPEL_MAGIC = 2, - EVENT_RENEW = 3, - EVENT_HOLY_NOVA = 4, - EVENT_HOLY_FIRE = 5, - EVENT_HOLY_WRATH = 6, - // phase-changing - EVENT_TRANSFORM = 7, - // snake form events - EVENT_POISON_CLOUD = 8, - EVENT_VENOM_SPIT = 9, - EVENT_PARASITIC_SERPENT = 10, - EVENT_FRENZY = 11, -}; - -enum Phases -{ - PHASE_ONE = 1, // troll form - PHASE_TWO = 2 // snake form -}; - -enum NPCs -{ - NPC_PARASITIC_SERPENT = 14884 }; class boss_venoxis : public CreatureScript @@ -95,57 +54,24 @@ class boss_venoxis : public CreatureScript void Reset() override { _Reset(); - // remove all spells and auras from previous attempts - me->RemoveAllAuras(); - me->SetReactState(REACT_PASSIVE); - // set some internally used variables to their defaults - _inMeleeRange = 0; - _transformed = false; - _frenzied = false; - events.SetPhase(PHASE_ONE); - } - - void JustDied(Unit* /*killer*/) override - { - _JustDied(); - Talk(SAY_VENOXIS_DEATH); - me->RemoveAllAuras(); } void EnterCombat(Unit* /*who*/) override { _EnterCombat(); - me->SetReactState(REACT_AGGRESSIVE); - // Always running events - events.ScheduleEvent(EVENT_THRASH, 5000); - // Phase one events (regular form) - events.ScheduleEvent(EVENT_HOLY_NOVA, 5000, 0, PHASE_ONE); - events.ScheduleEvent(EVENT_DISPEL_MAGIC, 35000, 0, PHASE_ONE); - events.ScheduleEvent(EVENT_HOLY_FIRE, 10000, 0, PHASE_ONE); - events.ScheduleEvent(EVENT_RENEW, 30000, 0, PHASE_ONE); - events.ScheduleEvent(EVENT_HOLY_WRATH, 60000, 0, PHASE_ONE); - - events.SetPhase(PHASE_ONE); + Talk(SAY_AGGRO); + } - // Set zone in combat - DoZoneInCombat(); + void JustDied(Unit* /*killer*/) override + { + _JustDied(); + Talk(SAY_DEATH); } - void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/) override + void KilledUnit(Unit* victim) override { - // check if venoxis is ready to transform - if (!_transformed && !HealthAbovePct(50)) - { - _transformed = true; - // schedule the event that changes our phase - events.ScheduleEvent(EVENT_TRANSFORM, 100); - } - // we're losing health, bad, go frenzy - else if (!_frenzied && !HealthAbovePct(20)) - { - _frenzied = true; - events.ScheduleEvent(EVENT_FRENZY, 100); - } + if (victim->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_PLAYER_KILL); } void UpdateAI(uint32 diff) override @@ -155,116 +81,26 @@ class boss_venoxis : public CreatureScript events.Update(diff); - // return back to main code if we're still casting if (me->HasUnitState(UNIT_STATE_CASTING)) return; - + /* while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { - // thrash is available in all phases - case EVENT_THRASH: - DoCast(me, SPELL_THRASH, true); - events.ScheduleEvent(EVENT_THRASH, urand(10000, 20000)); - break; - // troll form spells and Actions (first part) - case EVENT_DISPEL_MAGIC: - DoCast(me, SPELL_DISPEL_MAGIC); - events.ScheduleEvent(EVENT_DISPEL_MAGIC, urand(15000, 20000), 0, PHASE_ONE); - break; - case EVENT_RENEW: - DoCast(me, SPELL_RENEW); - events.ScheduleEvent(EVENT_RENEW, urand(25000, 30000), 0, PHASE_ONE); - break; - case EVENT_HOLY_NOVA: - _inMeleeRange = 0; - - for (uint8 i = 0; i < 10; ++i) - { - if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO, i)) - // check if target is within melee-distance - if (me->IsWithinMeleeRange(target)) - ++_inMeleeRange; - } - - // trigger spellcast only if we have 3 or more targets to affect - if (_inMeleeRange >= 3) - DoCastVictim(SPELL_HOLY_NOVA); - - events.ScheduleEvent(EVENT_HOLY_NOVA, urand(45000, 75000), 0, PHASE_ONE); - break; - case EVENT_HOLY_FIRE: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) - DoCast(target, SPELL_HOLY_FIRE); - events.ScheduleEvent(EVENT_HOLY_FIRE, urand(45000, 60000), 0, PHASE_ONE); - break; - case EVENT_HOLY_WRATH: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) - DoCast(target, SPELL_HOLY_WRATH); - events.ScheduleEvent(EVENT_HOLY_WRATH, urand(45000, 60000), 0, PHASE_ONE); - break; - - // - // snake form spells and Actions - // - - case EVENT_VENOM_SPIT: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) - DoCast(target, SPELL_VENOM_SPIT); - events.ScheduleEvent(EVENT_VENOM_SPIT, urand(5000, 15000), 0, PHASE_TWO); - break; - case EVENT_POISON_CLOUD: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) - DoCast(target, SPELL_POISON_CLOUD); - events.ScheduleEvent(EVENT_POISON_CLOUD, urand(15000, 20000), 0, PHASE_TWO); - break; - case EVENT_PARASITIC_SERPENT: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) - DoCast(target, SPELL_SUMMON_PARASITIC_SERPENT); - events.ScheduleEvent(EVENT_PARASITIC_SERPENT, 15000, 0, PHASE_TWO); - break; - case EVENT_FRENZY: - // frenzy at 20% health - DoCast(me, SPELL_FRENZY, true); - break; - - // - // shape and phase-changing - // - - case EVENT_TRANSFORM: - // shapeshift at 50% health - DoCast(me, SPELL_VENOXIS_TRANSFORM); - Talk(SAY_VENOXIS_TRANSFORM); - DoResetThreat(); - - // phase two events (snakeform) - events.ScheduleEvent(EVENT_VENOM_SPIT, 5000, 0, PHASE_TWO); - events.ScheduleEvent(EVENT_POISON_CLOUD, 10000, 0, PHASE_TWO); - events.ScheduleEvent(EVENT_PARASITIC_SERPENT, 30000, 0, PHASE_TWO); - - // transformed, start phase two - events.SetPhase(PHASE_TWO); - - break; default: break; } } + */ DoMeleeAttackIfReady(); } - - private: - uint8 _inMeleeRange; - bool _transformed; - bool _frenzied; }; CreatureAI* GetAI(Creature* creature) const override { - return new boss_venoxisAI(creature); + return GetZulGurubAI<boss_venoxisAI>(creature); } }; diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_wushoolay.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_wushoolay.cpp index 6644724a430..997e4ec3077 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_wushoolay.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_wushoolay.cpp @@ -16,27 +16,21 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Boss_Wushoolay -SD%Complete: 100 -SDComment: -SDCategory: Zul'Gurub -EndScriptData */ - +#include "ObjectMgr.h" #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "zulgurub.h" +enum Yells +{ +}; + enum Spells { - SPELL_LIGHTNINGCLOUD = 25033, - SPELL_LIGHTNINGWAVE = 24819 }; enum Events { - EVENT_LIGHTNINGCLOUD = 1, - EVENT_LIGHTNINGWAVE = 2 }; class boss_wushoolay : public CreatureScript @@ -46,23 +40,20 @@ class boss_wushoolay : public CreatureScript struct boss_wushoolayAI : public BossAI { - boss_wushoolayAI(Creature* creature) : BossAI(creature, DATA_EDGE_OF_MADNESS) { } + boss_wushoolayAI(Creature* creature) : BossAI(creature, DATA_HAZZARAH) + { + } void Reset() override { - _Reset(); } - void JustDied(Unit* /*killer*/) override + void EnterCombat(Unit* /*who*/) override { - _JustDied(); } - void EnterCombat(Unit* /*who*/) override + void JustDied(Unit* /*killer*/) override { - _EnterCombat(); - events.ScheduleEvent(EVENT_LIGHTNINGCLOUD, urand(5000, 10000)); - events.ScheduleEvent(EVENT_LIGHTNINGWAVE, urand(8000, 16000)); } void UpdateAI(uint32 diff) override @@ -74,23 +65,16 @@ class boss_wushoolay : public CreatureScript if (me->HasUnitState(UNIT_STATE_CASTING)) return; - + /* while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { - case EVENT_LIGHTNINGCLOUD: - DoCastVictim(SPELL_LIGHTNINGCLOUD, true); - events.ScheduleEvent(EVENT_LIGHTNINGCLOUD, urand(15000, 20000)); - break; - case EVENT_LIGHTNINGWAVE: - DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true), SPELL_LIGHTNINGWAVE); - events.ScheduleEvent(EVENT_LIGHTNINGWAVE, urand(12000, 16000)); - break; default: break; } } + */ DoMeleeAttackIfReady(); } @@ -106,4 +90,3 @@ void AddSC_boss_wushoolay() { new boss_wushoolay(); } - diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_zanzil.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_zanzil.cpp new file mode 100644 index 00000000000..6d22284ef62 --- /dev/null +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_zanzil.cpp @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * 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/>. + */ + +#include "ObjectMgr.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "zulgurub.h" + +enum Yells +{ + SAY_AGGRO = 0, + EMOTE_ZANZIL_ZOMBIES = 1, // ID - 96319 Zanzil's Resurrection Elixir + SAY_ZANZIL_ZOMBIES = 2, // ID - 96319 Zanzil's Resurrection Elixir + EMOTE_ZANZIL_GRAVEYARD_GAS = 3, // ID - 96338 Zanzil's Graveyard Gas + SAY_ZANZIL_GRAVEYARD_GAS = 4, // ID - 96338 Zanzil's Graveyard Gas + EMOTE_ZANZIL_BERSEKER = 5, // ID - 96316 Zanzil's Resurrection Elixir + SAY_ZANZIL_BERSEKER = 6, // ID - 96316 Zanzil's Resurrection Elixir + SAY_PLAYER_KILL = 7, + SAY_DEATH = 8 +}; + +enum Spells +{ +}; + +enum Events +{ +}; + +class boss_zanzil : public CreatureScript +{ + public: + boss_zanzil() : CreatureScript("boss_zanzil") { } + + struct boss_zanzilAI : public BossAI + { + boss_zanzilAI(Creature* creature) : BossAI(creature, DATA_ZANZIL) { } + + void Reset() override + { + _Reset(); + } + + void EnterCombat(Unit* /*who*/) override + { + _EnterCombat(); + Talk(SAY_AGGRO); + } + + void JustDied(Unit* /*killer*/) override + { + _JustDied(); + Talk(SAY_DEATH); + } + + void KilledUnit(Unit* victim) override + { + if (victim->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_PLAYER_KILL); + } + + 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) + { + default: + break; + } + } + */ + + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetZulGurubAI<boss_zanzilAI>(creature); + } +}; + +void AddSC_boss_zanzil() +{ + new boss_zanzil(); +} diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp index de1ed629a34..1f65805ea71 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp @@ -16,26 +16,24 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Instance_ZulGurub -SD%Complete: 80 -SDComment: Missing reset function after killing a boss for Ohgan, Thekal. -SDCategory: Zul'Gurub -EndScriptData */ - #include "ScriptMgr.h" #include "InstanceScript.h" #include "zulgurub.h" DoorData const doorData[] = { - { GO_FORCEFIELD, DATA_ARLOKK, DOOR_TYPE_ROOM, BOUNDARY_NONE }, - { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END + { GO_VENOXIS_COIL, DATA_VENOXIS, DOOR_TYPE_ROOM, BOUNDARY_NONE }, + { GO_ARENA_DOOR_1, DATA_MANDOKIR, DOOR_TYPE_ROOM, BOUNDARY_NONE }, + { GO_FORCEFIELD, DATA_KILNARA, DOOR_TYPE_ROOM, BOUNDARY_NONE }, + { GO_ZANZIL_DOOR, DATA_ZANZIL, DOOR_TYPE_ROOM, BOUNDARY_NONE }, + //{ GO_THE_CACHE_OF_MADNESS_DOOR, DATA_xxxxxxx, DOOR_TYPE_ROOM, BOUNDARY_NONE }, + { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } }; class instance_zulgurub : public InstanceMapScript { - public: instance_zulgurub(): InstanceMapScript(ZGScriptName, 309) { } + public: + instance_zulgurub() : InstanceMapScript(ZGScriptName, 859) { } struct instance_zulgurub_InstanceMapScript : public InstanceScript { @@ -43,46 +41,53 @@ class instance_zulgurub : public InstanceMapScript { SetBossNumber(EncounterCount); LoadDoorData(doorData); - } - - void Initialize() override - { - _zealotLorkhanGUID = 0; - _zealotZathGUID = 0; - _highPriestTekalGUID = 0; - _jindoTheHexxerGUID = 0; - _vilebranchSpeakerGUID = 0; - _arlokkGUID = 0; - _goGongOfBethekkGUID = 0; - } - - bool IsEncounterInProgress() const override - { - // not active in Zul'Gurub - return false; + venoxisGUID = 0; + mandokirGUID = 0; + kilnaraGUID = 0; + zanzilGUID = 0; + jindoGUID = 0; + hazzarahGUID = 0; + renatakiGUID = 0; + wushoolayGUID = 0; + grilekGUID = 0; + jindoTiggerGUID = 0; } void OnCreatureCreate(Creature* creature) override { switch (creature->GetEntry()) { - case NPC_ZEALOT_LORKHAN: - _zealotLorkhanGUID = creature->GetGUID(); + case NPC_VENOXIS: + venoxisGUID = creature->GetGUID(); + break; + case NPC_MANDOKIR: + mandokirGUID = creature->GetGUID(); + break; + case NPC_KILNARA: + kilnaraGUID = creature->GetGUID(); + break; + case NPC_ZANZIL: + zanzilGUID = creature->GetGUID(); + break; + case NPC_JINDO: + jindoGUID = creature->GetGUID(); break; - case NPC_ZEALOT_ZATH: - _zealotZathGUID = creature->GetGUID(); + case NPC_HAZZARAH: + hazzarahGUID = creature->GetGUID(); break; - case NPC_HIGH_PRIEST_THEKAL: - _highPriestTekalGUID = creature->GetGUID(); + case NPC_RENATAKI: + renatakiGUID = creature->GetGUID(); break; - case NPC_JINDO_THE_HEXXER: - _jindoTheHexxerGUID = creature->GetGUID(); + case NPC_WUSHOOLAY: + wushoolayGUID = creature->GetGUID(); break; - case NPC_VILEBRANCH_SPEAKER: - _vilebranchSpeakerGUID = creature->GetGUID(); + case NPC_GRILEK: + grilekGUID = creature->GetGUID(); break; - case NPC_ARLOKK: - _arlokkGUID = creature->GetGUID(); + case NPC_JINDO_TRIGGER: + jindoTiggerGUID = creature->GetGUID(); + break; + default: break; } } @@ -91,16 +96,13 @@ class instance_zulgurub : public InstanceMapScript { switch (go->GetEntry()) { + case GO_VENOXIS_COIL: + case GO_ARENA_DOOR_1: case GO_FORCEFIELD: + case GO_ZANZIL_DOOR: + case GO_THE_CACHE_OF_MADNESS_DOOR: AddDoor(go, true); break; - case GO_GONG_OF_BETHEKK: - _goGongOfBethekkGUID = go->GetGUID(); - if (GetBossState(DATA_ARLOKK) == DONE) - go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - else - go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - break; default: break; } @@ -110,7 +112,11 @@ class instance_zulgurub : public InstanceMapScript { switch (go->GetEntry()) { + case GO_VENOXIS_COIL: + case GO_ARENA_DOOR_1: case GO_FORCEFIELD: + case GO_ZANZIL_DOOR: + case GO_THE_CACHE_OF_MADNESS_DOOR: AddDoor(go, false); break; default: @@ -118,29 +124,76 @@ class instance_zulgurub : public InstanceMapScript } } - uint64 GetData64(uint32 uiData) const override + bool SetBossState(uint32 type, EncounterState state) override { - switch (uiData) + if (!InstanceScript::SetBossState(type, state)) + return false; + + switch (type) { - case DATA_LORKHAN: - return _zealotLorkhanGUID; - break; - case DATA_ZATH: - return _zealotZathGUID; - break; - case DATA_THEKAL: - return _highPriestTekalGUID; - break; + case DATA_VENOXIS: + case DATA_MANDOKIR: + case DATA_KILNARA: + case DATA_ZANZIL: case DATA_JINDO: - return _jindoTheHexxerGUID; + case DATA_HAZZARAH: + case DATA_RENATAKI: + case DATA_WUSHOOLAY: + case DATA_GRILEK: break; - case NPC_ARLOKK: - return _arlokkGUID; + default: break; - case GO_GONG_OF_BETHEKK: - return _goGongOfBethekkGUID; + } + + return true; + } + + /* + void SetData(uint32 type, uint32 data) override + { + switch (type) + { + } + } + + uint32 GetData(uint32 type) const override + { + switch (type) + { + } + + return 0; + } + */ + + uint64 GetData64(uint32 type) const override + { + switch (type) + { + case DATA_VENOXIS: + return venoxisGUID; + case DATA_MANDOKIR: + return mandokirGUID; + case DATA_KILNARA: + return kilnaraGUID; + case DATA_ZANZIL: + return zanzilGUID; + case DATA_JINDO: + return jindoGUID; + case DATA_HAZZARAH: + return hazzarahGUID; + case DATA_RENATAKI: + return renatakiGUID; + case DATA_WUSHOOLAY: + return wushoolayGUID; + case DATA_GRILEK: + return grilekGUID; + case DATA_JINDOR_TRIGGER: + return jindoTiggerGUID; + default: break; } + return 0; } @@ -155,7 +208,7 @@ class instance_zulgurub : public InstanceMapScript return saveStream.str(); } - void Load(const char* str) override + void Load(char const* str) override { if (!str) { @@ -172,12 +225,13 @@ class instance_zulgurub : public InstanceMapScript if (dataHead1 == 'Z' && dataHead2 == 'G') { - for (uint32 i = 0; i < EncounterCount; ++i) + for (uint8 i = 0; i < EncounterCount; ++i) { uint32 tmpState; loadStream >> tmpState; if (tmpState == IN_PROGRESS || tmpState > SPECIAL) tmpState = NOT_STARTED; + SetBossState(i, EncounterState(tmpState)); } } @@ -186,17 +240,18 @@ class instance_zulgurub : public InstanceMapScript OUT_LOAD_INST_DATA_COMPLETE; } - private: - //If all High Priest bosses were killed. Lorkhan, Zath and Ohgan are added too. - //Storing Lorkhan, Zath and Thekal because we need to cast on them later. Jindo is needed for healfunction too. - - uint64 _zealotLorkhanGUID; - uint64 _zealotZathGUID; - uint64 _highPriestTekalGUID; - uint64 _jindoTheHexxerGUID; - uint64 _vilebranchSpeakerGUID; - uint64 _arlokkGUID; - uint64 _goGongOfBethekkGUID; + + protected: + uint64 venoxisGUID; + uint64 mandokirGUID; + uint64 kilnaraGUID; + uint64 zanzilGUID; + uint64 jindoGUID; + uint64 hazzarahGUID; + uint64 renatakiGUID; + uint64 wushoolayGUID; + uint64 grilekGUID; + uint64 jindoTiggerGUID; }; InstanceScript* GetInstanceScript(InstanceMap* map) const override diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h b/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h index a9386ff1782..5fbd18b7590 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h +++ b/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2008-2014 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 @@ -18,51 +19,72 @@ #ifndef DEF_ZULGURUB_H #define DEF_ZULGURUB_H -uint32 const EncounterCount = 13; - #define ZGScriptName "instance_zulgurub" +uint32 const EncounterCount = 5; + enum DataTypes { - DATA_JEKLIK = 0, // Main boss - DATA_VENOXIS = 1, // Main boss - DATA_MARLI = 2, // Main boss - DATA_ARLOKK = 3, // Main boss - DATA_THEKAL = 4, // Main boss - DATA_HAKKAR = 5, // End boss - DATA_MANDOKIR = 6, // Optional boss - DATA_JINDO = 7, // Optional boss - DATA_GAHZRANKA = 8, // Optional boss - DATA_EDGE_OF_MADNESS = 9, // Optional Event Edge of Madness - one of: Gri'lek, Renataki, Hazza'rah, or Wushoolay - DATA_LORKHAN = 10, // Zealot Lor'Khan add to High priest Thekal! - DATA_ZATH = 11, // Zealot Zath add to High priest Thekal! - DATA_OHGAN = 12, // Bloodlord Mandokir's raptor mount - TYPE_EDGE_OF_MADNESS = 13 // Boss storage + DATA_VENOXIS = 0, + DATA_MANDOKIR = 1, + DATA_KILNARA = 2, + DATA_ZANZIL = 3, + DATA_JINDO = 4, + + // Cache of Madness + DATA_HAZZARAH = 5, + DATA_RENATAKI = 6, + DATA_WUSHOOLAY = 7, + DATA_GRILEK = 8, + + // Jin'do the Godbreaker + DATA_JINDOR_TRIGGER, }; enum CreatureIds { - NPC_ARLOKK = 14515, // Arlokk Event - NPC_PANTHER_TRIGGER = 15091, // Arlokk Event - NPC_ZULIAN_PROWLER = 15101, // Arlokk Event - NPC_ZEALOT_LORKHAN = 11347, - NPC_ZEALOT_ZATH = 11348, - NPC_HIGH_PRIEST_THEKAL = 14509, - NPC_JINDO_THE_HEXXER = 11380, - NPC_NIGHTMARE_ILLUSION = 15163, - NPC_SHADE_OF_JINDO = 14986, - NPC_SACRIFICED_TROLL = 14826, - NPC_MANDOKIR = 11382, // Mandokir Event - NPC_OHGAN = 14988, // Mandokir Event - NPC_VILEBRANCH_SPEAKER = 11391, // Mandokir Event - NPC_CHAINED_SPIRT = 15117 // Mandokir Event + NPC_VENOXIS = 52155, + NPC_MANDOKIR = 52151, + NPC_KILNARA = 52059, + NPC_ZANZIL = 52053, + NPC_JINDO = 52148, + + // Cache of Madness + NPC_HAZZARAH = 52271, + NPC_RENATAKI = 52269, + NPC_WUSHOOLAY = 52286, + NPC_GRILEK = 52258, + // Bloodlord Mandokir + NPC_CHAINED_SPIRIT = 52156, + NPC_OHGAN = 52157, + + // Jin'do the Godbreaker + NPC_JINDO_TRIGGER = 52150, + NPC_SPIRIT_OF_HAKKAR = 52222, + NPC_SHADOW_OF_HAKKAR = 52650 }; -enum GameobjectIds +enum GameObjectIds { - GO_FORCEFIELD = 180497, // Arlokk Event - GO_GONG_OF_BETHEKK = 180526 // Arlokk Event + // High Priest Venoxis + GO_VENOXIS_COIL = 208844, + + // Bloodlord Mandokir + GO_ARENA_DOOR_1 = 208845, + GO_ARENA_DOOR_2 = 208847, + GO_ARENA_DOOR_3 = 208848, + GO_ARENA_DOOR_4 = 208846, + GO_ARENA_DOOR_5 = 208849, + + // High Priestess Kilnara + GO_FORCEFIELD = 180497, + + // Zanzil + GO_ZANZIL_DOOR = 208850, + + // Cache of Madness + GO_THE_CACHE_OF_MADNESS_DOOR = 208843 }; template<class AI> diff --git a/src/server/scripts/EasternKingdoms/boss_kruul.cpp b/src/server/scripts/EasternKingdoms/boss_kruul.cpp deleted file mode 100644 index 13f9f76532e..00000000000 --- a/src/server/scripts/EasternKingdoms/boss_kruul.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (C) 2008-2014 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: Boss_Kruul -SD%Complete: 100 -SDComment: Highlord Kruul are presumably no longer in-game on regular bases, however future events could bring him back. -SDCategory: Bosses -EndScriptData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" - -enum Spells -{ - SPELL_SHADOWVOLLEY = 21341, - SPELL_CLEAVE = 20677, - SPELL_THUNDERCLAP = 23931, - SPELL_TWISTEDREFLECTION = 21063, - SPELL_VOIDBOLT = 21066, - SPELL_RAGE = 21340, - SPELL_CAPTURESOUL = 21054 -}; - -class boss_kruul : public CreatureScript -{ -public: - boss_kruul() : CreatureScript("boss_kruul") { } - - CreatureAI* GetAI(Creature* creature) const override - { - return new boss_kruulAI(creature); - } - - struct boss_kruulAI : public ScriptedAI - { - boss_kruulAI(Creature* creature) : ScriptedAI(creature) { } - - uint32 ShadowVolley_Timer; - uint32 Cleave_Timer; - uint32 ThunderClap_Timer; - uint32 TwistedReflection_Timer; - uint32 VoidBolt_Timer; - uint32 Rage_Timer; - uint32 Hound_Timer; - - void Reset() override - { - ShadowVolley_Timer = 10000; - Cleave_Timer = 14000; - ThunderClap_Timer = 20000; - TwistedReflection_Timer = 25000; - VoidBolt_Timer = 30000; - Rage_Timer = 60000; //Cast rage after 1 minute - Hound_Timer = 8000; - } - - void EnterCombat(Unit* /*who*/) override - { - } - - void KilledUnit(Unit* /*victim*/) override - { - // When a player, pet or totem gets killed, Lord Kazzak casts this spell to instantly regenerate 70, 000 health. - DoCast(me, SPELL_CAPTURESOUL); - } - - void SummonHounds(Unit* victim) - { - if (Creature* Hound = DoSpawnCreature(19207, float(irand(-9, 9)), float(irand(-9, 9)), 0, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000)) - Hound->AI()->AttackStart(victim); - } - - void UpdateAI(uint32 diff) override - { - //Return since we have no target - if (!UpdateVictim()) - return; - - //ShadowVolley_Timer - if (ShadowVolley_Timer <= diff) - { - if (urand(0, 99) < 45) - DoCastVictim(SPELL_SHADOWVOLLEY); - - ShadowVolley_Timer = 5000; - } else ShadowVolley_Timer -= diff; - - //Cleave_Timer - if (Cleave_Timer <= diff) - { - if (urand(0, 1)) - DoCastVictim(SPELL_CLEAVE); - - Cleave_Timer = 10000; - } else Cleave_Timer -= diff; - - //ThunderClap_Timer - if (ThunderClap_Timer <= diff) - { - if (urand(0, 9) < 2) - DoCastVictim(SPELL_THUNDERCLAP); - - ThunderClap_Timer = 12000; - } else ThunderClap_Timer -= diff; - - //TwistedReflection_Timer - if (TwistedReflection_Timer <= diff) - { - DoCastVictim(SPELL_TWISTEDREFLECTION); - TwistedReflection_Timer = 30000; - } else TwistedReflection_Timer -= diff; - - //VoidBolt_Timer - if (VoidBolt_Timer <= diff) - { - if (urand(0, 9) < 4) - DoCastVictim(SPELL_VOIDBOLT); - - VoidBolt_Timer = 18000; - } else VoidBolt_Timer -= diff; - - //Rage_Timer - if (Rage_Timer <= diff) - { - DoCast(me, SPELL_RAGE); - Rage_Timer = 70000; - } else Rage_Timer -= diff; - - //Hound_Timer - if (Hound_Timer <= diff) - { - SummonHounds(me->GetVictim()); - SummonHounds(me->GetVictim()); - SummonHounds(me->GetVictim()); - - Hound_Timer = 45000; - } else Hound_Timer -= diff; - - DoMeleeAttackIfReady(); - } - }; -}; - -void AddSC_boss_kruul() -{ - new boss_kruul(); -} diff --git a/src/server/scripts/EasternKingdoms/zone_arathi_highlands.cpp b/src/server/scripts/EasternKingdoms/zone_arathi_highlands.cpp index 0480b99b912..d34dc053fc5 100644 --- a/src/server/scripts/EasternKingdoms/zone_arathi_highlands.cpp +++ b/src/server/scripts/EasternKingdoms/zone_arathi_highlands.cpp @@ -49,8 +49,13 @@ enum ProfessorPhizzlethorpe SAY_PROGRESS_7 = 7, EMOTE_PROGRESS_8 = 8, SAY_PROGRESS_9 = 9, + EVENT_SAY_3 = 1, + EVENT_SAY_6 = 2, + EVENT_SAY_8 = 3, + // Quests QUEST_SUNKEN_TREASURE = 665, + QUEST_GOGGLE_BOGGLE = 26050, // Creatures NPC_VENGEFUL_SURGE = 2776, FACTION_SUNKEN_TREASURE = 113 @@ -73,33 +78,22 @@ class npc_professor_phizzlethorpe : public CreatureScript switch (waypointId) { - case 4: + case 6: Talk(SAY_PROGRESS_2, player); - break; - case 5: - Talk(SAY_PROGRESS_3, player); + events.ScheduleEvent(EVENT_SAY_3, 3000); break; case 8: Talk(EMOTE_PROGRESS_4); - break; - case 9: - me->SummonCreature(NPC_VENGEFUL_SURGE, -2052.96f, -2142.49f, 20.15f, 1.0f, TEMPSUMMON_CORPSE_DESPAWN, 0); - me->SummonCreature(NPC_VENGEFUL_SURGE, -2052.96f, -2142.49f, 20.15f, 1.0f, TEMPSUMMON_CORPSE_DESPAWN, 0); - break; - case 10: - Talk(SAY_PROGRESS_5, player); + me->SummonCreature(NPC_VENGEFUL_SURGE, -2065.505f, -2136.88f, 22.20362f, 1.0f, TEMPSUMMON_CORPSE_DESPAWN, 0); + me->SummonCreature(NPC_VENGEFUL_SURGE, -2059.249f, -2134.88f, 21.51582f, 1.0f, TEMPSUMMON_CORPSE_DESPAWN, 0); break; case 11: - Talk(SAY_PROGRESS_6, player); - SetRun(); + Talk(SAY_PROGRESS_5, player); + events.ScheduleEvent(EVENT_SAY_6, 11000); break; - case 19: + case 17: Talk(SAY_PROGRESS_7, player); - break; - case 20: - Talk(EMOTE_PROGRESS_8); - Talk(SAY_PROGRESS_9, player); - player->GroupEventHappens(QUEST_SUNKEN_TREASURE, me); + events.ScheduleEvent(EVENT_SAY_8, 6000); break; } } @@ -126,8 +120,34 @@ class npc_professor_phizzlethorpe : public CreatureScript void UpdateAI(uint32 diff) override { + Player* player = GetPlayerForEscort(); + if (!player) + return; + + events.Update(diff); + + while (uint32 event = events.ExecuteEvent()) + { + switch (event) + { + case EVENT_SAY_3: + Talk(SAY_PROGRESS_3, player); + break; + case EVENT_SAY_6: + Talk(SAY_PROGRESS_6, player); + SetRun(); + break; + case EVENT_SAY_8: + Talk(EMOTE_PROGRESS_8); + Talk(SAY_PROGRESS_9, player); + player->GroupEventHappens(QUEST_GOGGLE_BOGGLE, me); + break; + } + } npc_escortAI::UpdateAI(diff); } + + EventMap events; }; CreatureAI* GetAI(Creature* creature) const override diff --git a/src/server/scripts/EasternKingdoms/zone_burning_steppes.cpp b/src/server/scripts/EasternKingdoms/zone_burning_steppes.cpp index 9d046ff16d8..0c45ba98064 100644 --- a/src/server/scripts/EasternKingdoms/zone_burning_steppes.cpp +++ b/src/server/scripts/EasternKingdoms/zone_burning_steppes.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2014 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,152 +15,7 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Burning_Steppes -SD%Complete: 100 -SDComment: Quest support: 4224, 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 -######*/ - -#define GOSSIP_HELLO "Official buisness, John. I need some information about Marsha Windsor. Tell me about the last time you saw him." -#define GOSSIP_SELECT1 "So what did you do?" -#define GOSSIP_SELECT2 "Start making sense, dwarf. I don't want to have anything to do with your cracker, your pappy, or any sort of 'discreditin'." -#define GOSSIP_SELECT3 "Ironfoe?" -#define GOSSIP_SELECT4 "Interesting... continue John." -#define GOSSIP_SELECT5 "So that's how Windsor died..." -#define GOSSIP_SELECT6 "So how did he die?" -#define GOSSIP_SELECT7 "Ok so where the hell is he? Wait a minute! Are you drunk?" -#define GOSSIP_SELECT8 "WHY is he in Blackrock Depths?" -#define GOSSIP_SELECT9 "300? So the Dark Irons killed him and dragged him into the Depths?" -#define GOSSIP_SELECT10 "Ahh... Ironfoe" -#define GOSSIP_SELECT11 "Thanks, Ragged John. Your story was very uplifting and informative" - -enum RaggedJohn -{ - QUEST_THE_TRUE_MASTERS = 4224, - 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 OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - player->SEND_GOSSIP_MENU(2714, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+1: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - player->SEND_GOSSIP_MENU(2715, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+2: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); - player->SEND_GOSSIP_MENU(2716, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+3: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4); - player->SEND_GOSSIP_MENU(2717, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+4: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5); - player->SEND_GOSSIP_MENU(2718, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+5: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT6, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 6); - player->SEND_GOSSIP_MENU(2719, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+6: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT7, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 7); - player->SEND_GOSSIP_MENU(2720, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+7: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT8, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 8); - player->SEND_GOSSIP_MENU(2721, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+8: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT9, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 9); - player->SEND_GOSSIP_MENU(2722, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+9: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT10, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 10); - player->SEND_GOSSIP_MENU(2723, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+10: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT11, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 11); - player->SEND_GOSSIP_MENU(2725, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+11: - player->CLOSE_GOSSIP_MENU(); - player->AreaExploredOrEventHappens(QUEST_THE_TRUE_MASTERS); - break; - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) override - { - if (creature->IsQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(QUEST_THE_TRUE_MASTERS) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - - player->SEND_GOSSIP_MENU(2713, creature->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 68f41ce6588..db7f027d53d 100644 --- a/src/server/scripts/EasternKingdoms/zone_ghostlands.cpp +++ b/src/server/scripts/EasternKingdoms/zone_ghostlands.cpp @@ -19,7 +19,7 @@ /* ScriptData SDName: Ghostlands SD%Complete: 100 -SDComment: Quest support: 9212. +SDComment: SDCategory: Ghostlands EndScriptData */ @@ -35,6 +35,7 @@ EndContentData */ #include "WorldSession.h" /*###### + ## npc_ranger_lilatha ######*/ diff --git a/src/server/scripts/EasternKingdoms/zone_hinterlands.cpp b/src/server/scripts/EasternKingdoms/zone_hinterlands.cpp index 390a64fb21c..8888b662ff6 100644 --- a/src/server/scripts/EasternKingdoms/zone_hinterlands.cpp +++ b/src/server/scripts/EasternKingdoms/zone_hinterlands.cpp @@ -19,13 +19,12 @@ /* ScriptData SDName: Hinterlands SD%Complete: 100 -SDComment: Quest support: 863, 2742 +SDComment: Quest support: 836 SDCategory: The Hinterlands EndScriptData */ /* ContentData npc_oox09hl -npc_rinji EndContentData */ #include "ScriptMgr.h" @@ -37,7 +36,7 @@ EndContentData */ ## npc_oox09hl ######*/ -enum OOX +enum eOOX { SAY_OOX_START = 0, SAY_OOX_AGGRO = 1, @@ -86,7 +85,7 @@ public: } } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId) { switch (waypointId) { @@ -134,199 +133,7 @@ public: } }; -/*###### -## npc_rinji -######*/ - -enum Rinji -{ - SAY_RIN_BY_OUTRUNNER = 0, - SAY_RIN_FREE = 0, // from here - SAY_RIN_HELP = 1, - SAY_RIN_COMPLETE = 2, - SAY_RIN_PROGRESS_1 = 3, - SAY_RIN_PROGRESS_2 = 4, - QUEST_RINJI_TRAPPED = 2742, - NPC_RANGER = 2694, - NPC_OUTRUNNER = 2691, - GO_RINJI_CAGE = 142036 -}; - -struct Location -{ - float posX, posY, posZ; -}; - -Location AmbushSpawn[] = -{ - { 191.296204f, -2839.329346f, 107.388f }, - { 70.972466f, -2848.674805f, 109.459f } -}; - -Location AmbushMoveTo[] = -{ - { 166.630386f, -2824.780273f, 108.153f }, - { 70.886589f, -2874.335449f, 116.675f } -}; - -class npc_rinji : public CreatureScript -{ -public: - npc_rinji() : CreatureScript("npc_rinji") { } - - struct npc_rinjiAI : public npc_escortAI - { - npc_rinjiAI(Creature* creature) : npc_escortAI(creature) - { - _IsByOutrunner = false; - spawnId = 0; - } - - void Reset() override - { - postEventCount = 0; - postEventTimer = 3000; - } - - void JustRespawned() override - { - _IsByOutrunner = false; - spawnId = 0; - - npc_escortAI::JustRespawned(); - } - - void EnterCombat(Unit* who) override - { - if (HasEscortState(STATE_ESCORT_ESCORTING)) - { - if (who->GetEntry() == NPC_OUTRUNNER && !_IsByOutrunner) - { - if (Creature* talker = who->ToCreature()) - talker->AI()->Talk(SAY_RIN_BY_OUTRUNNER); - _IsByOutrunner = true; - } - - if (rand()%4) - return; - - //only if attacked and escorter is not in combat? - Talk(SAY_RIN_HELP); - } - } - - void DoSpawnAmbush(bool _first) - { - if (!_first) - spawnId = 1; - - me->SummonCreature(NPC_RANGER, AmbushSpawn[spawnId].posX, AmbushSpawn[spawnId].posY, AmbushSpawn[spawnId].posZ, 0.0f, - TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 60000); - - for (int i = 0; i < 2; ++i) - { - me->SummonCreature(NPC_OUTRUNNER, AmbushSpawn[spawnId].posX, AmbushSpawn[spawnId].posY, AmbushSpawn[spawnId].posZ, 0.0f, - TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 60000); - } - } - - void JustSummoned(Creature* summoned) override - { - summoned->SetWalk(false); - summoned->GetMotionMaster()->MovePoint(0, AmbushMoveTo[spawnId].posX, AmbushMoveTo[spawnId].posY, AmbushMoveTo[spawnId].posZ); - } - - void sQuestAccept(Player* player, Quest const* quest) - { - if (quest->GetQuestId() == QUEST_RINJI_TRAPPED) - { - if (GameObject* go = me->FindNearestGameObject(GO_RINJI_CAGE, INTERACTION_DISTANCE)) - go->UseDoorOrButton(); - - npc_escortAI::Start(false, false, player->GetGUID(), quest); - } - } - - void WaypointReached(uint32 waypointId) override - { - Player* player = GetPlayerForEscort(); - if (!player) - return; - - switch (waypointId) - { - case 1: - Talk(SAY_RIN_FREE, player); - break; - case 7: - DoSpawnAmbush(true); - break; - case 13: - DoSpawnAmbush(false); - break; - case 17: - Talk(SAY_RIN_COMPLETE, player); - player->GroupEventHappens(QUEST_RINJI_TRAPPED, me); - SetRun(); - postEventCount = 1; - break; - } - } - - void UpdateEscortAI(const uint32 diff) override - { - //Check if we have a current target - if (!UpdateVictim()) - { - if (HasEscortState(STATE_ESCORT_ESCORTING) && postEventCount) - { - if (postEventTimer <= diff) - { - postEventTimer = 3000; - - if (Player* player = GetPlayerForEscort()) - { - switch (postEventCount) - { - case 1: - Talk(SAY_RIN_PROGRESS_1, player); - ++postEventCount; - break; - case 2: - Talk(SAY_RIN_PROGRESS_2, player); - postEventCount = 0; - break; - } - } - else - { - me->DespawnOrUnsummon(); - return; - } - } - else - postEventTimer -= diff; - } - return; - } - DoMeleeAttackIfReady(); - } - - private: - uint32 postEventCount; - uint32 postEventTimer; - int spawnId; - bool _IsByOutrunner; - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_rinjiAI(creature); - } -}; - void AddSC_hinterlands() { new npc_oox09hl(); - new npc_rinji(); } diff --git a/src/server/scripts/EasternKingdoms/zone_ironforge.cpp b/src/server/scripts/EasternKingdoms/zone_ironforge.cpp index e50bbb9f3e0..5a0951c0b23 100644 --- a/src/server/scripts/EasternKingdoms/zone_ironforge.cpp +++ b/src/server/scripts/EasternKingdoms/zone_ironforge.cpp @@ -20,4 +20,6 @@ #include "ScriptedGossip.h" #include "Player.h" -void AddSC_ironforge() { } +void AddSC_ironforge() +{ +} diff --git a/src/server/scripts/EasternKingdoms/zone_isle_of_queldanas.cpp b/src/server/scripts/EasternKingdoms/zone_isle_of_queldanas.cpp index fc8fdf41f51..25ee8bc1702 100644 --- a/src/server/scripts/EasternKingdoms/zone_isle_of_queldanas.cpp +++ b/src/server/scripts/EasternKingdoms/zone_isle_of_queldanas.cpp @@ -44,7 +44,6 @@ enum ConvertedSentry SPELL_CONVERT_CREDIT = 45009 }; - class npc_converted_sentry : public CreatureScript { public: diff --git a/src/server/scripts/EasternKingdoms/zone_loch_modan.cpp b/src/server/scripts/EasternKingdoms/zone_loch_modan.cpp index 1926a032aeb..95be9c9e8b2 100644 --- a/src/server/scripts/EasternKingdoms/zone_loch_modan.cpp +++ b/src/server/scripts/EasternKingdoms/zone_loch_modan.cpp @@ -18,13 +18,12 @@ /* ScriptData SDName: Loch_Modan -SD%Complete: 100 -SDComment: Quest support: 3181 +SD%Complete: 0 +SDComment: SDCategory: Loch Modan EndScriptData */ /* ContentData -npc_mountaineer_pebblebitty EndContentData */ #include "ScriptMgr.h" @@ -32,75 +31,6 @@ EndContentData */ #include "ScriptedGossip.h" #include "Player.h" -/*###### -## npc_mountaineer_pebblebitty -######*/ - -#define GOSSIP_MP "Open the gate please, i need to get to Searing Gorge" - -#define GOSSIP_MP1 "But i need to get there, now open the gate!" -#define GOSSIP_MP2 "Ok, so what is this other way?" -#define GOSSIP_MP3 "Doesn't matter, i'm invulnerable." -#define GOSSIP_MP4 "Yes..." -#define GOSSIP_MP5 "Ok, i'll try to remember that." -#define GOSSIP_MP6 "A key? Ok!" - -class npc_mountaineer_pebblebitty : public CreatureScript -{ -public: - npc_mountaineer_pebblebitty() : CreatureScript("npc_mountaineer_pebblebitty") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF+1: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_MP1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - player->SEND_GOSSIP_MENU(1833, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+2: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_MP2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); - player->SEND_GOSSIP_MENU(1834, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+3: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_MP3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4); - player->SEND_GOSSIP_MENU(1835, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+4: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_MP4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5); - player->SEND_GOSSIP_MENU(1836, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+5: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_MP5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 6); - player->SEND_GOSSIP_MENU(1837, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+6: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_MP6, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 7); - player->SEND_GOSSIP_MENU(1838, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+7: - player->CLOSE_GOSSIP_MENU(); - break; - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) override - { - if (creature->IsQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (!player->GetQuestRewardStatus(3181) == 1) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_MP, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - - return true; - } -}; - void AddSC_loch_modan() { - new npc_mountaineer_pebblebitty(); } diff --git a/src/server/scripts/EasternKingdoms/zone_redridge_mountains.cpp b/src/server/scripts/EasternKingdoms/zone_redridge_mountains.cpp index 342bba3b729..f71f78fb9cb 100644 --- a/src/server/scripts/EasternKingdoms/zone_redridge_mountains.cpp +++ b/src/server/scripts/EasternKingdoms/zone_redridge_mountains.cpp @@ -17,8 +17,8 @@ /* Script Data Start SDName: Redridge Mountains -SD%Complete: 100% -SDComment: Support for quest 219. +SD%Complete: 0 +SDComment: Script Data End */ #include "ScriptMgr.h" @@ -26,147 +26,6 @@ Script Data End */ #include "ScriptedEscortAI.h" #include "Player.h" -enum CorporalKeeshan -{ - QUEST_MISSING_IN_ACTION = 219, - SAY_CORPORAL_1 = 0, - SAY_CORPORAL_2 = 1, - SAY_CORPORAL_3 = 2, - SAY_CORPORAL_4 = 3, - SAY_CORPORAL_5 = 4, - SPELL_MOCKING_BLOW = 21008, - SPELL_SHIELD_BASH = 11972 -}; - -class npc_corporal_keeshan : public CreatureScript -{ -public: - npc_corporal_keeshan() : CreatureScript("npc_corporal_keeshan") { } - - struct npc_corporal_keeshanAI : public npc_escortAI - { - npc_corporal_keeshanAI(Creature* creature) : npc_escortAI(creature) { } - - void Reset() override - { - timer = 0; - phase = 0; - mockingBlowTimer = 5000; - shieldBashTimer = 8000; - } - - void sQuestAccept(Player* player, Quest const* quest) - { - if (quest->GetQuestId() == QUEST_MISSING_IN_ACTION) - { - Talk(SAY_CORPORAL_1, player); - npc_escortAI::Start(true, false, player->GetGUID(), quest); - } - } - - void WaypointReached(uint32 waypointId) override - { - Player* player = GetPlayerForEscort(); - if (!player) - return; - - if (waypointId >= 65) - me->SetWalk(false); - - switch (waypointId) - { - case 39: - SetEscortPaused(true); - timer = 2000; - phase = 1; - break; - case 65: - me->SetWalk(false); - break; - case 115: - player->AreaExploredOrEventHappens(QUEST_MISSING_IN_ACTION); - timer = 2000; - phase = 4; - break; - } - } - - void UpdateAI(uint32 diff) override - { - if (HasEscortState(STATE_ESCORT_NONE)) - return; - - npc_escortAI::UpdateAI(diff); - - if (phase) - { - if (timer <= diff) - { - switch (phase) - { - case 1: - me->SetStandState(UNIT_STAND_STATE_SIT); - timer = 1000; - phase = 2; - break; - case 2: - Talk(SAY_CORPORAL_2); - timer = 15000; - phase = 3; - break; - case 3: - Talk(SAY_CORPORAL_3); - me->SetStandState(UNIT_STAND_STATE_STAND); - SetEscortPaused(false); - timer = 0; - phase = 0; - break; - case 4: - Talk(SAY_CORPORAL_4); - timer = 2500; - phase = 5; - break; - case 5: - Talk(SAY_CORPORAL_5); - timer = 0; - phase = 0; - break; - } - } else timer -= diff; - } - - if (!UpdateVictim()) - return; - - if (mockingBlowTimer <= diff) - { - DoCastVictim(SPELL_MOCKING_BLOW); - mockingBlowTimer = 5000; - } else mockingBlowTimer -= diff; - - if (shieldBashTimer <= diff) - { - DoCastVictim(SPELL_MOCKING_BLOW); - shieldBashTimer = 8000; - } else shieldBashTimer -= diff; - - DoMeleeAttackIfReady(); - } - - private: - uint32 phase; - uint32 timer; - uint32 mockingBlowTimer; - uint32 shieldBashTimer; - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_corporal_keeshanAI(creature); - } -}; - void AddSC_redridge_mountains() { - new npc_corporal_keeshan(); } diff --git a/src/server/scripts/EasternKingdoms/zone_silverpine_forest.cpp b/src/server/scripts/EasternKingdoms/zone_silverpine_forest.cpp index 68d34f109a5..1d68ac01f6d 100644 --- a/src/server/scripts/EasternKingdoms/zone_silverpine_forest.cpp +++ b/src/server/scripts/EasternKingdoms/zone_silverpine_forest.cpp @@ -19,13 +19,12 @@ /* ScriptData SDName: Silverpine_Forest SD%Complete: 100 -SDComment: Quest support: 435, 452 +SDComment: Quest support: 435 SDCategory: Silverpine Forest EndScriptData */ /* ContentData npc_deathstalker_erland -pyrewood_ambush EndContentData */ #include "ScriptMgr.h" @@ -37,7 +36,7 @@ EndContentData */ ## npc_deathstalker_erland ######*/ -enum Erland +enum eErland { SAY_QUESTACCEPT = 0, SAY_START = 1, @@ -67,7 +66,7 @@ public: { npc_deathstalker_erlandAI(Creature* creature) : npc_escortAI(creature) { } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId) { Player* player = GetPlayerForEscort(); if (!player) @@ -110,13 +109,13 @@ public: void Reset() override { } - void EnterCombat(Unit* who) override + void EnterCombat(Unit* who) { Talk(SAY_AGGRO, who); } }; - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) override + bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) { if (quest->GetQuestId() == QUEST_ESCORTING) { @@ -136,192 +135,10 @@ public: }; /*###### -## pyrewood_ambush -#######*/ - -#define QUEST_PYREWOOD_AMBUSH 452 - -#define NPCSAY_INIT "Get ready, they'll be arriving any minute..." //not blizzlike -#define NPCSAY_END "Thanks for your help!" //not blizzlike - -static float PyrewoodSpawnPoints[3][4] = -{ - //pos_x pos_y pos_z orien - //outside - /* - {-400.85f, 1513.64f, 18.67f, 0}, - {-397.32f, 1514.12f, 18.67f, 0}, - {-397.44f, 1511.09f, 18.67f, 0}, - */ - //door - {-396.17f, 1505.86f, 19.77f, 0}, - {-396.91f, 1505.77f, 19.77f, 0}, - {-397.94f, 1504.74f, 19.77f, 0}, -}; - -#define WAIT_SECS 6000 - -class pyrewood_ambush : public CreatureScript -{ -public: - pyrewood_ambush() : CreatureScript("pyrewood_ambush") { } - - bool OnQuestAccept(Player* player, Creature* creature, const Quest *quest) override - { - if (quest->GetQuestId() == QUEST_PYREWOOD_AMBUSH && !CAST_AI(pyrewood_ambush::pyrewood_ambushAI, creature->AI())->QuestInProgress) - { - CAST_AI(pyrewood_ambush::pyrewood_ambushAI, creature->AI())->QuestInProgress = true; - CAST_AI(pyrewood_ambush::pyrewood_ambushAI, creature->AI())->Phase = 0; - CAST_AI(pyrewood_ambush::pyrewood_ambushAI, creature->AI())->KillCount = 0; - CAST_AI(pyrewood_ambush::pyrewood_ambushAI, creature->AI())->PlayerGUID = player->GetGUID(); - } - - return true; - } - - CreatureAI* GetAI(Creature* creature) const override - { - return new pyrewood_ambushAI(creature); - } - - struct pyrewood_ambushAI : public ScriptedAI - { - pyrewood_ambushAI(Creature* creature) : ScriptedAI(creature), Summons(me) - { - QuestInProgress = false; - } - - uint32 Phase; - int8 KillCount; - uint32 WaitTimer; - uint64 PlayerGUID; - SummonList Summons; - - bool QuestInProgress; - - void Reset() override - { - WaitTimer = WAIT_SECS; - - if (!QuestInProgress) //fix reset values (see UpdateVictim) - { - Phase = 0; - KillCount = 0; - PlayerGUID = 0; - Summons.DespawnAll(); - } - } - - void EnterCombat(Unit* /*who*/) override { } - - void JustSummoned(Creature* summoned) override - { - Summons.Summon(summoned); - ++KillCount; - } - - void SummonedCreatureDespawn(Creature* summoned) override - { - Summons.Despawn(summoned); - --KillCount; - } - - void SummonCreatureWithRandomTarget(uint32 creatureId, int position) - { - if (Creature* summoned = me->SummonCreature(creatureId, PyrewoodSpawnPoints[position][0], PyrewoodSpawnPoints[position][1], PyrewoodSpawnPoints[position][2], PyrewoodSpawnPoints[position][3], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 15000)) - { - Unit* target = NULL; - if (PlayerGUID) - if (Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID)) - if (player->IsAlive() && RAND(0, 1)) - target = player; - - if (!target) - target = me; - - summoned->setFaction(168); - summoned->AddThreat(target, 32.0f); - summoned->AI()->AttackStart(target); - } - } - - void JustDied(Unit* /*killer*/) override - { - if (PlayerGUID) - if (Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID)) - if (player->GetQuestStatus(QUEST_PYREWOOD_AMBUSH) == QUEST_STATUS_INCOMPLETE) - player->FailQuest(QUEST_PYREWOOD_AMBUSH); - } - - void UpdateAI(uint32 diff) override - { - //TC_LOG_INFO("scripts", "DEBUG: p(%i) k(%i) d(%u) W(%i)", Phase, KillCount, diff, WaitTimer); - - if (!QuestInProgress) - return; - - if (KillCount && Phase < 6) - { - if (!UpdateVictim()) //reset() on target Despawn... - return; - - DoMeleeAttackIfReady(); - return; - } - - switch (Phase) - { - case 0: - if (WaitTimer == WAIT_SECS) - me->MonsterSay(NPCSAY_INIT, LANG_UNIVERSAL, NULL); //no blizzlike - - if (WaitTimer <= diff) - { - WaitTimer -= diff; - return; - } - break; - case 1: - SummonCreatureWithRandomTarget(2060, 1); - break; - case 2: - SummonCreatureWithRandomTarget(2061, 2); - SummonCreatureWithRandomTarget(2062, 0); - break; - case 3: - SummonCreatureWithRandomTarget(2063, 1); - SummonCreatureWithRandomTarget(2064, 2); - SummonCreatureWithRandomTarget(2065, 0); - break; - case 4: - SummonCreatureWithRandomTarget(2066, 1); - SummonCreatureWithRandomTarget(2067, 0); - SummonCreatureWithRandomTarget(2068, 2); - break; - case 5: //end - if (PlayerGUID) - { - if (Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID)) - { - me->MonsterSay(NPCSAY_END, LANG_UNIVERSAL, NULL); //not blizzlike - player->GroupEventHappens(QUEST_PYREWOOD_AMBUSH, me); - } - } - QuestInProgress = false; - Reset(); - break; - } - ++Phase; //prepare next phase - } - }; -}; - -/*###### ## AddSC ######*/ void AddSC_silverpine_forest() { new npc_deathstalker_erland(); - new pyrewood_ambush(); } diff --git a/src/server/scripts/EasternKingdoms/zone_stormwind_city.cpp b/src/server/scripts/EasternKingdoms/zone_stormwind_city.cpp index e7e374ea26e..f48c3f7556f 100644 --- a/src/server/scripts/EasternKingdoms/zone_stormwind_city.cpp +++ b/src/server/scripts/EasternKingdoms/zone_stormwind_city.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2014 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,629 +15,6 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Stormwind_City -SD%Complete: 100 -SDComment: Quest support: 1640, 1447, 4185, 11223, 434. -SDCategory: Stormwind City -EndScriptData */ - -/* ContentData -npc_archmage_malin -npc_bartleby -npc_lady_katrana_prestor -npc_tyrion -npc_tyrion_spybot -npc_marzon_silent_blade -npc_lord_gregor_lescovar -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "ScriptedEscortAI.h" -#include "Player.h" - -/*###### -## npc_archmage_malin -######*/ - -#define GOSSIP_ITEM_MALIN "Can you send me to Theramore? I have an urgent message for Lady Jaina from Highlord Bolvar." - -class npc_archmage_malin : public CreatureScript -{ -public: - npc_archmage_malin() : CreatureScript("npc_archmage_malin") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF) - { - player->CLOSE_GOSSIP_MENU(); - creature->CastSpell(player, 42711, true); - } - - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) override - { - if (creature->IsQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(11223) == QUEST_STATUS_COMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_MALIN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - - return true; - } -}; - -/*###### -## npc_bartleby -######*/ - -enum Bartleby -{ - FACTION_ENEMY = 168, - QUEST_BEAT = 1640 -}; - -class npc_bartleby : public CreatureScript -{ -public: - npc_bartleby() : CreatureScript("npc_bartleby") { } - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) override - { - if (quest->GetQuestId() == QUEST_BEAT) - { - creature->setFaction(FACTION_ENEMY); - creature->AI()->AttackStart(player); - } - return true; - } - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_bartlebyAI(creature); - } - - struct npc_bartlebyAI : public ScriptedAI - { - npc_bartlebyAI(Creature* creature) : ScriptedAI(creature) - { - m_uiNormalFaction = creature->getFaction(); - } - - uint32 m_uiNormalFaction; - - void Reset() override - { - if (me->getFaction() != m_uiNormalFaction) - me->setFaction(m_uiNormalFaction); - } - - void AttackedBy(Unit* pAttacker) override - { - if (me->GetVictim()) - return; - - if (me->IsFriendlyTo(pAttacker)) - return; - - AttackStart(pAttacker); - } - - void DamageTaken(Unit* pDoneBy, uint32 &uiDamage) override - { - if (uiDamage > me->GetHealth() || me->HealthBelowPctDamaged(15, uiDamage)) - { - //Take 0 damage - uiDamage = 0; - - if (Player* player = pDoneBy->ToPlayer()) - player->AreaExploredOrEventHappens(QUEST_BEAT); - EnterEvadeMode(); - } - } - }; -}; - -/*###### -## npc_lady_katrana_prestor -######*/ - -#define GOSSIP_ITEM_KAT_1 "Pardon the intrusion, Lady Prestor, but Highlord Bolvar suggested that I seek your advice." -#define GOSSIP_ITEM_KAT_2 "My apologies, Lady Prestor." -#define GOSSIP_ITEM_KAT_3 "Begging your pardon, Lady Prestor. That was not my intent." -#define GOSSIP_ITEM_KAT_4 "Thank you for your time, Lady Prestor." - -class npc_lady_katrana_prestor : public CreatureScript -{ -public: - npc_lady_katrana_prestor() : CreatureScript("npc_lady_katrana_prestor") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_KAT_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - player->SEND_GOSSIP_MENU(2694, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+1: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_KAT_3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - player->SEND_GOSSIP_MENU(2695, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+2: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_KAT_4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); - player->SEND_GOSSIP_MENU(2696, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+3: - player->CLOSE_GOSSIP_MENU(); - player->AreaExploredOrEventHappens(4185); - break; - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) override - { - if (creature->IsQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(4185) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_KAT_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - - player->SEND_GOSSIP_MENU(2693, creature->GetGUID()); - - return true; - } -}; - -/*###### -## npc_lord_gregor_lescovar -######*/ - -enum LordGregorLescovar -{ - SAY_GUARD_2 = 0, - SAY_LESCOVAR_2 = 0, - SAY_LESCOVAR_3 = 1, - SAY_LESCOVAR_4 = 2, - SAY_MARZON_1 = 0, - SAY_MARZON_2 = 1, - SAY_TYRION_2 = 1, - - NPC_STORMWIND_ROYAL = 1756, - NPC_MARZON_BLADE = 1755, - NPC_TYRION = 7766, - - QUEST_THE_ATTACK = 434 -}; - -class npc_lord_gregor_lescovar : public CreatureScript -{ -public: - npc_lord_gregor_lescovar() : CreatureScript("npc_lord_gregor_lescovar") { } - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_lord_gregor_lescovarAI(creature); - } - - struct npc_lord_gregor_lescovarAI : public npc_escortAI - { - npc_lord_gregor_lescovarAI(Creature* creature) : npc_escortAI(creature) { } - - uint32 uiTimer; - uint32 uiPhase; - - uint64 MarzonGUID; - - void Reset() override - { - uiTimer = 0; - uiPhase = 0; - - MarzonGUID = 0; - } - - void EnterEvadeMode() override - { - me->DisappearAndDie(); - - if (Creature* pMarzon = ObjectAccessor::GetCreature(*me, MarzonGUID)) - { - if (pMarzon->IsAlive()) - pMarzon->DisappearAndDie(); - } - } - - void EnterCombat(Unit* who) override - { - if (Creature* pMarzon = ObjectAccessor::GetCreature(*me, MarzonGUID)) - { - if (pMarzon->IsAlive() && !pMarzon->IsInCombat()) - pMarzon->AI()->AttackStart(who); - } - } - - void WaypointReached(uint32 waypointId) override - { - switch (waypointId) - { - case 14: - SetEscortPaused(true); - Talk(SAY_LESCOVAR_2); - uiTimer = 3000; - uiPhase = 1; - break; - case 16: - SetEscortPaused(true); - if (Creature* pMarzon = me->SummonCreature(NPC_MARZON_BLADE, -8411.360352f, 480.069733f, 123.760895f, 4.941504f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 1000)) - { - pMarzon->GetMotionMaster()->MovePoint(0, -8408.000977f, 468.611450f, 123.759903f); - MarzonGUID = pMarzon->GetGUID(); - } - uiTimer = 2000; - uiPhase = 4; - break; - } - } - //TO-DO: We don't have movemaps, also we can't make 2 npcs walks to one point propperly (and we can not use escort ai, because they are 2 different spawns and with same entry), because of it we make them, disappear. - void DoGuardsDisappearAndDie() - { - std::list<Creature*> GuardList; - me->GetCreatureListWithEntryInGrid(GuardList, NPC_STORMWIND_ROYAL, 8.0f); - if (!GuardList.empty()) - { - for (std::list<Creature*>::const_iterator itr = GuardList.begin(); itr != GuardList.end(); ++itr) - { - if (Creature* pGuard = *itr) - pGuard->DisappearAndDie(); - } - } - } - - void UpdateAI(uint32 uiDiff) override - { - if (uiPhase) - { - if (uiTimer <= uiDiff) - { - switch (uiPhase) - { - case 1: - if (Creature* pGuard = me->FindNearestCreature(NPC_STORMWIND_ROYAL, 8.0f, true)) - pGuard->AI()->Talk(SAY_GUARD_2); - uiTimer = 3000; - uiPhase = 2; - break; - case 2: - DoGuardsDisappearAndDie(); - uiTimer = 2000; - uiPhase = 3; - break; - case 3: - SetEscortPaused(false); - uiTimer = 0; - uiPhase = 0; - break; - case 4: - Talk(SAY_LESCOVAR_3); - uiTimer = 0; - uiPhase = 0; - break; - case 5: - if (Creature* pMarzon = ObjectAccessor::GetCreature(*me, MarzonGUID)) - pMarzon->AI()->Talk(SAY_MARZON_1); - uiTimer = 3000; - uiPhase = 6; - break; - case 6: - Talk(SAY_LESCOVAR_4); - if (Player* player = GetPlayerForEscort()) - player->AreaExploredOrEventHappens(QUEST_THE_ATTACK); - uiTimer = 2000; - uiPhase = 7; - break; - case 7: - if (Creature* pTyrion = me->FindNearestCreature(NPC_TYRION, 20.0f, true)) - pTyrion->AI()->Talk(SAY_TYRION_2); - if (Creature* pMarzon = ObjectAccessor::GetCreature(*me, MarzonGUID)) - pMarzon->setFaction(14); - me->setFaction(14); - uiTimer = 0; - uiPhase = 0; - break; - } - } else uiTimer -= uiDiff; - } - npc_escortAI::UpdateAI(uiDiff); - - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - } - }; -}; - -/*###### -## npc_marzon_silent_blade -######*/ - -class npc_marzon_silent_blade : public CreatureScript -{ -public: - npc_marzon_silent_blade() : CreatureScript("npc_marzon_silent_blade") { } - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_marzon_silent_bladeAI(creature); - } - - struct npc_marzon_silent_bladeAI : public ScriptedAI - { - npc_marzon_silent_bladeAI(Creature* creature) : ScriptedAI(creature) - { - me->SetWalk(true); - } - - void Reset() override - { - me->RestoreFaction(); - } - - void EnterCombat(Unit* who) override - { - Talk(SAY_MARZON_2); - - if (me->IsSummon()) - { - if (Unit* summoner = me->ToTempSummon()->GetSummoner()) - { - if (summoner->GetTypeId() == TYPEID_UNIT && summoner->IsAlive() && !summoner->IsInCombat()) - summoner->ToCreature()->AI()->AttackStart(who); - } - } - } - - void EnterEvadeMode() override - { - me->DisappearAndDie(); - - if (me->IsSummon()) - { - if (Unit* summoner = me->ToTempSummon()->GetSummoner()) - { - if (summoner->GetTypeId() == TYPEID_UNIT && summoner->IsAlive()) - summoner->ToCreature()->DisappearAndDie(); - } - } - } - - void MovementInform(uint32 uiType, uint32 /*uiId*/) override - { - if (uiType != POINT_MOTION_TYPE) - return; - - if (me->IsSummon()) - { - Unit* summoner = me->ToTempSummon()->GetSummoner(); - if (summoner && summoner->GetTypeId() == TYPEID_UNIT && summoner->IsAIEnabled) - { - npc_lord_gregor_lescovar::npc_lord_gregor_lescovarAI* ai = - CAST_AI(npc_lord_gregor_lescovar::npc_lord_gregor_lescovarAI, summoner->GetAI()); - if (ai) - { - ai->uiTimer = 2000; - ai->uiPhase = 5; - } - //me->ChangeOrient(0.0f, summoner); - } - } - } - - void UpdateAI(uint32 /*diff*/) override - { - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - } - }; -}; - -/*###### -## npc_tyrion_spybot -######*/ - -enum TyrionSpybot -{ - SAY_QUEST_ACCEPT_ATTACK = 0, - SAY_SPYBOT_1 = 1, - SAY_SPYBOT_2 = 2, - SAY_SPYBOT_3 = 3, - SAY_SPYBOT_4 = 4, - SAY_TYRION_1 = 0, - SAY_GUARD_1 = 1, - SAY_LESCOVAR_1 = 3, - - NPC_PRIESTESS_TYRIONA = 7779, - NPC_LORD_GREGOR_LESCOVAR = 1754, -}; - -class npc_tyrion_spybot : public CreatureScript -{ -public: - npc_tyrion_spybot() : CreatureScript("npc_tyrion_spybot") { } - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_tyrion_spybotAI(creature); - } - - struct npc_tyrion_spybotAI : public npc_escortAI - { - npc_tyrion_spybotAI(Creature* creature) : npc_escortAI(creature) { } - - uint32 uiTimer; - uint32 uiPhase; - - void Reset() override - { - uiTimer = 0; - uiPhase = 0; - } - - void WaypointReached(uint32 waypointId) override - { - switch (waypointId) - { - case 1: - SetEscortPaused(true); - uiTimer = 2000; - uiPhase = 1; - break; - case 5: - SetEscortPaused(true); - Talk(SAY_SPYBOT_1); - uiTimer = 2000; - uiPhase = 5; - break; - case 17: - SetEscortPaused(true); - Talk(SAY_SPYBOT_3); - uiTimer = 3000; - uiPhase = 8; - break; - } - } - - void UpdateAI(uint32 uiDiff) override - { - if (uiPhase) - { - if (uiTimer <= uiDiff) - { - switch (uiPhase) - { - case 1: - Talk(SAY_QUEST_ACCEPT_ATTACK); - uiTimer = 3000; - uiPhase = 2; - break; - case 2: - if (Creature* pTyrion = me->FindNearestCreature(NPC_TYRION, 10.0f)) - pTyrion->AI()->Talk(SAY_TYRION_1); - uiTimer = 3000; - uiPhase = 3; - break; - case 3: - me->UpdateEntry(NPC_PRIESTESS_TYRIONA); - uiTimer = 2000; - uiPhase = 4; - break; - case 4: - SetEscortPaused(false); - uiPhase = 0; - uiTimer = 0; - break; - case 5: - if (Creature* pGuard = me->FindNearestCreature(NPC_STORMWIND_ROYAL, 10.0f, true)) - pGuard->AI()->Talk(SAY_GUARD_1); - uiTimer = 3000; - uiPhase = 6; - break; - case 6: - Talk(SAY_SPYBOT_2); - uiTimer = 3000; - uiPhase = 7; - break; - case 7: - SetEscortPaused(false); - uiTimer = 0; - uiPhase = 0; - break; - case 8: - if (Creature* pLescovar = me->FindNearestCreature(NPC_LORD_GREGOR_LESCOVAR, 10.0f)) - pLescovar->AI()->Talk(SAY_LESCOVAR_1); - uiTimer = 3000; - uiPhase = 9; - break; - case 9: - Talk(SAY_SPYBOT_4); - uiTimer = 3000; - uiPhase = 10; - break; - case 10: - if (Creature* pLescovar = me->FindNearestCreature(NPC_LORD_GREGOR_LESCOVAR, 10.0f)) - { - if (Player* player = GetPlayerForEscort()) - { - CAST_AI(npc_lord_gregor_lescovar::npc_lord_gregor_lescovarAI, pLescovar->AI())->Start(false, false, player->GetGUID()); - CAST_AI(npc_lord_gregor_lescovar::npc_lord_gregor_lescovarAI, pLescovar->AI())->SetMaxPlayerDistance(200.0f); - } - } - me->DisappearAndDie(); - uiTimer = 0; - uiPhase = 0; - break; - } - } else uiTimer -= uiDiff; - } - npc_escortAI::UpdateAI(uiDiff); - - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - } - }; -}; - -/*###### -## npc_tyrion -######*/ - -enum Tyrion -{ - NPC_TYRION_SPYBOT = 8856 -}; - -class npc_tyrion : public CreatureScript -{ -public: - npc_tyrion() : CreatureScript("npc_tyrion") { } - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) override - { - if (quest->GetQuestId() == QUEST_THE_ATTACK) - { - if (Creature* pSpybot = creature->FindNearestCreature(NPC_TYRION_SPYBOT, 5.0f, true)) - { - CAST_AI(npc_tyrion_spybot::npc_tyrion_spybotAI, pSpybot->AI())->Start(false, false, player->GetGUID()); - CAST_AI(npc_tyrion_spybot::npc_tyrion_spybotAI, pSpybot->AI())->SetMaxPlayerDistance(200.0f); - } - return true; - } - return false; - } -}; - void AddSC_stormwind_city() { - new npc_archmage_malin(); - new npc_bartleby(); - new npc_lady_katrana_prestor(); - new npc_tyrion(); - new npc_tyrion_spybot(); - new npc_lord_gregor_lescovar(); - new npc_marzon_silent_blade(); } diff --git a/src/server/scripts/EasternKingdoms/zone_swamp_of_sorrows.cpp b/src/server/scripts/EasternKingdoms/zone_swamp_of_sorrows.cpp index 20e9f28e0b7..69b9ca85a23 100644 --- a/src/server/scripts/EasternKingdoms/zone_swamp_of_sorrows.cpp +++ b/src/server/scripts/EasternKingdoms/zone_swamp_of_sorrows.cpp @@ -16,136 +16,6 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedEscortAI.h" -#include "Player.h" - -/*###### -## npc_galen_goodward -######*/ - -enum Galen -{ - QUEST_GALENS_ESCAPE = 1393, - GO_GALENS_CAGE = 37118, - SAY_PERIODIC = 0, - SAY_QUEST_ACCEPTED = 1, - SAY_ATTACKED = 2, - SAY_QUEST_COMPLETE = 3, - EMOTE_WHISPER = 4, - EMOTE_DISAPPEAR = 5 -}; - -class npc_galen_goodward : public CreatureScript -{ -public: - npc_galen_goodward() : CreatureScript("npc_galen_goodward") { } - - struct npc_galen_goodwardAI : public npc_escortAI - { - npc_galen_goodwardAI(Creature* creature) : npc_escortAI(creature) - { - galensCageGUID = 0; - Reset(); - } - - void Reset() override - { - periodicSay = 6000; - } - - void EnterCombat(Unit* who) override - { - if (HasEscortState(STATE_ESCORT_ESCORTING)) - Talk(SAY_ATTACKED, who); - } - - void sQuestAccept(Player* player, Quest const* quest) - { - if (quest->GetQuestId() == QUEST_GALENS_ESCAPE) - { - Talk(SAY_QUEST_ACCEPTED, player); - npc_escortAI::Start(false, false, player->GetGUID(), quest); - } - } - - void WaypointStart(uint32 uiPointId) override - { - switch (uiPointId) - { - case 0: - { - GameObject* cage = NULL; - if (galensCageGUID) - cage = me->GetMap()->GetGameObject(galensCageGUID); - else - cage = GetClosestGameObjectWithEntry(me, GO_GALENS_CAGE, INTERACTION_DISTANCE); - if (cage) - { - cage->UseDoorOrButton(); - galensCageGUID = cage->GetGUID(); - } - break; - } - case 21: - Talk(EMOTE_DISAPPEAR); - break; - } - } - - void WaypointReached(uint32 waypointId) override - { - switch (waypointId) - { - case 0: - if (GameObject* cage = me->GetMap()->GetGameObject(galensCageGUID)) - cage->ResetDoorOrButton(); - break; - case 20: - if (Player* player = GetPlayerForEscort()) - { - me->SetFacingToObject(player); - Talk(SAY_QUEST_COMPLETE, player); - Talk(EMOTE_WHISPER, player); - player->GroupEventHappens(QUEST_GALENS_ESCAPE, me); - } - SetRun(true); - break; - } - } - - void UpdateAI(uint32 diff) override - { - npc_escortAI::UpdateAI(diff); - - if (HasEscortState(STATE_ESCORT_NONE)) - return; - - if (periodicSay < diff) - { - if (!HasEscortState(STATE_ESCORT_ESCORTING)) - Talk(SAY_PERIODIC); - periodicSay = 15000; - } - else - periodicSay -= diff; - - DoMeleeAttackIfReady(); - } - - private: - uint64 galensCageGUID; - uint32 periodicSay; - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_galen_goodwardAI(creature); - } -}; - void AddSC_swamp_of_sorrows() { - new npc_galen_goodward(); } diff --git a/src/server/scripts/EasternKingdoms/zone_tirisfal_glades.cpp b/src/server/scripts/EasternKingdoms/zone_tirisfal_glades.cpp index 6a4cb1e0196..b03965ea9e3 100644 --- a/src/server/scripts/EasternKingdoms/zone_tirisfal_glades.cpp +++ b/src/server/scripts/EasternKingdoms/zone_tirisfal_glades.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2014 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,203 +15,6 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Tirisfal_Glades -SD%Complete: 100 -SDComment: Quest support: 590, 1819 -SDCategory: Tirisfal Glades -EndScriptData */ - -/* ContentData -npc_calvin_montague -go_mausoleum_door -go_mausoleum_trigger -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "Player.h" - -/*###### -## npc_calvin_montague -######*/ - -enum Calvin -{ - SAY_COMPLETE = 0, - SPELL_DRINK = 2639, // possibly not correct spell (but iconId is correct) - QUEST_590 = 590, - FACTION_HOSTILE = 168 -}; - -class npc_calvin_montague : public CreatureScript -{ -public: - npc_calvin_montague() : CreatureScript("npc_calvin_montague") { } - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) override - { - if (quest->GetQuestId() == QUEST_590) - { - creature->setFaction(FACTION_HOSTILE); - creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); - CAST_AI(npc_calvin_montague::npc_calvin_montagueAI, creature->AI())->AttackStart(player); - } - return true; - } - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_calvin_montagueAI(creature); - } - - struct npc_calvin_montagueAI : public ScriptedAI - { - npc_calvin_montagueAI(Creature* creature) : ScriptedAI(creature) { } - - uint32 m_uiPhase; - uint32 m_uiPhaseTimer; - uint64 m_uiPlayerGUID; - - void Reset() override - { - m_uiPhase = 0; - m_uiPhaseTimer = 5000; - m_uiPlayerGUID = 0; - - me->RestoreFaction(); - - if (!me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC)) - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); - } - - void EnterCombat(Unit* /*who*/) override { } - - void AttackedBy(Unit* pAttacker) override - { - if (me->GetVictim() || me->IsFriendlyTo(pAttacker)) - return; - - AttackStart(pAttacker); - } - - void DamageTaken(Unit* pDoneBy, uint32 &uiDamage) override - { - if (uiDamage > me->GetHealth() || me->HealthBelowPctDamaged(15, uiDamage)) - { - uiDamage = 0; - - me->RestoreFaction(); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); - me->CombatStop(true); - - m_uiPhase = 1; - - if (pDoneBy->GetTypeId() == TYPEID_PLAYER) - m_uiPlayerGUID = pDoneBy->GetGUID(); - } - } - - void UpdateAI(uint32 diff) override - { - if (m_uiPhase) - { - if (m_uiPhaseTimer <= diff) - m_uiPhaseTimer = 7500; - else - { - m_uiPhaseTimer -= diff; - return; - } - - switch (m_uiPhase) - { - case 1: - Talk(SAY_COMPLETE); - ++m_uiPhase; - break; - case 2: - if (Player* player = ObjectAccessor::GetPlayer(*me, m_uiPlayerGUID)) - player->AreaExploredOrEventHappens(QUEST_590); - - DoCast(me, SPELL_DRINK, true); - ++m_uiPhase; - break; - case 3: - EnterEvadeMode(); - break; - } - - return; - } - - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - } - }; -}; - -/*###### -## go_mausoleum_door -## go_mausoleum_trigger -######*/ - -enum Mausoleum -{ - QUEST_ULAG = 1819, - NPC_ULAG = 6390, - GO_TRIGGER = 104593, - GO_DOOR = 176594 -}; - -class go_mausoleum_door : public GameObjectScript -{ -public: - go_mausoleum_door() : GameObjectScript("go_mausoleum_door") { } - - bool OnGossipHello(Player* player, GameObject* /*go*/) override - { - if (player->GetQuestStatus(QUEST_ULAG) != QUEST_STATUS_INCOMPLETE) - return false; - - if (!player->FindNearestCreature(NPC_ULAG, 50.0f)) - if (GameObject* pTrigger = player->FindNearestGameObject(GO_TRIGGER, 30.0f)) - { - pTrigger->SetGoState(GO_STATE_READY); - player->SummonCreature(NPC_ULAG, 2390.26f, 336.47f, 40.01f, 2.26f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 300000); - return false; - } - - return false; - } -}; - -class go_mausoleum_trigger : public GameObjectScript -{ -public: - go_mausoleum_trigger() : GameObjectScript("go_mausoleum_trigger") { } - - bool OnGossipHello(Player* player, GameObject* go) override - { - if (player->GetQuestStatus(QUEST_ULAG) != QUEST_STATUS_INCOMPLETE) - return false; - - if (GameObject* pDoor = player->FindNearestGameObject(GO_DOOR, 30.0f)) - { - go->SetGoState(GO_STATE_ACTIVE); - pDoor->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND); - return true; - } - - return false; - } -}; - void AddSC_tirisfal_glades() { - new npc_calvin_montague(); - new go_mausoleum_door(); - new go_mausoleum_trigger(); } diff --git a/src/server/scripts/Events/childrens_week.cpp b/src/server/scripts/Events/childrens_week.cpp index 353b5ab9501..c9798338b36 100644 --- a/src/server/scripts/Events/childrens_week.cpp +++ b/src/server/scripts/Events/childrens_week.cpp @@ -152,7 +152,7 @@ class npc_winterfin_playmate : public CreatureScript { npc_winterfin_playmateAI(Creature* creature) : ScriptedAI(creature) { } - void Reset() + void Reset() override { timer = 0; phase = 0; @@ -174,7 +174,7 @@ class npc_winterfin_playmate : public CreatureScript } } - void UpdateAI(uint32 diff) + void UpdateAI(uint32 diff) override { if (!phase) return; @@ -233,7 +233,7 @@ class npc_winterfin_playmate : public CreatureScript }; - CreatureAI* GetAI(Creature* creature) const + CreatureAI* GetAI(Creature* creature) const override { return new npc_winterfin_playmateAI(creature); } @@ -251,7 +251,7 @@ class npc_snowfall_glade_playmate : public CreatureScript { npc_snowfall_glade_playmateAI(Creature* creature) : ScriptedAI(creature) { } - void Reset() + void Reset() override { timer = 0; phase = 0; @@ -273,7 +273,7 @@ class npc_snowfall_glade_playmate : public CreatureScript } } - void UpdateAI(uint32 diff) + void UpdateAI(uint32 diff) override { if (!phase) return; @@ -352,7 +352,7 @@ class npc_the_biggest_tree : public CreatureScript me->SetDisplayId(DISPLAY_INVISIBLE); } - void Reset() + void Reset() override { timer = 1000; phase = 0; @@ -374,7 +374,7 @@ class npc_the_biggest_tree : public CreatureScript } } - void UpdateAI(uint32 diff) + void UpdateAI(uint32 diff) override { if (!phase) return; @@ -421,7 +421,7 @@ class npc_the_biggest_tree : public CreatureScript }; - CreatureAI* GetAI(Creature* creature) const + CreatureAI* GetAI(Creature* creature) const override { return new npc_the_biggest_treeAI(creature); } @@ -439,7 +439,7 @@ class npc_high_oracle_soo_roo : public CreatureScript { npc_high_oracle_soo_rooAI(Creature* creature) : ScriptedAI(creature) { } - void Reset() + void Reset() override { timer = 0; phase = 0; @@ -461,7 +461,7 @@ class npc_high_oracle_soo_roo : public CreatureScript } } - void UpdateAI(uint32 diff) + void UpdateAI(uint32 diff) override { if (!phase) return; @@ -510,7 +510,7 @@ class npc_high_oracle_soo_roo : public CreatureScript }; - CreatureAI* GetAI(Creature* creature) const + CreatureAI* GetAI(Creature* creature) const override { return new npc_high_oracle_soo_rooAI(creature); } @@ -528,7 +528,7 @@ class npc_elder_kekek : public CreatureScript { npc_elder_kekekAI(Creature* creature) : ScriptedAI(creature) { } - void Reset() + void Reset() override { timer = 0; phase = 0; @@ -550,7 +550,7 @@ class npc_elder_kekek : public CreatureScript } } - void UpdateAI(uint32 diff) + void UpdateAI(uint32 diff) override { if (!phase) return; @@ -598,7 +598,7 @@ class npc_elder_kekek : public CreatureScript }; - CreatureAI* GetAI(Creature* creature) const + CreatureAI* GetAI(Creature* creature) const override { return new npc_elder_kekekAI(creature); } @@ -617,7 +617,7 @@ class npc_the_etymidian : public CreatureScript { npc_the_etymidianAI(Creature* creature) : ScriptedAI(creature) { } - void Reset() + void Reset() override { timer = 0; phase = 0; @@ -639,7 +639,7 @@ class npc_the_etymidian : public CreatureScript } } - void UpdateAI(uint32 diff) + void UpdateAI(uint32 diff) override { if (!phase) return; @@ -695,7 +695,7 @@ class npc_the_etymidian : public CreatureScript }; - CreatureAI* GetAI(Creature* creature) const + CreatureAI* GetAI(Creature* creature) const override { return new npc_the_etymidianAI(creature); } @@ -713,7 +713,7 @@ class npc_alexstraza_the_lifebinder : public CreatureScript { npc_alexstraza_the_lifebinderAI(Creature* creature) : ScriptedAI(creature) { } - void Reset() + void Reset() override { timer = 0; phase = 0; @@ -761,7 +761,7 @@ class npc_alexstraza_the_lifebinder : public CreatureScript } } - void UpdateAI(uint32 diff) + void UpdateAI(uint32 diff) override { if (!phase) return; @@ -856,7 +856,7 @@ class npc_alexstraza_the_lifebinder : public CreatureScript }; - CreatureAI* GetAI(Creature* creature) const + CreatureAI* GetAI(Creature* creature) const override { return new npc_alexstraza_the_lifebinderAI(creature); } @@ -1009,7 +1009,7 @@ class npc_cw_area_trigger : public CreatureScript } }; - CreatureAI* GetAI(Creature* creature) const + CreatureAI* GetAI(Creature* creature) const override { return new npc_cw_area_triggerAI(creature); } @@ -1044,7 +1044,7 @@ class npc_grizzlemaw_cw_trigger : public CreatureScript } }; - CreatureAI* GetAI(Creature* creature) const + CreatureAI* GetAI(Creature* creature) const override { return new npc_grizzlemaw_cw_triggerAI(creature); } diff --git a/src/server/scripts/Kalimdor/CMakeLists.txt b/src/server/scripts/Kalimdor/CMakeLists.txt index 1adc8a53271..d52a9aca48b 100644 --- a/src/server/scripts/Kalimdor/CMakeLists.txt +++ b/src/server/scripts/Kalimdor/CMakeLists.txt @@ -106,7 +106,6 @@ set(scripts_STAT_SRCS Kalimdor/WailingCaverns/wailing_caverns.cpp Kalimdor/zone_durotar.cpp Kalimdor/zone_felwood.cpp - Kalimdor/boss_azuregos.cpp Kalimdor/zone_tanaris.cpp Kalimdor/zone_dustwallow_marsh.cpp Kalimdor/zone_winterspring.cpp @@ -118,6 +117,14 @@ set(scripts_STAT_SRCS Kalimdor/OnyxiasLair/instance_onyxias_lair.cpp Kalimdor/RagefireChasm/instance_ragefire_chasm.cpp Kalimdor/DireMaul/instance_dire_maul.cpp + Kalimdor/HallsOfOrigination/halls_of_origination.h + Kalimdor/HallsOfOrigination/instance_halls_of_origination.cpp + Kalimdor/HallsOfOrigination/boss_temple_guardian_anhuur.cpp + Kalimdor/HallsOfOrigination/boss_earthrager_ptah.cpp + Kalimdor/HallsOfOrigination/boss_anraphet.cpp + Kalimdor/Firelands/instance_firelands.cpp + Kalimdor/Firelands/firelands.h + Kalimdor/Firelands/boss_alysrazor.cpp ) message(" -> Prepared: Kalimdor") diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp index 5266f2b22c5..606188250dd 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp @@ -223,7 +223,7 @@ class spell_mark_of_kazrogal : public SpellScriptLoader } }; - SpellScript* GetSpellScript() const + SpellScript* GetSpellScript() const override { return new spell_mark_of_kazrogal_SpellScript(); } diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp index b228cb91382..b0a1856f45f 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp @@ -31,6 +31,7 @@ EndScriptData */ #include "WorldPacket.h" #include "Opcodes.h" #include "Chat.h" +#include "WorldSession.h" /* Battle of Mount Hyjal encounters: 0 - Rage Winterchill event @@ -191,7 +192,8 @@ public: i->GetSource()->GetSession()->SendPacket(&packet); WorldPacket data2(SMSG_PLAY_SOUND, 4); - data2 << 10986; + data2 << uint32(10986); + data2 << uint64(unit->GetGUID()); i->GetSource()->GetSession()->SendPacket(&data2); } } diff --git a/src/server/scripts/Kalimdor/Firelands/boss_alysrazor.cpp b/src/server/scripts/Kalimdor/Firelands/boss_alysrazor.cpp new file mode 100644 index 00000000000..100d14b756b --- /dev/null +++ b/src/server/scripts/Kalimdor/Firelands/boss_alysrazor.cpp @@ -0,0 +1,704 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * 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/>. + */ + +#include "ObjectMgr.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "PassiveAI.h" +#include "SpellScript.h" +#include "MoveSplineInit.h" +#include "Cell.h" +#include "CellImpl.h" +#include "GridNotifiers.h" +#include "GridNotifiersImpl.h" +#include "firelands.h" + +enum Texts +{ + // Egg Pile + EMOTE_CRACKING_EGGS = 0, // The Molten Eggs begin to crack and splinter! +}; + +enum Spells +{ + // Harbinger of Flame + SPELL_FIRE_IT_UP = 100093, + SPELL_FIEROBLAST_TRASH = 100094, + SPELL_FIEROCLAST_BARRAGE = 100095, + SPELL_FIRE_CHANNELING = 100109, + + // Blazing Monstrosity + SPELL_RIDE_MONSTROSITY = 93970, + SPELL_SHARE_HEALTH_LEFT = 101502, + SPELL_SHARE_HEALTH_RIGHT = 101503, + SPELL_SLEEP_ULTRA_HIGH_PRIORITY = 99480, + SPELL_GENERIC_DUMMY_CAST = 100088, + SPELL_LEFT_SIDE_SMACK_L = 100076, + SPELL_RIGHT_SIDE_SMACK_L = 100078, + SPELL_HEAD_BONK_L = 100080, + SPELL_TICKLE_L = 100082, + SPELL_KNOCKBACK_RIGHT = 100084, + SPELL_KNOCKBACK_LEFT = 100085, + SPELL_KNOCKBACK_FORWARD = 100086, + SPELL_KNOCKBACK_BACK = 100087, + SPELL_HEAD_BONK_R = 100089, + SPELL_LEFT_SIDE_SMACK_R = 100090, + SPELL_RIGHT_SIDE_SMACK_R = 100091, + SPELL_TICKLE_R = 100092, + SPELL_MOLTEN_BARRAGE_EFFECT_L = 100071, + SPELL_MOLTEN_BARRAGE_LEFT = 100072, + SPELL_MOLTEN_BARRAGE_RIGHT = 100073, + SPELL_MOLTEN_BARRAGE_EFFECT_R = 100074, + SPELL_MOLTEN_BARRAGE_VISUAL = 100075, + SPELL_AGGRO_CLOSEST = 100462, + SPELL_INVISIBILITY_AND_STEALTH_DETECTION = 18950, + + // Egg Pile + SPELL_SUMMON_SMOULDERING_HATCHLING = 100096, + SPELL_MOLTEN_EGG_TRASH_CALL_L = 100097, + SPELL_MOLTEN_EGG_TRASH_CALL_R = 100098, + SPELL_ALYSRAZOR_COSMETIC_EGG_XPLOSION = 100099, +}; + +#define SPELL_SHARE_HEALTH (me->GetEntry() == NPC_BLAZING_MONSTROSITY_LEFT ? SPELL_SHARE_HEALTH_LEFT : SPELL_SHARE_HEALTH_RIGHT) +#define SPELL_MOLTEN_BARRAGE (me->GetEntry() == NPC_BLAZING_MONSTROSITY_LEFT ? SPELL_MOLTEN_BARRAGE_LEFT : SPELL_MOLTEN_BARRAGE_RIGHT) +#define SPELL_MOLTEN_BARRAGE_EFFECT (me->GetEntry() == NPC_BLAZING_MONSTROSITY_LEFT ? SPELL_MOLTEN_BARRAGE_EFFECT_L : SPELL_MOLTEN_BARRAGE_EFFECT_R) + +enum Events +{ + // Blazing Monstrosity + EVENT_START_SPITTING = 1, + EVENT_CONTINUE_SPITTING = 2, + + // Harbinger of Flame + EVENT_FIEROBLAST = 1, + EVENT_FIEROCLAST_BARRAGE = 2, + + // Egg Pile + EVENT_SUMMON_SMOULDERING_HATCHLING = 1, +}; + +enum MiscData +{ + MODEL_INVISIBLE_STALKER = 11686, + ANIM_KIT_BIRD_WAKE = 1469, + ANIM_KIT_BIRD_TURN = 1473, +}; + +class RespawnEggEvent : public BasicEvent +{ + public: + explicit RespawnEggEvent(Creature* egg) : _egg(egg) { } + + bool Execute(uint64 /*time*/, uint32 /*diff*/) + { + _egg->RestoreDisplayId(); + return true; + } + + private: + Creature* _egg; +}; + +class MoltenEggCheck +{ + public: + explicit MoltenEggCheck(Creature* pile) : _eggPile(pile) { } + + bool operator()(Unit* object) const + { + if (object->GetEntry() != NPC_MOLTEN_EGG_TRASH) + return false; + + if (object->GetDisplayId() != object->GetNativeDisplayId()) + return false; + + if (_eggPile->GetDistance2d(object) > 20.0f) + return false; + + return true; + } + + private: + Creature* _eggPile; +}; + +class TrashRespawnWorker +{ + public: + void operator()(Creature* creature) const + { + switch (creature->GetEntry()) + { + case NPC_BLAZING_MONSTROSITY_LEFT: + case NPC_BLAZING_MONSTROSITY_RIGHT: + case NPC_EGG_PILE: + case NPC_HARBINGER_OF_FLAME: + case NPC_MOLTEN_EGG_TRASH: + if (!creature->IsAlive()) + creature->Respawn(true); + break; + case NPC_SMOULDERING_HATCHLING: + creature->DespawnOrUnsummon(); + break; + } + } +}; + +static void AlysrazorTrashEvaded(Creature* creature) +{ + TrashRespawnWorker check; + Trinity::CreatureWorker<TrashRespawnWorker> worker(creature, check); + creature->VisitNearbyGridObject(SIZE_OF_GRIDS, worker); +} + +class npc_harbinger_of_flame : public CreatureScript +{ + public: + npc_harbinger_of_flame() : CreatureScript("npc_harbinger_of_flame") { } + + struct npc_harbinger_of_flameAI : public ScriptedAI + { + npc_harbinger_of_flameAI(Creature* creature) : ScriptedAI(creature) + { + } + + void EnterCombat(Unit* /*target*/) + { + if (Creature* bird = ObjectAccessor::GetCreature(*me, me->GetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT))) + DoZoneInCombat(bird, 200.0f); + + me->InterruptSpell(CURRENT_CHANNELED_SPELL); + _events.Reset(); + _events.ScheduleEvent(EVENT_FIEROBLAST, 1); + _events.ScheduleEvent(EVENT_FIEROCLAST_BARRAGE, 6000); + } + + void JustReachedHome() override + { + AlysrazorTrashEvaded(me); + } + + void MoveInLineOfSight(Unit* unit) override + { + if (me->IsInCombat()) + return; + + if (!unit->IsCharmedOwnedByPlayerOrPlayer()) + return; + + ScriptedAI::MoveInLineOfSight(unit); + } + + void UpdateAI(uint32 diff) override + { + if (!me->IsInCombat()) + if (!me->GetCurrentSpell(CURRENT_CHANNELED_SPELL)) + if (Creature* fireBird = me->FindNearestCreature((me->GetHomePosition().GetPositionY() > -275.0f ? NPC_BLAZING_MONSTROSITY_LEFT : NPC_BLAZING_MONSTROSITY_RIGHT), 100.0f)) + DoCast(fireBird, SPELL_FIRE_CHANNELING); + + if (!UpdateVictim()) + return; + + _events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_FIEROBLAST: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, false, -SPELL_RIDE_MONSTROSITY)) + DoCast(target, SPELL_FIEROBLAST_TRASH); + _events.RescheduleEvent(EVENT_FIEROBLAST, 500); // cast time is longer, but thanks to UNIT_STATE_CASTING check it won't trigger more often (need this because this creature gets a stacking haste aura) + break; + case EVENT_FIEROCLAST_BARRAGE: + DoCastAOE(SPELL_FIEROCLAST_BARRAGE); + _events.ScheduleEvent(EVENT_FIEROCLAST_BARRAGE, urand(9000, 12000)); + break; + } + } + + DoMeleeAttackIfReady(); + } + + private: + EventMap _events; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return new npc_harbinger_of_flameAI(creature); + } +}; + +class npc_blazing_monstrosity : public CreatureScript +{ + public: + npc_blazing_monstrosity() : CreatureScript("npc_blazing_monstrosity") { } + + struct npc_blazing_monstrosityAI : public PassiveAI + { + npc_blazing_monstrosityAI(Creature* creature) : PassiveAI(creature), _summons(creature) + { + } + + void EnterEvadeMode() override + { + _summons.DespawnAll(); + _events.Reset(); + PassiveAI::EnterEvadeMode(); + } + + void JustDied(Unit* /*killer*/) override + { + _summons.DespawnAll(); + _events.Reset(); + } + + void JustReachedHome() override + { + AlysrazorTrashEvaded(me); + } + + void EnterCombat(Unit* /*target*/) + { + DoZoneInCombat(); + me->RemoveAurasDueToSpell(SPELL_SLEEP_ULTRA_HIGH_PRIORITY); + me->PlayOneShotAnimKit(ANIM_KIT_BIRD_WAKE); + _events.Reset(); + _events.ScheduleEvent(EVENT_START_SPITTING, 6000); + _events.ScheduleEvent(EVENT_CONTINUE_SPITTING, 9000); + } + + void PassengerBoarded(Unit* passenger, int8 /*seat*/, bool apply) override + { + if (!apply) + return; + + // Our passenger is another vehicle (boardable by players) + DoCast(passenger, SPELL_SHARE_HEALTH, true); + passenger->setFaction(35); + passenger->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + + // Hack to relocate vehicle on vehicle so exiting players are not moved under map + Movement::MoveSplineInit init(passenger); + init.DisableTransportPathTransformations(); + init.MoveTo(0.6654003f, 0.0f, 1.9815f); + init.SetFacing(0.0f); + init.Launch(); + } + + void JustSummoned(Creature* summon) override + { + _summons.Summon(summon); + } + + void SummonedCreatureDespawn(Creature* summon) override + { + _summons.Despawn(summon); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_START_SPITTING: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, false, -SPELL_RIDE_MONSTROSITY)) + DoCast(target, SPELL_MOLTEN_BARRAGE); + break; + case EVENT_CONTINUE_SPITTING: + DoCastAOE(SPELL_MOLTEN_BARRAGE_EFFECT); + if (Creature* egg = me->FindNearestCreature(NPC_EGG_PILE, 100.0f)) + egg->AI()->DoAction(me->GetEntry()); + break; + } + } + } + + private: + SummonList _summons; + EventMap _events; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return new npc_blazing_monstrosityAI(creature); + } +}; + +class npc_molten_barrage : public CreatureScript +{ + public: + npc_molten_barrage() : CreatureScript("npc_molten_barrage") { } + + struct npc_molten_barrageAI : public NullCreatureAI + { + npc_molten_barrageAI(Creature* creature) : NullCreatureAI(creature) + { + } + + void AttackStart(Unit* target) override + { + if (target) + me->GetMotionMaster()->MoveFollow(target, 0.0f, 0.0f, MOTION_SLOT_IDLE); + } + + void IsSummonedBy(Unit* /*summoner*/) override + { + DoCastAOE(SPELL_AGGRO_CLOSEST, true); + DoCast(me, SPELL_MOLTEN_BARRAGE_VISUAL); + DoCast(me, SPELL_INVISIBILITY_AND_STEALTH_DETECTION, true); + } + + void MovementInform(uint32 movementType, uint32 /*pointId*/) override + { + if (movementType != EFFECT_MOTION_TYPE) + return; + + DoCastAOE(SPELL_AGGRO_CLOSEST); + me->ClearUnitState(UNIT_STATE_CANNOT_TURN); + } + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return new npc_molten_barrageAI(creature); + } +}; + +class npc_egg_pile : public CreatureScript +{ + public: + npc_egg_pile() : CreatureScript("npc_egg_pile") { } + + struct npc_egg_pileAI : public CreatureAI + { + npc_egg_pileAI(Creature* creature) : CreatureAI(creature) + { + } + + void AttackStart(Unit* /*target*/) override { } + + void Reset() override + { + me->SetReactState(REACT_PASSIVE); + _events.Reset(); + _callHatchlingSpell = 0; + } + + void JustDied(Unit* /*killer*/) override + { + _events.Reset(); + std::list<Creature*> eggs; + GetCreatureListWithEntryInGrid(eggs, me, NPC_MOLTEN_EGG_TRASH, 20.0f); + for (std::list<Creature*>::const_iterator itr = eggs.begin(); itr != eggs.end(); ++itr) + (*itr)->CastSpell(*itr, SPELL_ALYSRAZOR_COSMETIC_EGG_XPLOSION, TRIGGERED_FULL_MASK); + + DoCast(me, SPELL_ALYSRAZOR_COSMETIC_EGG_XPLOSION, true); + } + + void JustReachedHome() override + { + AlysrazorTrashEvaded(me); + } + + void DoAction(int32 action) override + { + if (action != NPC_BLAZING_MONSTROSITY_LEFT && + action != NPC_BLAZING_MONSTROSITY_RIGHT) + return; + + if (action == NPC_BLAZING_MONSTROSITY_LEFT) + Talk(EMOTE_CRACKING_EGGS); + + _callHatchlingSpell = (action == NPC_BLAZING_MONSTROSITY_LEFT) ? SPELL_MOLTEN_EGG_TRASH_CALL_L : SPELL_MOLTEN_EGG_TRASH_CALL_R; + DoZoneInCombat(); + _events.Reset(); + _events.ScheduleEvent(EVENT_SUMMON_SMOULDERING_HATCHLING, 1); + } + + 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_SUMMON_SMOULDERING_HATCHLING: + { + std::list<Creature*> eggs; + MoltenEggCheck check(me); + Trinity::CreatureListSearcher<MoltenEggCheck> searcher(me, eggs, check); + me->VisitNearbyGridObject(20.0f, searcher); + if (!eggs.empty()) + { + Creature* egg = Trinity::Containers::SelectRandomContainerElement(eggs); + egg->CastSpell(egg, SPELL_SUMMON_SMOULDERING_HATCHLING, TRIGGERED_FULL_MASK); + egg->SetDisplayId(MODEL_INVISIBLE_STALKER); + egg->m_Events.AddEvent(new RespawnEggEvent(egg), egg->m_Events.CalculateTime(5000)); + } + + if (_callHatchlingSpell) + DoCastAOE(_callHatchlingSpell, true); + _events.ScheduleEvent(EVENT_SUMMON_SMOULDERING_HATCHLING, urand(6000, 10000)); + break; + } + default: + break; + } + } + + DoMeleeAttackIfReady(); + } + + private: + EventMap _events; + uint32 _callHatchlingSpell; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return new npc_egg_pileAI(creature); + } +}; + +class spell_alysrazor_cosmetic_egg_xplosion : public SpellScriptLoader +{ + public: + spell_alysrazor_cosmetic_egg_xplosion() : SpellScriptLoader("spell_alysrazor_cosmetic_egg_xplosion") { } + + class spell_alysrazor_cosmetic_egg_xplosion_SpellScript : public SpellScript + { + PrepareSpellScript(spell_alysrazor_cosmetic_egg_xplosion_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sCreatureDisplayInfoStore.LookupEntry(MODEL_INVISIBLE_STALKER)) + return false; + return true; + } + + void HandleExplosion(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + GetHitUnit()->SetDisplayId(MODEL_INVISIBLE_STALKER); + if (Creature* creature = GetHitCreature()) + creature->DespawnOrUnsummon(4000); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_alysrazor_cosmetic_egg_xplosion_SpellScript::HandleExplosion, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_alysrazor_cosmetic_egg_xplosion_SpellScript(); + } +}; + +class spell_alysrazor_turn_monstrosity : public SpellScriptLoader +{ + public: + spell_alysrazor_turn_monstrosity() : SpellScriptLoader("spell_alysrazor_turn_monstrosity") { } + + class spell_alysrazor_turn_monstrosity_SpellScript : public SpellScript + { + PrepareSpellScript(spell_alysrazor_turn_monstrosity_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_GENERIC_DUMMY_CAST)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_KNOCKBACK_RIGHT)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_KNOCKBACK_LEFT)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_KNOCKBACK_FORWARD)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_KNOCKBACK_BACK)) + return false; + return true; + } + + void KnockBarrage(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + GetHitUnit()->GetMotionMaster()->MoveIdle(); + if (TempSummon* summ = GetHitUnit()->ToTempSummon()) + if (Unit* summoner = summ->GetSummoner()) + GetHitUnit()->CastSpell(summoner, SPELL_GENERIC_DUMMY_CAST, TRIGGERED_FULL_MASK); + + float angle = 0.0f; + if (Unit* bird = GetCaster()->GetVehicleBase()) + { + bird->SetInFront(GetHitUnit()); + angle = bird->GetOrientation(); + } + + uint32 spellId = 0; + switch (GetSpellInfo()->Id) + { + case SPELL_RIGHT_SIDE_SMACK_R: + case SPELL_RIGHT_SIDE_SMACK_L: + spellId = SPELL_KNOCKBACK_RIGHT; + angle -= M_PI * 0.5f; + break; + case SPELL_LEFT_SIDE_SMACK_R: + case SPELL_LEFT_SIDE_SMACK_L: + spellId = SPELL_KNOCKBACK_LEFT; + angle += M_PI * 0.5f; + break; + case SPELL_HEAD_BONK_R: + case SPELL_HEAD_BONK_L: + spellId = SPELL_KNOCKBACK_FORWARD; + break; + case SPELL_TICKLE_R: + case SPELL_TICKLE_L: + spellId = SPELL_KNOCKBACK_BACK; + angle -= M_PI; + break; + } + + // Cannot wait for object update to process facing spline, it's needed in next spell cast + GetHitUnit()->SetOrientation(angle); + GetHitUnit()->SetFacingTo(angle); + GetHitUnit()->AddUnitState(UNIT_STATE_CANNOT_TURN); + GetHitUnit()->CastSpell(GetHitUnit(), spellId, TRIGGERED_FULL_MASK); + } + + void TurnBird(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + GetHitUnit()->PlayOneShotAnimKit(ANIM_KIT_BIRD_TURN); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_alysrazor_turn_monstrosity_SpellScript::KnockBarrage, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_alysrazor_turn_monstrosity_SpellScript::TurnBird, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_alysrazor_turn_monstrosity_SpellScript(); + } +}; + +class spell_alysrazor_aggro_closest : public SpellScriptLoader +{ + public: + spell_alysrazor_aggro_closest() : SpellScriptLoader("spell_alysrazor_aggro_closest") { } + + class spell_alysrazor_aggro_closest_SpellScript : public SpellScript + { + PrepareSpellScript(spell_alysrazor_aggro_closest_SpellScript); + + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_UNIT; + } + + void HandleEffect(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + float curThreat = GetCaster()->getThreatManager().getThreat(GetHitUnit(), true); + GetCaster()->getThreatManager().addThreat(GetHitUnit(), -curThreat + 50000.0f / std::min(1.0f, GetCaster()->GetDistance(GetHitUnit()))); + } + + void UpdateThreat() + { + GetCaster()->ClearUnitState(UNIT_STATE_CASTING); + GetCaster()->GetAI()->AttackStart(GetCaster()->ToCreature()->SelectVictim()); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_alysrazor_aggro_closest_SpellScript::HandleEffect, EFFECT_0, SPELL_EFFECT_DUMMY); + AfterCast += SpellCastFn(spell_alysrazor_aggro_closest_SpellScript::UpdateThreat); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_alysrazor_aggro_closest_SpellScript(); + } +}; + +class spell_alysrazor_fieroblast : public SpellScriptLoader +{ + public: + spell_alysrazor_fieroblast() : SpellScriptLoader("spell_alysrazor_fieroblast") { } + + class spell_alysrazor_fieroblast_SpellScript : public SpellScript + { + PrepareSpellScript(spell_alysrazor_fieroblast_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_FIRE_IT_UP)) + return false; + return true; + } + + void FireItUp() + { + GetCaster()->CastSpell(GetCaster(), SPELL_FIRE_IT_UP, TRIGGERED_FULL_MASK); + } + + void Register() override + { + AfterCast += SpellCastFn(spell_alysrazor_fieroblast_SpellScript::FireItUp); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_alysrazor_fieroblast_SpellScript(); + } +}; + +void AddSC_boss_alysrazor() +{ + new npc_harbinger_of_flame(); + new npc_blazing_monstrosity(); + new npc_molten_barrage(); + new npc_egg_pile(); + new spell_alysrazor_cosmetic_egg_xplosion(); + new spell_alysrazor_turn_monstrosity(); + new spell_alysrazor_aggro_closest(); + new spell_alysrazor_fieroblast(); +} diff --git a/src/server/scripts/Kalimdor/Firelands/firelands.h b/src/server/scripts/Kalimdor/Firelands/firelands.h new file mode 100644 index 00000000000..d02d244dfc6 --- /dev/null +++ b/src/server/scripts/Kalimdor/Firelands/firelands.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * 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/>. + */ + +#ifndef FIRELANDS_H_ +#define FIRELANDS_H_ + +#include "Map.h" +#include "CreatureAI.h" + +#define FirelandsScriptName "instance_firelands" + +uint32 const EncounterCount = 7; + +enum DataTypes +{ + DATA_BETH_TILAC = 0, + DATA_LORD_RHYOLITH = 1, + DATA_SHANNOX = 2, + DATA_ALYSRAZOR = 3, + DATA_BALEROC = 4, + DATA_MAJORDOMO_STAGHELM = 5, + DATA_RAGNAROS = 6, +}; + +enum CreatureIds +{ + NPC_BLAZING_MONSTROSITY_LEFT = 53786, + NPC_BLAZING_MONSTROSITY_RIGHT = 53791, + NPC_EGG_PILE = 53795, + NPC_HARBINGER_OF_FLAME = 53793, + NPC_MOLTEN_EGG_TRASH = 53914, + NPC_SMOULDERING_HATCHLING = 53794, +}; + +class DelayedAttackStartEvent : public BasicEvent +{ + public: + DelayedAttackStartEvent(Creature* owner) : _owner(owner) { } + + bool Execute(uint64 /*e_time*/, uint32 /*p_time*/) + { + _owner->AI()->DoZoneInCombat(_owner, 200.0f); + return true; + } + + private: + Creature* _owner; +}; + +template<class AI> +CreatureAI* GetFirelandsAI(Creature* creature) +{ + if (InstanceMap* instance = creature->GetMap()->ToInstanceMap()) + if (instance->GetInstanceScript()) + if (instance->GetScriptId() == sObjectMgr->GetScriptId(FirelandsScriptName)) + return new AI(creature); + return NULL; +} + +#endif // FIRELANDS_H_ diff --git a/src/server/scripts/Kalimdor/Firelands/instance_firelands.cpp b/src/server/scripts/Kalimdor/Firelands/instance_firelands.cpp new file mode 100644 index 00000000000..f53a749c777 --- /dev/null +++ b/src/server/scripts/Kalimdor/Firelands/instance_firelands.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * 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/>. + */ + +#include "ScriptMgr.h" +#include "InstanceScript.h" +#include "firelands.h" + +class instance_firelands : public InstanceMapScript +{ + public: + instance_firelands() : InstanceMapScript(FirelandsScriptName, 720) { } + + struct instance_firelands_InstanceScript : public InstanceScript + { + instance_firelands_InstanceScript(InstanceMap* map) : InstanceScript(map) + { + } + + void Initialize() override + { + SetBossNumber(EncounterCount); + } + + void OnCreatureCreate(Creature* creature) override + { + switch (creature->GetEntry()) + { + case NPC_SMOULDERING_HATCHLING: + // Cannot directly start attacking here as the creature is not yet on map + creature->m_Events.AddEvent(new DelayedAttackStartEvent(creature), creature->m_Events.CalculateTime(500)); + break; + } + } + }; + + InstanceScript* GetInstanceScript(InstanceMap* map) const override + { + return new instance_firelands_InstanceScript(map); + } +}; + +void AddSC_instance_firelands() +{ + new instance_firelands(); +} diff --git a/src/server/scripts/Kalimdor/HallsOfOrigination/boss_anraphet.cpp b/src/server/scripts/Kalimdor/HallsOfOrigination/boss_anraphet.cpp new file mode 100644 index 00000000000..c8963331702 --- /dev/null +++ b/src/server/scripts/Kalimdor/HallsOfOrigination/boss_anraphet.cpp @@ -0,0 +1,571 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * 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/>. + */ + +#include "ObjectMgr.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "SpellScript.h" +#include "SpellAuraEffects.h" +#include "GridNotifiers.h" +#include "Player.h" +#include "ObjectAccessor.h" +#include "halls_of_origination.h" + +enum Texts +{ + ANRAPHET_SAY_INTRO = 0, + ANRAPHET_SAY_AGGRO = 1, + ANRAPHET_SAY_OMEGA_STANCE = 2, + ANRAPHET_SAY_KILL = 3, + ANRAPHET_SAY_DEATH = 4, + + BRANN_SAY_DOOR_INTRO = 0, // Right, let's go! Just need to input the final entry sequence into the door mechanism... and... + BRANN_SAY_UNLOCK_DOOR = 1, // That did the trick! The control room should be right behind this... oh... wow... + BRANN_SAY_TROGGS = 2, // What? This isn't the control room! There's another entire defense mechanism in place, and the blasted Rock Troggs broke into here somehow. Troggs. Why did it have to be Troggs! + BRANN_SAY_THINK = 3, // Ok, let me think a moment. + BRANN_SAY_MIRRORS = 4, // Mirrors pointing all over the place. + BRANN_SAY_ELEMENTALS = 5, // Four platforms with huge elementals. + BRANN_SAY_GET_IT = 6, // I got it! I saw a tablet that mentioned this chamber. This is the Vault of Lights! Ok, simple enough. I need you adventurers to take out each of the four elementals to trigger the opening sequence for the far door! + BRANN_1_ELEMENTAL_DEAD = 7, // One down! + BRANN_2_ELEMENTAL_DEAD = 8, // Another one down! Just look at those light beams! They seem to be connecting to the far door! + BRANN_3_ELEMENTAL_DEAD = 9, // One more elemental to go! The door is almost open! + BRANN_4_ELEMENTAL_DEAD = 10, // That''s it, you''ve done it! The vault door is opening! Now we can... oh, no! + BRANN_SAY_ANRAPHET_DIED = 11, // We''ve done it! The control room is breached! + BRANN_SAY_MOMENT = 12 // Here we go! Now this should only take a moment... +}; + +enum Events +{ + EVENT_BRANN_MOVE_INTRO = 1, + EVENT_BRANN_UNLOCK_DOOR = 2, + EVENT_BRANN_THINK = 3, + EVENT_BRANN_SET_ORIENTATION_1 = 4, + EVENT_BRANN_SET_ORIENTATION_2 = 5, + EVENT_BRANN_SET_ORIENTATION_3 = 6, + EVENT_BRANN_SAY_ELEMENTALS = 7, + EVENT_BRANN_SAY_GET_IT = 8, + EVENT_BRANN_SET_ORIENTATION_4 = 9, + + EVENT_ANRAPHET_APPEAR = 10, + EVENT_ANRAPHET_ACTIVATE = 11, + EVENT_ANRAPHET_DESTROY = 12, + EVENT_ANRAPHET_READY = 13, + EVENT_ANRAPHET_NEMESIS_STRIKE = 14, + EVENT_ANRAPHET_ALPHA_BEAMS = 15, + EVENT_ANRAPHET_OMEGA_STANCE = 16, + EVENT_ANRAPHET_CRUMBLING_RUIN = 17, + EVENT_ANRAPHET_ACTIVATE_OMEGA = 18 +}; + +enum Spells +{ + SPELL_DESTRUCTION_PROTOCOL = 77437, + + SPELL_ALPHA_BEAMS = 76184, + SPELL_ALPHA_BEAMS_BACK_CAST = 76912, + + SPELL_CRUMBLING_RUIN = 75609, + + + SPELL_NEMESIS_STRIKE = 75604, + + SPELL_OMEGA_STANCE_SUMMON = 77106, + SPELL_OMEGA_STANCE = 75622, + SPELL_OMEGA_STANCE_SPIDER_TRIGGER = 77121, +}; + +enum Phases +{ + PHASE_INTRO = 1, + PHASE_COMBAT = 2, + + PHASE_MASK_COMBAT = (1 << PHASE_COMBAT), +}; + +enum Points +{ + POINT_ANRAPHET_ACTIVATE = 0, + MAX_BRANN_WAYPOINTS_INTRO = 17 +}; + +Position const AnraphetActivatePos = {-193.656f, 366.689f, 75.91001f, 3.138207f}; + +Position const BrannIntroWaypoint[MAX_BRANN_WAYPOINTS_INTRO] = +{ + {-429.583f, 367.019f, 89.79282f, 0.0f}, + {-409.9531f, 367.0469f, 89.81111f, 0.0f}, + {-397.8246f, 366.967f, 86.37722f, 0.0f}, + {-383.7813f, 366.8229f, 82.07919f, 0.0f}, + {-368.2604f, 366.7448f, 77.0984f, 0.0f}, + {-353.6458f, 366.4896f, 75.92504f, 0.0f}, + {-309.0608f, 366.7205f, 75.91345f, 0.0f}, + {-276.3303f, 367.0f, 75.92413f, 0.0f}, + {-246.5104f, 366.6389f, 75.87791f, 0.0f}, + {-202.0417f, 366.7517f, 75.92508f, 0.0f}, + {-187.6024f, 366.7656f, 76.23077f, 0.0f}, + {-155.0938f, 366.783f, 86.45834f, 0.0f}, + {-143.5694f, 366.8177f, 89.73354f, 0.0f}, + {-128.5608f, 366.8629f, 89.74199f, 0.0f}, + {-103.559f, 366.5938f, 89.79725f, 0.0f}, + {-71.58507f, 367.0278f, 89.77069f, 0.0f}, + {-35.04861f, 366.6563f, 89.77447f, 0.0f}, +}; + +class boss_anraphet : public CreatureScript +{ +public: + boss_anraphet() : CreatureScript("boss_anraphet") { } + + struct boss_anraphetAI : public BossAI + { + boss_anraphetAI(Creature* creature) : BossAI(creature, DATA_ANRAPHET) { } + + void ScheduleCombatEvents() + { + events.ScheduleEvent(EVENT_ANRAPHET_NEMESIS_STRIKE, 8000, 0, PHASE_COMBAT); + events.ScheduleEvent(EVENT_ANRAPHET_ALPHA_BEAMS, 10000, 0, PHASE_COMBAT); + events.ScheduleEvent(EVENT_ANRAPHET_OMEGA_STANCE, 35000, 0, PHASE_COMBAT); + } + + void Reset() override + { + _Reset(); + me->SetWalk(false); + events.SetPhase(PHASE_INTRO); + if (instance->GetData(DATA_DEAD_ELEMENTALS) == 4) + { + // Set to combat automatically, Brann's event won't repeat + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + events.SetPhase(PHASE_COMBAT); + ScheduleCombatEvents(); + me->SetHomePosition(AnraphetActivatePos); + } + } + + void EnterCombat(Unit* /*who*/) override + { + instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, 1); + Talk(ANRAPHET_SAY_AGGRO); + _EnterCombat(); + } + + void JustDied(Unit* /*killer*/) override + { + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); + Talk(ANRAPHET_SAY_DEATH); + + if (Creature* brann = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_BRANN_0_GUID))) + brann->AI()->DoAction(ACTION_ANRAPHET_DIED); + + _JustDied(); + } + + void KilledUnit(Unit* victim) override + { + if (victim->GetTypeId() == TYPEID_PLAYER) + Talk(ANRAPHET_SAY_KILL); + } + + void JustReachedHome() override + { + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); + _JustReachedHome(); + instance->SetBossState(DATA_ANRAPHET, FAIL); + } + + void DoAction(int32 action) override + { + if (action == ACTION_ANRAPHET_INTRO) + events.ScheduleEvent(EVENT_ANRAPHET_APPEAR, 6000, 0, PHASE_INTRO); + } + + void MovementInform(uint32 type, uint32 point) override + { + if (type != POINT_MOTION_TYPE) + return; + + if (point == POINT_ANRAPHET_ACTIVATE) + { + events.ScheduleEvent(EVENT_ANRAPHET_ACTIVATE, 1500, 0, PHASE_INTRO); + me->SetHomePosition(AnraphetActivatePos); + } + } + + void UpdateAI(uint32 diff) override + { + if ((events.GetPhaseMask() & PHASE_MASK_COMBAT) && (!UpdateVictim() || !CheckInRoom())) + return; + + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_ANRAPHET_APPEAR: + me->SetWalk(true); + me->GetMotionMaster()->MovePoint(POINT_ANRAPHET_ACTIVATE, AnraphetActivatePos); + break; + case EVENT_ANRAPHET_ACTIVATE: + me->SetWalk(false); + Talk(ANRAPHET_SAY_INTRO); + events.ScheduleEvent(EVENT_ANRAPHET_DESTROY, 17500, 0, PHASE_INTRO); + return; + case EVENT_ANRAPHET_DESTROY: + DoCastAOE(SPELL_DESTRUCTION_PROTOCOL); + events.ScheduleEvent(EVENT_ANRAPHET_READY, 6000, 0, PHASE_INTRO); + break; + case EVENT_ANRAPHET_READY: + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + events.SetPhase(PHASE_COMBAT); + ScheduleCombatEvents(); + break; + case EVENT_ANRAPHET_NEMESIS_STRIKE: + DoCastVictim(SPELL_NEMESIS_STRIKE); + events.ScheduleEvent(EVENT_ANRAPHET_NEMESIS_STRIKE, 21500, 0, PHASE_COMBAT); + break; + case EVENT_ANRAPHET_ALPHA_BEAMS: + DoCast(me, SPELL_ALPHA_BEAMS); + events.ScheduleEvent(EVENT_ANRAPHET_CRUMBLING_RUIN, 12500, 0, PHASE_COMBAT); + events.ScheduleEvent(EVENT_ANRAPHET_ALPHA_BEAMS, urand(40000, 45000), 0, PHASE_COMBAT); + break; + case EVENT_ANRAPHET_OMEGA_STANCE: + DoCast(me, SPELL_OMEGA_STANCE_SUMMON); + DoCast(me, SPELL_OMEGA_STANCE); + Talk(ANRAPHET_SAY_OMEGA_STANCE); + events.ScheduleEvent(EVENT_ANRAPHET_OMEGA_STANCE, urand(45000, 50000), 0, PHASE_COMBAT); + events.ScheduleEvent(EVENT_ANRAPHET_CRUMBLING_RUIN, 13000, 0, PHASE_COMBAT); + break; + case EVENT_ANRAPHET_CRUMBLING_RUIN: + DoCast(me, SPELL_CRUMBLING_RUIN); + break; + } + } + + if (events.GetPhaseMask() & PHASE_MASK_COMBAT) + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetHallsOfOriginationAI<boss_anraphetAI>(creature); + } +}; + +class npc_omega_stance : public CreatureScript +{ + public: + npc_omega_stance() : CreatureScript("npc_omega_stance") { } + + struct npc_omega_stanceAI : public ScriptedAI + { + npc_omega_stanceAI(Creature* creature) : ScriptedAI(creature) { } + + void IsSummonedBy(Unit* /*who*/) override + { + DoCast(me, SPELL_OMEGA_STANCE_SPIDER_TRIGGER, true); + } + + void EnterEvadeMode() override { } + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return new npc_omega_stanceAI(creature); + } +}; + +class npc_alpha_beam : public CreatureScript +{ + public: + npc_alpha_beam() : CreatureScript("npc_alpha_beam") { } + + struct npc_alpha_beamAI : public ScriptedAI + { + npc_alpha_beamAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { } + + void IsSummonedBy(Unit* /*summoner*/) override + { + if (Creature* anraphet = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_ANRAPHET_GUID))) + anraphet->CastSpell(me, SPELL_ALPHA_BEAMS_BACK_CAST); + } + + void EnterEvadeMode() override { } // Never evade + + private: + InstanceScript* _instance; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetHallsOfOriginationAI<npc_alpha_beamAI>(creature); + } +}; + +class npc_brann_bronzebeard_anraphet : public CreatureScript +{ + public: + npc_brann_bronzebeard_anraphet() : CreatureScript("npc_brann_bronzebeard_anraphet") { } + + struct npc_brann_bronzebeard_anraphetAI : public CreatureAI + { + npc_brann_bronzebeard_anraphetAI(Creature* creature) : CreatureAI(creature), _currentPoint(0), _instance(creature->GetInstanceScript()) { } + + void sGossipSelect(Player* /*player*/, uint32 sender, uint32 action) override + { + if (_instance->GetBossState(DATA_VAULT_OF_LIGHTS) == DONE) + return; + + if (me->GetCreatureTemplate()->GossipMenuId == sender && !action) + { + _instance->SetBossState(DATA_VAULT_OF_LIGHTS, IN_PROGRESS); + _currentPoint = 0; + events.Reset(); + me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + me->SetWalk(true); + Talk(BRANN_SAY_DOOR_INTRO); + events.ScheduleEvent(EVENT_BRANN_UNLOCK_DOOR, 7500); + } + } + + void DoAction(int32 action) override + { + switch (action) + { + case ACTION_ELEMENTAL_DIED: + { + uint32 dead = _instance->GetData(DATA_DEAD_ELEMENTALS); + Talk(BRANN_1_ELEMENTAL_DEAD + dead - 1); + if (dead == 4) + { + _instance->DoCastSpellOnPlayers(SPELL_VAULT_OF_LIGHTS_CREDIT); + if (Creature* anraphet = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_ANRAPHET_GUID))) + anraphet->AI()->DoAction(ACTION_ANRAPHET_INTRO); + } + break; + } + case ACTION_ANRAPHET_DIED: + me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + events.ScheduleEvent(EVENT_BRANN_MOVE_INTRO, 1000); + break; + } + } + + void UpdateAI(uint32 diff) override + { + events.Update(diff); + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_BRANN_MOVE_INTRO: + if (_currentPoint < MAX_BRANN_WAYPOINTS_INTRO) + me->GetMotionMaster()->MovePoint(_currentPoint, BrannIntroWaypoint[_currentPoint]); + break; + case EVENT_BRANN_UNLOCK_DOOR: + Talk(BRANN_SAY_UNLOCK_DOOR); + _instance->SetBossState(DATA_VAULT_OF_LIGHTS, DONE); + _instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_VAULT_OF_LIGHTS_EVENT); + events.ScheduleEvent(EVENT_BRANN_MOVE_INTRO, 3500); + break; + case EVENT_BRANN_THINK: + Talk(BRANN_SAY_THINK); + events.ScheduleEvent(EVENT_BRANN_SET_ORIENTATION_1, 6000); + break; + case EVENT_BRANN_SET_ORIENTATION_1: + me->SetFacingTo(5.445427f); + Talk(BRANN_SAY_MIRRORS); + events.ScheduleEvent(EVENT_BRANN_SET_ORIENTATION_2, 1000); + break; + case EVENT_BRANN_SET_ORIENTATION_2: + me->SetFacingTo(0.6283185f); + events.ScheduleEvent(EVENT_BRANN_SET_ORIENTATION_3, 2500); + break; + case EVENT_BRANN_SET_ORIENTATION_3: + me->SetFacingTo(0.01745329f); + events.ScheduleEvent(EVENT_BRANN_SAY_ELEMENTALS, 200); + break; + case EVENT_BRANN_SAY_ELEMENTALS: + Talk(BRANN_SAY_ELEMENTALS); + events.ScheduleEvent(EVENT_BRANN_SAY_GET_IT, 3500); + break; + case EVENT_BRANN_SAY_GET_IT: + Talk(BRANN_SAY_GET_IT); + me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + break; + case EVENT_BRANN_SET_ORIENTATION_4: + me->SetFacingTo(3.141593f); + break; + } + } + } + + void MovementInform(uint32 movementType, uint32 pointId) override + { + if (movementType != POINT_MOTION_TYPE) + return; + + _currentPoint = pointId + 1; + uint32 delay = 1; + + switch (pointId) + { + case 0: + Talk(BRANN_SAY_TROGGS); + events.ScheduleEvent(EVENT_BRANN_THINK, 15000); + return; + case 1: + Talk(BRANN_SAY_ANRAPHET_DIED); + delay = 1000; + break; + case 14: + Talk(BRANN_SAY_MOMENT); + delay = 2200; + break; + case 16: + events.ScheduleEvent(EVENT_BRANN_SET_ORIENTATION_4, 6000); + return; + default: + break; + } + + events.ScheduleEvent(EVENT_BRANN_MOVE_INTRO, delay); + } + + protected: + EventMap events; + uint32 _currentPoint; + InstanceScript* _instance; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetHallsOfOriginationAI<npc_brann_bronzebeard_anraphetAI>(creature); + } +}; + +class spell_anraphet_alpha_beams : public SpellScriptLoader +{ +public: + spell_anraphet_alpha_beams() : SpellScriptLoader("spell_anraphet_alpha_beams") { } + + class spell_anraphet_alpha_beams_SpellScript : public SpellScript + { + PrepareSpellScript(spell_anraphet_alpha_beams_SpellScript); + + void FilterTargets(std::list<WorldObject*>& targets) + { + if (targets.empty()) + return; + + WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets); + targets.clear(); + targets.push_back(target); + } + + void Register() + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_anraphet_alpha_beams_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_anraphet_alpha_beams_SpellScript(); + } +}; + +class spell_anraphet_omega_stance_summon : public SpellScriptLoader +{ +public: + spell_anraphet_omega_stance_summon() : SpellScriptLoader("spell_anraphet_omega_stance_summon") { } + + class spell_anraphet_omega_stance_summon_SpellScript : public SpellScript + { + PrepareSpellScript(spell_anraphet_omega_stance_summon_SpellScript); + + void ModDestHeight(SpellEffIndex /*effIndex*/) + { + Position offset = {0.0f, 0.0f, 30.0f, 0.0f}; + const_cast<WorldLocation*>(GetExplTargetDest())->RelocateOffset(offset); + GetHitDest()->RelocateOffset(offset); + } + + void Register() + { + OnEffectLaunch += SpellEffectFn(spell_anraphet_omega_stance_summon_SpellScript::ModDestHeight, EFFECT_0, SPELL_EFFECT_SUMMON); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_anraphet_omega_stance_summon_SpellScript(); + } +}; + +class spell_omega_stance_spider_effect : public SpellScriptLoader +{ +public: + spell_omega_stance_spider_effect() : SpellScriptLoader("spell_omega_stance_spider_effect") { } + + class spell_omega_stance_spider_effect_SpellScript : public SpellScript + { + PrepareSpellScript(spell_omega_stance_spider_effect_SpellScript); + + void SetDestPosition(SpellEffIndex effIndex) + { + // Do our own calculations for the destination position. + /// TODO: Remove this once we find a general rule for WorldObject::MovePosition (this spell shouldn't take the Z change into consideration) + Unit* caster = GetCaster(); + float angle = float(rand_norm()) * static_cast<float>(2 * M_PI); + uint32 dist = caster->GetObjectSize() + GetSpellInfo()->Effects[effIndex].CalcRadius(GetCaster()) * (float)rand_norm(); + + float x = caster->GetPositionX() + dist * std::cos(angle); + float y = caster->GetPositionY() + dist * std::sin(angle); + float z = caster->GetMap()->GetHeight(x, y, caster->GetPositionZ()); + + const_cast<WorldLocation*>(GetExplTargetDest())->Relocate(x, y, z); + GetHitDest()->Relocate(x, y, z); + } + + void Register() + { + OnEffectLaunch += SpellEffectFn(spell_omega_stance_spider_effect_SpellScript::SetDestPosition, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_omega_stance_spider_effect_SpellScript(); + } +}; + +void AddSC_boss_anraphet() +{ + new boss_anraphet(); + new spell_anraphet_alpha_beams(); + new npc_brann_bronzebeard_anraphet(); + new npc_alpha_beam(); + new spell_anraphet_omega_stance_summon(); + new spell_omega_stance_spider_effect(); + new npc_omega_stance(); +} diff --git a/src/server/scripts/Kalimdor/HallsOfOrigination/boss_earthrager_ptah.cpp b/src/server/scripts/Kalimdor/HallsOfOrigination/boss_earthrager_ptah.cpp new file mode 100644 index 00000000000..e444d6793e6 --- /dev/null +++ b/src/server/scripts/Kalimdor/HallsOfOrigination/boss_earthrager_ptah.cpp @@ -0,0 +1,346 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * 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/>. + */ + +#include "ObjectMgr.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "SpellScript.h" +#include "SpellAuraEffects.h" +#include "Player.h" +#include "Weather.h" +#include "WorldSession.h" +#include "halls_of_origination.h" + +enum Texts +{ + SAY_AGGRO = 0, + SAY_DEATH = 1, +}; + +enum Events +{ + EVENT_RAGING_SMASH = 1, + EVENT_FLAME_BOLT = 2, + EVENT_EARTH_SPIKE = 3, + EVENT_PTAH_EXPLODE = 4, + EVENT_QUICKSAND = 5, +}; + +enum Spells +{ + SPELL_RAGING_SMASH = 83650, + SPELL_FLAME_BOLT = 77370, + SPELL_EARTH_SPIKE_WARN = 94974, + + SPELL_PTAH_EXPLOSION = 75519, + SPELL_SANDSTORM = 75491, + + SPELL_SUMMON_QUICKSAND = 75550, // Spell not in DBC, no SMSG_SPELL_START/GO for it + + SPELL_BEETLE_BURROW = 75463, + + SPELL_SUMMON_JEWELED_SCARAB = 75462, + SPELL_SUMMON_DUSTBONE_HORROR = 75521, +}; + +enum Phases +{ + PHASE_NORMAL = 1, + PHASE_DISPERSE = 2, + + PHASE_MASK_DISPERSE = (1 << PHASE_DISPERSE), + PHASE_MASK_NORMAL = (1 << PHASE_NORMAL), +}; + +enum PtahData +{ + DATA_SUMMON_DEATHS = 0 +}; + +class SummonScarab : public BasicEvent +{ +public: + SummonScarab(Unit* owner, InstanceScript* instance) : _owner(owner), _instance(instance) { } + + bool Execute(uint64 /*execTime*/, uint32 /*diff*/) + { + if (!_instance || _instance->GetBossState(DATA_EARTHRAGER_PTAH) != IN_PROGRESS) + return true; // delete event + + _owner->CastSpell(_owner, SPELL_SUMMON_JEWELED_SCARAB); + _owner->RemoveAurasDueToSpell(SPELL_BEETLE_BURROW); + return true; + } +protected: + Unit* _owner; + InstanceScript* _instance; +}; + +class boss_earthrager_ptah : public CreatureScript +{ +public: + boss_earthrager_ptah() : CreatureScript("boss_earthrager_ptah") { } + + struct boss_earthrager_ptahAI : public BossAI + { + boss_earthrager_ptahAI(Creature* creature) : BossAI(creature, DATA_EARTHRAGER_PTAH), _summonDeaths(0), _hasDispersed(false) { } + + void Cleanup() + { + std::list<Creature*> units; + + GetCreatureListWithEntryInGrid(units, me, NPC_DUSTBONE_HORROR, 100.0f); + for (std::list<Creature*>::iterator itr = units.begin(); itr != units.end(); ++itr) + (*itr)->DespawnOrUnsummon(); + + GetCreatureListWithEntryInGrid(units, me, NPC_JEWELED_SCARAB, 100.0f); + for (std::list<Creature*>::iterator itr = units.begin(); itr != units.end(); ++itr) + (*itr)->DespawnOrUnsummon(); + } + + void SendWeather(WeatherState weather, float grade) const + { + WorldPacket data(SMSG_WEATHER, 9); + data << uint32(weather); + data << float(grade); + data << uint8(0); + SendPacketToPlayers(&data); + } + + // Send packet to all players in Tomb of the Earthrager + void SendPacketToPlayers(WorldPacket const* data) const + { + Map::PlayerList const& players = me->GetMap()->GetPlayers(); + if (!players.isEmpty()) + for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) + if (Player* player = itr->GetSource()) + if (player->GetAreaId() == AREA_TOMB_OF_THE_EARTHRAGER) + player->GetSession()->SendPacket(data); + } + + void Reset() override + { + _summonDeaths = 0; + _hasDispersed = false; + Cleanup(); + _Reset(); + events.SetPhase(PHASE_NORMAL); + events.ScheduleEvent(EVENT_RAGING_SMASH, urand(7000, 12000), 0, PHASE_NORMAL); + events.ScheduleEvent(EVENT_FLAME_BOLT, 15000, 0, PHASE_NORMAL); + events.ScheduleEvent(EVENT_EARTH_SPIKE, urand(16000, 21000), 0, PHASE_NORMAL); + } + + void DamageTaken(Unit* /*attacker*/, uint32& damage) override + { + if (me->HealthBelowPctDamaged(50, damage) && (events.GetPhaseMask() & PHASE_MASK_NORMAL) && !_hasDispersed) + { + events.SetPhase(PHASE_DISPERSE); + _hasDispersed = true; + + me->AttackStop(); + DoCast(me, SPELL_SANDSTORM); + SendWeather(WEATHER_STATE_LIGHT_SANDSTORM, 1.0f); + events.ScheduleEvent(EVENT_PTAH_EXPLODE, 6000, 0, PHASE_DISPERSE); + events.ScheduleEvent(EVENT_QUICKSAND, 10000, 0, PHASE_DISPERSE); + + std::list<Creature*> stalkers; + GetCreatureListWithEntryInGrid(stalkers, me, NPC_BEETLE_STALKER, 100.0f); + std::list<Creature*> beetlers = stalkers; + + Trinity::Containers::RandomResizeList(beetlers, 9); // Holds the summoners of Jeweled Scarab + + for (std::list<Creature*>::iterator itr = beetlers.begin(); itr != beetlers.end(); ++itr) + { + stalkers.remove((*itr)); // Remove it to prevent a single trigger from spawning multiple npcs. + (*itr)->CastSpell((*itr), SPELL_BEETLE_BURROW); // Cast visual + // Summon after 5 seconds. + (*itr)->m_Events.AddEvent(new SummonScarab((*itr), instance), (*itr)->m_Events.CalculateTime(5000)); + } + + Trinity::Containers::RandomResizeList(stalkers, 2); // Holds the summoners of Dustbone Horror + + for (std::list<Creature*>::iterator itr = stalkers.begin(); itr != stalkers.end(); ++itr) + (*itr)->CastSpell((*itr), SPELL_SUMMON_DUSTBONE_HORROR); + } + } + + void SetData(uint32 index, uint32 /*value*/) override + { + if (index == DATA_SUMMON_DEATHS) + { + ++_summonDeaths; + if (_summonDeaths == 11) // All summons died + { + SendWeather(WEATHER_STATE_FOG, 0.0f); + me->RemoveAurasDueToSpell(SPELL_PTAH_EXPLOSION); + events.SetPhase(PHASE_NORMAL); + events.ScheduleEvent(EVENT_RAGING_SMASH, urand(7000, 12000), 0, PHASE_NORMAL); + events.ScheduleEvent(EVENT_FLAME_BOLT, 15000, 0, PHASE_NORMAL); + events.ScheduleEvent(EVENT_EARTH_SPIKE, urand(16000, 21000), 0, PHASE_NORMAL); + } + } + } + + void EnterCombat(Unit* /*who*/) override + { + instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, 1); + Talk(SAY_AGGRO); + _EnterCombat(); + } + + void JustDied(Unit* /*killer*/) override + { + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); + Talk(SAY_DEATH); + _JustDied(); + Cleanup(); + } + + void JustReachedHome() override + { + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); + _JustReachedHome(); + instance->SetBossState(DATA_EARTHRAGER_PTAH, FAIL); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim() || !CheckInRoom()) + return; + + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_RAGING_SMASH: + DoCastVictim(SPELL_RAGING_SMASH); + events.ScheduleEvent(EVENT_RAGING_SMASH, urand(7000, 12000), 0, PHASE_NORMAL); + break; + case EVENT_FLAME_BOLT: + DoCast(me, SPELL_FLAME_BOLT); + events.ScheduleEvent(EVENT_FLAME_BOLT, 15000, 0, PHASE_NORMAL); + break; + case EVENT_EARTH_SPIKE: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true)) + DoCast(target, SPELL_EARTH_SPIKE_WARN); + events.ScheduleEvent(EVENT_EARTH_SPIKE, urand(16000, 21000), 0, PHASE_NORMAL); + break; + case EVENT_PTAH_EXPLODE: + DoCast(me, SPELL_PTAH_EXPLOSION); + break; + case EVENT_QUICKSAND: + // Spell not in DBC, it is not cast either, according to sniffs + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true)) + if (Creature* quicksand = me->SummonCreature(NPC_QUICKSAND, *target)) + quicksand->SetUInt32Value(UNIT_CREATED_BY_SPELL, SPELL_SUMMON_QUICKSAND); + events.ScheduleEvent(EVENT_QUICKSAND, 10000, 0, PHASE_DISPERSE); + break; + } + } + + if (events.GetPhaseMask() & PHASE_MASK_NORMAL) // Do not melee in the disperse phase + DoMeleeAttackIfReady(); + } + + protected: + uint8 _summonDeaths; + bool _hasDispersed; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetHallsOfOriginationAI<boss_earthrager_ptahAI>(creature); + } +}; + +class spell_earthrager_ptah_flame_bolt : public SpellScriptLoader +{ + public: + spell_earthrager_ptah_flame_bolt() : SpellScriptLoader("spell_earthrager_ptah_flame_bolt") { } + + class spell_earthrager_ptah_flame_bolt_SpellScript : public SpellScript + { + PrepareSpellScript(spell_earthrager_ptah_flame_bolt_SpellScript); + + void FilterTargets(std::list<WorldObject*>& targets) + { + Trinity::Containers::RandomResizeList(targets, GetCaster()->GetMap()->IsHeroic() ? 3 : 2); + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_earthrager_ptah_flame_bolt_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_earthrager_ptah_flame_bolt_SpellScript(); + } +}; + +class spell_earthrager_ptah_explosion : public SpellScriptLoader +{ +public: + spell_earthrager_ptah_explosion() : SpellScriptLoader("spell_earthrager_ptah_explosion") { } + + class spell_earthrager_ptah_explosion_AuraScript : public AuraScript + { + PrepareAuraScript(spell_earthrager_ptah_explosion_AuraScript); + + void SetFlags(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Unit* ptah = GetCaster()) + { + ptah->SetFlag(UNIT_FIELD_FLAGS, uint32(UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_UNK_29 | UNIT_FLAG_UNK_31)); + ptah->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH); + } + } + + void RemoveFlags(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Unit* ptah = GetCaster()) + { + ptah->RemoveFlag(UNIT_FIELD_FLAGS, uint32(UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_UNK_29 | UNIT_FLAG_UNK_31)); + ptah->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH); + } + } + + void Register() + { + OnEffectApply += AuraEffectApplyFn(spell_earthrager_ptah_explosion_AuraScript::SetFlags, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + OnEffectRemove += AuraEffectRemoveFn(spell_earthrager_ptah_explosion_AuraScript::RemoveFlags, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_earthrager_ptah_explosion_AuraScript(); + } +}; + +void AddSC_boss_earthrager_ptah() +{ + new boss_earthrager_ptah(); + new spell_earthrager_ptah_flame_bolt(); + new spell_earthrager_ptah_explosion(); +} diff --git a/src/server/scripts/Kalimdor/HallsOfOrigination/boss_temple_guardian_anhuur.cpp b/src/server/scripts/Kalimdor/HallsOfOrigination/boss_temple_guardian_anhuur.cpp new file mode 100644 index 00000000000..7aed7a66a00 --- /dev/null +++ b/src/server/scripts/Kalimdor/HallsOfOrigination/boss_temple_guardian_anhuur.cpp @@ -0,0 +1,404 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * 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/>. + */ + +#include "ObjectMgr.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "SpellScript.h" +#include "SpellAuraEffects.h" +#include "GridNotifiers.h" +#include "Player.h" +#include "halls_of_origination.h" + +enum Texts +{ + SAY_AGGRO = 0, + SAY_SHIELD = 1, + EMOTE_SHIELD = 2, + EMOTE_UNSHIELD = 3, + SAY_KILL = 4, + SAY_DEATH = 5 +}; + +enum Events +{ + EVENT_DIVINE_RECKONING = 1, + EVENT_BURNING_LIGHT = 2, + EVENT_SEAR = 3, +}; + +enum Spells +{ + SPELL_DIVINE_RECKONING = 75592, + SPELL_BURNING_LIGHT = 75115, + SPELL_REVERBERATING_HYMN = 75322, + SPELL_SHIELD_OF_LIGHT = 74938, + + SPELL_ACTIVATE_BEACONS = 76599, + SPELL_TELEPORT = 74969, + + SPELL_SHIELD_VISUAL_RIGHT = 83698, + SPELL_BEAM_OF_LIGHT_RIGHT = 76573, + + SPELL_SHIELD_VISUAL_LEFT = 83697, + SPELL_BEAM_OF_LIGHT_LEFT = 74930, + + SPELL_SEARING_LIGHT = 75194, +}; + +enum Phases +{ + PHASE_SHIELDED = 0, + PHASE_FIRST_SHIELD = 1, // Ready to be shielded for the first time + PHASE_SECOND_SHIELD = 2, // First shield already happened, ready to be shielded a second time + PHASE_FINAL = 3 // Already shielded twice, ready to finish the encounter normally. +}; + +enum Actions +{ + ACTION_DISABLE_BEACON, +}; + +class boss_temple_guardian_anhuur : public CreatureScript +{ +public: + boss_temple_guardian_anhuur() : CreatureScript("boss_temple_guardian_anhuur") { } + + struct boss_temple_guardian_anhuurAI : public BossAI + { + boss_temple_guardian_anhuurAI(Creature* creature) : BossAI(creature, DATA_TEMPLE_GUARDIAN_ANHUUR) { } + + void CleanStalkers() + { + std::list<Creature*> stalkers; + GetCreatureListWithEntryInGrid(stalkers, me, NPC_CAVE_IN_STALKER, 100.0f); + for (std::list<Creature*>::iterator itr = stalkers.begin(); itr != stalkers.end(); ++itr) + { + (*itr)->RemoveAurasDueToSpell(SPELL_BEAM_OF_LIGHT_RIGHT); + (*itr)->RemoveAurasDueToSpell(SPELL_BEAM_OF_LIGHT_LEFT); + } + } + + void Reset() override + { + _phase = PHASE_FIRST_SHIELD; + _oldPhase = PHASE_FIRST_SHIELD; + _beacons = 0; + _Reset(); + CleanStalkers(); + me->RemoveAurasDueToSpell(SPELL_SHIELD_OF_LIGHT); + events.ScheduleEvent(EVENT_DIVINE_RECKONING, urand(10000, 12000)); + events.ScheduleEvent(EVENT_BURNING_LIGHT, 12000); + } + + void DamageTaken(Unit* /*attacker*/, uint32& damage) override + { + if ((me->HealthBelowPctDamaged(66, damage) && _phase == PHASE_FIRST_SHIELD) || + (me->HealthBelowPctDamaged(33, damage) && _phase == PHASE_SECOND_SHIELD)) + { + _beacons = 2; + _phase++; // Increase the phase + _oldPhase = _phase; + + _phase = PHASE_SHIELDED; + + me->InterruptNonMeleeSpells(true); + me->AttackStop(); + DoCast(me, SPELL_TELEPORT); + + DoCast(me, SPELL_SHIELD_OF_LIGHT); + me->SetFlag(UNIT_FIELD_FLAGS, uint32(UNIT_FLAG_UNK_31)); + + DoCastAOE(SPELL_ACTIVATE_BEACONS); + + std::list<Creature*> stalkers; + GameObject* door = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_ANHUUR_DOOR)); + GetCreatureListWithEntryInGrid(stalkers, me, NPC_CAVE_IN_STALKER, 100.0f); + + stalkers.remove_if(Trinity::HeightDifferenceCheck(door, 0.0f, false)); // Target only the bottom ones + for (std::list<Creature*>::iterator itr = stalkers.begin(); itr != stalkers.end(); ++itr) + { + if ((*itr)->GetPositionX() > door->GetPositionX()) + { + (*itr)->CastSpell((*itr), SPELL_SHIELD_VISUAL_LEFT, true); + (*itr)->CastSpell((*itr), SPELL_BEAM_OF_LIGHT_LEFT, true); + } + else + { + (*itr)->CastSpell((*itr), SPELL_SHIELD_VISUAL_RIGHT, true); + (*itr)->CastSpell((*itr), SPELL_BEAM_OF_LIGHT_RIGHT, true); + } + } + + DoCast(me, SPELL_REVERBERATING_HYMN); + + Talk(EMOTE_SHIELD); + Talk(SAY_SHIELD); + } + } + + void DoAction(int32 action) override + { + if (action == ACTION_DISABLE_BEACON) + { + --_beacons; + if (!_beacons) + { + me->RemoveAurasDueToSpell(SPELL_SHIELD_OF_LIGHT); + Talk(EMOTE_UNSHIELD); + _phase = _oldPhase; + } + } + } + + void EnterCombat(Unit* /*who*/) override + { + instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, 1); + Talk(SAY_AGGRO); + _EnterCombat(); + } + + void JustDied(Unit* /*killer*/) override + { + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); + Talk(SAY_DEATH); + _JustDied(); + } + + void KilledUnit(Unit* victim) override + { + if (victim->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_KILL); + } + + void JustReachedHome() override + { + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); + _JustReachedHome(); + instance->SetBossState(DATA_TEMPLE_GUARDIAN_ANHUUR, FAIL); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim() || !CheckInRoom() || me->GetCurrentSpell(CURRENT_CHANNELED_SPELL) || _phase == PHASE_SHIELDED) + return; + + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_DIVINE_RECKONING: + DoCastVictim(SPELL_DIVINE_RECKONING); + events.ScheduleEvent(EVENT_DIVINE_RECKONING, urand(10000, 12000)); + break; + case EVENT_BURNING_LIGHT: + { + Unit* unit = SelectTarget(SELECT_TARGET_RANDOM, 0, NonTankTargetSelector(me)); + if (!unit) + unit = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true); + DoCast(unit, SPELL_BURNING_LIGHT); + events.ScheduleEvent(EVENT_SEAR, 2000); + events.ScheduleEvent(EVENT_BURNING_LIGHT, 12000); + break; + } + case EVENT_SEAR: + { + Unit* target = me->FindNearestCreature(NPC_SEARING_LIGHT, 100.0f); + if (!target) + break; + + std::list<Creature*> stalkers; + GetCreatureListWithEntryInGrid(stalkers, me, NPC_CAVE_IN_STALKER, 100.0f); + stalkers.remove_if(Trinity::HeightDifferenceCheck(ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_ANHUUR_DOOR)), 5.0f, true)); + + if (stalkers.empty()) + break; + + stalkers.sort(Trinity::ObjectDistanceOrderPred(target)); + + // Get the closest statue face (any of its eyes) + Creature* eye1 = stalkers.front(); + stalkers.remove(eye1); // Remove the eye. + stalkers.sort(Trinity::ObjectDistanceOrderPred(eye1)); // Find the second eye. + Creature* eye2 = stalkers.front(); + + eye1->CastSpell(eye1, SPELL_SEARING_LIGHT, true); + eye2->CastSpell(eye2, SPELL_SEARING_LIGHT, true); + break; + } + } + } + + DoMeleeAttackIfReady(); + } + + private: + uint8 _phase; + uint8 _oldPhase; + uint8 _beacons; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetHallsOfOriginationAI<boss_temple_guardian_anhuurAI>(creature); + } +}; + +class spell_anhuur_shield_of_light : public SpellScriptLoader +{ + public: + spell_anhuur_shield_of_light() : SpellScriptLoader("spell_anhuur_shield_of_light") { } + + class spell_anhuur_shield_of_light_SpellScript : public SpellScript + { + PrepareSpellScript(spell_anhuur_shield_of_light_SpellScript); + + void FilterTargets(std::list<WorldObject*>& targets) + { + if (InstanceMap* instance = GetCaster()->GetMap()->ToInstanceMap()) + { + if (InstanceScript* const script = instance->GetInstanceScript()) + { + if (GameObject* go = ObjectAccessor::GetGameObject(*GetCaster(), script->GetData64(DATA_ANHUUR_DOOR))) + { + targets.remove_if(Trinity::HeightDifferenceCheck(go, 5.0f, false)); + targets.remove(GetCaster()); + targets.sort(Trinity::ObjectDistanceOrderPred(GetCaster())); + targets.resize(2); + } + } + } + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_anhuur_shield_of_light_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENTRY); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_anhuur_shield_of_light_SpellScript(); + } +}; + +class spell_anhuur_disable_beacon_beams : public SpellScriptLoader +{ + public: + spell_anhuur_disable_beacon_beams() : SpellScriptLoader("spell_anhuur_disable_beacon_beams") { } + + class spell_anhuur_disable_beacon_beams_SpellScript : public SpellScript + { + PrepareSpellScript(spell_anhuur_disable_beacon_beams_SpellScript); + + void HandleScript(SpellEffIndex /*effIndex*/) + { + GetHitUnit()->RemoveAurasDueToSpell(GetEffectValue()); + } + + void Notify(SpellEffIndex /*index*/) + { + if (InstanceMap* instance = GetCaster()->GetMap()->ToInstanceMap()) + if (InstanceScript* const script = instance->GetInstanceScript()) + if (Creature* anhuur = instance->GetCreature(script->GetData64(DATA_ANHUUR_GUID))) + anhuur->AI()->DoAction(ACTION_DISABLE_BEACON); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_anhuur_disable_beacon_beams_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHit += SpellEffectFn(spell_anhuur_disable_beacon_beams_SpellScript::Notify, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_anhuur_disable_beacon_beams_SpellScript(); + } +}; + +class spell_anhuur_activate_beacons : public SpellScriptLoader +{ + public: + spell_anhuur_activate_beacons() : SpellScriptLoader("spell_anhuur_activate_beacons") { } + + class spell_anhuur_activate_beacons_SpellScript : public SpellScript + { + PrepareSpellScript(spell_anhuur_activate_beacons_SpellScript); + + void Activate(SpellEffIndex index) + { + PreventHitDefaultEffect(index); + GetHitGObj()->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_anhuur_activate_beacons_SpellScript::Activate, EFFECT_0, SPELL_EFFECT_ACTIVATE_OBJECT); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_anhuur_activate_beacons_SpellScript(); + } +}; + +class spell_anhuur_divine_reckoning : public SpellScriptLoader +{ +public: + spell_anhuur_divine_reckoning() : SpellScriptLoader("spell_anhuur_divine_reckoning") { } + + class spell_anhuur_divine_reckoning_AuraScript : public AuraScript + { + PrepareAuraScript(spell_anhuur_divine_reckoning_AuraScript); + + void OnPeriodic(AuraEffect const* aurEff) + { + if (Unit* caster = GetCaster()) + { + CustomSpellValues values; + values.AddSpellMod(SPELLVALUE_BASE_POINT0, aurEff->GetAmount()); + caster->CastCustomSpell(GetSpellInfo()->Effects[EFFECT_0].TriggerSpell, values, GetTarget()); + } + } + + void Register() + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_anhuur_divine_reckoning_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_anhuur_divine_reckoning_AuraScript(); + } +}; + +void AddSC_boss_temple_guardian_anhuur() +{ + new boss_temple_guardian_anhuur(); + new spell_anhuur_shield_of_light(); + new spell_anhuur_disable_beacon_beams(); + new spell_anhuur_activate_beacons(); + new spell_anhuur_divine_reckoning(); +} diff --git a/src/server/scripts/Kalimdor/HallsOfOrigination/halls_of_origination.h b/src/server/scripts/Kalimdor/HallsOfOrigination/halls_of_origination.h new file mode 100644 index 00000000000..b4022baaadc --- /dev/null +++ b/src/server/scripts/Kalimdor/HallsOfOrigination/halls_of_origination.h @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * 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/>. + */ + +#ifndef HALLS_OF_ORIGINATION_H +#define HALLS_OF_ORIGINATION_H + +#define HoOScriptName "instance_halls_of_origination" + +uint32 const EncounterCount = 12; + +enum Data +{ + // Bosses + DATA_TEMPLE_GUARDIAN_ANHUUR, + DATA_EARTHRAGER_PTAH, + DATA_VAULT_OF_LIGHTS, + DATA_FIRE_WARDEN, + DATA_EARTH_WARDEN, + DATA_WATER_WARDEN, + DATA_AIR_WARDEN, + DATA_ANRAPHET, + DATA_ISISET, + DATA_AMMUNAE, + DATA_SETESH, + DATA_RAJH, + + // Temple Guardian Anhuur + DATA_ANHUUR_GUID, + DATA_ANHUUR_LEFT_BEACON, + DATA_ANHUUR_RIGHT_BEACON, + DATA_ANHUUR_BRIDGE, + DATA_ANHUUR_DOOR, + + // Anraphet + DATA_BRANN_0_GUID, + DATA_DEAD_ELEMENTALS, + DATA_ANRAPHET_GUID, +}; + +enum Creatures +{ + BOSS_TEMPLE_GUARDIAN_ANHUUR = 39425, + NPC_CAVE_IN_STALKER = 40183, + NPC_SEARING_LIGHT = 40283, + + BOSS_EARTHRAGER_PTAH = 39428, + NPC_BEETLE_STALKER = 40459, // Summons both Jeweled Scarab and Dustbone Horror + NPC_JEWELED_SCARAB = 40458, + NPC_DUSTBONE_HORROR = 40450, + NPC_QUICKSAND = 40503, // Summoned by a spell not in dbc (75550) + + BOSS_ANRAPHET = 39788, + NPC_FIRE_WARDEN = 39800, + NPC_EARTH_WARDEN = 39801, + NPC_WATER_WARDEN = 39802, + NPC_AIR_WARDEN = 39803, + + WARDEN_ENTRY_DATA_DELTA = NPC_FIRE_WARDEN - DATA_FIRE_WARDEN, + + NPC_BRANN_BRONZEBEARD_0 = 39908, + NPC_OMEGA_STANCE = 41194, +}; + +enum GameObjects +{ + GO_ANHUURS_BRIDGE = 206506, + GO_DOODAD_ULDUM_ELEVATOR_COL01 = 207725, + GO_ANHUURS_DOOR = 202307, + GO_ANHUURS_RIGHT_BEACON = 203136, + GO_ANHUURS_LEFT_BEACON = 203133, + + GO_VAULT_OF_LIGHTS_DOOR = 202313, + GO_SUN_MIRROR = 207726, + GO_ANRAPHET_DOOR = 202314, + + GO_DOODAD_ULDUM_LIGHTMACHINE_01 = 207375, + GO_DOODAD_ULDUM_LIGHTMACHINE_02 = 207374, + GO_DOODAD_ULDUM_LIGHTMACHINE_03 = 207377, + GO_DOODAD_ULDUM_LIGHTMACHINE_04 = 207376, + + GO_DOODAD_ULDUM_LASERBEAMS01 = 207662, // Matches GO_DOODAD_ULDUM_LIGHTMACHINE_02 + GO_DOODAD_ULDUM_LASERBEAMS_01 = 207663, // Matches GO_DOODAD_ULDUM_LIGHTMACHINE_01 + GO_DOODAD_ULDUM_LASERBEAMS_02 = 207664, // Matches GO_DOODAD_ULDUM_LIGHTMACHINE_04 + GO_DOODAD_ULDUM_LASERBEAMS_03 = 207665, // Matches GO_DOODAD_ULDUM_LIGHTMACHINE_03 +}; + +enum Misc +{ + AREA_TOMB_OF_THE_EARTHRAGER = 5610, + ACHIEV_VAULT_OF_LIGHTS_EVENT = 24212, // Faster Than The Speed Of Light + SPELL_VAULT_OF_LIGHTS_CREDIT = 94067, // Not in DBC +}; + +enum GlobalActions +{ + ACTION_ANRAPHET_INTRO, + ACTION_ELEMENTAL_DIED, + ACTION_ANRAPHET_DIED, + ACTION_OMEGA_TRIGGER, +}; + +template<class AI> +CreatureAI* GetHallsOfOriginationAI(Creature* creature) +{ + if (InstanceMap* instance = creature->GetMap()->ToInstanceMap()) + if (instance->GetInstanceScript()) + if (instance->GetScriptId() == sObjectMgr->GetScriptId(HoOScriptName)) + return new AI(creature); + return NULL; +} + +#endif // HALLS_OF_ORIGINATION_H diff --git a/src/server/scripts/Kalimdor/HallsOfOrigination/instance_halls_of_origination.cpp b/src/server/scripts/Kalimdor/HallsOfOrigination/instance_halls_of_origination.cpp new file mode 100644 index 00000000000..a8c1c4f6108 --- /dev/null +++ b/src/server/scripts/Kalimdor/HallsOfOrigination/instance_halls_of_origination.cpp @@ -0,0 +1,282 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * 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/>. + */ + +#include "ObjectMgr.h" +#include "ScriptMgr.h" +#include "InstanceScript.h" +#include "ScriptedCreature.h" +#include "Map.h" +#include "PoolMgr.h" +#include "AccountMgr.h" +#include "halls_of_origination.h" +#include "Player.h" +#include "WorldPacket.h" +#include "WorldSession.h" + +DoorData const doorData[] = +{ + {GO_ANHUURS_DOOR, DATA_TEMPLE_GUARDIAN_ANHUUR, DOOR_TYPE_PASSAGE, BOUNDARY_NONE }, + {GO_ANHUURS_BRIDGE, DATA_TEMPLE_GUARDIAN_ANHUUR, DOOR_TYPE_PASSAGE, BOUNDARY_NONE }, + {GO_DOODAD_ULDUM_ELEVATOR_COL01, DATA_TEMPLE_GUARDIAN_ANHUUR, DOOR_TYPE_PASSAGE, BOUNDARY_NONE }, + {GO_VAULT_OF_LIGHTS_DOOR, DATA_VAULT_OF_LIGHTS, DOOR_TYPE_PASSAGE, BOUNDARY_NONE }, + {GO_DOODAD_ULDUM_LIGHTMACHINE_02, DATA_EARTH_WARDEN, DOOR_TYPE_PASSAGE, BOUNDARY_NONE }, + {GO_DOODAD_ULDUM_LASERBEAMS01, DATA_EARTH_WARDEN, DOOR_TYPE_PASSAGE, BOUNDARY_NONE }, + {GO_DOODAD_ULDUM_LIGHTMACHINE_01, DATA_FIRE_WARDEN, DOOR_TYPE_PASSAGE, BOUNDARY_NONE }, + {GO_DOODAD_ULDUM_LASERBEAMS_01, DATA_FIRE_WARDEN, DOOR_TYPE_PASSAGE, BOUNDARY_NONE }, + {GO_DOODAD_ULDUM_LIGHTMACHINE_03, DATA_WATER_WARDEN, DOOR_TYPE_PASSAGE, BOUNDARY_NONE }, + {GO_DOODAD_ULDUM_LASERBEAMS_03, DATA_WATER_WARDEN, DOOR_TYPE_PASSAGE, BOUNDARY_NONE }, + {GO_DOODAD_ULDUM_LIGHTMACHINE_04, DATA_AIR_WARDEN, DOOR_TYPE_PASSAGE, BOUNDARY_NONE }, + {GO_DOODAD_ULDUM_LASERBEAMS_02, DATA_AIR_WARDEN, DOOR_TYPE_PASSAGE, BOUNDARY_NONE }, + {0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } +}; + +class instance_halls_of_origination : public InstanceMapScript +{ + public: + instance_halls_of_origination() : InstanceMapScript(HoOScriptName, 644) { } + + struct instance_halls_of_origination_InstanceMapScript : public InstanceScript + { + instance_halls_of_origination_InstanceMapScript(InstanceMap* map) : InstanceScript(map) + { + SetBossNumber(EncounterCount); + LoadDoorData(doorData); + TempleGuardianAnhuurGUID = 0; + AnhuursBridgeGUID = 0; + AnhuursDoorGUID = 0; + AnhuurRightBeaconGUID = 0; + AnhuurLeftBeaconGUID = 0; + BrannBronzebeardGUID = 0; + AnraphetGUID = 0; + AnraphetDoorGUID = 0; + SunMirrorGUID = 0; + _deadElementals = 0; + } + + void OnGameObjectCreate(GameObject* go) override + { + switch (go->GetEntry()) + { + case GO_ANHUURS_BRIDGE: + AnhuursBridgeGUID = go->GetGUID(); + case GO_DOODAD_ULDUM_ELEVATOR_COL01: + case GO_VAULT_OF_LIGHTS_DOOR: + case GO_DOODAD_ULDUM_LIGHTMACHINE_01: + case GO_DOODAD_ULDUM_LIGHTMACHINE_02: + case GO_DOODAD_ULDUM_LIGHTMACHINE_03: + case GO_DOODAD_ULDUM_LIGHTMACHINE_04: + case GO_DOODAD_ULDUM_LASERBEAMS01: + case GO_DOODAD_ULDUM_LASERBEAMS_01: + case GO_DOODAD_ULDUM_LASERBEAMS_02: + case GO_DOODAD_ULDUM_LASERBEAMS_03: + AddDoor(go, true); + break; + case GO_ANHUURS_DOOR: + AnhuursDoorGUID = go->GetGUID(); + AddDoor(go, true); + break; + case GO_ANHUURS_RIGHT_BEACON: + AnhuurRightBeaconGUID = go->GetGUID(); + break; + case GO_ANHUURS_LEFT_BEACON: + AnhuurLeftBeaconGUID = go->GetGUID(); + break; + case GO_SUN_MIRROR: + SunMirrorGUID = go->GetGUID(); + break; + case GO_ANRAPHET_DOOR: + AnraphetDoorGUID = go->GetGUID(); + break; + } + } + + void OnGameObjectRemove(GameObject* go) override + { + switch (go->GetEntry()) + { + case GO_ANHUURS_BRIDGE: + case GO_DOODAD_ULDUM_ELEVATOR_COL01: + case GO_ANHUURS_DOOR: + case GO_VAULT_OF_LIGHTS_DOOR: + case GO_DOODAD_ULDUM_LIGHTMACHINE_01: + case GO_DOODAD_ULDUM_LIGHTMACHINE_02: + case GO_DOODAD_ULDUM_LIGHTMACHINE_03: + case GO_DOODAD_ULDUM_LIGHTMACHINE_04: + case GO_DOODAD_ULDUM_LASERBEAMS01: + case GO_DOODAD_ULDUM_LASERBEAMS_01: + case GO_DOODAD_ULDUM_LASERBEAMS_02: + case GO_DOODAD_ULDUM_LASERBEAMS_03: + AddDoor(go, false); + break; + } + } + + void OnCreatureCreate(Creature* creature) override + { + switch (creature->GetEntry()) + { + case BOSS_TEMPLE_GUARDIAN_ANHUUR: + TempleGuardianAnhuurGUID = creature->GetGUID(); + break; + case NPC_BRANN_BRONZEBEARD_0: + BrannBronzebeardGUID = creature->GetGUID(); + break; + case BOSS_ANRAPHET: + AnraphetGUID = creature->GetGUID(); + break; + } + } + + uint32 GetData(uint32 data) const override + { + switch (data) + { + case DATA_DEAD_ELEMENTALS: + return _deadElementals; + default: + break; + } + + return 0; + } + + uint64 GetData64(uint32 index) const override + { + switch (index) + { + case DATA_ANHUUR_BRIDGE: + return AnhuursBridgeGUID; + case DATA_ANHUUR_DOOR: + return AnhuursDoorGUID; + case DATA_ANHUUR_LEFT_BEACON: + return AnhuurLeftBeaconGUID; + case DATA_ANHUUR_RIGHT_BEACON: + return AnhuurRightBeaconGUID; + case DATA_ANHUUR_GUID: + return TempleGuardianAnhuurGUID; + case DATA_BRANN_0_GUID: + return BrannBronzebeardGUID; + case DATA_ANRAPHET_GUID: + return AnraphetGUID; + } + + return 0; + } + + void IncreaseDeadElementals(uint32 inc) + { + _deadElementals += inc; + if (_deadElementals == 4) + { + if (GameObject* mirror = instance->GetGameObject(SunMirrorGUID)) + mirror->SetGoState(GO_STATE_ACTIVE); + if (GameObject* door = instance->GetGameObject(AnraphetDoorGUID)) + door->SetGoState(GO_STATE_ACTIVE); + } + } + + void OnUnitDeath(Unit* unit) override + { + Creature* creature = unit->ToCreature(); + if (!creature) + return; + + switch (creature->GetEntry()) + { + case NPC_FIRE_WARDEN: + case NPC_EARTH_WARDEN: + case NPC_WATER_WARDEN: + case NPC_AIR_WARDEN: + uint32 data = creature->GetEntry() - WARDEN_ENTRY_DATA_DELTA; + SetBossState(data, IN_PROGRESS); // Needs to be set to IN_PROGRESS or else the gameobjects state won't be updated + SetBossState(data, DONE); + IncreaseDeadElementals(1); + if (Creature* brann = instance->GetCreature(BrannBronzebeardGUID)) + brann->AI()->DoAction(ACTION_ELEMENTAL_DIED); + break; + } + } + + std::string GetSaveData() override + { + OUT_SAVE_INST_DATA; + + std::ostringstream saveStream; + saveStream << "H O " << GetBossSaveData() << _deadElementals; + + OUT_SAVE_INST_DATA_COMPLETE; + return saveStream.str(); + } + + void Load(const char* str) override + { + if (!str) + { + OUT_LOAD_INST_DATA_FAIL; + return; + } + + OUT_LOAD_INST_DATA(str); + + char dataHead1, dataHead2; + + std::istringstream loadStream(str); + loadStream >> dataHead1 >> dataHead2; + + if (dataHead1 == 'H' && dataHead2 == 'O') + { + for (uint32 i = 0; i < EncounterCount; ++i) + { + uint32 tmpState; + loadStream >> tmpState; + if (tmpState == IN_PROGRESS || tmpState > SPECIAL) + tmpState = NOT_STARTED; + SetBossState(i, EncounterState(tmpState)); + } + uint32 tmp; + loadStream >> tmp; + IncreaseDeadElementals(tmp); + } + else + OUT_LOAD_INST_DATA_FAIL; + + OUT_LOAD_INST_DATA_COMPLETE; + } + + protected: + uint64 TempleGuardianAnhuurGUID; + uint64 AnhuursBridgeGUID; + uint64 AnhuursDoorGUID; + uint64 AnhuurRightBeaconGUID; + uint64 AnhuurLeftBeaconGUID; + uint64 BrannBronzebeardGUID; + uint64 AnraphetGUID; + uint64 AnraphetDoorGUID; + uint64 SunMirrorGUID; + uint32 _deadElementals; + }; + + InstanceScript* GetInstanceScript(InstanceMap* map) const override + { + return new instance_halls_of_origination_InstanceMapScript(map); + } +}; + +void AddSC_instance_halls_of_origination() +{ + new instance_halls_of_origination(); +} diff --git a/src/server/scripts/Kalimdor/boss_azuregos.cpp b/src/server/scripts/Kalimdor/boss_azuregos.cpp deleted file mode 100644 index db41213e94e..00000000000 --- a/src/server/scripts/Kalimdor/boss_azuregos.cpp +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> - * - * 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/>. - */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "SpellScript.h" -#include "SpellAuraEffects.h" -#include "Player.h" - -enum Say -{ - SAY_TELEPORT = 0 -}; - -enum Spells -{ - SPELL_MARK_OF_FROST = 23182, - SPELL_AURA_OF_FROST = 23186, - SPELL_MARK_OF_FROST_AURA = 23184, - SPELL_MANA_STORM = 21097, - SPELL_CHILL = 21098, - SPELL_FROST_BREATH = 21099, - SPELL_REFLECT = 22067, - SPELL_CLEAVE = 8255, // Perhaps not right ID - SPELL_ENRAGE = 23537 -}; - -enum Events -{ - EVENT_MARK_OF_FROST = 1, - EVENT_MANA_STORM, - EVENT_CHILL, - EVENT_BREATH, - EVENT_TELEPORT, - EVENT_REFLECT, - EVENT_CLEAVE, - EVENT_ENRAGE -}; - -class boss_azuregos : public CreatureScript -{ - public: - boss_azuregos() : CreatureScript("boss_azuregos") { } - - struct boss_azuregosAI : public WorldBossAI - { - boss_azuregosAI(Creature* creature) : WorldBossAI(creature) { } - - void Reset() override - { - _Reset(); - } - - void EnterCombat(Unit* /*who*/) override - { - DoCast(me, SPELL_MARK_OF_FROST_AURA, true); - _enraged = false; - - events.ScheduleEvent(EVENT_MARK_OF_FROST, 35000); - events.ScheduleEvent(EVENT_MANA_STORM, urand(5000, 17000)); - events.ScheduleEvent(EVENT_CHILL, urand(10000, 30000)); - events.ScheduleEvent(EVENT_BREATH, urand(2000, 8000)); - events.ScheduleEvent(EVENT_TELEPORT, 30000); - events.ScheduleEvent(EVENT_REFLECT, urand(15000, 30000)); - events.ScheduleEvent(EVENT_CLEAVE, 7000); - } - - void KilledUnit(Unit* who) override - { - if (who->GetTypeId() == TYPEID_PLAYER) - who->CastSpell(who, SPELL_MARK_OF_FROST, true); - } - - 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_MANA_STORM: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 60.0f, true)) - DoCast(target, SPELL_MANA_STORM); - events.ScheduleEvent(EVENT_MANA_STORM, urand(7500, 12500)); - break; - case EVENT_CHILL: - DoCastVictim(SPELL_CHILL); - events.ScheduleEvent(EVENT_CHILL, urand(13000, 25000)); - break; - case EVENT_BREATH: - DoCastVictim(SPELL_FROST_BREATH); - events.ScheduleEvent(EVENT_BREATH, urand(10000, 15000)); - break; - case EVENT_TELEPORT: - { - Talk(SAY_TELEPORT); - ThreatContainer::StorageType const& threatlist = me->getThreatManager().getThreatList(); - for (ThreatContainer::StorageType::const_iterator i = threatlist.begin(); i != threatlist.end(); ++i) - { - if (Player* player = ObjectAccessor::GetPlayer(*me, (*i)->getUnitGuid())) - DoTeleportPlayer(player, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()+3, player->GetOrientation()); - } - - DoResetThreat(); - events.ScheduleEvent(EVENT_TELEPORT, 30000); - break; - } - case EVENT_REFLECT: - DoCast(me, SPELL_REFLECT); - events.ScheduleEvent(EVENT_REFLECT, urand(20000, 35000)); - break; - case EVENT_CLEAVE: - DoCastVictim(SPELL_CLEAVE); - events.ScheduleEvent(EVENT_CLEAVE, 7000); - break; - default: - break; - } - } - - if (HealthBelowPct(26) && !_enraged) - { - DoCast(me, SPELL_ENRAGE); - _enraged = true; - } - - DoMeleeAttackIfReady(); - } - - private: - bool _enraged; - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new boss_azuregosAI(creature); - } -}; - -class MarkOfFrostTargetSelector -{ - public: - MarkOfFrostTargetSelector() { } - - bool operator()(WorldObject* object) const - { - if (Unit* unit = object->ToUnit()) - return !(unit->HasAura(SPELL_MARK_OF_FROST) && !unit->HasAura(SPELL_AURA_OF_FROST)); - return true; - } -}; - -class spell_mark_of_frost : public SpellScriptLoader -{ - public: - spell_mark_of_frost() : SpellScriptLoader("spell_mark_of_frost") { } - - class spell_mark_of_frost_SpellScript : public SpellScript - { - PrepareSpellScript(spell_mark_of_frost_SpellScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - if (!sSpellMgr->GetSpellInfo(SPELL_MARK_OF_FROST)) - return false; - if (!sSpellMgr->GetSpellInfo(SPELL_AURA_OF_FROST)) - return false; - return true; - } - - void FilterTargets(std::list<WorldObject*>& targets) - { - targets.remove_if(MarkOfFrostTargetSelector()); - } - - void HandleEffect(SpellEffIndex effIndex) - { - PreventHitDefaultEffect(effIndex); - GetHitUnit()->CastSpell(GetHitUnit(), SPELL_AURA_OF_FROST, true); - } - - void Register() override - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mark_of_frost_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); - OnEffectHitTarget += SpellEffectFn(spell_mark_of_frost_SpellScript::HandleEffect, EFFECT_0, SPELL_EFFECT_APPLY_AURA); - } - }; - - SpellScript* GetSpellScript() const override - { - return new spell_mark_of_frost_SpellScript(); - } -}; - -void AddSC_boss_azuregos() -{ - new boss_azuregos(); - new spell_mark_of_frost(); -} diff --git a/src/server/scripts/Kalimdor/zone_azshara.cpp b/src/server/scripts/Kalimdor/zone_azshara.cpp index e62e17593ba..b4515da25ef 100644 --- a/src/server/scripts/Kalimdor/zone_azshara.cpp +++ b/src/server/scripts/Kalimdor/zone_azshara.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2014 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,519 +15,6 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Azshara -SD%Complete: 90 -SDComment: Quest support: 2744, 3141, 9364, 10994 -SDCategory: Azshara -EndScriptData */ - -/* ContentData -npc_spitelashes -npc_loramus_thalipedes -npc_rizzle_sprysprocket -npc_depth_charge -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "Player.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) { } - - uint32 morphtimer; - bool spellhit; - - void Reset() override - { - morphtimer = 0; - spellhit = false; - } - - void EnterCombat(Unit* /*who*/) override { } - - void SpellHit(Unit* unit, const SpellInfo* 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_loramus_thalipedes -######*/ - -#define GOSSIP_HELLO_LT1 "Can you help me?" -#define GOSSIP_HELLO_LT2 "Tell me your story" -#define GOSSIP_SELECT_LT1 "Please continue" -#define GOSSIP_SELECT_LT2 "I do not understand" -#define GOSSIP_SELECT_LT3 "Indeed" -#define GOSSIP_SELECT_LT4 "I will do this with or your help, Loramus" -#define GOSSIP_SELECT_LT5 "Yes" - -class npc_loramus_thalipedes : public CreatureScript -{ -public: - npc_loramus_thalipedes() : CreatureScript("npc_loramus_thalipedes") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF+1: - player->CLOSE_GOSSIP_MENU(); - player->AreaExploredOrEventHappens(2744); - break; - - case GOSSIP_ACTION_INFO_DEF+2: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT_LT1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 21); - player->SEND_GOSSIP_MENU(1813, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+21: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT_LT2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 22); - player->SEND_GOSSIP_MENU(1814, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+22: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT_LT3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 23); - player->SEND_GOSSIP_MENU(1815, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+23: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT_LT4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 24); - player->SEND_GOSSIP_MENU(1816, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+24: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT_LT5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 25); - player->SEND_GOSSIP_MENU(1817, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+25: - player->CLOSE_GOSSIP_MENU(); - player->AreaExploredOrEventHappens(3141); - break; - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) override - { - if (creature->IsQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(2744) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_LT1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - - if (player->GetQuestStatus(3141) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_LT2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - - return true; - } -}; - -/*#### -# npc_rizzle_sprysprocket -####*/ - -enum RizzleSprysprocketData -{ - QUEST_CHASING_THE_MOONSTONE = 10994, - - NPC_DEPTH_CHARGE = 23025, - - SPELL_RIZZLE_BLACKJACK = 39865, - SPELL_RIZZLE_ESCAPE = 39871, - SPELL_RIZZLE_FROST_GRENADE = 40525, - SPELL_DEPTH_CHARGE_TRAP = 38576, - SPELL_PERIODIC_DEPTH_CHARGE = 39912, - SPELL_GIVE_SOUTHFURY_MOONSTONE = 39886, - - SAY_RIZZLE_START = 0, - SAY_RIZZLE_GRENADE = 1, - SAY_RIZZLE_FINAL = 2, - MSG_ESCAPE_NOTICE = 3 -}; - -#define GOSSIP_GET_MOONSTONE "Hand over the Southfury moonstone and I'll let you go." - -Position const WPs[58] = -{ - {3691.97f, -3962.41f, 35.9118f, 3.67f}, - {3675.02f, -3960.49f, 35.9118f, 3.67f}, - {3653.19f, -3958.33f, 33.9118f, 3.59f}, - {3621.12f, -3958.51f, 29.9118f, 3.48f}, - {3604.86f, -3963, 29.9118f, 3.48f}, - {3569.94f, -3970.25f, 29.9118f, 3.44f}, - {3541.03f, -3975.64f, 29.9118f, 3.41f}, - {3510.84f, -3978.71f, 29.9118f, 3.41f}, - {3472.7f, -3997.07f, 29.9118f, 3.35f}, - {3439.15f, -4014.55f, 29.9118f, 3.29f}, - {3412.8f, -4025.87f, 29.9118f, 3.25f}, - {3384.95f, -4038.04f, 29.9118f, 3.24f}, - {3346.77f, -4052.93f, 29.9118f, 3.22f}, - {3299.56f, -4071.59f, 29.9118f, 3.20f}, - {3261.22f, -4080.38f, 30.9118f, 3.19f}, - {3220.68f, -4083.09f, 31.9118f, 3.18f}, - {3187.11f, -4070.45f, 33.9118f, 3.16f}, - {3162.78f, -4062.75f, 33.9118f, 3.15f}, - {3136.09f, -4050.32f, 33.9118f, 3.07f}, - {3119.47f, -4044.51f, 36.0363f, 3.07f}, - {3098.95f, -4019.8f, 33.9118f, 3.07f}, - {3073.07f, -4011.42f, 33.9118f, 3.07f}, - {3051.71f, -3993.37f, 33.9118f, 3.02f}, - {3027.52f, -3978.6f, 33.9118f, 3.00f}, - {3003.78f, -3960.14f, 33.9118f, 2.98f}, - {2977.99f, -3941.98f, 31.9118f, 2.96f}, - {2964.57f, -3932.07f, 30.9118f, 2.96f}, - {2947.9f, -3921.31f, 29.9118f, 2.96f}, - {2924.91f, -3910.8f, 29.9118f, 2.94f}, - {2903.04f, -3896.42f, 29.9118f, 2.93f}, - {2884.75f, -3874.03f, 29.9118f, 2.90f}, - {2868.19f, -3851.48f, 29.9118f, 2.82f}, - {2854.62f, -3819.72f, 29.9118f, 2.80f}, - {2825.53f, -3790.4f, 29.9118f, 2.744f}, - {2804.31f, -3773.05f, 29.9118f, 2.71f}, - {2769.78f, -3763.57f, 29.9118f, 2.70f}, - {2727.23f, -3745.92f, 30.9118f, 2.69f}, - {2680.12f, -3737.49f, 30.9118f, 2.67f}, - {2647.62f, -3739.94f, 30.9118f, 2.66f}, - {2616.6f, -3745.75f, 30.9118f, 2.64f}, - {2589.38f, -3731.97f, 30.9118f, 2.61f}, - {2562.94f, -3722.35f, 31.9118f, 2.56f}, - {2521.05f, -3716.6f, 31.9118f, 2.55f}, - {2485.26f, -3706.67f, 31.9118f, 2.51f}, - {2458.93f, -3696.67f, 31.9118f, 2.51f}, - {2432, -3692.03f, 31.9118f, 2.46f}, - {2399.59f, -3681.97f, 31.9118f, 2.45f}, - {2357.75f, -3666.6f, 31.9118f, 2.44f}, - {2311.99f, -3656.88f, 31.9118f, 2.94f}, - {2263.41f, -3649.55f, 31.9118f, 3.02f}, - {2209.05f, -3641.76f, 31.9118f, 2.99f}, - {2164.83f, -3637.64f, 31.9118f, 3.15f}, - {2122.42f, -3639, 31.9118f, 3.21f}, - {2075.73f, -3643.59f, 31.9118f, 3.22f}, - {2033.59f, -3649.52f, 31.9118f, 3.42f}, - {1985.22f, -3662.99f, 31.9118f, 3.42f}, - {1927.09f, -3679.56f, 33.9118f, 3.42f}, - {1873.57f, -3695.32f, 33.9118f, 3.44f} -}; - -class npc_rizzle_sprysprocket : public CreatureScript -{ -public: - npc_rizzle_sprysprocket() : CreatureScript("npc_rizzle_sprysprocket") { } - - struct npc_rizzle_sprysprocketAI : public ScriptedAI - { - npc_rizzle_sprysprocketAI(Creature* creature) : ScriptedAI(creature) { } - - void Reset() override - { - SpellEscapeTimer = 1300; - TeleportTimer = 3500; - CheckTimer = 10000; - GrenadeTimer = 30000; - MustDieTimer = 3000; - CurrWP = 0; - - PlayerGUID = 0; - - MustDie = false; - Escape = false; - ContinueWP = false; - Reached = false; - } - - void EnterCombat(Unit* /*who*/) override { } - - void AttackStart(Unit* who) override - { - if (!who || PlayerGUID) - return; - - Player* player = who->ToPlayer(); - - if (player && player->GetQuestStatus(QUEST_CHASING_THE_MOONSTONE) == QUEST_STATUS_INCOMPLETE) - { - PlayerGUID = who->GetGUID(); - Talk(SAY_RIZZLE_START); - DoCast(who, SPELL_RIZZLE_BLACKJACK, false); - return; - } - } - - void sGossipSelect(Player* player, uint32 /*sender*/, uint32 /*action*/) override - { - player->CLOSE_GOSSIP_MENU(); - me->CastSpell(player, SPELL_GIVE_SOUTHFURY_MOONSTONE, true); - MustDieTimer = 3000; - MustDie = true; - } - - void MovementInform(uint32 type, uint32 id) override - { - if (type != POINT_MOTION_TYPE) - return; - - if (id == 57) - { - me->DespawnOrUnsummon(); - return; - } - - ++CurrWP; - ContinueWP = true; - } - - void UpdateAI(uint32 diff) override - { - if (MustDie) - { - if (MustDieTimer <= diff) - { - me->DespawnOrUnsummon(); - return; - } else MustDieTimer -= diff; - } - - if (!Escape) - { - if (!PlayerGUID) - return; - - if (SpellEscapeTimer <= diff) - { - DoCast(me, SPELL_RIZZLE_ESCAPE, false); - SpellEscapeTimer = 10000; - } else SpellEscapeTimer -= diff; - - if (TeleportTimer <= diff) - { - // temp solution - unit can't be teleported by core using spelleffect 5, only players - DoTeleportTo(3706.39f, -3969.15f, 35.9118f); - - //begin swimming and summon depth charges - Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID); - if (!player) - return; - - Talk(MSG_ESCAPE_NOTICE, player); - DoCast(me, SPELL_PERIODIC_DEPTH_CHARGE); - me->SetHover(true); - me->SetSwim(true); - me->SetSpeed(MOVE_RUN, 0.85f, true); - me->GetMotionMaster()->MovementExpired(); - me->GetMotionMaster()->MovePoint(CurrWP, WPs[CurrWP]); - Escape = true; - } else TeleportTimer -= diff; - - return; - } - - if (ContinueWP) - { - me->GetMotionMaster()->MovePoint(CurrWP, WPs[CurrWP]); - ContinueWP = false; - } - - if (GrenadeTimer <= diff) - { - if (Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID)) - { - Talk(SAY_RIZZLE_GRENADE, player); - DoCast(player, SPELL_RIZZLE_FROST_GRENADE, true); - } - GrenadeTimer = 30000; - } else GrenadeTimer -= diff; - - if (CheckTimer <= diff) - { - Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID); - if (!player) - { - me->DespawnOrUnsummon(); - return; - } - - if (me->IsWithinDist(player, 10) && me->GetPositionX() > player->GetPositionX() && !Reached) - { - Talk(SAY_RIZZLE_FINAL); - me->SetUInt32Value(UNIT_NPC_FLAGS, 1); - me->setFaction(35); - me->GetMotionMaster()->MoveIdle(); - me->RemoveAurasDueToSpell(SPELL_PERIODIC_DEPTH_CHARGE); - Reached = true; - } - - CheckTimer = 1000; - } else CheckTimer -= diff; - } - - private: - uint64 PlayerGUID; - uint32 SpellEscapeTimer; - uint32 TeleportTimer; - uint32 CheckTimer; - uint32 GrenadeTimer; - uint32 MustDieTimer; - uint32 CurrWP; - bool MustDie; - bool Escape; - bool ContinueWP; - bool Reached; - }; - - bool OnGossipHello(Player* player, Creature* creature) override - { - if (player->GetQuestStatus(QUEST_CHASING_THE_MOONSTONE) != QUEST_STATUS_INCOMPLETE) - return true; - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_GET_MOONSTONE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - player->SEND_GOSSIP_MENU(10811, creature->GetGUID()); - return true; - } - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_rizzle_sprysprocketAI(creature); - } -}; - -/*#### -# npc_depth_charge -####*/ -class npc_depth_charge : public CreatureScript -{ -public: - npc_depth_charge() : CreatureScript("npc_depth_charge") { } - - struct npc_depth_chargeAI : public ScriptedAI - { - npc_depth_chargeAI(Creature* creature) : ScriptedAI(creature) { } - - bool WeMustDie; - uint32 WeMustDieTimer; - - void Reset() override - { - me->SetHover(true); - me->SetSwim(true); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - WeMustDie = false; - WeMustDieTimer = 1000; - } - - void EnterCombat(Unit* /*who*/) override { } - - void AttackStart(Unit* /*who*/) override { } - - void MoveInLineOfSight(Unit* who) override - { - if (!who) - return; - - if (who->GetTypeId() == TYPEID_PLAYER && me->IsWithinDistInMap(who, 5)) - { - DoCast(who, SPELL_DEPTH_CHARGE_TRAP); - WeMustDie = true; - return; - } - } - - void UpdateAI(uint32 diff) override - { - if (WeMustDie) - { - if (WeMustDieTimer <= diff) - me->DespawnOrUnsummon(); - else - WeMustDieTimer -= diff; - } - return; - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_depth_chargeAI(creature); - } -}; - void AddSC_azshara() { - new npc_spitelashes(); - new npc_loramus_thalipedes(); - 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 be70b2e9fa4..c3c1d7c146b 100644 --- a/src/server/scripts/Kalimdor/zone_azuremyst_isle.cpp +++ b/src/server/scripts/Kalimdor/zone_azuremyst_isle.cpp @@ -19,7 +19,7 @@ /* ScriptData SDName: Azuremyst_Isle SD%Complete: 75 -SDComment: Quest support: 9283, 9537, 9582, 9554, 9531, ? (special flight path, proper model for mount missing). Injured Draenei cosmetic only, 9582. +SDComment: Quest support: 9283, 9537, 9582, 9554, ? (special flight path, proper model for mount missing). Injured Draenei cosmetic only, 9582. SDCategory: Azuremyst Isle EndScriptData */ @@ -28,7 +28,6 @@ npc_draenei_survivor npc_engineer_spark_overgrind npc_injured_draenei npc_magwin -npc_geezle go_ravager_cage npc_death_ravager EndContentData */ @@ -735,7 +734,6 @@ void AddSC_azuremyst_isle() new npc_engineer_spark_overgrind(); new npc_injured_draenei(); new npc_magwin(); - new npc_geezle(); new npc_death_ravager(); new go_ravager_cage(); new npc_stillpine_capitive(); diff --git a/src/server/scripts/Kalimdor/zone_darkshore.cpp b/src/server/scripts/Kalimdor/zone_darkshore.cpp index 688dada2fc5..1799709c7af 100644 --- a/src/server/scripts/Kalimdor/zone_darkshore.cpp +++ b/src/server/scripts/Kalimdor/zone_darkshore.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2014 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,378 +15,6 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Darkshore -SD%Complete: 100 -SDComment: Quest support: 731, 2078, 5321 -SDCategory: Darkshore -EndScriptData */ - -/* ContentData -npc_kerlonian -npc_prospector_remtravel -npc_threshwackonator -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "ScriptedEscortAI.h" -#include "ScriptedFollowerAI.h" -#include "Player.h" -#include "SpellInfo.h" - -/*#### -# npc_kerlonian -####*/ - -enum Kerlonian -{ - SAY_KER_START = 0, - EMOTE_KER_SLEEP = 1, - SAY_KER_SLEEP = 2, - SAY_KER_ALERT_1 = 3, - SAY_KER_END = 4, - EMOTE_KER_AWAKEN = 5, - - SPELL_SLEEP_VISUAL = 25148, - SPELL_AWAKEN = 17536, - QUEST_SLEEPER_AWAKENED = 5321, - NPC_LILADRIS = 11219, //attackers entries unknown - FACTION_KER_ESCORTEE = 113 -}; - -/// @todo make concept similar as "ringo" -escort. Find a way to run the scripted attacks, _if_ player are choosing road. -class npc_kerlonian : public CreatureScript -{ -public: - npc_kerlonian() : CreatureScript("npc_kerlonian") { } - - struct npc_kerlonianAI : public FollowerAI - { - npc_kerlonianAI(Creature* creature) : FollowerAI(creature) { } - - uint32 FallAsleepTimer; - - void Reset() override - { - FallAsleepTimer = urand(10000, 45000); - } - - void MoveInLineOfSight(Unit* who) override - - { - FollowerAI::MoveInLineOfSight(who); - - if (!me->GetVictim() && !HasFollowState(STATE_FOLLOW_COMPLETE) && who->GetEntry() == NPC_LILADRIS) - { - if (me->IsWithinDistInMap(who, INTERACTION_DISTANCE*5)) - { - if (Player* player = GetLeaderForFollower()) - { - if (player->GetQuestStatus(QUEST_SLEEPER_AWAKENED) == QUEST_STATUS_INCOMPLETE) - player->GroupEventHappens(QUEST_SLEEPER_AWAKENED, me); - - Talk(SAY_KER_END); - } - - SetFollowComplete(); - } - } - } - - void SpellHit(Unit* /*pCaster*/, const SpellInfo* pSpell) override - { - if (HasFollowState(STATE_FOLLOW_INPROGRESS | STATE_FOLLOW_PAUSED) && pSpell->Id == SPELL_AWAKEN) - ClearSleeping(); - } - - void SetSleeping() - { - SetFollowPaused(true); - - Talk(EMOTE_KER_SLEEP); - - Talk(SAY_KER_SLEEP); - - me->SetStandState(UNIT_STAND_STATE_SLEEP); - DoCast(me, SPELL_SLEEP_VISUAL, false); - } - - void ClearSleeping() - { - me->RemoveAurasDueToSpell(SPELL_SLEEP_VISUAL); - me->SetStandState(UNIT_STAND_STATE_STAND); - - Talk(EMOTE_KER_AWAKEN); - - SetFollowPaused(false); - } - - void UpdateFollowerAI(uint32 diff) override - { - if (!UpdateVictim()) - { - if (!HasFollowState(STATE_FOLLOW_INPROGRESS)) - return; - - if (!HasFollowState(STATE_FOLLOW_PAUSED)) - { - if (FallAsleepTimer <= diff) - { - SetSleeping(); - FallAsleepTimer = urand(25000, 90000); - } - else - FallAsleepTimer -= diff; - } - - return; - } - - DoMeleeAttackIfReady(); - } - }; - - bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) override - { - if (quest->GetQuestId() == QUEST_SLEEPER_AWAKENED) - { - if (npc_kerlonianAI* pKerlonianAI = CAST_AI(npc_kerlonian::npc_kerlonianAI, creature->AI())) - { - creature->SetStandState(UNIT_STAND_STATE_STAND); - creature->AI()->Talk(SAY_KER_START, player); - pKerlonianAI->StartFollow(player, FACTION_KER_ESCORTEE, quest); - } - } - - return true; - } - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_kerlonianAI(creature); - } -}; - -/*#### -# npc_prospector_remtravel -####*/ - -enum Remtravel -{ - SAY_REM_START = 0, - SAY_REM_AGGRO = 1, - SAY_REM_RAMP1_1 = 2, - SAY_REM_RAMP1_2 = 3, - SAY_REM_BOOK = 4, - SAY_REM_TENT1_1 = 5, - SAY_REM_TENT1_2 = 6, - SAY_REM_MOSS = 7, - EMOTE_REM_MOSS = 8, - SAY_REM_MOSS_PROGRESS = 9, - SAY_REM_PROGRESS = 10, - SAY_REM_REMEMBER = 11, - EMOTE_REM_END = 12, - - FACTION_ESCORTEE = 10, - QUEST_ABSENT_MINDED_PT2 = 731, - NPC_GRAVEL_SCOUT = 2158, - NPC_GRAVEL_BONE = 2159, - NPC_GRAVEL_GEO = 2160 -}; - -class npc_prospector_remtravel : public CreatureScript -{ -public: - npc_prospector_remtravel() : CreatureScript("npc_prospector_remtravel") { } - - struct npc_prospector_remtravelAI : public npc_escortAI - { - npc_prospector_remtravelAI(Creature* creature) : npc_escortAI(creature) { } - - void Reset() override { } - - void EnterCombat(Unit* who) override - { - if (urand(0, 1)) - Talk(SAY_REM_AGGRO, who); - } - - void JustSummoned(Creature* /*pSummoned*/) override - { - //unsure if it should be any - //pSummoned->AI()->AttackStart(me); - } - - void WaypointReached(uint32 waypointId) override - { - if (Player* player = GetPlayerForEscort()) - { - switch (waypointId) - { - case 0: - Talk(SAY_REM_START, player); - break; - case 5: - Talk(SAY_REM_RAMP1_1, player); - break; - case 6: - DoSpawnCreature(NPC_GRAVEL_SCOUT, -10.0f, 5.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); - DoSpawnCreature(NPC_GRAVEL_BONE, -10.0f, 7.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); - break; - case 9: - Talk(SAY_REM_RAMP1_2, player); - break; - case 14: - //depend quest rewarded? - Talk(SAY_REM_BOOK, player); - break; - case 15: - Talk(SAY_REM_TENT1_1, player); - break; - case 16: - DoSpawnCreature(NPC_GRAVEL_SCOUT, -10.0f, 5.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); - DoSpawnCreature(NPC_GRAVEL_BONE, -10.0f, 7.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); - break; - case 17: - Talk(SAY_REM_TENT1_2, player); - break; - case 26: - Talk(SAY_REM_MOSS, player); - break; - case 27: - Talk(EMOTE_REM_MOSS, player); - break; - case 28: - Talk(SAY_REM_MOSS_PROGRESS, player); - break; - case 29: - DoSpawnCreature(NPC_GRAVEL_SCOUT, -15.0f, 3.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); - DoSpawnCreature(NPC_GRAVEL_BONE, -15.0f, 5.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); - DoSpawnCreature(NPC_GRAVEL_GEO, -15.0f, 7.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); - break; - case 31: - Talk(SAY_REM_PROGRESS, player); - break; - case 41: - Talk(SAY_REM_REMEMBER, player); - break; - case 42: - Talk(EMOTE_REM_END, player); - player->GroupEventHappens(QUEST_ABSENT_MINDED_PT2, me); - break; - } - } - } - }; - - bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) override - { - if (quest->GetQuestId() == QUEST_ABSENT_MINDED_PT2) - { - if (npc_escortAI* pEscortAI = CAST_AI(npc_prospector_remtravel::npc_prospector_remtravelAI, creature->AI())) - pEscortAI->Start(false, false, player->GetGUID()); - - creature->setFaction(FACTION_ESCORTEE); - } - - return true; - } - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_prospector_remtravelAI(creature); - } -}; - -/*#### -# npc_threshwackonator -####*/ - -enum Threshwackonator -{ - EMOTE_START = 0, - SAY_AT_CLOSE = 1, - QUEST_GYROMAST_REV = 2078, - NPC_GELKAK = 6667, - FACTION_HOSTILE = 14 -}; - -#define GOSSIP_ITEM_INSERT_KEY "[PH] Insert key" - -class npc_threshwackonator : public CreatureScript -{ -public: - npc_threshwackonator() : CreatureScript("npc_threshwackonator") { } - - struct npc_threshwackonatorAI : public FollowerAI - { - npc_threshwackonatorAI(Creature* creature) : FollowerAI(creature) { } - - void Reset() override { } - - void MoveInLineOfSight(Unit* who) override - - { - FollowerAI::MoveInLineOfSight(who); - - if (!me->GetVictim() && !HasFollowState(STATE_FOLLOW_COMPLETE) && who->GetEntry() == NPC_GELKAK) - { - if (me->IsWithinDistInMap(who, 10.0f)) - { - Talk(SAY_AT_CLOSE, who); - DoAtEnd(); - } - } - } - - void DoAtEnd() - { - me->setFaction(FACTION_HOSTILE); - - if (Player* pHolder = GetLeaderForFollower()) - AttackStart(pHolder); - - SetFollowComplete(); - } - }; - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF+1) - { - player->CLOSE_GOSSIP_MENU(); - - if (npc_threshwackonatorAI* pThreshAI = CAST_AI(npc_threshwackonator::npc_threshwackonatorAI, creature->AI())) - { - creature->AI()->Talk(EMOTE_START); - pThreshAI->StartFollow(player); - } - } - - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) override - { - if (player->GetQuestStatus(QUEST_GYROMAST_REV) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_INSERT_KEY, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - return true; - } - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_threshwackonatorAI(creature); - } -}; - void AddSC_darkshore() { - new npc_kerlonian(); - new npc_prospector_remtravel(); - new npc_threshwackonator(); } diff --git a/src/server/scripts/Kalimdor/zone_desolace.cpp b/src/server/scripts/Kalimdor/zone_desolace.cpp index 0a56253cabd..5cb58058151 100644 --- a/src/server/scripts/Kalimdor/zone_desolace.cpp +++ b/src/server/scripts/Kalimdor/zone_desolace.cpp @@ -19,14 +19,12 @@ /* ScriptData SDName: Desolace SD%Complete: 100 -SDComment: Quest support: 5561 +SDComment: Quest support: 5561, 5581 SDCategory: Desolace EndScriptData */ /* ContentData npc_aged_dying_ancient_kodo -go_iruxos -npc_dalinda_malem go_demon_portal EndContentData */ @@ -65,8 +63,7 @@ public: { npc_aged_dying_ancient_kodoAI(Creature* creature) : ScriptedAI(creature) { } - void MoveInLineOfSight(Unit* who) override - + void MoveInLineOfSight(Unit* who) { if (who->GetEntry() == NPC_SMEED && me->IsWithinDistInMap(who, 10.0f) && !me->HasAura(SPELL_KODO_KOMBO_GOSSIP)) { @@ -77,7 +74,7 @@ public: } } - void SpellHit(Unit* caster, SpellInfo const* spell) override + void SpellHit(Unit* caster, SpellInfo const* spell) { if (spell->Id == SPELL_KODO_KOMBO_ITEM) { @@ -119,106 +116,6 @@ public: }; /*###### -## go_iruxos -## Hand of Iruxos -######*/ - -enum Iruxos -{ - QUEST_HAND_IRUXOS = 5381, - NPC_DEMON_SPIRIT = 11876 -}; - -class go_iruxos : public GameObjectScript -{ - public: - go_iruxos() : GameObjectScript("go_iruxos") { } - - bool OnGossipHello(Player* player, GameObject* go) override - { - if (player->GetQuestStatus(QUEST_HAND_IRUXOS) == QUEST_STATUS_INCOMPLETE && !go->FindNearestCreature(NPC_DEMON_SPIRIT, 25.0f, true)) - player->SummonCreature(NPC_DEMON_SPIRIT, go->GetPositionX(), go->GetPositionY(), go->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000); - - return true; - } -}; - -/*###### -## npc_dalinda_malem. Quest 1440 -######*/ - -enum Dalinda -{ - QUEST_RETURN_TO_VAHLARRIEL = 1440 -}; - -class npc_dalinda : public CreatureScript -{ -public: - npc_dalinda() : CreatureScript("npc_dalinda") { } - - struct npc_dalindaAI : public npc_escortAI - { - npc_dalindaAI(Creature* creature) : npc_escortAI(creature) { } - - void Reset() override { } - - void EnterCombat(Unit* /*who*/) override { } - - void JustDied(Unit* /*killer*/) override - { - if (Player* player = GetPlayerForEscort()) - player->FailQuest(QUEST_RETURN_TO_VAHLARRIEL); - return; - } - - void WaypointReached(uint32 waypointId) override - { - Player* player = GetPlayerForEscort(); - - switch (waypointId) - { - case 1: - me->SetStandState(UNIT_STAND_STATE_STAND); - break; - case 15: - if (player) - player->GroupEventHappens(QUEST_RETURN_TO_VAHLARRIEL, me); - break; - } - } - - void UpdateAI(uint32 diff) override - { - npc_escortAI::UpdateAI(diff); - - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - } - }; - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) override - { - if (quest->GetQuestId() == QUEST_RETURN_TO_VAHLARRIEL) - { - if (npc_escortAI* escortAI = CAST_AI(npc_dalinda::npc_dalindaAI, creature->AI())) - { - escortAI->Start(true, false, player->GetGUID()); - creature->setFaction(113); - } - } - return true; - } - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_dalindaAI(creature); - } -}; - -/*###### ## go_demon_portal ######*/ @@ -233,7 +130,7 @@ class go_demon_portal : public GameObjectScript public: go_demon_portal() : GameObjectScript("go_demon_portal") { } - bool OnGossipHello(Player* player, GameObject* go) override + bool OnGossipHello(Player* player, GameObject* go) { if (player->GetQuestStatus(QUEST_PORTAL_OF_THE_LEGION) == QUEST_STATUS_INCOMPLETE && !go->FindNearestCreature(NPC_DEMON_GUARDIAN, 5.0f, true)) { @@ -248,7 +145,5 @@ class go_demon_portal : public GameObjectScript void AddSC_desolace() { new npc_aged_dying_ancient_kodo(); - new go_iruxos(); - new npc_dalinda(); new go_demon_portal(); } diff --git a/src/server/scripts/Kalimdor/zone_durotar.cpp b/src/server/scripts/Kalimdor/zone_durotar.cpp index 358814d440a..ca4bafdd453 100644 --- a/src/server/scripts/Kalimdor/zone_durotar.cpp +++ b/src/server/scripts/Kalimdor/zone_durotar.cpp @@ -17,13 +17,12 @@ #include "ScriptMgr.h" #include "ScriptedCreature.h" -#include "Vehicle.h" #include "SpellScript.h" #include "Player.h" /*###### -##Quest 5441: Lazy Peons -##npc_lazy_peon +## Quest 25134: Lazy Peons +## npc_lazy_peon ######*/ enum LazyPeonYells @@ -33,10 +32,10 @@ enum LazyPeonYells enum LazyPeon { - QUEST_LAZY_PEONS = 5441, - GO_LUMBERPILE = 175784, - SPELL_BUFF_SLEEP = 17743, - SPELL_AWAKEN_PEON = 19938 + QUEST_LAZY_PEONS = 25134, + GO_LUMBERPILE = 175784, + SPELL_BUFF_SLEEP = 17743, + SPELL_AWAKEN_PEON = 19938 }; class npc_lazy_peon : public CreatureScript @@ -65,13 +64,13 @@ public: work = false; } - void MovementInform(uint32 /*type*/, uint32 id) override + void MovementInform(uint32 /*type*/, uint32 id) { if (id == 1) work = true; } - void SpellHit(Unit* caster, const SpellInfo* spell) override + void SpellHit(Unit* caster, const SpellInfo* spell) { if (spell->Id != SPELL_AWAKEN_PEON) return; @@ -94,7 +93,7 @@ public: if (RebuffTimer <= diff) { DoCast(me, SPELL_BUFF_SLEEP); - RebuffTimer = 300000; //Rebuff agian in 5 minutes + RebuffTimer = 300000; //Rebuff agian in 5 minutes } else RebuffTimer -= diff; @@ -105,434 +104,6 @@ public: }; }; -enum Texts -{ - // Tiger Matriarch Credit - SAY_MATRIARCH_AGGRO = 0, - - // Troll Volunteer - SAY_VOLUNTEER_START = 0, - SAY_VOLUNTEER_END = 1, -}; - -enum Spells -{ - // Tiger Matriarch Credit - SPELL_SUMMON_MATRIARCH = 75187, - SPELL_NO_SUMMON_AURA = 75213, - SPELL_DETECT_INVIS = 75180, - SPELL_SUMMON_ZENTABRA_TRIGGER = 75212, - - // Tiger Matriarch - SPELL_POUNCE = 61184, - SPELL_FURIOUS_BITE = 75164, - SPELL_SUMMON_ZENTABRA = 75181, - SPELL_SPIRIT_OF_THE_TIGER_RIDER = 75166, - SPELL_EJECT_PASSENGERS = 50630, - - // Troll Volunteer - SPELL_VOLUNTEER_AURA = 75076, - SPELL_PETACT_AURA = 74071, - SPELL_QUEST_CREDIT = 75106, - SPELL_MOUNTING_CHECK = 75420, - SPELL_TURNIN = 73953, - SPELL_AOE_TURNIN = 75107, - - // Vol'jin War Drums - SPELL_MOTIVATE_1 = 75088, - SPELL_MOTIVATE_2 = 75086, -}; - -enum Creatures -{ - // Tiger Matriarch Credit - NPC_TIGER_VEHICLE = 40305, - - // Troll Volunteer - NPC_URUZIN = 40253, - NPC_VOLUNTEER_1 = 40264, - NPC_VOLUNTEER_2 = 40260, - - // Vol'jin War Drums - NPC_CITIZEN_1 = 40256, - NPC_CITIZEN_2 = 40257, -}; - -enum Events -{ - // Tiger Matriarch Credit - EVENT_CHECK_SUMMON_AURA = 1, - - // Tiger Matriarch - EVENT_POUNCE = 2, - EVENT_NOSUMMON = 3, -}; - -enum Points -{ - POINT_URUZIN = 4026400, -}; - -class npc_tiger_matriarch_credit : public CreatureScript -{ - public: - npc_tiger_matriarch_credit() : CreatureScript("npc_tiger_matriarch_credit") { } - - struct npc_tiger_matriarch_creditAI : public ScriptedAI - { - npc_tiger_matriarch_creditAI(Creature* creature) : ScriptedAI(creature) - { - SetCombatMovement(false); - events.ScheduleEvent(EVENT_CHECK_SUMMON_AURA, 2000); - } - - void UpdateAI(uint32 diff) override - { - events.Update(diff); - - if (events.ExecuteEvent() == EVENT_CHECK_SUMMON_AURA) - { - std::list<Creature*> tigers; - GetCreatureListWithEntryInGrid(tigers, me, NPC_TIGER_VEHICLE, 15.0f); - if (!tigers.empty()) - { - for (std::list<Creature*>::iterator itr = tigers.begin(); itr != tigers.end(); ++itr) - { - if (!(*itr)->IsSummon()) - continue; - - if (Unit* summoner = (*itr)->ToTempSummon()->GetSummoner()) - if (!summoner->HasAura(SPELL_NO_SUMMON_AURA) && !summoner->HasAura(SPELL_SUMMON_ZENTABRA_TRIGGER) - && !summoner->IsInCombat()) - { - me->AddAura(SPELL_NO_SUMMON_AURA, summoner); - me->AddAura(SPELL_DETECT_INVIS, summoner); - summoner->CastSpell(summoner, SPELL_SUMMON_MATRIARCH, true); - Talk(SAY_MATRIARCH_AGGRO, summoner); - } - } - } - - events.ScheduleEvent(EVENT_CHECK_SUMMON_AURA, 5000); - } - } - - private: - EventMap events; - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_tiger_matriarch_creditAI(creature); - } -}; - -class npc_tiger_matriarch : public CreatureScript -{ - public: - npc_tiger_matriarch() : CreatureScript("npc_tiger_matriarch") { } - - struct npc_tiger_matriarchAI : public ScriptedAI - { - npc_tiger_matriarchAI(Creature* creature) : ScriptedAI(creature), - _tigerGuid(0) - { - } - - void EnterCombat(Unit* /*target*/) override - { - _events.Reset(); - _events.ScheduleEvent(EVENT_POUNCE, 100); - _events.ScheduleEvent(EVENT_NOSUMMON, 50000); - } - - void IsSummonedBy(Unit* summoner) override - { - if (summoner->GetTypeId() != TYPEID_PLAYER || !summoner->GetVehicle()) - return; - - _tigerGuid = summoner->GetVehicle()->GetBase()->GetGUID(); - if (Unit* tiger = ObjectAccessor::GetUnit(*me, _tigerGuid)) - { - me->AddThreat(tiger, 500000.0f); - DoCast(me, SPELL_FURIOUS_BITE); - } - } - - void KilledUnit(Unit* victim) override - { - if (victim->GetTypeId() != TYPEID_UNIT || !victim->IsSummon()) - return; - - if (Unit* vehSummoner = victim->ToTempSummon()->GetSummoner()) - { - vehSummoner->RemoveAurasDueToSpell(SPELL_NO_SUMMON_AURA); - vehSummoner->RemoveAurasDueToSpell(SPELL_DETECT_INVIS); - vehSummoner->RemoveAurasDueToSpell(SPELL_SPIRIT_OF_THE_TIGER_RIDER); - vehSummoner->RemoveAurasDueToSpell(SPELL_SUMMON_ZENTABRA_TRIGGER); - } - me->DespawnOrUnsummon(); - } - - void DamageTaken(Unit* attacker, uint32& damage) override - { - if (!attacker->IsSummon()) - return; - - if (HealthBelowPct(20)) - { - damage = 0; - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - if (Unit* vehSummoner = attacker->ToTempSummon()->GetSummoner()) - { - vehSummoner->AddAura(SPELL_SUMMON_ZENTABRA_TRIGGER, vehSummoner); - vehSummoner->CastSpell(vehSummoner, SPELL_SUMMON_ZENTABRA, true); - attacker->CastSpell(attacker, SPELL_EJECT_PASSENGERS, true); - vehSummoner->RemoveAurasDueToSpell(SPELL_NO_SUMMON_AURA); - vehSummoner->RemoveAurasDueToSpell(SPELL_DETECT_INVIS); - vehSummoner->RemoveAurasDueToSpell(SPELL_SPIRIT_OF_THE_TIGER_RIDER); - vehSummoner->RemoveAurasDueToSpell(SPELL_SUMMON_ZENTABRA_TRIGGER); - } - - me->DespawnOrUnsummon(); - } - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - if (!_tigerGuid) - return; - - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_POUNCE: - DoCastVictim(SPELL_POUNCE); - _events.ScheduleEvent(EVENT_POUNCE, 30000); - break; - case EVENT_NOSUMMON: // Reapply SPELL_NO_SUMMON_AURA - if (Unit* tiger = ObjectAccessor::GetUnit(*me, _tigerGuid)) - { - if (tiger->IsSummon()) - if (Unit* vehSummoner = tiger->ToTempSummon()->GetSummoner()) - me->AddAura(SPELL_NO_SUMMON_AURA, vehSummoner); - } - _events.ScheduleEvent(EVENT_NOSUMMON, 50000); - break; - default: - break; - } - } - - DoMeleeAttackIfReady(); - } - - private: - EventMap _events; - uint64 _tigerGuid; - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_tiger_matriarchAI(creature); - } -}; - -// These models was found in sniff. -/// @todo generalize these models with race from dbc -uint32 const trollmodel[] = -{11665, 11734, 11750, 12037, 12038, 12042, 12049, 12849, 13529, 14759, 15570, 15701, -15702, 1882, 1897, 1976, 2025, 27286, 2734, 2735, 4084, 4085, 4087, 4089, 4231, 4357, -4358, 4360, 4361, 4362, 4363, 4370, 4532, 4537, 4540, 4610, 6839, 7037, 9767, 9768}; - -class npc_troll_volunteer : public CreatureScript -{ - public: - npc_troll_volunteer() : CreatureScript("npc_troll_volunteer") { } - - struct npc_troll_volunteerAI : public ScriptedAI - { - npc_troll_volunteerAI(Creature* creature) : ScriptedAI(creature) - { - } - - void InitializeAI() override - { - if (me->isDead() || !me->GetOwner()) - return; - - Reset(); - - switch (urand(0, 3)) - { - case 0: - _mountModel = 6471; - break; - case 1: - _mountModel = 6473; - break; - case 2: - _mountModel = 6469; - break; - default: - _mountModel = 6472; - break; - } - me->SetDisplayId(trollmodel[urand(0, 39)]); - if (Player* player = me->GetOwner()->ToPlayer()) - me->GetMotionMaster()->MoveFollow(player, 5.0f, float(rand_norm() + 1.0f) * M_PI / 3.0f * 4.0f); - } - - void Reset() override - { - _complete = false; - me->AddAura(SPELL_VOLUNTEER_AURA, me); - me->AddAura(SPELL_MOUNTING_CHECK, me); - DoCast(me, SPELL_PETACT_AURA); - me->SetReactState(REACT_PASSIVE); - Talk(SAY_VOLUNTEER_START); - } - - // This is needed for mount check aura to know what mountmodel the npc got stored - uint32 GetMountId() - { - return _mountModel; - } - - void MovementInform(uint32 type, uint32 id) override - { - if (type != POINT_MOTION_TYPE) - return; - if (id == POINT_URUZIN) - me->DespawnOrUnsummon(); - } - - void SpellHit(Unit* caster, SpellInfo const* spell) override - { - if (spell->Id == SPELL_AOE_TURNIN && caster->GetEntry() == NPC_URUZIN && !_complete) - { - _complete = true; // Preventing from giving credit twice - DoCast(me, SPELL_TURNIN); - DoCast(me, SPELL_QUEST_CREDIT); - me->RemoveAurasDueToSpell(SPELL_MOUNTING_CHECK); - me->Dismount(); - Talk(SAY_VOLUNTEER_END); - me->GetMotionMaster()->MovePoint(POINT_URUZIN, caster->GetPositionX(), caster->GetPositionY(), caster->GetPositionZ()); - } - } - - private: - uint32 _mountModel; - bool _complete; - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_troll_volunteerAI(creature); - } -}; - -typedef npc_troll_volunteer::npc_troll_volunteerAI VolunteerAI; - -class spell_mount_check : public SpellScriptLoader -{ - public: - spell_mount_check() : SpellScriptLoader("spell_mount_check") { } - - class spell_mount_check_AuraScript : public AuraScript - { - PrepareAuraScript(spell_mount_check_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - if (!sSpellMgr->GetSpellInfo(SPELL_MOUNTING_CHECK)) - return false; - return true; - } - - void HandleEffectPeriodic(AuraEffect const* /*aurEff*/) - { - Unit* target = GetTarget(); - Unit* owner = target->GetOwner(); - - if (!owner) - return; - - if (owner->IsMounted() && !target->IsMounted()) - { - if (VolunteerAI* volunteerAI = CAST_AI(VolunteerAI, target->GetAI())) - target->Mount(volunteerAI->GetMountId()); - } - else if (!owner->IsMounted() && target->IsMounted()) - target->Dismount(); - - target->SetSpeed(MOVE_RUN, owner->GetSpeedRate(MOVE_RUN)); - target->SetSpeed(MOVE_WALK, owner->GetSpeedRate(MOVE_WALK)); - } - - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_mount_check_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); - } - }; - - AuraScript* GetAuraScript() const override - { - return new spell_mount_check_AuraScript(); - } -}; - -class spell_voljin_war_drums : public SpellScriptLoader -{ - public: - spell_voljin_war_drums() : SpellScriptLoader("spell_voljin_war_drums") { } - - class spell_voljin_war_drums_SpellScript : public SpellScript - { - PrepareSpellScript(spell_voljin_war_drums_SpellScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - if (!sSpellMgr->GetSpellInfo(SPELL_MOTIVATE_1)) - return false; - if (!sSpellMgr->GetSpellInfo(SPELL_MOTIVATE_2)) - return false; - return true; - } - - void HandleDummy(SpellEffIndex /*effIndex*/) - { - Unit* caster = GetCaster(); - if (Unit* target = GetHitUnit()) - { - uint32 motivate = 0; - if (target->GetEntry() == NPC_CITIZEN_1) - motivate = SPELL_MOTIVATE_1; - else if (target->GetEntry() == NPC_CITIZEN_2) - motivate = SPELL_MOTIVATE_2; - if (motivate) - caster->CastSpell(target, motivate, false); - } - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_voljin_war_drums_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; - - SpellScript* GetSpellScript() const override - { - return new spell_voljin_war_drums_SpellScript(); - } -}; - enum VoodooSpells { SPELL_BREW = 16712, // Special Brew @@ -586,10 +157,5 @@ class spell_voodoo : public SpellScriptLoader void AddSC_durotar() { new npc_lazy_peon(); - new npc_tiger_matriarch_credit(); - new npc_tiger_matriarch(); - new npc_troll_volunteer(); - new spell_mount_check(); - new spell_voljin_war_drums(); new spell_voodoo(); } diff --git a/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp b/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp index aa9774bfd62..91c481a3a9d 100644 --- a/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp +++ b/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp @@ -19,16 +19,13 @@ /* ScriptData SDName: Dustwallow_Marsh SD%Complete: 95 -SDComment: Quest support: 11180, 558, 11126, 11142, 11174, Vendor Nat Pagle +SDComment: Quest support: 1270, 1222, 27245 SDCategory: Dustwallow Marsh EndScriptData */ /* ContentData -npc_risen_husk_spirit -npc_lady_jaina_proudmoore -npc_nat_pagle -npc_private_hendel -npc_cassa_crimsonwing - handled by npc_taxi +npc_stinky +go_blackhoof_cage EndContentData */ #include "ScriptMgr.h" @@ -766,13 +763,7 @@ public: void AddSC_dustwallow_marsh() { - new npc_risen_husk_spirit(); - new npc_lady_jaina_proudmoore(); - new npc_nat_pagle(); - new npc_private_hendel(); - new npc_zelfrax(); new npc_stinky(); - new npc_theramore_guard(); new spell_ooze_zap(); new spell_ooze_zap_channel_end(); new spell_energize_aoe(); diff --git a/src/server/scripts/Kalimdor/zone_felwood.cpp b/src/server/scripts/Kalimdor/zone_felwood.cpp index b79bc1f088b..9383a05f655 100644 --- a/src/server/scripts/Kalimdor/zone_felwood.cpp +++ b/src/server/scripts/Kalimdor/zone_felwood.cpp @@ -19,12 +19,11 @@ /* ScriptData SDName: Felwood SD%Complete: 95 -SDComment: Quest support: 4101, 4102 +SDComment: Quest support: SDCategory: Felwood EndScriptData */ /* ContentData -npcs_riverbreeze_and_silversky EndContentData */ #include "ScriptMgr.h" @@ -32,75 +31,6 @@ EndContentData */ #include "ScriptedGossip.h" #include "Player.h" -/*###### -## npcs_riverbreeze_and_silversky -######*/ - -#define GOSSIP_ITEM_BEACON "Please make me a Cenarion Beacon" - -enum RiverbreezeAndSilversky -{ - SPELL_CENARION_BEACON = 15120, - - NPC_ARATHANDRIS_SILVERSKY = 9528, - NPC_MAYBESS_RIVERBREEZE = 9529, - - QUEST_CLEASING_FELWOOD_A = 4101, - QUEST_CLEASING_FELWOOD_H = 4102 -}; - -class npcs_riverbreeze_and_silversky : public CreatureScript -{ -public: - npcs_riverbreeze_and_silversky() : CreatureScript("npcs_riverbreeze_and_silversky") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF+1) - { - player->CLOSE_GOSSIP_MENU(); - creature->CastSpell(player, SPELL_CENARION_BEACON, false); - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) override - { - if (creature->IsQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - uint32 creatureId = creature->GetEntry(); - - if (creatureId == NPC_ARATHANDRIS_SILVERSKY) - { - if (player->GetQuestRewardStatus(QUEST_CLEASING_FELWOOD_A)) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_BEACON, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - player->SEND_GOSSIP_MENU(2848, creature->GetGUID()); - } else if (player->GetTeam() == HORDE) - player->SEND_GOSSIP_MENU(2845, creature->GetGUID()); - else - player->SEND_GOSSIP_MENU(2844, creature->GetGUID()); - } - - if (creatureId == NPC_MAYBESS_RIVERBREEZE) - { - if (player->GetQuestRewardStatus(QUEST_CLEASING_FELWOOD_H)) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_BEACON, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - player->SEND_GOSSIP_MENU(2849, creature->GetGUID()); - } else if (player->GetTeam() == ALLIANCE) - player->SEND_GOSSIP_MENU(2843, creature->GetGUID()); - else - player->SEND_GOSSIP_MENU(2842, creature->GetGUID()); - } - - return true; - } -}; - void AddSC_felwood() { - new npcs_riverbreeze_and_silversky(); } diff --git a/src/server/scripts/Kalimdor/zone_feralas.cpp b/src/server/scripts/Kalimdor/zone_feralas.cpp index fa5336df1f3..2186752b135 100644 --- a/src/server/scripts/Kalimdor/zone_feralas.cpp +++ b/src/server/scripts/Kalimdor/zone_feralas.cpp @@ -16,237 +16,7 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Feralas -SD%Complete: 100 -SDComment: Quest support: 3520, 2767, Special vendor Gregan Brewspewer -SDCategory: Feralas -EndScriptData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedEscortAI.h" -#include "ScriptedGossip.h" -#include "SpellScript.h" -#include "Player.h" -#include "WorldSession.h" - -/*###### -## npc_gregan_brewspewer -######*/ - -#define GOSSIP_HELLO "Buy somethin', will ya?" - -class npc_gregan_brewspewer : public CreatureScript -{ -public: - npc_gregan_brewspewer() : CreatureScript("npc_gregan_brewspewer") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF+1) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); - player->SEND_GOSSIP_MENU(2434, creature->GetGUID()); - } - if (action == GOSSIP_ACTION_TRADE) - player->GetSession()->SendListInventory(creature->GetGUID()); - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) override - { - if (creature->IsQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (creature->IsVendor() && player->GetQuestStatus(3909) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - - player->SEND_GOSSIP_MENU(2433, creature->GetGUID()); - return true; - } - -}; - -/*###### -## npc_oox22fe -######*/ - -enum OOX -{ - SAY_OOX_START = 0, - SAY_OOX_AGGRO = 1, - SAY_OOX_AMBUSH = 2, - SAY_OOX_END = 3, - - NPC_YETI = 7848, - NPC_GORILLA = 5260, - NPC_WOODPAW_REAVER = 5255, - NPC_WOODPAW_BRUTE = 5253, - NPC_WOODPAW_ALPHA = 5258, - NPC_WOODPAW_MYSTIC = 5254, - - QUEST_RESCUE_OOX22FE = 2767, - FACTION_ESCORTEE_A = 774, - FACTION_ESCORTEE_H = 775 -}; - -class npc_oox22fe : public CreatureScript -{ -public: - npc_oox22fe() : CreatureScript("npc_oox22fe") { } - - bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) override - { - if (quest->GetQuestId() == QUEST_RESCUE_OOX22FE) - { - creature->AI()->Talk(SAY_OOX_START); - //change that the npc is not lying dead on the ground - creature->SetStandState(UNIT_STAND_STATE_STAND); - - if (player->GetTeam() == ALLIANCE) - creature->setFaction(FACTION_ESCORTEE_A); - - if (player->GetTeam() == HORDE) - creature->setFaction(FACTION_ESCORTEE_H); - - if (npc_escortAI* pEscortAI = CAST_AI(npc_oox22fe::npc_oox22feAI, creature->AI())) - pEscortAI->Start(true, false, player->GetGUID()); - - } - return true; - } - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_oox22feAI(creature); - } - - struct npc_oox22feAI : public npc_escortAI - { - npc_oox22feAI(Creature* creature) : npc_escortAI(creature) { } - - void WaypointReached(uint32 waypointId) override - { - switch (waypointId) - { - // First Ambush(3 Yetis) - case 11: - Talk(SAY_OOX_AMBUSH); - me->SummonCreature(NPC_YETI, -4841.01f, 1593.91f, 73.42f, 3.98f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); - me->SummonCreature(NPC_YETI, -4837.61f, 1568.58f, 78.21f, 3.13f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); - me->SummonCreature(NPC_YETI, -4841.89f, 1569.95f, 76.53f, 0.68f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); - break; - //Second Ambush(3 Gorillas) - case 21: - Talk(SAY_OOX_AMBUSH); - me->SummonCreature(NPC_GORILLA, -4595.81f, 2005.99f, 53.08f, 3.74f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); - me->SummonCreature(NPC_GORILLA, -4597.53f, 2008.31f, 52.70f, 3.78f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); - me->SummonCreature(NPC_GORILLA, -4599.37f, 2010.59f, 52.77f, 3.84f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); - break; - //Third Ambush(4 Gnolls) - case 30: - Talk(SAY_OOX_AMBUSH); - me->SummonCreature(NPC_WOODPAW_REAVER, -4425.14f, 2075.87f, 47.77f, 3.77f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); - me->SummonCreature(NPC_WOODPAW_BRUTE, -4426.68f, 2077.98f, 47.57f, 3.77f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); - me->SummonCreature(NPC_WOODPAW_MYSTIC, -4428.33f, 2080.24f, 47.43f, 3.87f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); - me->SummonCreature(NPC_WOODPAW_ALPHA, -4430.04f, 2075.54f, 46.83f, 3.81f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); - break; - case 37: - Talk(SAY_OOX_END); - // Award quest credit - if (Player* player = GetPlayerForEscort()) - player->GroupEventHappens(QUEST_RESCUE_OOX22FE, me); - break; - } - } - - void Reset() override - { - if (!HasEscortState(STATE_ESCORT_ESCORTING)) - me->SetStandState(UNIT_STAND_STATE_DEAD); - } - - void EnterCombat(Unit* /*who*/) override - { - //For an small probability the npc says something when he get aggro - if (urand(0, 9) > 7) - Talk(SAY_OOX_AGGRO); - } - - void JustSummoned(Creature* summoned) override - { - summoned->AI()->AttackStart(me); - } - }; - -}; - -/*###### -## npc_screecher_spirit -######*/ - -class npc_screecher_spirit : public CreatureScript -{ -public: - npc_screecher_spirit() : CreatureScript("npc_screecher_spirit") { } - - bool OnGossipHello(Player* player, Creature* creature) override - { - player->SEND_GOSSIP_MENU(2039, creature->GetGUID()); - player->TalkedToCreature(creature->GetEntry(), creature->GetGUID()); - creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - - return true; - } - -}; - -enum GordunniTrap -{ - GO_GORDUNNI_DIRT_MOUND = 144064, -}; - -class spell_gordunni_trap : public SpellScriptLoader -{ - public: - spell_gordunni_trap() : SpellScriptLoader("spell_gordunni_trap") { } - - class spell_gordunni_trap_SpellScript : public SpellScript - { - PrepareSpellScript(spell_gordunni_trap_SpellScript); - - void HandleDummy() - { - if (Unit* caster = GetCaster()) - if (GameObject* chest = caster->SummonGameObject(GO_GORDUNNI_DIRT_MOUND, caster->GetPositionX(), caster->GetPositionY(), caster->GetPositionZ(), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0)) - { - chest->SetSpellId(GetSpellInfo()->Id); - caster->RemoveGameObject(chest, false); - } - } - - void Register() override - { - OnCast += SpellCastFn(spell_gordunni_trap_SpellScript::HandleDummy); - } - }; - - SpellScript* GetSpellScript() const override - { - return new spell_gordunni_trap_SpellScript(); - } -}; - -/*###### -## AddSC -######*/ - void AddSC_feralas() { - new npc_gregan_brewspewer(); - new npc_oox22fe(); - new npc_screecher_spirit(); - new spell_gordunni_trap(); + } diff --git a/src/server/scripts/Kalimdor/zone_moonglade.cpp b/src/server/scripts/Kalimdor/zone_moonglade.cpp index 0c07d5dc6df..901946df74b 100644 --- a/src/server/scripts/Kalimdor/zone_moonglade.cpp +++ b/src/server/scripts/Kalimdor/zone_moonglade.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2014 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,21 +15,6 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Moonglade -SD%Complete: 100 -SDComment: Quest support: 30, 272, 5929, 5930, 10965. Special Flight Paths for Druid class. -SDCategory: Moonglade -EndScriptData */ - -/* ContentData -npc_bunthen_plainswind -npc_great_bear_spirit -npc_silva_filnaveth -npc_clintar_spirit -npc_clintar_dreamwalker -EndContentData */ - #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "ScriptedEscortAI.h" @@ -42,521 +26,6 @@ EndContentData */ #include "Cell.h" #include "CellImpl.h" -/*###### -## npc_bunthen_plainswind -######*/ - -enum Bunthen -{ - QUEST_SEA_LION_HORDE = 30, - QUEST_SEA_LION_ALLY = 272, - TAXI_PATH_ID_ALLY = 315, - TAXI_PATH_ID_HORDE = 316 -}; - -#define GOSSIP_ITEM_THUNDER "I'd like to fly to Thunder Bluff." -#define GOSSIP_ITEM_AQ_END "Do you know where I can find Half Pendant of Aquatic Endurance?" - -class npc_bunthen_plainswind : public CreatureScript -{ -public: - npc_bunthen_plainswind() : CreatureScript("npc_bunthen_plainswind") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF + 1: - player->CLOSE_GOSSIP_MENU(); - if (player->getClass() == CLASS_DRUID && player->GetTeam() == HORDE) - player->ActivateTaxiPathTo(TAXI_PATH_ID_HORDE); - break; - case GOSSIP_ACTION_INFO_DEF + 2: - player->SEND_GOSSIP_MENU(5373, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 3: - player->SEND_GOSSIP_MENU(5376, creature->GetGUID()); - break; - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) override - { - if (player->getClass() != CLASS_DRUID) - player->SEND_GOSSIP_MENU(4916, creature->GetGUID()); - else if (player->GetTeam() != HORDE) - { - if (player->GetQuestStatus(QUEST_SEA_LION_ALLY) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_AQ_END, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - - player->SEND_GOSSIP_MENU(4917, creature->GetGUID()); - } - else if (player->getClass() == CLASS_DRUID && player->GetTeam() == HORDE) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_THUNDER, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - - if (player->GetQuestStatus(QUEST_SEA_LION_HORDE) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_AQ_END, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); - - player->SEND_GOSSIP_MENU(4918, creature->GetGUID()); - } - return true; - } - -}; - -/*###### -## npc_great_bear_spirit -######*/ - -#define GOSSIP_BEAR1 "What do you represent, spirit?" -#define GOSSIP_BEAR2 "I seek to understand the importance of strength of the body." -#define GOSSIP_BEAR3 "I seek to understand the importance of strength of the heart." -#define GOSSIP_BEAR4 "I have heard your words, Great Bear Spirit, and I understand. I now seek your blessings to fully learn the way of the Claw." - -class npc_great_bear_spirit : public CreatureScript -{ -public: - npc_great_bear_spirit() : CreatureScript("npc_great_bear_spirit") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_BEAR2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - player->SEND_GOSSIP_MENU(4721, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 1: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_BEAR3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - player->SEND_GOSSIP_MENU(4733, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 2: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_BEAR4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); - player->SEND_GOSSIP_MENU(4734, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 3: - player->SEND_GOSSIP_MENU(4735, creature->GetGUID()); - if (player->GetQuestStatus(5929) == QUEST_STATUS_INCOMPLETE) - player->AreaExploredOrEventHappens(5929); - if (player->GetQuestStatus(5930) == QUEST_STATUS_INCOMPLETE) - player->AreaExploredOrEventHappens(5930); - break; - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) override - { - //ally or horde quest - if (player->GetQuestStatus(5929) == QUEST_STATUS_INCOMPLETE || player->GetQuestStatus(5930) == QUEST_STATUS_INCOMPLETE) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_BEAR1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - player->SEND_GOSSIP_MENU(4719, creature->GetGUID()); - } - else - player->SEND_GOSSIP_MENU(4718, creature->GetGUID()); - - return true; - } - -}; - -/*###### -## npc_silva_filnaveth -######*/ - -#define GOSSIP_ITEM_RUTHERAN "I'd like to fly to Rut'theran Village." -#define GOSSIP_ITEM_AQ_AGI "Do you know where I can find Half Pendant of Aquatic Agility?" - -class npc_silva_filnaveth : public CreatureScript -{ -public: - npc_silva_filnaveth() : CreatureScript("npc_silva_filnaveth") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF + 1: - player->CLOSE_GOSSIP_MENU(); - if (player->getClass() == CLASS_DRUID && player->GetTeam() == ALLIANCE) - player->ActivateTaxiPathTo(TAXI_PATH_ID_ALLY); - break; - case GOSSIP_ACTION_INFO_DEF + 2: - player->SEND_GOSSIP_MENU(5374, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 3: - player->SEND_GOSSIP_MENU(5375, creature->GetGUID()); - break; - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) override - { - if (player->getClass() != CLASS_DRUID) - player->SEND_GOSSIP_MENU(4913, creature->GetGUID()); - else if (player->GetTeam() != ALLIANCE) - { - if (player->GetQuestStatus(QUEST_SEA_LION_HORDE) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_AQ_AGI, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - - player->SEND_GOSSIP_MENU(4915, creature->GetGUID()); - } - else if (player->getClass() == CLASS_DRUID && player->GetTeam() == ALLIANCE) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_RUTHERAN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - - if (player->GetQuestStatus(QUEST_SEA_LION_ALLY) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_AQ_AGI, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); - - player->SEND_GOSSIP_MENU(4914, creature->GetGUID()); - } - return true; - } - -}; - -/*###### -## npc_clintar_spirit -######*/ - -float const Clintar_spirit_WP[41][5] = -{ - //pos_x pos_y pos_z orien waitTime - {7465.28f, -3115.46f, 439.327f, 0.83f, 4000}, - {7476.49f, -3101, 443.457f, 0.89f, 0}, - {7486.57f, -3085.59f, 439.478f, 1.07f, 0}, - {7472.19f, -3085.06f, 443.142f, 3.07f, 0}, - {7456.92f, -3085.91f, 438.862f, 3.24f, 0}, - {7446.68f, -3083.43f, 438.245f, 2.40f, 0}, - {7446.17f, -3080.21f, 439.826f, 1.10f, 6000}, - {7452.41f, -3085.8f, 438.984f, 5.78f, 0}, - {7469.11f, -3084.94f, 443.048f, 6.25f, 0}, - {7483.79f, -3085.44f, 439.607f, 6.25f, 0}, - {7491.14f, -3090.96f, 439.983f, 5.44f, 0}, - {7497.62f, -3098.22f, 436.854f, 5.44f, 0}, - {7498.72f, -3113.41f, 434.596f, 4.84f, 0}, - {7500.06f, -3122.51f, 434.749f, 5.17f, 0}, - {7504.96f, -3131.53f, 434.475f, 4.74f, 0}, - {7504.31f, -3133.53f, 435.693f, 3.84f, 6000}, - {7504.55f, -3133.27f, 435.476f, 0.68f, 15000}, - {7501.99f, -3126.01f, 434.93f, 1.83f, 0}, - {7490.76f, -3114.97f, 434.431f, 2.51f, 0}, - {7479.64f, -3105.51f, 431.123f, 1.83f, 0}, - {7474.63f, -3086.59f, 428.994f, 1.83f, 2000}, - {7472.96f, -3074.18f, 427.566f, 1.57f, 0}, - {7472.25f, -3063, 428.268f, 1.55f, 0}, - {7473.46f, -3054.22f, 427.588f, 0.36f, 0}, - {7475.08f, -3053.6f, 428.653f, 0.36f, 6000}, - {7474.66f, -3053.56f, 428.433f, 3.19f, 4000}, - {7471.81f, -3058.84f, 427.073f, 4.29f, 0}, - {7472.16f, -3064.91f, 427.772f, 4.95f, 0}, - {7471.56f, -3085.36f, 428.924f, 4.72f, 0}, - {7473.56f, -3093.48f, 429.294f, 5.04f, 0}, - {7478.94f, -3104.29f, 430.638f, 5.23f, 0}, - {7484.46f, -3109.61f, 432.769f, 5.79f, 0}, - {7490.23f, -3111.08f, 434.431f, 0.02f, 0}, - {7496.29f, -3108, 434.783f, 1.15f, 0}, - {7497.46f, -3100.66f, 436.191f, 1.50f, 0}, - {7495.64f, -3093.39f, 438.349f, 2.10f, 0}, - {7492.44f, -3086.01f, 440.267f, 1.38f, 0}, - {7498.26f, -3076.44f, 440.808f, 0.71f, 0}, - {7506.4f, -3067.35f, 443.64f, 0.77f, 0}, - {7518.37f, -3057.42f, 445.584f, 0.74f, 0}, - {7517.51f, -3056.3f, 444.568f, 2.49f, 4500} -}; - -Position const AspectRavenSummon = {7472.96f, -3074.18f, 427.566f, 0.0f}; -Position const ClintarSpiritSummon = {7459.2275f, -3122.5632f, 438.9842f, 0.8594f}; - -enum ClintarSpirit -{ - ASPECT_RAVEN = 22915, - - // Texts for EnterCombat, the event and the end of the event are missing - CLINTAR_SPIRIT_SAY_START = 0, -}; - -class npc_clintar_spirit : public CreatureScript -{ -public: - npc_clintar_spirit() : CreatureScript("npc_clintar_spirit") { } - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_clintar_spiritAI(creature); - } - - struct npc_clintar_spiritAI : public npc_escortAI - { - public: - npc_clintar_spiritAI(Creature* creature) : npc_escortAI(creature) - { - PlayerGUID = 0; - } - - uint8 Step; - uint32 CurrWP; - uint32 EventTimer; - uint32 checkPlayerTimer; - - uint64 PlayerGUID; - - bool EventOnWait; - - void Reset() override - { - if (!PlayerGUID) - { - Step = 0; - CurrWP = 0; - EventTimer = 0; - PlayerGUID = 0; - checkPlayerTimer = 1000; - EventOnWait = false; - } - } - - void IsSummonedBy(Unit* /*summoner*/) override - { - std::list<Player*> playerOnQuestList; - Trinity::AnyPlayerInObjectRangeCheck checker(me, 5.0f); - Trinity::PlayerListSearcher<Trinity::AnyPlayerInObjectRangeCheck> searcher(me, playerOnQuestList, checker); - me->VisitNearbyWorldObject(5.0f, searcher); - for (std::list<Player*>::const_iterator itr = playerOnQuestList.begin(); itr != playerOnQuestList.end(); ++itr) - { - // Check if found player target has active quest - if (Player* player = (*itr)) - { - if (player->GetQuestStatus(10965) == QUEST_STATUS_INCOMPLETE) - { - StartEvent(player); - break; - } - } - else - break; - } - } - - void JustDied(Unit* /*killer*/) override - { - if (!PlayerGUID) - return; - - Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID); - if (player && player->GetQuestStatus(10965) == QUEST_STATUS_INCOMPLETE) - { - player->FailQuest(10965); - PlayerGUID = 0; - Reset(); - } - } - - void EnterEvadeMode() override - { - Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID); - if (player && player->IsInCombat() && player->getAttackerForHelper()) - { - AttackStart(player->getAttackerForHelper()); - return; - } - npc_escortAI::EnterEvadeMode(); - } - - void StartEvent(Player* player) - { - if (player && player->GetQuestStatus(10965) == QUEST_STATUS_INCOMPLETE) - { - 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]); - } - PlayerGUID = player->GetGUID(); - Start(true, false, PlayerGUID); - } - return; - } - - void UpdateAI(uint32 diff) override - { - npc_escortAI::UpdateAI(diff); - - if (!PlayerGUID) - { - me->setDeathState(JUST_DIED); - return; - } - - if (!me->IsInCombat() && !EventOnWait) - { - if (checkPlayerTimer <= diff) - { - Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID); - if (player && player->IsInCombat() && player->getAttackerForHelper()) - AttackStart(player->getAttackerForHelper()); - checkPlayerTimer = 1000; - } else checkPlayerTimer -= diff; - } - - if (EventOnWait && EventTimer <= diff) - { - Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID); - if (!player || player->GetQuestStatus(10965) == QUEST_STATUS_NONE) - { - me->setDeathState(JUST_DIED); - return; - } - - switch (CurrWP) - { - case 0: - switch (Step) - { - case 0: - Talk(CLINTAR_SPIRIT_SAY_START, player); - EventTimer = 8000; - Step = 1; - break; - case 1: - EventOnWait = false; - break; - } - break; - case 6: - switch (Step) - { - case 0: - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 133); - EventTimer = 5000; - Step = 1; - break; - case 1: - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0); - // Needs text - EventOnWait = false; - break; - } - break; - case 15: - switch (Step) - { - case 0: - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 133); - EventTimer = 5000; - Step = 1; - break; - case 1: - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0); - EventOnWait = false; - break; - } - break; - case 16: - switch (Step) - { - case 0: - // Needs text - EventTimer = 15000; - Step = 1; - break; - case 1: - EventOnWait = false; - break; - } - break; - case 20: - switch (Step) - { - case 0: - if (Creature* mob = me->SummonCreature(ASPECT_RAVEN, AspectRavenSummon, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 2000)) - { - mob->AddThreat(me, 10000.0f); - mob->AI()->AttackStart(me); - } - EventTimer = 2000; - Step = 1; - break; - case 1: - EventOnWait = false; - break; - } - break; - case 24: - switch (Step) - { - case 0: - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 133); - EventTimer = 5000; - Step = 1; - break; - case 1: - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0); - EventOnWait = false; - break; - } - break; - case 25: - switch (Step) - { - case 0: - // Needs text - EventTimer = 4000; - Step = 1; - break; - case 1: - EventOnWait = false; - break; - } - break; - case 40: - switch (Step) - { - case 0: - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 2); - // Needs text - player->CompleteQuest(10965); - EventTimer = 1500; - Step = 1; - break; - case 1: - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0); - EventTimer = 3000; - Step = 2; - break; - case 2: - player->TalkedToCreature(me->GetEntry(), me->GetGUID()); - PlayerGUID = 0; - Reset(); - me->setDeathState(JUST_DIED); - break; - } - break; - default: - EventOnWait = false; - break; - } - - } else if (EventOnWait) EventTimer -= diff; - } - - void WaypointReached(uint32 waypointId) override - { - CurrWP = waypointId; - EventTimer = 0; - Step = 0; - EventOnWait = true; - } - }; - -}; - /*#### # npc_omen ####*/ @@ -705,10 +174,6 @@ public: void AddSC_moonglade() { - new npc_bunthen_plainswind(); - new npc_great_bear_spirit(); - new npc_silva_filnaveth(); - new npc_clintar_spirit(); new npc_omen(); new npc_giant_spotlight(); } diff --git a/src/server/scripts/Kalimdor/zone_mulgore.cpp b/src/server/scripts/Kalimdor/zone_mulgore.cpp index fa35371f3f2..23def62047d 100644 --- a/src/server/scripts/Kalimdor/zone_mulgore.cpp +++ b/src/server/scripts/Kalimdor/zone_mulgore.cpp @@ -19,13 +19,12 @@ /* ScriptData SDName: Mulgore SD%Complete: 100 -SDComment: Support for quest: 11129, 772 +SDComment: Support for quest: 11129, 861 SDCategory: Mulgore EndScriptData */ /* ContentData npc_kyle_frenzied -npc_plains_vision EndContentData */ #include "ScriptMgr.h" @@ -57,7 +56,7 @@ public: CreatureAI* GetAI(Creature* creature) const override { - return new npc_kyle_frenziedAI(creature); + return new npc_kyle_frenziedAI (creature); } struct npc_kyle_frenziedAI : public ScriptedAI @@ -82,7 +81,7 @@ public: me->UpdateEntry(NPC_KYLE_FRENZIED); } - void SpellHit(Unit* Caster, SpellInfo const* Spell) override + void SpellHit(Unit* Caster, SpellInfo const* Spell) { if (!me->GetVictim() && !EventActive && Spell->Id == SPELL_LUNCH) { @@ -102,12 +101,12 @@ public: } } - void MovementInform(uint32 Type, uint32 PointId) override + void MovementInform(uint32 type, uint32 pointId) override { - if (Type != POINT_MOTION_TYPE || !EventActive) + if (type != POINT_MOTION_TYPE || !EventActive) return; - if (PointId == POINT_ID) + if (pointId == POINT_ID) IsMovingToLunch = false; } @@ -165,126 +164,7 @@ public: }; -/*##### -# npc_plains_vision -######*/ - -Position const wpPlainVision[50] = -{ - {-2226.32f, -408.095f, -9.36235f, 0.0f}, - {-2203.04f, -437.212f, -5.72498f, 0.0f}, - {-2163.91f, -457.851f, -7.09049f, 0.0f}, - {-2123.87f, -448.137f, -9.29591f, 0.0f}, - {-2104.66f, -427.166f, -6.49513f, 0.0f}, - {-2101.48f, -422.826f, -5.3567f, 0.0f}, - {-2097.56f, -417.083f, -7.16716f, 0.0f}, - {-2084.87f, -398.626f, -9.88973f, 0.0f}, - {-2072.71f, -382.324f, -10.2488f, 0.0f}, - {-2054.05f, -356.728f, -6.22468f, 0.0f}, - {-2051.8f, -353.645f, -5.35791f, 0.0f}, - {-2049.08f, -349.912f, -6.15723f, 0.0f}, - {-2030.6f, -310.724f, -9.59302f, 0.0f}, - {-2002.15f, -249.308f, -10.8124f, 0.0f}, - {-1972.85f, -195.811f, -10.6316f, 0.0f}, - {-1940.93f, -147.652f, -11.7055f, 0.0f}, - {-1888.06f, -81.943f, -11.4404f, 0.0f}, - {-1837.05f, -34.0109f, -12.258f, 0.0f}, - {-1796.12f, -14.6462f, -10.3581f, 0.0f}, - {-1732.61f, -4.27746f, -10.0213f, 0.0f}, - {-1688.94f, -0.829945f, -11.7103f, 0.0f}, - {-1681.32f, 13.0313f, -9.48056f, 0.0f}, - {-1677.04f, 36.8349f, -7.10318f, 0.0f}, - {-1675.2f, 68.559f, -8.95384f, 0.0f}, - {-1676.57f, 89.023f, -9.65104f, 0.0f}, - {-1678.16f, 110.939f, -10.1782f, 0.0f}, - {-1677.86f, 128.681f, -5.73869f, 0.0f}, - {-1675.27f, 144.324f, -3.47916f, 0.0f}, - {-1671.7f, 163.169f, -1.23098f, 0.0f}, - {-1666.61f, 181.584f, 5.26145f, 0.0f}, - {-1661.51f, 196.154f, 8.95252f, 0.0f}, - {-1655.47f, 210.811f, 8.38727f, 0.0f}, - {-1647.07f, 226.947f, 5.27755f, 0.0f}, - {-1621.65f, 232.91f, 2.69579f, 0.0f}, - {-1600.23f, 237.641f, 2.98539f, 0.0f}, - {-1576.07f, 242.546f, 4.66541f, 0.0f}, - {-1554.57f, 248.494f, 6.60377f, 0.0f}, - {-1547.53f, 259.302f, 10.6741f, 0.0f}, - {-1541.7f, 269.847f, 16.4418f, 0.0f}, - {-1539.83f, 278.989f, 21.0597f, 0.0f}, - {-1540.16f, 290.219f, 27.8247f, 0.0f}, - {-1538.99f, 298.983f, 34.0032f, 0.0f}, - {-1540.38f, 307.337f, 41.3557f, 0.0f}, - {-1536.61f, 314.884f, 48.0179f, 0.0f}, - {-1532.42f, 323.277f, 55.6667f, 0.0f}, - {-1528.77f, 329.774f, 61.1525f, 0.0f}, - {-1525.65f, 333.18f, 63.2161f, 0.0f}, - {-1517.01f, 350.713f, 62.4286f, 0.0f}, - {-1511.39f, 362.537f, 62.4539f, 0.0f}, - {-1508.68f, 366.822f, 62.733f, 0.0f} -}; - -class npc_plains_vision : public CreatureScript -{ -public: - npc_plains_vision() : CreatureScript("npc_plains_vision") { } - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_plains_visionAI(creature); - } - - struct npc_plains_visionAI : public ScriptedAI - { - npc_plains_visionAI(Creature* creature) : ScriptedAI(creature) { } - - bool newWaypoint; - uint8 WayPointId; - uint8 amountWP; - - void Reset() override - { - WayPointId = 0; - newWaypoint = true; - amountWP = 49; - } - - void EnterCombat(Unit* /*who*/) override { } - - void MovementInform(uint32 type, uint32 id) override - { - if (type != POINT_MOTION_TYPE) - return; - - if (id < amountWP) - { - ++WayPointId; - newWaypoint = true; - } - else - { - me->setDeathState(JUST_DIED); - me->RemoveCorpse(); - } - } - - void UpdateAI(uint32 /*diff*/) override - { - if (newWaypoint) - { - me->GetMotionMaster()->MovePoint(WayPointId, wpPlainVision[WayPointId]); - newWaypoint = false; - } - } - }; - -}; - -/*##### -# -######*/ - void AddSC_mulgore() { new npc_kyle_frenzied(); - new npc_plains_vision(); } diff --git a/src/server/scripts/Kalimdor/zone_orgrimmar.cpp b/src/server/scripts/Kalimdor/zone_orgrimmar.cpp index 36ea884cf50..22daddff5b9 100644 --- a/src/server/scripts/Kalimdor/zone_orgrimmar.cpp +++ b/src/server/scripts/Kalimdor/zone_orgrimmar.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2014 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,239 +15,6 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Orgrimmar -SD%Complete: 100 -SDComment: Quest support: 2460, 6566 -SDCategory: Orgrimmar -EndScriptData */ - -/* ContentData -npc_shenthul -npc_thrall_warchief -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "Player.h" - -/*###### -## npc_shenthul -######*/ - -enum Shenthul -{ - QUEST_SHATTERED_SALUTE = 2460 -}; - -class npc_shenthul : public CreatureScript -{ -public: - npc_shenthul() : CreatureScript("npc_shenthul") { } - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) override - { - if (quest->GetQuestId() == QUEST_SHATTERED_SALUTE) - { - CAST_AI(npc_shenthul::npc_shenthulAI, creature->AI())->CanTalk = true; - CAST_AI(npc_shenthul::npc_shenthulAI, creature->AI())->PlayerGUID = player->GetGUID(); - } - return true; - } - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_shenthulAI(creature); - } - - struct npc_shenthulAI : public ScriptedAI - { - npc_shenthulAI(Creature* creature) : ScriptedAI(creature) { } - - bool CanTalk; - bool CanEmote; - uint32 SaluteTimer; - uint32 ResetTimer; - uint64 PlayerGUID; - - void Reset() override - { - CanTalk = false; - CanEmote = false; - SaluteTimer = 6000; - ResetTimer = 0; - PlayerGUID = 0; - } - - void EnterCombat(Unit* /*who*/) override { } - - void UpdateAI(uint32 diff) override - { - if (CanEmote) - { - if (ResetTimer <= diff) - { - if (Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID)) - { - if (player->GetTypeId() == TYPEID_PLAYER && player->GetQuestStatus(QUEST_SHATTERED_SALUTE) == QUEST_STATUS_INCOMPLETE) - player->FailQuest(QUEST_SHATTERED_SALUTE); - } - Reset(); - } else ResetTimer -= diff; - } - - if (CanTalk && !CanEmote) - { - if (SaluteTimer <= diff) - { - me->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE); - CanEmote = true; - ResetTimer = 60000; - } else SaluteTimer -= diff; - } - - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - } - - void ReceiveEmote(Player* player, uint32 emote) override - { - if (emote == TEXT_EMOTE_SALUTE && player->GetQuestStatus(QUEST_SHATTERED_SALUTE) == QUEST_STATUS_INCOMPLETE) - { - if (CanEmote) - { - player->AreaExploredOrEventHappens(QUEST_SHATTERED_SALUTE); - Reset(); - } - } - } - }; - -}; - -/*###### -## npc_thrall_warchief -######*/ - -enum ThrallWarchief -{ - QUEST_6566 = 6566, - - SPELL_CHAIN_LIGHTNING = 16033, - SPELL_SHOCK = 16034 -}; - -#define GOSSIP_HTW "Please share your wisdom with me, Warchief." -#define GOSSIP_STW1 "What discoveries?" -#define GOSSIP_STW2 "Usurper?" -#define GOSSIP_STW3 "With all due respect, Warchief - why not allow them to be destroyed? Does this not strengthen our position?" -#define GOSSIP_STW4 "I... I did not think of it that way, Warchief." -#define GOSSIP_STW5 "I live only to serve, Warchief! My life is empty and meaningless without your guidance." -#define GOSSIP_STW6 "Of course, Warchief!" - -/// @todo verify abilities/timers -class npc_thrall_warchief : public CreatureScript -{ -public: - npc_thrall_warchief() : CreatureScript("npc_thrall_warchief") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF+1: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_STW1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); - player->SEND_GOSSIP_MENU(5733, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+2: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_STW2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3); - player->SEND_GOSSIP_MENU(5734, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+3: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_STW3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4); - player->SEND_GOSSIP_MENU(5735, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+4: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_STW4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5); - player->SEND_GOSSIP_MENU(5736, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+5: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_STW5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+6); - player->SEND_GOSSIP_MENU(5737, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+6: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_STW6, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+7); - player->SEND_GOSSIP_MENU(5738, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+7: - player->CLOSE_GOSSIP_MENU(); - player->AreaExploredOrEventHappens(QUEST_6566); - break; - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) override - { - if (creature->IsQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(QUEST_6566) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HTW, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - return true; - } - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_thrall_warchiefAI(creature); - } - - struct npc_thrall_warchiefAI : public ScriptedAI - { - npc_thrall_warchiefAI(Creature* creature) : ScriptedAI(creature) { } - - uint32 ChainLightningTimer; - uint32 ShockTimer; - - void Reset() override - { - ChainLightningTimer = 2000; - ShockTimer = 8000; - } - - void EnterCombat(Unit* /*who*/) override { } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - if (ChainLightningTimer <= diff) - { - DoCastVictim(SPELL_CHAIN_LIGHTNING); - ChainLightningTimer = 9000; - } else ChainLightningTimer -= diff; - - if (ShockTimer <= diff) - { - DoCastVictim(SPELL_SHOCK); - ShockTimer = 15000; - } else ShockTimer -= diff; - - DoMeleeAttackIfReady(); - } - }; - -}; - void AddSC_orgrimmar() { - new npc_shenthul(); - new npc_thrall_warchief(); } diff --git a/src/server/scripts/Kalimdor/zone_silithus.cpp b/src/server/scripts/Kalimdor/zone_silithus.cpp index 04cec70b7ad..00ef96dc785 100644 --- a/src/server/scripts/Kalimdor/zone_silithus.cpp +++ b/src/server/scripts/Kalimdor/zone_silithus.cpp @@ -19,13 +19,13 @@ /* ScriptData SDName: Silithus SD%Complete: 100 -SDComment: Quest support: 8304, 8507. +SDComment: Quest support: 7785, 8304. SDCategory: Silithus EndScriptData */ /* ContentData npcs_rutgar_and_frankal -quest_a_pawn_on_the_eternal_pawn +go_wind_stone EndContentData */ #include "ScriptMgr.h" diff --git a/src/server/scripts/Kalimdor/zone_stonetalon_mountains.cpp b/src/server/scripts/Kalimdor/zone_stonetalon_mountains.cpp index 7b29ced9860..251006ff545 100644 --- a/src/server/scripts/Kalimdor/zone_stonetalon_mountains.cpp +++ b/src/server/scripts/Kalimdor/zone_stonetalon_mountains.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2014 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,164 +15,6 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Stonetalon_Mountains -SD%Complete: 95 -SDComment: Quest support: 6627, 6523 -SDCategory: Stonetalon Mountains -EndScriptData */ - -/* ContentData -npc_braug_dimspirit -npc_kaya_flathoof -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "ScriptedEscortAI.h" -#include "Player.h" - -/*###### -## npc_braug_dimspirit -######*/ - -#define GOSSIP_HBD1 "Ysera" -#define GOSSIP_HBD2 "Neltharion" -#define GOSSIP_HBD3 "Nozdormu" -#define GOSSIP_HBD4 "Alexstrasza" -#define GOSSIP_HBD5 "Malygos" - -class npc_braug_dimspirit : public CreatureScript -{ -public: - npc_braug_dimspirit() : CreatureScript("npc_braug_dimspirit") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF+1) - { - player->CLOSE_GOSSIP_MENU(); - creature->CastSpell(player, 6766, false); - - } - if (action == GOSSIP_ACTION_INFO_DEF+2) - { - player->CLOSE_GOSSIP_MENU(); - player->AreaExploredOrEventHappens(6627); - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) override - { - if (creature->IsQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(6627) == QUEST_STATUS_INCOMPLETE) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HBD1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HBD2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HBD3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HBD4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HBD5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - - player->SEND_GOSSIP_MENU(5820, creature->GetGUID()); - } - else - player->SEND_GOSSIP_MENU(5819, creature->GetGUID()); - - return true; - } - -}; - -/*###### -## npc_kaya_flathoof -######*/ - -enum Kaya -{ - FACTION_ESCORTEE_H = 775, - - NPC_GRIMTOTEM_RUFFIAN = 11910, - NPC_GRIMTOTEM_BRUTE = 11912, - NPC_GRIMTOTEM_SORCERER = 11913, - - SAY_START = 0, - SAY_AMBUSH = 1, - SAY_END = 2, - - QUEST_PROTECT_KAYA = 6523 -}; - -class npc_kaya_flathoof : public CreatureScript -{ -public: - npc_kaya_flathoof() : CreatureScript("npc_kaya_flathoof") { } - - struct npc_kaya_flathoofAI : public npc_escortAI - { - npc_kaya_flathoofAI(Creature* creature) : npc_escortAI(creature) { } - - void WaypointReached(uint32 waypointId) override - { - Player* player = GetPlayerForEscort(); - if (!player) - return; - - switch (waypointId) - { - case 16: - Talk(SAY_AMBUSH); - me->SummonCreature(NPC_GRIMTOTEM_BRUTE, -48.53f, -503.34f, -46.31f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); - me->SummonCreature(NPC_GRIMTOTEM_RUFFIAN, -38.85f, -503.77f, -45.90f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); - me->SummonCreature(NPC_GRIMTOTEM_SORCERER, -36.37f, -496.23f, -45.71f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); - break; - case 18: - me->SetInFront(player); - Talk(SAY_END); - player->GroupEventHappens(QUEST_PROTECT_KAYA, me); - break; - } - } - - void JustSummoned(Creature* summoned) override - { - summoned->AI()->AttackStart(me); - } - - void Reset() override { } - }; - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) override - { - if (quest->GetQuestId() == QUEST_PROTECT_KAYA) - { - if (npc_escortAI* pEscortAI = CAST_AI(npc_kaya_flathoof::npc_kaya_flathoofAI, creature->AI())) - pEscortAI->Start(true, false, player->GetGUID()); - - creature->AI()->Talk(SAY_START); - creature->setFaction(113); - creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); - } - return true; - } - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_kaya_flathoofAI(creature); - } - -}; - -/*###### -## AddSC -######*/ - void AddSC_stonetalon_mountains() { - new npc_braug_dimspirit(); - new npc_kaya_flathoof(); } diff --git a/src/server/scripts/Kalimdor/zone_tanaris.cpp b/src/server/scripts/Kalimdor/zone_tanaris.cpp index 23e8e2f26ff..af0bfdd982d 100644 --- a/src/server/scripts/Kalimdor/zone_tanaris.cpp +++ b/src/server/scripts/Kalimdor/zone_tanaris.cpp @@ -19,17 +19,14 @@ /* ScriptData SDName: Tanaris SD%Complete: 80 -SDComment: Quest support: 648, 1560, 2954, 4005, 10277, 10279(Special flight path). +SDComment: Quest support: 648, 10277, 10279(Special flight path). SDCategory: Tanaris EndScriptData */ /* ContentData -npc_aquementas npc_custodian_of_time npc_steward_of_time -npc_stone_watcher_of_norgannon npc_OOX17 -npc_tooga EndContentData */ #include "ScriptMgr.h" @@ -59,7 +56,7 @@ public: CreatureAI* GetAI(Creature* creature) const override { - return new npc_aquementasAI(creature); + return new npc_aquementasAI (creature); } struct npc_aquementasAI : public ScriptedAI @@ -100,7 +97,7 @@ public: } } - void EnterCombat(Unit* who) override + void EnterCombat(Unit* who) { Talk(AGGRO_YELL_AQUE, who); } @@ -183,7 +180,7 @@ public: { npc_custodian_of_timeAI(Creature* creature) : npc_escortAI(creature) { } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId) { if (Player* player = GetPlayerForEscort()) { @@ -250,8 +247,7 @@ public: } } - void MoveInLineOfSight(Unit* who) override - + void MoveInLineOfSight(Unit* who) { if (HasEscortState(STATE_ESCORT_ESCORTING)) return; @@ -291,7 +287,7 @@ class npc_steward_of_time : public CreatureScript public: npc_steward_of_time() : CreatureScript("npc_steward_of_time") { } - bool OnQuestAccept(Player* player, Creature* /*creature*/, Quest const* quest) override + bool OnQuestAccept(Player* player, Creature* /*creature*/, Quest const* quest) { if (quest->GetQuestId() == 10279) //Quest: To The Master's Lair player->CastSpell(player, 34891, true); //(Flight through Caverns) @@ -299,7 +295,7 @@ public: return false; } - bool OnGossipSelect(Player* player, Creature* /*creature*/, uint32 /*sender*/, uint32 action) override + bool OnGossipSelect(Player* player, Creature* /*creature*/, uint32 /*sender*/, uint32 action) { player->PlayerTalkClass->ClearMenus(); if (action == GOSSIP_ACTION_INFO_DEF + 1) @@ -308,7 +304,7 @@ public: return true; } - bool OnGossipHello(Player* player, Creature* creature) override + bool OnGossipHello(Player* player, Creature* creature) { if (creature->IsQuestGiver()) player->PrepareQuestMenu(creature->GetGUID()); @@ -327,70 +323,6 @@ public: }; /*###### -## npc_stone_watcher_of_norgannon -######*/ - -#define GOSSIP_ITEM_NORGANNON_1 "What function do you serve?" -#define GOSSIP_ITEM_NORGANNON_2 "What are the Plates of Uldum?" -#define GOSSIP_ITEM_NORGANNON_3 "Where are the Plates of Uldum?" -#define GOSSIP_ITEM_NORGANNON_4 "Excuse me? We've been \"reschedueled for visitations\"? What does that mean?!" -#define GOSSIP_ITEM_NORGANNON_5 "So, what's inside Uldum?" -#define GOSSIP_ITEM_NORGANNON_6 "I will return when i have the Plates of Uldum." - -class npc_stone_watcher_of_norgannon : public CreatureScript -{ -public: - npc_stone_watcher_of_norgannon() : CreatureScript("npc_stone_watcher_of_norgannon") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_NORGANNON_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - player->SEND_GOSSIP_MENU(1675, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+1: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_NORGANNON_3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); - player->SEND_GOSSIP_MENU(1676, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+2: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_NORGANNON_4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3); - player->SEND_GOSSIP_MENU(1677, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+3: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_NORGANNON_5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4); - player->SEND_GOSSIP_MENU(1678, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+4: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_NORGANNON_6, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5); - player->SEND_GOSSIP_MENU(1679, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+5: - player->CLOSE_GOSSIP_MENU(); - player->AreaExploredOrEventHappens(2954); - break; - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) override - { - if (creature->IsQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(2954) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_NORGANNON_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - - player->SEND_GOSSIP_MENU(1674, creature->GetGUID()); - - return true; - } - -}; - -/*###### ## npc_OOX17 ######*/ @@ -413,7 +345,7 @@ class npc_OOX17 : public CreatureScript public: npc_OOX17() : CreatureScript("npc_OOX17") { } - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) override + bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) { if (quest->GetQuestId() == Q_OOX17) { @@ -438,7 +370,7 @@ public: { npc_OOX17AI(Creature* creature) : npc_escortAI(creature) { } - void WaypointReached(uint32 waypointId) override + void WaypointReached(uint32 waypointId) { if (Player* player = GetPlayerForEscort()) { @@ -508,7 +440,7 @@ class npc_tooga : public CreatureScript public: npc_tooga() : CreatureScript("npc_tooga") { } - bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) override + bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) { if (quest->GetQuestId() == QUEST_TOOGA) { @@ -543,8 +475,7 @@ public: TortaGUID = 0; } - void MoveInLineOfSight(Unit* who) override - + void MoveInLineOfSight(Unit* who) { FollowerAI::MoveInLineOfSight(who); @@ -562,7 +493,7 @@ public: } } - void MovementInform(uint32 MotionType, uint32 PointId) override + void MovementInform(uint32 MotionType, uint32 PointId) { FollowerAI::MovementInform(MotionType, PointId); @@ -573,7 +504,7 @@ public: SetFollowComplete(); } - void UpdateFollowerAI(uint32 Diff) override + void UpdateFollowerAI(uint32 Diff) { if (!UpdateVictim()) { @@ -645,10 +576,7 @@ public: void AddSC_tanaris() { - new npc_aquementas(); new npc_custodian_of_time(); new npc_steward_of_time(); - new npc_stone_watcher_of_norgannon(); 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 dabfee00065..42caaaca9fd 100644 --- a/src/server/scripts/Kalimdor/zone_the_barrens.cpp +++ b/src/server/scripts/Kalimdor/zone_the_barrens.cpp @@ -19,16 +19,11 @@ /* ScriptData SDName: The_Barrens SD%Complete: 90 -SDComment: Quest support: 863, 898, 1719, 2458, 4921, 6981, +SDComment: Quest support: 863 SDCategory: Barrens EndScriptData */ /* ContentData -npc_beaten_corpse -npc_gilthares -npc_sputtervalve -npc_taskmaster_fizzule -npc_twiggy_flathead npc_wizzlecrank_shredder EndContentData */ @@ -652,9 +647,5 @@ public: void AddSC_the_barrens() { - new npc_beaten_corpse(); - new npc_gilthares(); - new npc_taskmaster_fizzule(); - new npc_twiggy_flathead(); new npc_wizzlecrank_shredder(); } diff --git a/src/server/scripts/Kalimdor/zone_thousand_needles.cpp b/src/server/scripts/Kalimdor/zone_thousand_needles.cpp index b36037d9995..46df1cb3397 100644 --- a/src/server/scripts/Kalimdor/zone_thousand_needles.cpp +++ b/src/server/scripts/Kalimdor/zone_thousand_needles.cpp @@ -16,448 +16,6 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Thousand Needles -SD%Complete: 100 -SDComment: Support for Quest: 1950, 4770, 4904, 4966, 5151. -SDCategory: Thousand Needles -EndScriptData */ - -/* ContentData -npc_kanati -npc_lakota_windsong -npc_swiftmountain -npc_plucky -npc_enraged_panther -go_panther_cage -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "ScriptedEscortAI.h" -#include "Player.h" - -/*##### -# npc_kanati -######*/ - -enum Kanati -{ - SAY_KAN_START = 0, - - QUEST_PROTECT_KANATI = 4966, - NPC_GALAK_ASS = 10720 -}; - -Position const GalakLoc = {-4867.387695f, -1357.353760f, -48.226f, 0.0f}; - -class npc_kanati : public CreatureScript -{ -public: - npc_kanati() : CreatureScript("npc_kanati") { } - - bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) override - { - if (quest->GetQuestId() == QUEST_PROTECT_KANATI) - if (npc_kanatiAI* pEscortAI = CAST_AI(npc_kanati::npc_kanatiAI, creature->AI())) - pEscortAI->Start(false, false, player->GetGUID(), quest, true); - - return true; - } - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_kanatiAI(creature); - } - - struct npc_kanatiAI : public npc_escortAI - { - npc_kanatiAI(Creature* creature) : npc_escortAI(creature) { } - - void Reset() override { } - - void WaypointReached(uint32 waypointId) override - { - switch (waypointId) - { - case 0: - Talk(SAY_KAN_START); - DoSpawnGalak(); - break; - case 1: - if (Player* player = GetPlayerForEscort()) - player->GroupEventHappens(QUEST_PROTECT_KANATI, me); - break; - } - } - - void DoSpawnGalak() - { - for (int i = 0; i < 3; ++i) - me->SummonCreature(NPC_GALAK_ASS, GalakLoc, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - } - - void JustSummoned(Creature* summoned) override - { - summoned->AI()->AttackStart(me); - } - }; - -}; - -/*###### -# npc_lakota_windsong -######*/ - -enum Lakota -{ - SAY_LAKO_START = 0, - SAY_LAKO_LOOK_OUT = 1, - SAY_LAKO_HERE_COME = 2, - SAY_LAKO_MORE = 3, - SAY_LAKO_END = 4, - - QUEST_FREE_AT_LAST = 4904, - NPC_GRIM_BANDIT = 10758, - FACTION_ESCORTEE_LAKO = 232, //guessed - - ID_AMBUSH_1 = 0, - ID_AMBUSH_2 = 2, - ID_AMBUSH_3 = 4 -}; - -Position const BanditLoc[6] = -{ - {-4905.479492f, -2062.732666f, 84.352f, 0.0f}, - {-4915.201172f, -2073.528320f, 84.733f, 0.0f}, - {-4878.883301f, -1986.947876f, 91.966f, 0.0f}, - {-4877.503906f, -1966.113403f, 91.859f, 0.0f}, - {-4767.985352f, -1873.169189f, 90.192f, 0.0f}, - {-4788.861328f, -1888.007813f, 89.888f, 0.0f} -}; - -class npc_lakota_windsong : public CreatureScript -{ -public: - npc_lakota_windsong() : CreatureScript("npc_lakota_windsong") { } - - bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) override - { - if (quest->GetQuestId() == QUEST_FREE_AT_LAST) - { - creature->AI()->Talk(SAY_LAKO_START, player); - creature->setFaction(FACTION_ESCORTEE_LAKO); - - if (npc_lakota_windsongAI* pEscortAI = CAST_AI(npc_lakota_windsong::npc_lakota_windsongAI, creature->AI())) - pEscortAI->Start(false, false, player->GetGUID(), quest); - } - return true; - } - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_lakota_windsongAI(creature); - } - - struct npc_lakota_windsongAI : public npc_escortAI - { - npc_lakota_windsongAI(Creature* creature) : npc_escortAI(creature) { } - - void Reset() override { } - - void WaypointReached(uint32 waypointId) override - { - switch (waypointId) - { - case 8: - Talk(SAY_LAKO_LOOK_OUT); - DoSpawnBandits(ID_AMBUSH_1); - break; - case 14: - Talk(SAY_LAKO_HERE_COME); - DoSpawnBandits(ID_AMBUSH_2); - break; - case 21: - Talk(SAY_LAKO_MORE); - DoSpawnBandits(ID_AMBUSH_3); - break; - case 45: - if (Player* player = GetPlayerForEscort()) - player->GroupEventHappens(QUEST_FREE_AT_LAST, me); - break; - } - } - - void DoSpawnBandits(int AmbushId) - { - for (int i = 0; i < 2; ++i) - me->SummonCreature(NPC_GRIM_BANDIT, BanditLoc[i+AmbushId], TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 60000); - } - }; - -}; - -/*###### -# npc_paoka_swiftmountain -######*/ - -enum Packa -{ - SAY_START = 0, - SAY_WYVERN = 1, - SAY_COMPLETE = 2, - - QUEST_HOMEWARD = 4770, - NPC_WYVERN = 4107, - FACTION_ESCORTEE = 232 //guessed -}; - -Position const WyvernLoc[3] = -{ - {-4990.606f, -906.057f, -5.343f, 0.0f}, - {-4970.241f, -927.378f, -4.951f, 0.0f}, - {-4985.364f, -952.528f, -5.199f, 0.0f} -}; - -class npc_paoka_swiftmountain : public CreatureScript -{ -public: - npc_paoka_swiftmountain() : CreatureScript("npc_paoka_swiftmountain") { } - - bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) override - { - if (quest->GetQuestId() == QUEST_HOMEWARD) - { - creature->AI()->Talk(SAY_START, player); - creature->setFaction(FACTION_ESCORTEE); - - if (npc_paoka_swiftmountainAI* pEscortAI = CAST_AI(npc_paoka_swiftmountain::npc_paoka_swiftmountainAI, creature->AI())) - pEscortAI->Start(false, false, player->GetGUID(), quest); - } - return true; - } - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_paoka_swiftmountainAI(creature); - } - - struct npc_paoka_swiftmountainAI : public npc_escortAI - { - npc_paoka_swiftmountainAI(Creature* creature) : npc_escortAI(creature) { } - - void Reset() override { } - - void WaypointReached(uint32 waypointId) override - { - switch (waypointId) - { - case 15: - Talk(SAY_WYVERN); - DoSpawnWyvern(); - break; - case 26: - Talk(SAY_COMPLETE); - break; - case 27: - if (Player* player = GetPlayerForEscort()) - player->GroupEventHappens(QUEST_HOMEWARD, me); - break; - } - } - - void DoSpawnWyvern() - { - for (int i = 0; i < 3; ++i) - me->SummonCreature(NPC_WYVERN, WyvernLoc[i], TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 60000); - } - }; -}; - -/*##### -# npc_plucky -######*/ - -#define GOSSIP_P "Please tell me the Phrase.." - -enum Plucky -{ - FACTION_FRIENDLY = 35, - QUEST_SCOOP = 1950, - SPELL_PLUCKY_HUMAN = 9192, - SPELL_PLUCKY_CHICKEN = 9220 -}; - -class npc_plucky : public CreatureScript -{ -public: - npc_plucky() : CreatureScript("npc_plucky") { } - - bool OnGossipSelect(Player* player, Creature* /*creature*/, uint32 /*sender*/, uint32 action) override - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF+1: - player->CLOSE_GOSSIP_MENU(); - player->CompleteQuest(QUEST_SCOOP); - break; - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) override - { - if (player->GetQuestStatus(QUEST_SCOOP) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_P, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - - player->SEND_GOSSIP_MENU(738, creature->GetGUID()); - - return true; - } - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_pluckyAI(creature); - } - - struct npc_pluckyAI : public ScriptedAI - { - npc_pluckyAI(Creature* creature) : ScriptedAI(creature) { NormFaction = creature->getFaction(); } - - uint32 NormFaction; - uint32 ResetTimer; - - void Reset() override - { - ResetTimer = 120000; - - if (me->getFaction() != NormFaction) - me->setFaction(NormFaction); - - if (me->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP)) - me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - - DoCast(me, SPELL_PLUCKY_CHICKEN, false); - } - - void ReceiveEmote(Player* player, uint32 TextEmote) override - { - if (player->GetQuestStatus(QUEST_SCOOP) == QUEST_STATUS_INCOMPLETE) - { - if (TextEmote == TEXT_EMOTE_BECKON) - { - me->setFaction(FACTION_FRIENDLY); - me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - DoCast(me, SPELL_PLUCKY_HUMAN, false); - } - } - - if (TextEmote == TEXT_EMOTE_CHICKEN) - { - if (me->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP)) - return; - else - { - me->setFaction(FACTION_FRIENDLY); - me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - DoCast(me, SPELL_PLUCKY_HUMAN, false); - me->HandleEmoteCommand(EMOTE_ONESHOT_WAVE); - } - } - } - - void UpdateAI(uint32 Diff) override - { - if (me->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP)) - { - if (ResetTimer <= Diff) - { - if (!me->GetVictim()) - EnterEvadeMode(); - else - me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - - return; - } - else - ResetTimer -= Diff; - } - - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - } - }; - -}; - -enum PantherCage -{ - ENRAGED_PANTHER = 10992 -}; - -class go_panther_cage : public GameObjectScript -{ -public: - go_panther_cage() : GameObjectScript("go_panther_cage") { } - - bool OnGossipHello(Player* player, GameObject* go) override - { - go->UseDoorOrButton(); - if (player->GetQuestStatus(5151) == QUEST_STATUS_INCOMPLETE) - { - if (Creature* panther = go->FindNearestCreature(ENRAGED_PANTHER, 5, true)) - { - panther->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - panther->SetReactState(REACT_AGGRESSIVE); - panther->AI()->AttackStart(player); - } - } - - return true; - } -}; - -class npc_enraged_panther : public CreatureScript -{ -public: - npc_enraged_panther() : CreatureScript("npc_enraged_panther") { } - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_enraged_pantherAI(creature); - } - - struct npc_enraged_pantherAI : public ScriptedAI - { - npc_enraged_pantherAI(Creature* creature) : ScriptedAI(creature) { } - - void Reset() override - { - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - me->SetReactState(REACT_PASSIVE); - } - - void UpdateAI(uint32 /*diff*/) override - { - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - } - }; - -}; - void AddSC_thousand_needles() { - new npc_kanati(); - new npc_lakota_windsong(); - new npc_paoka_swiftmountain(); - new npc_plucky(); - new npc_enraged_panther(); - new go_panther_cage(); } diff --git a/src/server/scripts/Kalimdor/zone_thunder_bluff.cpp b/src/server/scripts/Kalimdor/zone_thunder_bluff.cpp index 3b303ffa463..ea76dac829a 100644 --- a/src/server/scripts/Kalimdor/zone_thunder_bluff.cpp +++ b/src/server/scripts/Kalimdor/zone_thunder_bluff.cpp @@ -48,33 +48,9 @@ class npc_cairne_bloodhoof : public CreatureScript public: npc_cairne_bloodhoof() : CreatureScript("npc_cairne_bloodhoof") { } - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_SENDER_INFO) - { - player->CastSpell(player, 23123, false); - player->SEND_GOSSIP_MENU(7014, creature->GetGUID()); - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) override - { - if (creature->IsQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(925) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HCB, GOSSIP_SENDER_MAIN, GOSSIP_SENDER_INFO); - - player->SEND_GOSSIP_MENU(7013, creature->GetGUID()); - - return true; - } - CreatureAI* GetAI(Creature* creature) const override { - return new npc_cairne_bloodhoofAI(creature); + return new npc_cairne_bloodhoofAI (creature); } struct npc_cairne_bloodhoofAI : public ScriptedAI diff --git a/src/server/scripts/Kalimdor/zone_ungoro_crater.cpp b/src/server/scripts/Kalimdor/zone_ungoro_crater.cpp index 09f82b0417c..80354cbb1fd 100644 --- a/src/server/scripts/Kalimdor/zone_ungoro_crater.cpp +++ b/src/server/scripts/Kalimdor/zone_ungoro_crater.cpp @@ -16,334 +16,6 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Ungoro Crater -SD%Complete: 100 -SDComment: Support for Quest: 4245, 4491 -SDCategory: Ungoro Crater -EndScriptData */ - -/* ContentData -npc_a-me -npc_ringo -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedEscortAI.h" -#include "ScriptedFollowerAI.h" -#include "Player.h" -#include "SpellInfo.h" - -enum AmeData -{ - SAY_READY = 0, - SAY_AGGRO1 = 1, - SAY_SEARCH = 2, - SAY_AGGRO2 = 3, - SAY_AGGRO3 = 4, - SAY_FINISH = 5, - - SPELL_DEMORALIZINGSHOUT = 13730, - - QUEST_CHASING_AME = 4245, - ENTRY_TARLORD = 6519, - ENTRY_TARLORD1 = 6519, - ENTRY_STOMPER = 6513, -}; - -class npc_ame : public CreatureScript -{ -public: - npc_ame() : CreatureScript("npc_ame") { } - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) override - { - if (quest->GetQuestId() == QUEST_CHASING_AME) - { - CAST_AI(npc_escortAI, (creature->AI()))->Start(false, false, player->GetGUID()); - creature->AI()->Talk(SAY_READY, player); - creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); - // Change faction so mobs attack - creature->setFaction(113); - } - return true; - } - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_ameAI(creature); - } - - struct npc_ameAI : public npc_escortAI - { - npc_ameAI(Creature* creature) : npc_escortAI(creature) { } - - uint32 DemoralizingShoutTimer; - - void WaypointReached(uint32 waypointId) override - { - if (Player* player = GetPlayerForEscort()) - { - switch (waypointId) - { - case 19: - me->SummonCreature(ENTRY_STOMPER, -6391.69f, -1730.49f, -272.83f, 4.96f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - Talk(SAY_AGGRO1, player); - break; - case 28: - Talk(SAY_SEARCH, player); - break; - case 38: - me->SummonCreature(ENTRY_TARLORD, -6370.75f, -1382.84f, -270.51f, 6.06f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - Talk(SAY_AGGRO2, player); - break; - case 49: - me->SummonCreature(ENTRY_TARLORD1, -6324.44f, -1181.05f, -270.17f, 4.34f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - Talk(SAY_AGGRO3, player); - break; - case 55: - Talk(SAY_FINISH, player); - player->GroupEventHappens(QUEST_CHASING_AME, me); - break; - } - } - } - - void Reset() override - { - DemoralizingShoutTimer = 5000; - } - - void JustSummoned(Creature* summoned) override - { - summoned->AI()->AttackStart(me); - } - - void JustDied(Unit* /*killer*/) override - { - if (Player* player = GetPlayerForEscort()) - player->FailQuest(QUEST_CHASING_AME); - } - - void UpdateAI(uint32 diff) override - { - npc_escortAI::UpdateAI(diff); - if (!UpdateVictim()) - return; - - if (DemoralizingShoutTimer <= diff) - { - DoCastVictim(SPELL_DEMORALIZINGSHOUT); - DemoralizingShoutTimer = 70000; - } else DemoralizingShoutTimer -= diff; - } - }; -}; - -/*#### -# npc_ringo -####*/ - -enum Ringo -{ - SAY_RIN_START = 0, - - SAY_FAINT = 1, - - SAY_WAKE = 2, - - SAY_RIN_END_1 = 3, - SAY_SPR_END_2 = 0, - SAY_RIN_END_3 = 4, - EMOTE_RIN_END_4 = 5, - EMOTE_RIN_END_5 = 6, - SAY_RIN_END_6 = 7, - SAY_SPR_END_7 = 1, - EMOTE_RIN_END_8 = 8, - - SPELL_REVIVE_RINGO = 15591, - QUEST_A_LITTLE_HELP = 4491, - NPC_SPRAGGLE = 9997, - FACTION_ESCORTEE = 113 -}; - -class npc_ringo : public CreatureScript -{ -public: - npc_ringo() : CreatureScript("npc_ringo") { } - - bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) override - { - if (quest->GetQuestId() == QUEST_A_LITTLE_HELP) - { - if (npc_ringoAI* ringoAI = CAST_AI(npc_ringo::npc_ringoAI, creature->AI())) - { - creature->SetStandState(UNIT_STAND_STATE_STAND); - ringoAI->StartFollow(player, FACTION_ESCORTEE, quest); - } - } - - return true; - } - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_ringoAI(creature); - } - - struct npc_ringoAI : public FollowerAI - { - npc_ringoAI(Creature* creature) : FollowerAI(creature) { } - - uint32 FaintTimer; - uint32 EndEventProgress; - uint32 EndEventTimer; - - uint64 SpraggleGUID; - - void Reset() override - { - FaintTimer = urand(30000, 60000); - EndEventProgress = 0; - EndEventTimer = 1000; - SpraggleGUID = 0; - } - - void MoveInLineOfSight(Unit* who) override - - { - FollowerAI::MoveInLineOfSight(who); - - if (!me->GetVictim() && !HasFollowState(STATE_FOLLOW_COMPLETE) && who->GetEntry() == NPC_SPRAGGLE) - { - if (me->IsWithinDistInMap(who, INTERACTION_DISTANCE)) - { - if (Player* player = GetLeaderForFollower()) - { - if (player->GetQuestStatus(QUEST_A_LITTLE_HELP) == QUEST_STATUS_INCOMPLETE) - player->GroupEventHappens(QUEST_A_LITTLE_HELP, me); - } - - SpraggleGUID = who->GetGUID(); - SetFollowComplete(true); - } - } - } - - void SpellHit(Unit* /*pCaster*/, const SpellInfo* pSpell) override - { - if (HasFollowState(STATE_FOLLOW_INPROGRESS | STATE_FOLLOW_PAUSED) && pSpell->Id == SPELL_REVIVE_RINGO) - ClearFaint(); - } - - void SetFaint() - { - if (!HasFollowState(STATE_FOLLOW_POSTEVENT)) - { - SetFollowPaused(true); - - Talk(SAY_FAINT); - } - - //what does actually happen here? Emote? Aura? - me->SetStandState(UNIT_STAND_STATE_SLEEP); - } - - void ClearFaint() - { - me->SetStandState(UNIT_STAND_STATE_STAND); - - if (HasFollowState(STATE_FOLLOW_POSTEVENT)) - return; - - Talk(SAY_WAKE); - - SetFollowPaused(false); - } - - void UpdateFollowerAI(uint32 Diff) override - { - if (!UpdateVictim()) - { - if (HasFollowState(STATE_FOLLOW_POSTEVENT)) - { - if (EndEventTimer <= Diff) - { - Creature* spraggle = ObjectAccessor::GetCreature(*me, SpraggleGUID); - if (!spraggle || !spraggle->IsAlive()) - { - SetFollowComplete(); - return; - } - - switch (EndEventProgress) - { - case 1: - Talk(SAY_RIN_END_1); - EndEventTimer = 3000; - break; - case 2: - spraggle->AI()->Talk(SAY_SPR_END_2); - EndEventTimer = 5000; - break; - case 3: - Talk(SAY_RIN_END_3); - EndEventTimer = 1000; - break; - case 4: - Talk(EMOTE_RIN_END_4); - SetFaint(); - EndEventTimer = 9000; - break; - case 5: - Talk(EMOTE_RIN_END_5); - ClearFaint(); - EndEventTimer = 1000; - break; - case 6: - Talk(SAY_RIN_END_6); - EndEventTimer = 3000; - break; - case 7: - spraggle->AI()->Talk(SAY_SPR_END_7); - EndEventTimer = 10000; - break; - case 8: - Talk(EMOTE_RIN_END_8); - EndEventTimer = 5000; - break; - case 9: - SetFollowComplete(); - break; - } - - ++EndEventProgress; - } - else - EndEventTimer -= Diff; - } - else if (HasFollowState(STATE_FOLLOW_INPROGRESS) && !HasFollowState(STATE_FOLLOW_PAUSED)) - { - if (FaintTimer <= Diff) - { - SetFaint(); - FaintTimer = urand(60000, 120000); - } - else - FaintTimer -= Diff; - } - - return; - } - - DoMeleeAttackIfReady(); - } - }; -}; - void AddSC_ungoro_crater() { - new npc_ame(); - new npc_ringo(); } diff --git a/src/server/scripts/Maelstrom/CMakeLists.txt b/src/server/scripts/Maelstrom/CMakeLists.txt new file mode 100644 index 00000000000..79f0789fd3f --- /dev/null +++ b/src/server/scripts/Maelstrom/CMakeLists.txt @@ -0,0 +1,14 @@ +# This file is free software; as a special exception the author gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +set(scripts_STAT_SRCS + ${scripts_STAT_SRCS} + Maelstrom/kezan.cpp +) + +message(" -> Prepared: The Maelstrom") diff --git a/src/server/scripts/Maelstrom/kezan.cpp b/src/server/scripts/Maelstrom/kezan.cpp new file mode 100644 index 00000000000..7deae4267eb --- /dev/null +++ b/src/server/scripts/Maelstrom/kezan.cpp @@ -0,0 +1,18 @@ +/* + * 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 3 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/>. + */ + +void AddSC_kezan() +{ +} diff --git a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_elder_nadox.cpp b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_elder_nadox.cpp index ab142c1375c..f415eeacc78 100644 --- a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_elder_nadox.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_elder_nadox.cpp @@ -145,7 +145,7 @@ class boss_elder_nadox : public CreatureScript } } - if (me->HealthBelowPct(100 - AmountHealthModifier * 25)) + if (me->HealthBelowPct(100 - AmountHealthModifier* 25)) { Talk(EMOTE_HATCHES, me); DoCast(me, SPELL_SUMMON_SWARM_GUARD); @@ -271,7 +271,7 @@ public: void FilterTargets(std::list<WorldObject*>& targets) { - targets.remove_if(GuardianCheck()); + targets.remove_if (GuardianCheck()); } void Register() override diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp index f352b4faace..9404694e706 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp +++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp @@ -20,7 +20,6 @@ #include "SpellAuraEffects.h" #include "Spell.h" #include "Vehicle.h" -#include "MapManager.h" #include "GameObjectAI.h" #include "ScriptedCreature.h" #include "ruby_sanctum.h" 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 2e24398d49a..b39734224f6 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp @@ -132,9 +132,9 @@ bool GrandChampionsOutVehicle(Creature* me) if (pGrandChampion1 && pGrandChampion2 && pGrandChampion3) { - if (!pGrandChampion1->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && - !pGrandChampion2->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && - !pGrandChampion3->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT)) + if (!pGrandChampion1->m_movementInfo.transport.guid && + !pGrandChampion2->m_movementInfo.transport.guid && + !pGrandChampion3->m_movementInfo.transport.guid) return true; } @@ -383,7 +383,7 @@ public: } }else uiPhaseTimer -= uiDiff; - if (!UpdateVictim() || me->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT)) + if (!UpdateVictim() || me->m_movementInfo.transport.guid) return; if (uiInterceptTimer <= uiDiff) @@ -525,7 +525,7 @@ public: uiFireBallTimer = 5000; } else uiFireBallTimer -= uiDiff; - if (!UpdateVictim() || me->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT)) + if (!UpdateVictim() || me->m_movementInfo.transport.guid) return; if (uiFireBallTimer <= uiDiff) @@ -661,7 +661,7 @@ public: } }else uiPhaseTimer -= uiDiff; - if (!UpdateVictim() || me->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT)) + if (!UpdateVictim() || me->m_movementInfo.transport.guid) return; if (uiChainLightningTimer <= uiDiff) @@ -805,7 +805,7 @@ public: } }else uiPhaseTimer -= uiDiff; - if (!UpdateVictim() || me->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT)) + if (!UpdateVictim() || me->m_movementInfo.transport.guid) return; if (uiLightningArrowsTimer <= uiDiff) @@ -951,7 +951,7 @@ public: } } else uiPhaseTimer -= uiDiff; - if (!UpdateVictim() || me->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT)) + if (!UpdateVictim() || me->m_movementInfo.transport.guid) return; if (uiEviscerateTimer <= uiDiff) diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp index d59e723d070..a60d2cfd823 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp @@ -356,7 +356,7 @@ class boss_lady_deathwhisper : public CreatureScript void DamageTaken(Unit* /*damageDealer*/, uint32& damage) override { // phase transition - if (events.IsInPhase(PHASE_ONE) && damage > me->GetPower(POWER_MANA)) + if (events.IsInPhase(PHASE_ONE) && damage > uint32(me->GetPower(POWER_MANA))) { Talk(SAY_PHASE_2); Talk(EMOTE_PHASE_2); 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 223f3731032..569a81ee9cc 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp @@ -343,9 +343,7 @@ enum MiscData SOUND_PAIN = 17360, // separate sound, not attached to any text EQUIP_ASHBRINGER_GLOWING = 50442, - EQUIP_BROKEN_FROSTMOURNE = 50840, - - MOVIE_FALL_OF_THE_LICH_KING = 16, + EQUIP_BROKEN_FROSTMOURNE = 50840 }; enum Misc @@ -377,25 +375,6 @@ class NecroticPlagueTargetCheck : public std::unary_function<Unit*, bool> uint32 _notAura2; }; -class HeightDifferenceCheck -{ - public: - HeightDifferenceCheck(GameObject* go, float diff, bool reverse) - : _baseObject(go), _difference(diff), _reverse(reverse) - { - } - - bool operator()(WorldObject* unit) const - { - return (unit->GetPositionZ() - _baseObject->GetPositionZ() > _difference) != _reverse; - } - - private: - GameObject* _baseObject; - float _difference; - bool _reverse; -}; - class FrozenThroneResetWorker { public: @@ -1493,7 +1472,7 @@ class npc_valkyr_shadowguard : public CreatureScript { std::list<Creature*> triggers; GetCreatureListWithEntryInGrid(triggers, me, NPC_WORLD_TRIGGER, 150.0f); - triggers.remove_if(HeightDifferenceCheck(platform, 5.0f, true)); + triggers.remove_if(Trinity::HeightDifferenceCheck(platform, 5.0f, true)); if (triggers.empty()) return; @@ -2283,7 +2262,7 @@ class spell_the_lich_king_quake : public SpellScriptLoader void FilterTargets(std::list<WorldObject*>& targets) { if (GameObject* platform = ObjectAccessor::GetGameObject(*GetCaster(), GetCaster()->GetInstanceScript()->GetData64(DATA_ARTHAS_PLATFORM))) - targets.remove_if(HeightDifferenceCheck(platform, 5.0f, false)); + targets.remove_if(Trinity::HeightDifferenceCheck(platform, 5.0f, false)); } void HandleSendEvent(SpellEffIndex /*effIndex*/) @@ -3114,41 +3093,6 @@ class spell_the_lich_king_jump_remove_aura : public SpellScriptLoader } }; -class spell_the_lich_king_play_movie : public SpellScriptLoader -{ - public: - spell_the_lich_king_play_movie() : SpellScriptLoader("spell_the_lich_king_play_movie") { } - - class spell_the_lich_king_play_movie_SpellScript : public SpellScript - { - PrepareSpellScript(spell_the_lich_king_play_movie_SpellScript); - - bool Validate(SpellInfo const* /*spell*/) override - { - if (!sMovieStore.LookupEntry(MOVIE_FALL_OF_THE_LICH_KING)) - return false; - return true; - } - - void HandleScript(SpellEffIndex effIndex) - { - PreventHitDefaultEffect(effIndex); - if (Player* player = GetHitPlayer()) - player->SendMovieStart(MOVIE_FALL_OF_THE_LICH_KING); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_the_lich_king_play_movie_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - } - }; - - SpellScript* GetSpellScript() const override - { - return new spell_the_lich_king_play_movie_SpellScript(); - } -}; - class achievement_been_waiting_long_time : public AchievementCriteriaScript { public: @@ -3218,7 +3162,6 @@ void AddSC_boss_the_lich_king() new spell_the_lich_king_jump(); new spell_the_lich_king_jump_remove_aura(); new spell_trigger_spell_from_caster("spell_the_lich_king_mass_resurrection", SPELL_MASS_RESURRECTION_REAL); - new spell_the_lich_king_play_movie(); new achievement_been_waiting_long_time(); new achievement_neck_deep_in_vile(); } diff --git a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp index 514a2b52475..3dd39d85eb2 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp @@ -600,13 +600,9 @@ class instance_icecrown_citadel : public InstanceMapScript go->SetGoState(GO_STATE_ACTIVE); break; case GO_ARTHAS_PLATFORM: - // this enables movement at The Frozen Throne, when printed this value is 0.000000f - // however, when represented as integer client will accept only this value - go->SetUInt32Value(GAMEOBJECT_PARENTROTATION, 5535469); ArthasPlatformGUID = go->GetGUID(); break; case GO_ARTHAS_PRECIPICE: - go->SetUInt32Value(GAMEOBJECT_PARENTROTATION, 4178312); ArthasPrecipiceGUID = go->GetGUID(); break; case GO_DOODAD_ICECROWN_THRONEFROSTYEDGE01: diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp index fefdfa633ea..5291e4baed3 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp @@ -95,8 +95,8 @@ enum Spells SPELL_RANDOM_PORTAL = 56047, SPELL_PORTAL_BEAM = 56046, // Malygos cast on portal to activate it during PHASE_NOT_STARTED - //Phase I - SPELL_BERSERK = 60670, + // Phase I + SPELL_BERSERK = 60670, SPELL_MALYGOS_BERSERK = 47008, // it's the berserk spell that will hit only Malygos after 10 min of 60670 SPELL_PORTAL_VISUAL_CLOSED = 55949, SPELL_SUMMON_POWER_PARK = 56142, @@ -1513,7 +1513,7 @@ public: } } - void UpdateAI(uint32 /*diff*/) + void UpdateAI(uint32 /*diff*/) override { } diff --git a/src/server/scripts/Northrend/Nexus/Nexus/boss_commander_stoutbeard.cpp b/src/server/scripts/Northrend/Nexus/Nexus/boss_commander_stoutbeard.cpp index c1ecdff8576..03f1f504e01 100644 --- a/src/server/scripts/Northrend/Nexus/Nexus/boss_commander_stoutbeard.cpp +++ b/src/server/scripts/Northrend/Nexus/Nexus/boss_commander_stoutbeard.cpp @@ -35,7 +35,6 @@ enum CommanderStoutbeard SPELL_WHIRLWIND_2 = 38618 }; - class boss_commander_stoutbeard : public CreatureScript { public: diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp index f0b8e123c63..132fef56c75 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp @@ -535,7 +535,6 @@ class spell_auriaya_sentinel_blast : public SpellScriptLoader } }; - class achievement_nine_lives : public AchievementCriteriaScript { public: 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 52cda5148cf..16dac4b2d4d 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp @@ -535,7 +535,7 @@ class boss_flame_leviathan : public CreatureScript } private: - //! Copypasta from DoSpellAttackIfReady, only difference is the target - it cannot be selected trough getVictim this way - + //! Copypasta from DoSpellAttackIfReady, only difference is the target - it cannot be selected trough GetVictim this way - //! I also removed the spellInfo check void DoBatteringRamIfReady() { @@ -1181,7 +1181,7 @@ class npc_lorekeeper : public CreatureScript if (Creature* Branz = creature->FindNearestCreature(NPC_BRANZ_BRONZBEARD, 1000, true)) { Delorah->GetMotionMaster()->MovePoint(0, Branz->GetPositionX()-4, Branz->GetPositionY(), Branz->GetPositionZ()); - /// @todo Delorah->AI()->Talk(xxxx, Branz->GetGUID()); when reached at branz + /// @todo Delorah->AI()->Talk(xxxx, Branz); when reached at branz } } } diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_keleseth.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_keleseth.cpp index 890c39fa775..a840f29072f 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_keleseth.cpp +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_keleseth.cpp @@ -348,7 +348,6 @@ class spell_frost_tomb : public SpellScriptLoader } }; - class achievement_on_the_rocks : public AchievementCriteriaScript { public: diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/utgarde_keep.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/utgarde_keep.cpp index e54c8847d46..ebd0b4c0bb0 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/utgarde_keep.cpp +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/utgarde_keep.cpp @@ -21,6 +21,11 @@ #include "SpellScript.h" #include "SpellAuraEffects.h" +enum Spells +{ + SPELL_UK_SECOUND_WIND_TRIGGER = 42771 +}; + uint32 ForgeSearch[3] = { GO_GLOWING_ANVIL_1, @@ -295,10 +300,56 @@ class npc_enslaved_proto_drake : public CreatureScript } }; +class spell_uk_second_wind_proc : public SpellScriptLoader +{ + public: + spell_uk_second_wind_proc() : SpellScriptLoader("spell_uk_second_wind_proc") { } + + class spell_uk_second_wind_proc_AuraScript : public AuraScript + { + PrepareAuraScript(spell_uk_second_wind_proc_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_UK_SECOUND_WIND_TRIGGER)) + return false; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + if (eventInfo.GetProcTarget() == GetTarget()) + return false; + if (!(eventInfo.GetDamageInfo() || eventInfo.GetDamageInfo()->GetSpellInfo()->GetAllEffectsMechanicMask() & ((1 << MECHANIC_ROOT) | (1 << MECHANIC_STUN)))) + return false; + return true; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + GetTarget()->CastCustomSpell(SPELL_UK_SECOUND_WIND_TRIGGER, SPELLVALUE_BASE_POINT0, 5, GetTarget(), true, NULL, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_uk_second_wind_proc_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_uk_second_wind_proc_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + + }; + + AuraScript* GetAuraScript() const override + { + return new spell_uk_second_wind_proc_AuraScript(); + } +}; + void AddSC_utgarde_keep() { new npc_dragonflayer_forge_master(); new npc_enslaved_proto_drake(); new spell_ticking_time_bomb(); new spell_fixate(); + new spell_uk_second_wind_proc(); } diff --git a/src/server/scripts/Northrend/zone_dalaran.cpp b/src/server/scripts/Northrend/zone_dalaran.cpp index 21fc93578ae..30e86fc3b63 100644 --- a/src/server/scripts/Northrend/zone_dalaran.cpp +++ b/src/server/scripts/Northrend/zone_dalaran.cpp @@ -129,52 +129,7 @@ public: } }; -/*###### -## npc_hira_snowdawn -######*/ - -enum HiraSnowdawn -{ - SPELL_COLD_WEATHER_FLYING = 54197 -}; - -#define GOSSIP_TEXT_TRAIN_HIRA "I seek training to ride a steed." - -class npc_hira_snowdawn : public CreatureScript -{ -public: - npc_hira_snowdawn() : CreatureScript("npc_hira_snowdawn") { } - - bool OnGossipHello(Player* player, Creature* creature) override - { - if (!creature->IsVendor() || !creature->IsTrainer()) - return false; - - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_TRAIN_HIRA, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRAIN); - - if (player->getLevel() >= 80 && player->HasSpell(SPELL_COLD_WEATHER_FLYING)) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - - return true; - } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_TRAIN) - player->GetSession()->SendTrainerList(creature->GetGUID()); - - if (action == GOSSIP_ACTION_TRADE) - player->GetSession()->SendListInventory(creature->GetGUID()); - - return true; - } -}; - void AddSC_dalaran() { new npc_mageguard_dalaran; - new npc_hira_snowdawn; } diff --git a/src/server/scripts/OutdoorPvP/CMakeLists.txt b/src/server/scripts/OutdoorPvP/CMakeLists.txt index 01347e134ea..3c22f1431d8 100644 --- a/src/server/scripts/OutdoorPvP/CMakeLists.txt +++ b/src/server/scripts/OutdoorPvP/CMakeLists.txt @@ -17,8 +17,6 @@ set(scripts_STAT_SRCS OutdoorPvP/OutdoorPvPNA.cpp OutdoorPvP/OutdoorPvPHP.cpp OutdoorPvP/OutdoorPvPTF.h - OutdoorPvP/OutdoorPvPEP.h - OutdoorPvP/OutdoorPvPEP.cpp OutdoorPvP/OutdoorPvPHP.h OutdoorPvP/OutdoorPvPZM.h OutdoorPvP/OutdoorPvPNA.h diff --git a/src/server/scripts/OutdoorPvP/OutdoorPvPEP.cpp b/src/server/scripts/OutdoorPvP/OutdoorPvPEP.cpp deleted file mode 100644 index e3246a5f55f..00000000000 --- a/src/server/scripts/OutdoorPvP/OutdoorPvPEP.cpp +++ /dev/null @@ -1,785 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> - * - * 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/>. - */ - -#include "ScriptMgr.h" -#include "OutdoorPvPEP.h" -#include "WorldPacket.h" -#include "Player.h" -#include "GameObject.h" -#include "ObjectMgr.h" -#include "ObjectAccessor.h" -#include "OutdoorPvPMgr.h" -#include "Creature.h" -#include "Language.h" -#include "World.h" -#include "GossipDef.h" - -OPvPCapturePointEP_EWT::OPvPCapturePointEP_EWT(OutdoorPvP* pvp) -: OPvPCapturePoint(pvp), m_TowerState(EP_TS_N), m_UnitsSummonedSide(0) -{ - SetCapturePointData(EPCapturePoints[EP_EWT].entry, EPCapturePoints[EP_EWT].map, EPCapturePoints[EP_EWT].x, EPCapturePoints[EP_EWT].y, EPCapturePoints[EP_EWT].z, EPCapturePoints[EP_EWT].o, EPCapturePoints[EP_EWT].rot0, EPCapturePoints[EP_EWT].rot1, EPCapturePoints[EP_EWT].rot2, EPCapturePoints[EP_EWT].rot3); - AddObject(EP_EWT_FLAGS, EPTowerFlags[EP_EWT].entry, EPTowerFlags[EP_EWT].map, EPTowerFlags[EP_EWT].x, EPTowerFlags[EP_EWT].y, EPTowerFlags[EP_EWT].z, EPTowerFlags[EP_EWT].o, EPTowerFlags[EP_EWT].rot0, EPTowerFlags[EP_EWT].rot1, EPTowerFlags[EP_EWT].rot2, EPTowerFlags[EP_EWT].rot3); -} - -void OPvPCapturePointEP_EWT::ChangeState() -{ - // if changing from controlling alliance to horde or vice versa - if ( m_OldState == OBJECTIVESTATE_ALLIANCE && m_OldState != m_State ) - { - sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_LOSE_EWT_A)); - ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_EWT, 0); - } - else if ( m_OldState == OBJECTIVESTATE_HORDE && m_OldState != m_State ) - { - sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_LOSE_EWT_H)); - ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_EWT, 0); - } - - uint32 artkit = 21; - - switch (m_State) - { - case OBJECTIVESTATE_ALLIANCE: - m_TowerState = EP_TS_A; - artkit = 2; - SummonSupportUnitAtNorthpassTower(ALLIANCE); - ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_EWT, ALLIANCE); - if (m_OldState != m_State) sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_CAPTURE_EWT_A)); - break; - case OBJECTIVESTATE_HORDE: - m_TowerState = EP_TS_H; - artkit = 1; - SummonSupportUnitAtNorthpassTower(HORDE); - ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_EWT, HORDE); - if (m_OldState != m_State) sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_CAPTURE_EWT_H)); - break; - case OBJECTIVESTATE_NEUTRAL: - m_TowerState = EP_TS_N; - break; - case OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE: - case OBJECTIVESTATE_HORDE_ALLIANCE_CHALLENGE: - m_TowerState = EP_TS_N_A; - break; - case OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE: - case OBJECTIVESTATE_ALLIANCE_HORDE_CHALLENGE: - m_TowerState = EP_TS_N_H; - break; - } - - GameObject* flag = HashMapHolder<GameObject>::Find(m_capturePointGUID); - GameObject* flag2 = HashMapHolder<GameObject>::Find(m_Objects[EP_EWT_FLAGS]); - if (flag) - { - flag->SetGoArtKit(artkit); - } - if (flag2) - { - flag2->SetGoArtKit(artkit); - } - - UpdateTowerState(); - - // complete quest objective - if (m_TowerState == EP_TS_A || m_TowerState == EP_TS_H) - SendObjectiveComplete(EP_EWT_CM, 0); -} - -void OPvPCapturePointEP_EWT::SendChangePhase() -{ - // send this too, sometimes the slider disappears, dunno why :( - SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 1); - // send these updates to only the ones in this objective - uint32 phase = (uint32)ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f); - SendUpdateWorldState(EP_UI_TOWER_SLIDER_POS, phase); - // send this too, sometimes it resets :S - SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, m_neutralValuePct); -} - -void OPvPCapturePointEP_EWT::FillInitialWorldStates(WorldPacket &data) -{ - data << EP_EWT_A << uint32(bool(m_TowerState & EP_TS_A)); - data << EP_EWT_H << uint32(bool(m_TowerState & EP_TS_H)); - data << EP_EWT_N_A << uint32(bool(m_TowerState & EP_TS_N_A)); - data << EP_EWT_N_H << uint32(bool(m_TowerState & EP_TS_N_H)); - data << EP_EWT_N << uint32(bool(m_TowerState & EP_TS_N)); -} - -void OPvPCapturePointEP_EWT::UpdateTowerState() -{ - m_PvP->SendUpdateWorldState(EP_EWT_A, bool(m_TowerState & EP_TS_A)); - m_PvP->SendUpdateWorldState(EP_EWT_H, bool(m_TowerState & EP_TS_H)); - m_PvP->SendUpdateWorldState(EP_EWT_N_A, bool(m_TowerState & EP_TS_N_A)); - m_PvP->SendUpdateWorldState(EP_EWT_N_H, bool(m_TowerState & EP_TS_N_H)); - m_PvP->SendUpdateWorldState(EP_EWT_N, bool(m_TowerState & EP_TS_N)); -} - -bool OPvPCapturePointEP_EWT::HandlePlayerEnter(Player* player) -{ - if (OPvPCapturePoint::HandlePlayerEnter(player)) - { - player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 1); - uint32 phase = (uint32)ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f); - player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_POS, phase); - player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, m_neutralValuePct); - return true; - } - return false; -} - -void OPvPCapturePointEP_EWT::HandlePlayerLeave(Player* player) -{ - player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 0); - OPvPCapturePoint::HandlePlayerLeave(player); -} - -void OPvPCapturePointEP_EWT::SummonSupportUnitAtNorthpassTower(uint32 team) -{ - if (m_UnitsSummonedSide != team) - { - m_UnitsSummonedSide = team; - creature_type const* ct = nullptr; - if (team == ALLIANCE) - ct = EP_EWT_Summons_A; - else - ct = EP_EWT_Summons_H; - - for (uint8 i = 0; i < EP_EWT_NUM_CREATURES; ++i) - { - DelCreature(i); - AddCreature(i, ct[i].entry, ct[i].map, ct[i].x, ct[i].y, ct[i].z, ct[i].o, OutdoorPvP::GetTeamIdByTeam(team), 1000000); - } - } -} - -// NPT -OPvPCapturePointEP_NPT::OPvPCapturePointEP_NPT(OutdoorPvP* pvp) -: OPvPCapturePoint(pvp), m_TowerState(EP_TS_N), m_SummonedGOSide(0) -{ - SetCapturePointData(EPCapturePoints[EP_NPT].entry, EPCapturePoints[EP_NPT].map, EPCapturePoints[EP_NPT].x, EPCapturePoints[EP_NPT].y, EPCapturePoints[EP_NPT].z, EPCapturePoints[EP_NPT].o, EPCapturePoints[EP_NPT].rot0, EPCapturePoints[EP_NPT].rot1, EPCapturePoints[EP_NPT].rot2, EPCapturePoints[EP_NPT].rot3); - AddObject(EP_NPT_FLAGS, EPTowerFlags[EP_NPT].entry, EPTowerFlags[EP_NPT].map, EPTowerFlags[EP_NPT].x, EPTowerFlags[EP_NPT].y, EPTowerFlags[EP_NPT].z, EPTowerFlags[EP_NPT].o, EPTowerFlags[EP_NPT].rot0, EPTowerFlags[EP_NPT].rot1, EPTowerFlags[EP_NPT].rot2, EPTowerFlags[EP_NPT].rot3); -} - -void OPvPCapturePointEP_NPT::ChangeState() -{ - // if changing from controlling alliance to horde or vice versa - if ( m_OldState == OBJECTIVESTATE_ALLIANCE && m_OldState != m_State ) - { - sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_LOSE_NPT_A)); - ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_NPT, 0); - } - else if ( m_OldState == OBJECTIVESTATE_HORDE && m_OldState != m_State ) - { - sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_LOSE_NPT_H)); - ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_NPT, 0); - } - - uint32 artkit = 21; - - switch (m_State) - { - case OBJECTIVESTATE_ALLIANCE: - m_TowerState = EP_TS_A; - artkit = 2; - SummonGO(ALLIANCE); - ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_NPT, ALLIANCE); - if (m_OldState != m_State) sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_CAPTURE_NPT_A)); - break; - case OBJECTIVESTATE_HORDE: - m_TowerState = EP_TS_H; - artkit = 1; - SummonGO(HORDE); - ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_NPT, HORDE); - if (m_OldState != m_State) sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_CAPTURE_NPT_H)); - break; - case OBJECTIVESTATE_NEUTRAL: - m_TowerState = EP_TS_N; - m_SummonedGOSide = 0; - DelObject(EP_NPT_BUFF); - break; - case OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE: - m_TowerState = EP_TS_N_A; - break; - case OBJECTIVESTATE_HORDE_ALLIANCE_CHALLENGE: - m_TowerState = EP_TS_N_A; - m_SummonedGOSide = 0; - DelObject(EP_NPT_BUFF); - break; - case OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE: - m_TowerState = EP_TS_N_H; - break; - case OBJECTIVESTATE_ALLIANCE_HORDE_CHALLENGE: - m_TowerState = EP_TS_N_H; - m_SummonedGOSide = 0; - DelObject(EP_NPT_BUFF); - break; - } - - GameObject* flag = HashMapHolder<GameObject>::Find(m_capturePointGUID); - GameObject* flag2 = HashMapHolder<GameObject>::Find(m_Objects[EP_NPT_FLAGS]); - if (flag) - { - flag->SetGoArtKit(artkit); - } - if (flag2) - { - flag2->SetGoArtKit(artkit); - } - - UpdateTowerState(); - - // complete quest objective - if (m_TowerState == EP_TS_A || m_TowerState == EP_TS_H) - SendObjectiveComplete(EP_NPT_CM, 0); -} - -void OPvPCapturePointEP_NPT::SendChangePhase() -{ - // send this too, sometimes the slider disappears, dunno why :( - SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 1); - // send these updates to only the ones in this objective - uint32 phase = (uint32)ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f); - SendUpdateWorldState(EP_UI_TOWER_SLIDER_POS, phase); - // send this too, sometimes it resets :S - SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, m_neutralValuePct); -} - -void OPvPCapturePointEP_NPT::FillInitialWorldStates(WorldPacket &data) -{ - data << EP_NPT_A << uint32(bool(m_TowerState & EP_TS_A)); - data << EP_NPT_H << uint32(bool(m_TowerState & EP_TS_H)); - data << EP_NPT_N_A << uint32(bool(m_TowerState & EP_TS_N_A)); - data << EP_NPT_N_H << uint32(bool(m_TowerState & EP_TS_N_H)); - data << EP_NPT_N << uint32(bool(m_TowerState & EP_TS_N)); -} - -void OPvPCapturePointEP_NPT::UpdateTowerState() -{ - m_PvP->SendUpdateWorldState(EP_NPT_A, bool(m_TowerState & EP_TS_A)); - m_PvP->SendUpdateWorldState(EP_NPT_H, bool(m_TowerState & EP_TS_H)); - m_PvP->SendUpdateWorldState(EP_NPT_N_A, bool(m_TowerState & EP_TS_N_A)); - m_PvP->SendUpdateWorldState(EP_NPT_N_H, bool(m_TowerState & EP_TS_N_H)); - m_PvP->SendUpdateWorldState(EP_NPT_N, bool(m_TowerState & EP_TS_N)); -} - -bool OPvPCapturePointEP_NPT::HandlePlayerEnter(Player* player) -{ - if (OPvPCapturePoint::HandlePlayerEnter(player)) - { - player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 1); - uint32 phase = (uint32)ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f); - player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_POS, phase); - player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, m_neutralValuePct); - return true; - } - return false; -} - -void OPvPCapturePointEP_NPT::HandlePlayerLeave(Player* player) -{ - player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 0); - OPvPCapturePoint::HandlePlayerLeave(player); -} - -void OPvPCapturePointEP_NPT::SummonGO(uint32 team) -{ - if (m_SummonedGOSide != team) - { - m_SummonedGOSide = team; - DelObject(EP_NPT_BUFF); - AddObject(EP_NPT_BUFF, EP_NPT_LordaeronShrine.entry, EP_NPT_LordaeronShrine.map, EP_NPT_LordaeronShrine.x, EP_NPT_LordaeronShrine.y, EP_NPT_LordaeronShrine.z, EP_NPT_LordaeronShrine.o, EP_NPT_LordaeronShrine.rot0, EP_NPT_LordaeronShrine.rot1, EP_NPT_LordaeronShrine.rot2, EP_NPT_LordaeronShrine.rot3); - GameObject* go = HashMapHolder<GameObject>::Find(m_Objects[EP_NPT_BUFF]); - if (go) - go->SetUInt32Value(GAMEOBJECT_FACTION, (team == ALLIANCE ? 84 : 83)); - } -} - -// CGT -OPvPCapturePointEP_CGT::OPvPCapturePointEP_CGT(OutdoorPvP* pvp) -: OPvPCapturePoint(pvp), m_TowerState(EP_TS_N), m_GraveyardSide(0) -{ - SetCapturePointData(EPCapturePoints[EP_CGT].entry, EPCapturePoints[EP_CGT].map, EPCapturePoints[EP_CGT].x, EPCapturePoints[EP_CGT].y, EPCapturePoints[EP_CGT].z, EPCapturePoints[EP_CGT].o, EPCapturePoints[EP_CGT].rot0, EPCapturePoints[EP_CGT].rot1, EPCapturePoints[EP_CGT].rot2, EPCapturePoints[EP_CGT].rot3); - AddObject(EP_CGT_FLAGS, EPTowerFlags[EP_CGT].entry, EPTowerFlags[EP_CGT].map, EPTowerFlags[EP_CGT].x, EPTowerFlags[EP_CGT].y, EPTowerFlags[EP_CGT].z, EPTowerFlags[EP_CGT].o, EPTowerFlags[EP_CGT].rot0, EPTowerFlags[EP_CGT].rot1, EPTowerFlags[EP_CGT].rot2, EPTowerFlags[EP_CGT].rot3); -} - -void OPvPCapturePointEP_CGT::ChangeState() -{ - // if changing from controlling alliance to horde or vice versa - if ( m_OldState == OBJECTIVESTATE_ALLIANCE && m_OldState != m_State ) - { - sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_LOSE_CGT_A)); - ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_CGT, 0); - } - else if ( m_OldState == OBJECTIVESTATE_HORDE && m_OldState != m_State ) - { - sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_LOSE_CGT_H)); - ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_CGT, 0); - } - - uint32 artkit = 21; - - switch (m_State) - { - case OBJECTIVESTATE_ALLIANCE: - m_TowerState = EP_TS_A; - artkit = 2; - LinkGraveYard(ALLIANCE); - ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_CGT, ALLIANCE); - if (m_OldState != m_State) sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_CAPTURE_CGT_A)); - break; - case OBJECTIVESTATE_HORDE: - m_TowerState = EP_TS_H; - artkit = 1; - LinkGraveYard(HORDE); - ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_CGT, HORDE); - if (m_OldState != m_State) sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_CAPTURE_CGT_H)); - break; - case OBJECTIVESTATE_NEUTRAL: - m_TowerState = EP_TS_N; - break; - case OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE: - case OBJECTIVESTATE_HORDE_ALLIANCE_CHALLENGE: - m_TowerState = EP_TS_N_A; - break; - case OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE: - case OBJECTIVESTATE_ALLIANCE_HORDE_CHALLENGE: - m_TowerState = EP_TS_N_H; - break; - } - - GameObject* flag = HashMapHolder<GameObject>::Find(m_capturePointGUID); - GameObject* flag2 = HashMapHolder<GameObject>::Find(m_Objects[EP_CGT_FLAGS]); - if (flag) - { - flag->SetGoArtKit(artkit); - } - if (flag2) - { - flag2->SetGoArtKit(artkit); - } - - UpdateTowerState(); - - // complete quest objective - if (m_TowerState == EP_TS_A || m_TowerState == EP_TS_H) - SendObjectiveComplete(EP_CGT_CM, 0); -} - -void OPvPCapturePointEP_CGT::SendChangePhase() -{ - // send this too, sometimes the slider disappears, dunno why :( - SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 1); - // send these updates to only the ones in this objective - uint32 phase = (uint32)ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f); - SendUpdateWorldState(EP_UI_TOWER_SLIDER_POS, phase); - // send this too, sometimes it resets :S - SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, m_neutralValuePct); -} - -void OPvPCapturePointEP_CGT::FillInitialWorldStates(WorldPacket &data) -{ - data << EP_CGT_A << uint32(bool(m_TowerState & EP_TS_A)); - data << EP_CGT_H << uint32(bool(m_TowerState & EP_TS_H)); - data << EP_CGT_N_A << uint32(bool(m_TowerState & EP_TS_N_A)); - data << EP_CGT_N_H << uint32(bool(m_TowerState & EP_TS_N_H)); - data << EP_CGT_N << uint32(bool(m_TowerState & EP_TS_N)); -} - -void OPvPCapturePointEP_CGT::UpdateTowerState() -{ - m_PvP->SendUpdateWorldState(EP_CGT_A, bool(m_TowerState & EP_TS_A)); - m_PvP->SendUpdateWorldState(EP_CGT_H, bool(m_TowerState & EP_TS_H)); - m_PvP->SendUpdateWorldState(EP_CGT_N_A, bool(m_TowerState & EP_TS_N_A)); - m_PvP->SendUpdateWorldState(EP_CGT_N_H, bool(m_TowerState & EP_TS_N_H)); - m_PvP->SendUpdateWorldState(EP_CGT_N, bool(m_TowerState & EP_TS_N)); -} - -bool OPvPCapturePointEP_CGT::HandlePlayerEnter(Player* player) -{ - if (OPvPCapturePoint::HandlePlayerEnter(player)) - { - player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 1); - uint32 phase = (uint32)ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f); - player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_POS, phase); - player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, m_neutralValuePct); - return true; - } - return false; -} - -void OPvPCapturePointEP_CGT::HandlePlayerLeave(Player* player) -{ - player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 0); - OPvPCapturePoint::HandlePlayerLeave(player); -} - -void OPvPCapturePointEP_CGT::LinkGraveYard(uint32 team) -{ - if (m_GraveyardSide != team) - { - m_GraveyardSide = team; - sObjectMgr->RemoveGraveYardLink(EP_GraveYardId, EP_GraveYardZone, team, false); - sObjectMgr->AddGraveYardLink(EP_GraveYardId, EP_GraveYardZone, team, false); - } -} - -// PWT -OPvPCapturePointEP_PWT::OPvPCapturePointEP_PWT(OutdoorPvP* pvp) -: OPvPCapturePoint(pvp), m_FlightMasterSpawned(0), m_TowerState(EP_TS_N) -{ - SetCapturePointData(EPCapturePoints[EP_PWT].entry, EPCapturePoints[EP_PWT].map, EPCapturePoints[EP_PWT].x, EPCapturePoints[EP_PWT].y, EPCapturePoints[EP_PWT].z, EPCapturePoints[EP_PWT].o, EPCapturePoints[EP_PWT].rot0, EPCapturePoints[EP_PWT].rot1, EPCapturePoints[EP_PWT].rot2, EPCapturePoints[EP_PWT].rot3); - AddObject(EP_PWT_FLAGS, EPTowerFlags[EP_PWT].entry, EPTowerFlags[EP_PWT].map, EPTowerFlags[EP_PWT].x, EPTowerFlags[EP_PWT].y, EPTowerFlags[EP_PWT].z, EPTowerFlags[EP_PWT].o, EPTowerFlags[EP_PWT].rot0, EPTowerFlags[EP_PWT].rot1, EPTowerFlags[EP_PWT].rot2, EPTowerFlags[EP_PWT].rot3); -} - -void OPvPCapturePointEP_PWT::ChangeState() -{ - // if changing from controlling alliance to horde or vice versa - if ( m_OldState == OBJECTIVESTATE_ALLIANCE && m_OldState != m_State ) - { - sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_LOSE_PWT_A)); - ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_PWT, 0); - } - else if ( m_OldState == OBJECTIVESTATE_HORDE && m_OldState != m_State ) - { - sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_LOSE_PWT_H)); - ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_PWT, 0); - } - - uint32 artkit = 21; - - switch (m_State) - { - case OBJECTIVESTATE_ALLIANCE: - m_TowerState = EP_TS_A; - SummonFlightMaster(ALLIANCE); - artkit = 2; - ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_PWT, ALLIANCE); - if (m_OldState != m_State) sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_CAPTURE_PWT_A)); - break; - case OBJECTIVESTATE_HORDE: - m_TowerState = EP_TS_H; - SummonFlightMaster(HORDE); - artkit = 1; - ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_PWT, HORDE); - if (m_OldState != m_State) sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_CAPTURE_PWT_H)); - break; - case OBJECTIVESTATE_NEUTRAL: - m_TowerState = EP_TS_N; - DelCreature(EP_PWT_FLIGHTMASTER); - m_FlightMasterSpawned = 0; - break; - case OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE: - m_TowerState = EP_TS_N_A; - break; - case OBJECTIVESTATE_HORDE_ALLIANCE_CHALLENGE: - m_TowerState = EP_TS_N_A; - DelCreature(EP_PWT_FLIGHTMASTER); - m_FlightMasterSpawned = 0; - break; - case OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE: - m_TowerState = EP_TS_N_H; - break; - case OBJECTIVESTATE_ALLIANCE_HORDE_CHALLENGE: - m_TowerState = EP_TS_N_H; - DelCreature(EP_PWT_FLIGHTMASTER); - m_FlightMasterSpawned = 0; - break; - } - - GameObject* flag = HashMapHolder<GameObject>::Find(m_capturePointGUID); - GameObject* flag2 = HashMapHolder<GameObject>::Find(m_Objects[EP_PWT_FLAGS]); - if (flag) - { - flag->SetGoArtKit(artkit); - } - if (flag2) - { - flag2->SetGoArtKit(artkit); - } - - UpdateTowerState(); - - // complete quest objective - if (m_TowerState == EP_TS_A || m_TowerState == EP_TS_H) - SendObjectiveComplete(EP_PWT_CM, 0); -} - -void OPvPCapturePointEP_PWT::SendChangePhase() -{ - // send this too, sometimes the slider disappears, dunno why :( - SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 1); - // send these updates to only the ones in this objective - uint32 phase = (uint32)ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f); - SendUpdateWorldState(EP_UI_TOWER_SLIDER_POS, phase); - // send this too, sometimes it resets :S - SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, m_neutralValuePct); -} - -void OPvPCapturePointEP_PWT::FillInitialWorldStates(WorldPacket &data) -{ - data << EP_PWT_A << uint32(bool(m_TowerState & EP_TS_A)); - data << EP_PWT_H << uint32(bool(m_TowerState & EP_TS_H)); - data << EP_PWT_N_A << uint32(bool(m_TowerState & EP_TS_N_A)); - data << EP_PWT_N_H << uint32(bool(m_TowerState & EP_TS_N_H)); - data << EP_PWT_N << uint32(bool(m_TowerState & EP_TS_N)); -} - -void OPvPCapturePointEP_PWT::UpdateTowerState() -{ - m_PvP->SendUpdateWorldState(EP_PWT_A, bool(m_TowerState & EP_TS_A)); - m_PvP->SendUpdateWorldState(EP_PWT_H, bool(m_TowerState & EP_TS_H)); - m_PvP->SendUpdateWorldState(EP_PWT_N_A, bool(m_TowerState & EP_TS_N_A)); - m_PvP->SendUpdateWorldState(EP_PWT_N_H, bool(m_TowerState & EP_TS_N_H)); - m_PvP->SendUpdateWorldState(EP_PWT_N, bool(m_TowerState & EP_TS_N)); -} - -bool OPvPCapturePointEP_PWT::HandlePlayerEnter(Player* player) -{ - if (OPvPCapturePoint::HandlePlayerEnter(player)) - { - player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 1); - uint32 phase = (uint32)ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f); - player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_POS, phase); - player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, m_neutralValuePct); - return true; - } - return false; -} - -void OPvPCapturePointEP_PWT::HandlePlayerLeave(Player* player) -{ - player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 0); - OPvPCapturePoint::HandlePlayerLeave(player); -} - -void OPvPCapturePointEP_PWT::SummonFlightMaster(uint32 team) -{ - if (m_FlightMasterSpawned != team) - { - m_FlightMasterSpawned = team; - DelCreature(EP_PWT_FLIGHTMASTER); - AddCreature(EP_PWT_FLIGHTMASTER, EP_PWT_FlightMaster.entry, EP_PWT_FlightMaster.map, EP_PWT_FlightMaster.x, EP_PWT_FlightMaster.y, EP_PWT_FlightMaster.z, EP_PWT_FlightMaster.o, OutdoorPvP::GetTeamIdByTeam(team)); - /* - // sky - we need update gso code - - Creature* c = HashMapHolder<Creature>::Find(m_Creatures[EP_PWT_FLIGHTMASTER]); - //Spawn flight master as friendly to capturing team - c->SetUInt32Value(GAMEOBJECT_FACTION, (team == ALLIANCE ? 55 : 68)); - if (c) - { - GossipOption gso; - gso.Action = GOSSIP_OPTION_OUTDOORPVP; - gso.GossipId = 0; - gso.OptionText.assign(sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_FLIGHT_NPT)); - gso.Id = 50; - gso.Icon = 0; - gso.NpcFlag = 0; - gso.BoxMoney = 0; - gso.Coded = false; - c->addGossipOption(gso); - - gso.Action = GOSSIP_OPTION_OUTDOORPVP; - gso.GossipId = 0; - gso.OptionText.assign(sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_FLIGHT_EWT)); - gso.Id = 50; - gso.Icon = 0; - gso.NpcFlag = 0; - gso.BoxMoney = 0; - gso.Coded = false; - c->addGossipOption(gso); - - gso.Action = GOSSIP_OPTION_OUTDOORPVP; - gso.GossipId = 0; - gso.OptionText.assign(sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_FLIGHT_CGT)); - gso.Id = 50; - gso.Icon = 0; - gso.NpcFlag = 0; - gso.BoxMoney = 0; - gso.Coded = false; - c->addGossipOption(gso); - } - */ - } -} - -// ep -OutdoorPvPEP::OutdoorPvPEP() -{ - m_TypeId = OUTDOOR_PVP_EP; - memset(EP_Controls, 0, sizeof(EP_Controls)); - m_AllianceTowersControlled = 0; - m_HordeTowersControlled = 0; -} - -bool OutdoorPvPEP::SetupOutdoorPvP() -{ - for (uint8 i = 0; i < EPBuffZonesNum; ++i) - RegisterZone(EPBuffZones[i]); - - AddCapturePoint(new OPvPCapturePointEP_EWT(this)); - AddCapturePoint(new OPvPCapturePointEP_PWT(this)); - AddCapturePoint(new OPvPCapturePointEP_CGT(this)); - AddCapturePoint(new OPvPCapturePointEP_NPT(this)); - return true; -} - -bool OutdoorPvPEP::Update(uint32 diff) -{ - if (OutdoorPvP::Update(diff)) - { - m_AllianceTowersControlled = 0; - m_HordeTowersControlled = 0; - for (int i = 0; i < EP_TOWER_NUM; ++i) - { - if (EP_Controls[i] == ALLIANCE) - ++m_AllianceTowersControlled; - else if (EP_Controls[i] == HORDE) - ++m_HordeTowersControlled; - SendUpdateWorldState(EP_UI_TOWER_COUNT_A, m_AllianceTowersControlled); - SendUpdateWorldState(EP_UI_TOWER_COUNT_H, m_HordeTowersControlled); - BuffTeams(); - } - return true; - } - return false; -} - -void OutdoorPvPEP::HandlePlayerEnterZone(Player* player, uint32 zone) -{ - // add buffs - if (player->GetTeam() == ALLIANCE) - { - if (m_AllianceTowersControlled && m_AllianceTowersControlled < 5) - player->CastSpell(player, EP_AllianceBuffs[m_AllianceTowersControlled-1], true); - } - else - { - if (m_HordeTowersControlled && m_HordeTowersControlled < 5) - player->CastSpell(player, EP_HordeBuffs[m_HordeTowersControlled-1], true); - } - OutdoorPvP::HandlePlayerEnterZone(player, zone); -} - -void OutdoorPvPEP::HandlePlayerLeaveZone(Player* player, uint32 zone) -{ - // remove buffs - if (player->GetTeam() == ALLIANCE) - { - for (int i = 0; i < 4; ++i) - player->RemoveAurasDueToSpell(EP_AllianceBuffs[i]); - } - else - { - for (int i = 0; i < 4; ++i) - player->RemoveAurasDueToSpell(EP_HordeBuffs[i]); - } - OutdoorPvP::HandlePlayerLeaveZone(player, zone); -} - -void OutdoorPvPEP::BuffTeams() -{ - for (PlayerSet::iterator itr = m_players[0].begin(); itr != m_players[0].end(); ++itr) - { - if (Player* player = ObjectAccessor::FindPlayer(*itr)) - { - for (int i = 0; i < 4; ++i) - player->RemoveAurasDueToSpell(EP_AllianceBuffs[i]); - if (m_AllianceTowersControlled && m_AllianceTowersControlled < 5) - player->CastSpell(player, EP_AllianceBuffs[m_AllianceTowersControlled-1], true); - } - } - for (PlayerSet::iterator itr = m_players[1].begin(); itr != m_players[1].end(); ++itr) - { - if (Player* player = ObjectAccessor::FindPlayer(*itr)) - { - for (int i = 0; i < 4; ++i) - player->RemoveAurasDueToSpell(EP_HordeBuffs[i]); - if (m_HordeTowersControlled && m_HordeTowersControlled < 5) - player->CastSpell(player, EP_HordeBuffs[m_HordeTowersControlled-1], true); - } - } -} - -void OutdoorPvPEP::SetControlledState(uint32 index, uint32 state) -{ - EP_Controls[index] = state; -} - -void OutdoorPvPEP::FillInitialWorldStates(WorldPacket & data) -{ - data << EP_UI_TOWER_COUNT_A << m_AllianceTowersControlled; - data << EP_UI_TOWER_COUNT_H << m_HordeTowersControlled; - data << EP_UI_TOWER_SLIDER_DISPLAY << uint32(0); - data << EP_UI_TOWER_SLIDER_POS << uint32(50); - data << EP_UI_TOWER_SLIDER_N << uint32(100); - for (OPvPCapturePointMap::iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr) - { - itr->second->FillInitialWorldStates(data); - } -} - -void OutdoorPvPEP::SendRemoveWorldStates(Player* player) -{ - player->SendUpdateWorldState(EP_UI_TOWER_COUNT_A, 0); - player->SendUpdateWorldState(EP_UI_TOWER_COUNT_H, 0); - player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 0); - player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_POS, 0); - player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, 0); - - player->SendUpdateWorldState(EP_EWT_A, 0); - player->SendUpdateWorldState(EP_EWT_H, 0); - player->SendUpdateWorldState(EP_EWT_N, 0); - player->SendUpdateWorldState(EP_EWT_N_A, 0); - player->SendUpdateWorldState(EP_EWT_N_H, 0); - - player->SendUpdateWorldState(EP_PWT_A, 0); - player->SendUpdateWorldState(EP_PWT_H, 0); - player->SendUpdateWorldState(EP_PWT_N, 0); - player->SendUpdateWorldState(EP_PWT_N_A, 0); - player->SendUpdateWorldState(EP_PWT_N_H, 0); - - player->SendUpdateWorldState(EP_NPT_A, 0); - player->SendUpdateWorldState(EP_NPT_H, 0); - player->SendUpdateWorldState(EP_NPT_N, 0); - player->SendUpdateWorldState(EP_NPT_N_A, 0); - player->SendUpdateWorldState(EP_NPT_N_H, 0); - - player->SendUpdateWorldState(EP_CGT_A, 0); - player->SendUpdateWorldState(EP_CGT_H, 0); - player->SendUpdateWorldState(EP_CGT_N, 0); - player->SendUpdateWorldState(EP_CGT_N_A, 0); - player->SendUpdateWorldState(EP_CGT_N_H, 0); -} - -class OutdoorPvP_eastern_plaguelands : public OutdoorPvPScript -{ - public: - - OutdoorPvP_eastern_plaguelands() - : OutdoorPvPScript("outdoorpvp_ep") - { - } - - OutdoorPvP* GetOutdoorPvP() const override - { - return new OutdoorPvPEP(); - } -}; - -void AddSC_outdoorpvp_ep() -{ - new OutdoorPvP_eastern_plaguelands(); -} diff --git a/src/server/scripts/OutdoorPvP/OutdoorPvPEP.h b/src/server/scripts/OutdoorPvP/OutdoorPvPEP.h deleted file mode 100644 index 50b412348cf..00000000000 --- a/src/server/scripts/OutdoorPvP/OutdoorPvPEP.h +++ /dev/null @@ -1,331 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> - * - * 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/>. - */ - -#ifndef OUTDOOR_PVP_EP_ -#define OUTDOOR_PVP_EP_ - -#include "DBCStructure.h" -#include "OutdoorPvP.h" - -const uint32 EP_AllianceBuffs[4] = {11413, 11414, 11415, 1386}; - -const uint32 EP_HordeBuffs[4] = {30880, 30683, 30682, 29520}; - -const uint32 EP_GraveYardZone = 139; - -const uint32 EP_GraveYardId = 927; - -const uint8 EPBuffZonesNum = 3; - -const uint32 EP_EWT_CM = 17690; -const uint32 EP_CGT_CM = 17689; -const uint32 EP_NPT_CM = 17696; -const uint32 EP_PWT_CM = 17698; - -const uint32 EPBuffZones[EPBuffZonesNum] = {139, 2017, 2057}; - -enum EP_TaxiNodes -{ - EP_CGT_Taxi = 87, - EP_EWT_Taxi = 86, - EP_NPT_Taxi = 85, - EP_PWT_Taxi = 84 -}; - -enum EP_EastwallTowerWorldStates -{ - EP_EWT_A = 2354, - EP_EWT_H = 2356, - EP_EWT_N_A = 2359, // ally conquested - EP_EWT_N_H = 2360, - EP_EWT_N = 2361 -}; - -enum EP_NorthpassTowerWorldStates -{ - EP_NPT_N = 2352, - EP_NPT_N_A = 2362, - EP_NPT_N_H = 2363, - EP_NPT_A = 2372, - EP_NPT_H = 2373 -}; - -enum EP_PlagewoodTowerWorldStates -{ - EP_PWT_N_A = 2366, - EP_PWT_N_H = 2353, //2367 not present! use neutral! - EP_PWT_A = 2370, - EP_PWT_H = 2371, - EP_PWT_N = 2353 -}; - -enum EP_CrownGuardTowerWorldStates -{ - EP_CGT_N_A = 2374, - EP_CGT_N_H = 2375, - EP_CGT_A = 2378, - EP_CGT_H = 2379, - EP_CGT_N = 2355 -}; - -enum EP_WorldStates -{ - EP_UI_TOWER_SLIDER_DISPLAY = 2426, - EP_UI_TOWER_SLIDER_POS = 2427, - EP_UI_TOWER_SLIDER_N = 2428, - - EP_UI_TOWER_COUNT_A = 2327, - EP_UI_TOWER_COUNT_H = 2328 -}; - -enum EP_Summons -{ - EP_EWT_COMMANDER = 0, - EP_EWT_SOLDIER1, - EP_EWT_SOLDIER2, - EP_EWT_SOLDIER3, - EP_EWT_SOLDIER4, - EP_PWT_FLIGHTMASTER, -}; - -enum EP_GoSummons -{ - EP_NPT_BUFF = 0, - EP_NPT_FLAGS, - EP_EWT_FLAGS, - EP_CGT_FLAGS, - EP_PWT_FLAGS -}; - -enum EP_Towers -{ - EP_EWT = 0, // plaguelands 03 - EP_NPT, // plaguelands 01 - EP_PWT, // plaguelands 04 - EP_CGT, // plaguelands 02 - EP_TOWER_NUM -}; - -const go_type EPCapturePoints[EP_TOWER_NUM] = -{ - {182097, 0, 2574.51f, -4794.89f, 144.704f, -1.45003f, -0.097056f, 0.095578f, -0.656229f, 0.742165f}, - {181899, 0, 3181.08f, -4379.36f, 174.123f, -2.03472f, -0.065392f, 0.119494f, -0.842275f, 0.521553f}, - {182098, 0, 2962.71f, -3042.31f, 154.789f, 2.08426f, -0.074807f, -0.113837f, 0.855928f, 0.49883f}, - {182096, 0, 1860.85f, -3731.23f, 196.716f, -2.53214f, 0.033967f, -0.131914f, 0.944741f, -0.298177f} -}; - -const go_type EPTowerFlags[EP_TOWER_NUM] = -{ - {182106, 0, 2569.60f, -4772.93f, 115.399f, 2.72271f, 0.0f, 0.0f, 0.978148f, 0.207912f}, - {182106, 0, 3148.17f, -4365.51f, 145.029f, 1.53589f, 0.0f, 0.0f, 0.694658f, 0.71934f}, - {182106, 0, 2992.63f, -3022.95f, 125.593f, 3.03687f, 0.0f, 0.0f, 0.99863f, 0.052336f}, - {182106, 0, 1838.42f, -3703.56f, 167.713f, 0.890118f, 0.0f, 0.0f, 0.430511f, 0.902585f} -}; - -const uint32 EPTowerPlayerEnterEvents[EP_TOWER_NUM] = {10691, 10699, 10701, 10705}; - -const uint32 EPTowerPlayerLeaveEvents[EP_TOWER_NUM] = {10692, 10698, 10700, 10704}; - -const uint8 EP_NUM_CREATURES = 6; -const uint8 EP_EWT_NUM_CREATURES = 5; - -// one lordaeron commander, 4 soldiers -// should be spawned at EWT and follow a path, but trans-grid pathing isn't safe, so summon them directly at NPT -const creature_type EP_EWT_Summons_A[EP_EWT_NUM_CREATURES] = -{ - {17635, 0, 3167.61f, -4352.09f, 138.20f, 4.5811f}, - {17647, 0, 3172.74f, -4352.99f, 139.14f, 4.9873f}, - {17647, 0, 3165.89f, -4354.46f, 138.67f, 3.7244f}, - {17647, 0, 3164.65f, -4350.26f, 138.22f, 2.4794f}, - {17647, 0, 3169.91f, -4349.68f, 138.37f, 0.7444f} -}; - -const creature_type EP_EWT_Summons_H[EP_EWT_NUM_CREATURES] = -{ - {17995, 0, 3167.61f, -4352.09f, 138.20f, 4.5811f}, - {17996, 0, 3172.74f, -4352.99f, 139.14f, 4.9873f}, - {17996, 0, 3165.89f, -4354.46f, 138.67f, 3.7244f}, - {17996, 0, 3164.65f, -4350.26f, 138.22f, 2.4794f}, - {17996, 0, 3169.91f, -4349.68f, 138.37f, 0.7444f} -}; - -enum EP_TowerStates -{ - EP_TS_N = 1, - EP_TS_N_A = 2, - EP_TS_N_H = 4, - EP_TS_A_P = 8, - EP_TS_H_P = 16, - EP_TS_A = 32, - EP_TS_H = 64 -}; - -// when spawning, pay attention at setting the faction manually! -const creature_type EP_PWT_FlightMaster = {17209, 0, 2987.5f, -3049.11f, 120.126f, 5.75959f}; - -// after spawning, modify the faction so that only the controller will be able to use it with SetUInt32Value(GAMEOBJECT_FACTION, faction_id); -const go_type EP_NPT_LordaeronShrine = {181682, 0, 3167.72f, -4355.91f, 138.785f, 1.69297f, 0.0f, 0.0f, 0.748956f, 0.66262f}; - -class OutdoorPvPEP; - -class OPvPCapturePointEP_EWT : public OPvPCapturePoint -{ - public: - - OPvPCapturePointEP_EWT(OutdoorPvP* pvp); - - void ChangeState(); - - void SendChangePhase(); - - void FillInitialWorldStates(WorldPacket & data); - - // used when player is activated/inactivated in the area - bool HandlePlayerEnter(Player* player); - void HandlePlayerLeave(Player* player); - - protected: - - void SummonSupportUnitAtNorthpassTower(uint32 team); - - void UpdateTowerState(); - - protected: - - uint32 m_TowerState; - - uint32 m_UnitsSummonedSide; -}; - -class OPvPCapturePointEP_NPT : public OPvPCapturePoint -{ - public: - - OPvPCapturePointEP_NPT(OutdoorPvP* pvp); - - void ChangeState(); - - void SendChangePhase(); - - void FillInitialWorldStates(WorldPacket & data); - - // used when player is activated/inactivated in the area - bool HandlePlayerEnter(Player* player); - void HandlePlayerLeave(Player* player); - - protected: - - void SummonGO(uint32 team); - - void UpdateTowerState(); - - protected: - - uint32 m_TowerState; - - uint32 m_SummonedGOSide; -}; - -class OPvPCapturePointEP_CGT : public OPvPCapturePoint -{ - public: - - OPvPCapturePointEP_CGT(OutdoorPvP* pvp); - - void ChangeState(); - - void SendChangePhase(); - - void FillInitialWorldStates(WorldPacket & data); - - // used when player is activated/inactivated in the area - bool HandlePlayerEnter(Player* player); - void HandlePlayerLeave(Player* player); - - protected: - - void LinkGraveYard(uint32 team); - - void UpdateTowerState(); - - protected: - - uint32 m_TowerState; - - uint32 m_GraveyardSide; -}; - -class OPvPCapturePointEP_PWT : public OPvPCapturePoint -{ - public: - - OPvPCapturePointEP_PWT(OutdoorPvP* pvp); - - void ChangeState(); - - void SendChangePhase(); - - void FillInitialWorldStates(WorldPacket & data); - - // used when player is activated/inactivated in the area - bool HandlePlayerEnter(Player* player); - void HandlePlayerLeave(Player* player); - - protected: - - void SummonFlightMaster(uint32 team); - - void UpdateTowerState(); - - protected: - - uint32 m_FlightMasterSpawned; - - uint32 m_TowerState; -}; - -class OutdoorPvPEP : public OutdoorPvP -{ - public: - - OutdoorPvPEP(); - - bool SetupOutdoorPvP(); - - void HandlePlayerEnterZone(Player* player, uint32 zone); - void HandlePlayerLeaveZone(Player* player, uint32 zone); - - bool Update(uint32 diff); - - void FillInitialWorldStates(WorldPacket &data); - - void SendRemoveWorldStates(Player* player); - - void BuffTeams(); - - void SetControlledState(uint32 index, uint32 state); - - private: - - // how many towers are controlled - uint32 EP_Controls[EP_TOWER_NUM]; - - uint32 m_AllianceTowersControlled; - uint32 m_HordeTowersControlled; -}; - -#endif diff --git a/src/server/scripts/Outland/Auchindoun/ManaTombs/boss_pandemonius.cpp b/src/server/scripts/Outland/Auchindoun/ManaTombs/boss_pandemonius.cpp index 9a1d686f688..2a359419e79 100644 --- a/src/server/scripts/Outland/Auchindoun/ManaTombs/boss_pandemonius.cpp +++ b/src/server/scripts/Outland/Auchindoun/ManaTombs/boss_pandemonius.cpp @@ -39,7 +39,6 @@ enum Pandemonius H_SPELL_DARK_SHELL = 38759 }; - class boss_pandemonius : public CreatureScript { public: diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp index 5ae0e1601c5..9c6ed2ff120 100644 --- a/src/server/scripts/Spells/spell_dk.cpp +++ b/src/server/scripts/Spells/spell_dk.cpp @@ -33,42 +33,35 @@ enum DeathKnightSpells SPELL_DK_BLACK_ICE_R1 = 49140, SPELL_DK_BLOOD_BOIL_TRIGGERED = 65658, SPELL_DK_BLOOD_GORGED_HEAL = 50454, - SPELL_DK_BLOOD_PRESENCE = 48266, + SPELL_DK_BLOOD_PRESENCE = 48263, + SPELL_DK_BLOOD_PRESENCE_TRIGGERED = 61261, + SPELL_DK_BLOOD_SHIELD_MASTERY = 77513, + SPELL_DK_BLOOD_SHIELD_ABSORB = 77535, + SPELL_DK_BUTCHERY = 50163, SPELL_DK_CORPSE_EXPLOSION_TRIGGERED = 43999, - SPELL_DK_CORPSE_EXPLOSION_VISUAL = 51270, SPELL_DK_DEATH_COIL_DAMAGE = 47632, SPELL_DK_DEATH_COIL_HEAL = 47633, SPELL_DK_DEATH_STRIKE_HEAL = 45470, - SPELL_DK_FROST_PRESENCE = 48263, - SPELL_DK_FROST_PRESENCE_TRIGGERED = 61261, + SPELL_DK_DEATH_STRIKE_ENABLER = 89832, + SPELL_DK_FROST_PRESENCE = 48266, SPELL_DK_GHOUL_EXPLODE = 47496, SPELL_DK_GLYPH_OF_ICEBOUND_FORTITUDE = 58625, SPELL_DK_IMPROVED_BLOOD_PRESENCE_R1 = 50365, + SPELL_DK_IMPROVED_DEATH_STRIKE = 62905, SPELL_DK_IMPROVED_FROST_PRESENCE_R1 = 50384, + SPELL_DK_IMPROVED_FROST_PRESENCE_TRIGGERED = 63621, SPELL_DK_IMPROVED_UNHOLY_PRESENCE_R1 = 50391, - SPELL_DK_IMPROVED_BLOOD_PRESENCE_TRIGGERED = 63611, SPELL_DK_IMPROVED_UNHOLY_PRESENCE_TRIGGERED = 63622, SPELL_DK_ITEM_SIGIL_VENGEFUL_HEART = 64962, SPELL_DK_ITEM_T8_MELEE_4P_BONUS = 64736, SPELL_DK_MASTER_OF_GHOULS = 52143, SPELL_DK_RAISE_DEAD_USE_REAGENT = 48289, SPELL_DK_RUNIC_POWER_ENERGIZE = 49088, + SPELL_DK_RUNE_TAP = 48982, SPELL_DK_SCENT_OF_BLOOD = 50422, SPELL_DK_SCOURGE_STRIKE_TRIGGERED = 70890, SPELL_DK_UNHOLY_PRESENCE = 48265, - SPELL_DK_UNHOLY_PRESENCE_TRIGGERED = 49772, - SPELL_DK_WILL_OF_THE_NECROPOLIS_TALENT_R1 = 49189, - SPELL_DK_WILL_OF_THE_NECROPOLIS_AURA_R1 = 52284 -}; - -enum DeathKnightSpellIcons -{ - DK_ICON_ID_IMPROVED_DEATH_STRIKE = 2751 -}; - -enum Misc -{ - NPC_DK_GHOUL = 26125 + SPELL_DK_WILL_OF_THE_NECROPOLIS = 96171 }; // 50462 - Anti-Magic Shell (on raid member) @@ -298,15 +291,14 @@ class spell_dk_blood_gorged : public SpellScriptLoader void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) { - PreventDefaultAction(); - int32 bp = int32(eventInfo.GetDamageInfo()->GetDamage() * 1.5f); - GetTarget()->CastCustomSpell(SPELL_DK_BLOOD_GORGED_HEAL, SPELLVALUE_BASE_POINT0, bp, _procTarget, true, NULL, aurEff); + int32 heal = int32(CalculatePct(eventInfo.GetDamageInfo()->GetDamage(), 150)); + GetTarget()->CastCustomSpell(SPELL_DK_BLOOD_GORGED_HEAL, SPELLVALUE_BASE_POINT0, heal, _procTarget, true, NULL, aurEff); } void Register() override { DoCheckProc += AuraCheckProcFn(spell_dk_blood_gorged_AuraScript::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_dk_blood_gorged_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + OnEffectProc += AuraEffectProcFn(spell_dk_blood_gorged_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); } private: @@ -319,130 +311,42 @@ class spell_dk_blood_gorged : public SpellScriptLoader } }; -class CorpseExplosionCheck -{ -public: - explicit CorpseExplosionCheck(uint64 casterGUID, bool allowGhoul) : _casterGUID(casterGUID), - _allowGhoul(allowGhoul) { } - - bool operator()(WorldObject* obj) const - { - if (Unit* target = obj->ToUnit()) - { - if ((target->isDead() || (_allowGhoul && target->GetEntry() == NPC_DK_GHOUL && target->GetOwnerGUID() == _casterGUID)) - && !(target->GetCreatureTypeMask() & CREATURE_TYPEMASK_MECHANICAL_OR_ELEMENTAL) - && target->GetDisplayId() == target->GetNativeDisplayId()) - return false; - } - - return true; - } - -private: - uint64 _casterGUID; - bool _allowGhoul; -}; - -// 49158 - Corpse Explosion (51325, 51326, 51327, 51328) -class spell_dk_corpse_explosion : public SpellScriptLoader +// -48979 - Butchery +class spell_dk_butchery : public SpellScriptLoader { public: - spell_dk_corpse_explosion() : SpellScriptLoader("spell_dk_corpse_explosion") { } + spell_dk_butchery() : SpellScriptLoader("spell_dk_butchery") { } - class spell_dk_corpse_explosion_SpellScript : public SpellScript + class spell_dk_blood_gorged_AuraScript : public AuraScript { - PrepareSpellScript(spell_dk_corpse_explosion_SpellScript); + PrepareAuraScript(spell_dk_blood_gorged_AuraScript); - bool Validate(SpellInfo const* spellInfo) override + bool Validate(SpellInfo const* /*spellInfo*/) override { - if (!sSpellMgr->GetSpellInfo(SPELL_DK_CORPSE_EXPLOSION_TRIGGERED) - || !sSpellMgr->GetSpellInfo(SPELL_DK_GHOUL_EXPLODE) - || !sSpellMgr->GetSpellInfo(SPELL_DK_CORPSE_EXPLOSION_VISUAL) - || !sSpellMgr->GetSpellInfo(spellInfo->Effects[EFFECT_1].CalcValue())) + if (!sSpellMgr->GetSpellInfo(SPELL_DK_BUTCHERY)) return false; return true; } - bool Load() override - { - _target = NULL; - return true; - } - - void CheckTarget(WorldObject*& target) - { - if (CorpseExplosionCheck(GetCaster()->GetGUID(), true)(target)) - target = NULL; - - _target = target; - } - - void CheckTargets(std::list<WorldObject*>& targets) - { - WorldObject* target = _target; - if (!target) - { - targets.remove_if(CorpseExplosionCheck(GetCaster()->GetGUID(), false)); - if (targets.empty()) - { - FinishCast(SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW); - return; - } - target = Trinity::Containers::SelectRandomContainerElement(targets); - targets.clear(); - targets.push_back(target); - } - else - targets.clear(); - } - - void HandleDamage(SpellEffIndex effIndex, Unit* target) - { - if (effIndex == EFFECT_0) - GetCaster()->CastCustomSpell(GetSpellInfo()->Effects[EFFECT_1].CalcValue(), SPELLVALUE_BASE_POINT0, GetEffectValue(), target, true); - else if (effIndex == EFFECT_1) - GetCaster()->CastCustomSpell(GetEffectValue(), SPELLVALUE_BASE_POINT0, GetSpell()->CalculateDamage(EFFECT_0, NULL), target, true); - } - - void HandleCorpseExplosion(SpellEffIndex effIndex) + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) { - if (Unit* unitTarget = GetHitUnit()) - { - if (unitTarget->IsAlive()) // Living ghoul as a target - { - unitTarget->CastSpell(unitTarget, SPELL_DK_GHOUL_EXPLODE, false); - // Corpse Explosion (Suicide) and Set corpse look handled in SpellScript of SPELL_DK_GHOUL_EXPLODE - } - else // Some corpse - { - HandleDamage(effIndex, unitTarget); - // Corpse Explosion (Suicide) - unitTarget->CastSpell(unitTarget, SPELL_DK_CORPSE_EXPLOSION_TRIGGERED, true); - // Set corpse look - GetCaster()->CastSpell(unitTarget, SPELL_DK_CORPSE_EXPLOSION_VISUAL, true); - } - } + PreventDefaultAction(); + GetTarget()->CastCustomSpell(SPELL_DK_BUTCHERY, SPELLVALUE_BASE_POINT0, aurEff->GetAmount(), GetTarget(), true, NULL, aurEff); } void Register() override { - OnObjectTargetSelect += SpellObjectTargetSelectFn(spell_dk_corpse_explosion_SpellScript::CheckTarget, EFFECT_0, TARGET_UNIT_TARGET_ANY); - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_dk_corpse_explosion_SpellScript::CheckTargets, EFFECT_1, TARGET_UNIT_DEST_AREA_ENTRY); - OnEffectHitTarget += SpellEffectFn(spell_dk_corpse_explosion_SpellScript::HandleCorpseExplosion, EFFECT_0, SPELL_EFFECT_DUMMY); - OnEffectHitTarget += SpellEffectFn(spell_dk_corpse_explosion_SpellScript::HandleCorpseExplosion, EFFECT_1, SPELL_EFFECT_DUMMY); + OnEffectProc += AuraEffectProcFn(spell_dk_blood_gorged_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); } - - private: - WorldObject* _target; }; - SpellScript* GetSpellScript() const override + AuraScript* GetAuraScript() const override { - return new spell_dk_corpse_explosion_SpellScript(); + return new spell_dk_blood_gorged_AuraScript(); } }; -// -47541, 52375, 59134, -62900 - Death Coil +// 47541, 52375, 59134, -62900 - Death Coil class spell_dk_death_coil : public SpellScriptLoader { public: @@ -640,7 +544,7 @@ class spell_dk_death_pact : public SpellScriptLoader } }; -// -49998 - Death Strike +// 49998 - Death Strike class spell_dk_death_strike : public SpellScriptLoader { public: @@ -652,30 +556,39 @@ class spell_dk_death_strike : public SpellScriptLoader bool Validate(SpellInfo const* /*spellInfo*/) override { - if (!sSpellMgr->GetSpellInfo(SPELL_DK_DEATH_STRIKE_HEAL)) + if (!sSpellMgr->GetSpellInfo(SPELL_DK_DEATH_STRIKE_ENABLER) || + !sSpellMgr->GetSpellInfo(SPELL_DK_DEATH_STRIKE_HEAL) || + !sSpellMgr->GetSpellInfo(SPELL_DK_BLOOD_SHIELD_MASTERY) || + !sSpellMgr->GetSpellInfo(SPELL_DK_BLOOD_SHIELD_ABSORB)) return false; return true; } void HandleDummy(SpellEffIndex /*effIndex*/) { - Unit* caster = GetCaster(); - if (Unit* target = GetHitUnit()) + if (AuraEffect* enabler = GetCaster()->GetAuraEffect(SPELL_DK_DEATH_STRIKE_ENABLER, EFFECT_0, GetCaster()->GetGUID())) { - uint32 count = target->GetDiseasesByCaster(caster->GetGUID()); - int32 bp = int32(count * caster->CountPctFromMaxHealth(int32(GetSpellInfo()->Effects[EFFECT_0].DamageMultiplier))); - // Improved Death Strike - if (AuraEffect const* aurEff = caster->GetAuraEffect(SPELL_AURA_ADD_PCT_MODIFIER, SPELLFAMILY_DEATHKNIGHT, DK_ICON_ID_IMPROVED_DEATH_STRIKE, 0)) - AddPct(bp, caster->CalculateSpellDamage(caster, aurEff->GetSpellInfo(), 2)); - caster->CastCustomSpell(caster, SPELL_DK_DEATH_STRIKE_HEAL, &bp, NULL, NULL, false); + // Call CalculateAmount() to constantly fire the AuraEffect's HandleCalcAmount method + int32 heal = CalculatePct(enabler->CalculateAmount(GetCaster()), GetSpellInfo()->Effects[EFFECT_0].DamageMultiplier); + + if (AuraEffect const* aurEff = GetCaster()->GetAuraEffectOfRankedSpell(SPELL_DK_IMPROVED_DEATH_STRIKE, EFFECT_2)) + heal = AddPct(heal, aurEff->GetAmount()); + + heal = std::max(heal, int32(GetCaster()->CountPctFromMaxHealth(GetEffectValue()))); + GetCaster()->CastCustomSpell(SPELL_DK_DEATH_STRIKE_HEAL, SPELLVALUE_BASE_POINT0, heal, GetCaster(), true); } + + if (!GetCaster()->HasAura(SPELL_DK_BLOOD_PRESENCE)) + return; + + if (AuraEffect const* aurEff = GetCaster()->GetAuraEffect(SPELL_DK_BLOOD_SHIELD_MASTERY, EFFECT_0)) + GetCaster()->CastCustomSpell(SPELL_DK_BLOOD_SHIELD_ABSORB, SPELLVALUE_BASE_POINT0, GetCaster()->CountPctFromMaxHealth(aurEff->GetAmount()), GetCaster()); } void Register() override { OnEffectHitTarget += SpellEffectFn(spell_dk_death_strike_SpellScript::HandleDummy, EFFECT_2, SPELL_EFFECT_DUMMY); } - }; SpellScript* GetSpellScript() const override @@ -684,6 +597,80 @@ class spell_dk_death_strike : public SpellScriptLoader } }; +// 89832 - Death Strike (Save damage taken in last 5 sec) +class spell_dk_death_strike_enabler : public SpellScriptLoader +{ + public: + spell_dk_death_strike_enabler() : SpellScriptLoader("spell_dk_death_strike_enabler") { } + + class spell_dk_death_strike_enabler_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dk_death_strike_enabler_AuraScript); + + bool Load() override + { + for (uint8 i = 0; i < 5; ++i) + _damagePerSecond[i] = 0; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + return eventInfo.GetDamageInfo(); + } + + void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) + { + if (!GetUnitOwner()->HasAura(SPELL_DK_BLOOD_PRESENCE)) + { + for (uint8 i = 0; i < 5; ++i) + _damagePerSecond[i] = 0; + } + else + _damagePerSecond[0] += eventInfo.GetDamageInfo()->GetDamage(); + } + + // Cheap hack to have update calls + void CalcPeriodic(AuraEffect const* /*aurEff*/, bool& isPeriodic, int32& amplitude) + { + isPeriodic = true; + amplitude = 1000; + } + + void Update(AuraEffect* /*aurEff*/) + { + // Move backwards all datas by one + for (uint8 i = 4; i > 0; --i) + _damagePerSecond[i] = _damagePerSecond[i - 1]; + _damagePerSecond[0] = 0; + } + + void HandleCalcAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& canBeRecalculated) + { + canBeRecalculated = true; + amount = 0; + for (uint8 i = 0; i < 5; ++i) + amount += int32(_damagePerSecond[i]); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_dk_death_strike_enabler_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_dk_death_strike_enabler_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + DoEffectCalcPeriodic += AuraEffectCalcPeriodicFn(spell_dk_death_strike_enabler_AuraScript::CalcPeriodic, EFFECT_0, SPELL_AURA_DUMMY); + OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_dk_death_strike_enabler_AuraScript::Update, EFFECT_0, SPELL_AURA_DUMMY); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_death_strike_enabler_AuraScript::HandleCalcAmount, EFFECT_0, SPELL_AURA_DUMMY); + } + + uint32 _damagePerSecond[5]; + }; + + AuraScript* GetAuraScript() const override + { + return new spell_dk_death_strike_enabler_AuraScript(); + } +}; + // 47496 - Explode, Ghoul spell for Corpse Explosion class spell_dk_ghoul_explode : public SpellScriptLoader { @@ -694,34 +681,24 @@ class spell_dk_ghoul_explode : public SpellScriptLoader { PrepareSpellScript(spell_dk_ghoul_explode_SpellScript); - bool Validate(SpellInfo const* spellInfo) override + bool Validate(SpellInfo const* /*spellInfo*/) override { - if (!sSpellMgr->GetSpellInfo(SPELL_DK_CORPSE_EXPLOSION_TRIGGERED) - || spellInfo->Effects[EFFECT_2].CalcValue() <= 0) + if (!sSpellMgr->GetSpellInfo(SPELL_DK_CORPSE_EXPLOSION_TRIGGERED)) return false; return true; } - void HandleDamage(SpellEffIndex /*effIndex*/) - { - int32 value = int32(GetCaster()->CountPctFromMaxHealth(GetSpellInfo()->Effects[EFFECT_2].CalcValue(GetCaster()))); - SetEffectValue(value); - } - void Suicide(SpellEffIndex /*effIndex*/) { if (Unit* unitTarget = GetHitUnit()) { // Corpse Explosion (Suicide) unitTarget->CastSpell(unitTarget, SPELL_DK_CORPSE_EXPLOSION_TRIGGERED, true); - // Set corpse look - GetCaster()->CastSpell(unitTarget, SPELL_DK_CORPSE_EXPLOSION_VISUAL, true); } } void Register() override { - OnEffectLaunchTarget += SpellEffectFn(spell_dk_ghoul_explode_SpellScript::HandleDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); OnEffectHitTarget += SpellEffectFn(spell_dk_ghoul_explode_SpellScript::Suicide, EFFECT_1, SPELL_EFFECT_SCHOOL_DAMAGE); } }; @@ -796,29 +773,44 @@ class spell_dk_improved_blood_presence : public SpellScriptLoader if (!sSpellMgr->GetSpellInfo(SPELL_DK_BLOOD_PRESENCE) || !sSpellMgr->GetSpellInfo(SPELL_DK_FROST_PRESENCE) || !sSpellMgr->GetSpellInfo(SPELL_DK_UNHOLY_PRESENCE) - || !sSpellMgr->GetSpellInfo(SPELL_DK_IMPROVED_BLOOD_PRESENCE_TRIGGERED)) + || !sSpellMgr->GetSpellInfo(SPELL_DK_BLOOD_PRESENCE_TRIGGERED)) return false; return true; } - void HandleEffectApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) + void HandleModDamagePctTaken(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + if ((target->HasAura(SPELL_DK_FROST_PRESENCE) || target->HasAura(SPELL_DK_UNHOLY_PRESENCE)) && !target->HasAura(SPELL_DK_BLOOD_PRESENCE_TRIGGERED)) + target->CastCustomSpell(SPELL_DK_BLOOD_PRESENCE_TRIGGERED, SPELLVALUE_BASE_POINT0, -aurEff->GetAmount(), target, true, NULL, aurEff); + } + + void HandleModAttackerMeleeCritChance(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) { Unit* target = GetTarget(); - if ((target->HasAura(SPELL_DK_FROST_PRESENCE) || target->HasAura(SPELL_DK_UNHOLY_PRESENCE)) && !target->HasAura(SPELL_DK_IMPROVED_BLOOD_PRESENCE_TRIGGERED)) - target->CastCustomSpell(SPELL_DK_IMPROVED_BLOOD_PRESENCE_TRIGGERED, SPELLVALUE_BASE_POINT1, aurEff->GetAmount(), target, true, NULL, aurEff); + if (target->HasAura(SPELL_DK_BLOOD_PRESENCE)) + if (AuraEffect* triggeredEff = target->GetAuraEffect(SPELL_DK_BLOOD_PRESENCE_TRIGGERED, EFFECT_1)) + triggeredEff->SetAmount(aurEff->GetAmount()); } void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { Unit* target = GetTarget(); - if (!target->HasAura(SPELL_DK_BLOOD_PRESENCE)) - target->RemoveAura(SPELL_DK_IMPROVED_BLOOD_PRESENCE_TRIGGERED); + + if (target->HasAura(SPELL_DK_BLOOD_PRESENCE)) + { + if (AuraEffect* triggeredEff = target->GetAuraEffect(SPELL_DK_BLOOD_PRESENCE_TRIGGERED, EFFECT_1)) + triggeredEff->SetAmount(0); + } + else + target->RemoveAura(SPELL_DK_BLOOD_PRESENCE_TRIGGERED); } void Register() override { - AfterEffectApply += AuraEffectApplyFn(spell_dk_improved_blood_presence_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - AfterEffectRemove += AuraEffectRemoveFn(spell_dk_improved_blood_presence_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + AfterEffectApply += AuraEffectApplyFn(spell_dk_improved_blood_presence_AuraScript::HandleModDamagePctTaken, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + AfterEffectApply += AuraEffectApplyFn(spell_dk_improved_blood_presence_AuraScript::HandleModAttackerMeleeCritChance, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + AfterEffectRemove += AuraEffectRemoveFn(spell_dk_improved_blood_presence_AuraScript::HandleEffectRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); } }; @@ -841,9 +833,8 @@ class spell_dk_improved_frost_presence : public SpellScriptLoader bool Validate(SpellInfo const* /*spellInfo*/) override { if (!sSpellMgr->GetSpellInfo(SPELL_DK_BLOOD_PRESENCE) - || !sSpellMgr->GetSpellInfo(SPELL_DK_FROST_PRESENCE) || !sSpellMgr->GetSpellInfo(SPELL_DK_UNHOLY_PRESENCE) - || !sSpellMgr->GetSpellInfo(SPELL_DK_FROST_PRESENCE_TRIGGERED)) + || !sSpellMgr->GetSpellInfo(SPELL_DK_IMPROVED_FROST_PRESENCE_TRIGGERED)) return false; return true; } @@ -851,15 +842,13 @@ class spell_dk_improved_frost_presence : public SpellScriptLoader void HandleEffectApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) { Unit* target = GetTarget(); - if ((target->HasAura(SPELL_DK_BLOOD_PRESENCE) || target->HasAura(SPELL_DK_UNHOLY_PRESENCE)) && !target->HasAura(SPELL_DK_FROST_PRESENCE_TRIGGERED)) - target->CastCustomSpell(SPELL_DK_FROST_PRESENCE_TRIGGERED, SPELLVALUE_BASE_POINT0, aurEff->GetAmount(), target, true, NULL, aurEff); + if ((target->HasAura(SPELL_DK_BLOOD_PRESENCE) || target->HasAura(SPELL_DK_UNHOLY_PRESENCE)) && !target->HasAura(SPELL_DK_IMPROVED_FROST_PRESENCE_TRIGGERED)) + target->CastCustomSpell(SPELL_DK_IMPROVED_FROST_PRESENCE_TRIGGERED, SPELLVALUE_BASE_POINT0, aurEff->GetAmount(), target, true, NULL, aurEff); } void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { - Unit* target = GetTarget(); - if (!target->HasAura(SPELL_DK_FROST_PRESENCE)) - target->RemoveAura(SPELL_DK_FROST_PRESENCE_TRIGGERED); + GetTarget()->RemoveAura(SPELL_DK_IMPROVED_FROST_PRESENCE_TRIGGERED); } void Register() override @@ -889,9 +878,7 @@ class spell_dk_improved_unholy_presence : public SpellScriptLoader { if (!sSpellMgr->GetSpellInfo(SPELL_DK_BLOOD_PRESENCE) || !sSpellMgr->GetSpellInfo(SPELL_DK_FROST_PRESENCE) - || !sSpellMgr->GetSpellInfo(SPELL_DK_UNHOLY_PRESENCE) - || !sSpellMgr->GetSpellInfo(SPELL_DK_IMPROVED_UNHOLY_PRESENCE_TRIGGERED) - || !sSpellMgr->GetSpellInfo(SPELL_DK_UNHOLY_PRESENCE_TRIGGERED)) + || !sSpellMgr->GetSpellInfo(SPELL_DK_IMPROVED_UNHOLY_PRESENCE_TRIGGERED)) return false; return true; } @@ -899,25 +886,13 @@ class spell_dk_improved_unholy_presence : public SpellScriptLoader void HandleEffectApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) { Unit* target = GetTarget(); - if (target->HasAura(SPELL_DK_UNHOLY_PRESENCE) && !target->HasAura(SPELL_DK_IMPROVED_UNHOLY_PRESENCE_TRIGGERED)) - { - // Not listed as any effect, only base points set in dbc - int32 basePoints = GetSpellInfo()->Effects[EFFECT_1].CalcValue(); - target->CastCustomSpell(target, SPELL_DK_IMPROVED_UNHOLY_PRESENCE_TRIGGERED, &basePoints, &basePoints, &basePoints, true, NULL, aurEff); - } - - if ((target->HasAura(SPELL_DK_BLOOD_PRESENCE) || target->HasAura(SPELL_DK_FROST_PRESENCE)) && !target->HasAura(SPELL_DK_UNHOLY_PRESENCE_TRIGGERED)) - target->CastCustomSpell(SPELL_DK_UNHOLY_PRESENCE_TRIGGERED, SPELLVALUE_BASE_POINT0, aurEff->GetAmount(), target, true, NULL, aurEff); + if ((target->HasAura(SPELL_DK_BLOOD_PRESENCE) || target->HasAura(SPELL_DK_FROST_PRESENCE)) && !target->HasAura(SPELL_DK_IMPROVED_UNHOLY_PRESENCE_TRIGGERED)) + target->CastCustomSpell(SPELL_DK_IMPROVED_UNHOLY_PRESENCE_TRIGGERED, SPELLVALUE_BASE_POINT0, aurEff->GetAmount(), target, true, NULL, aurEff); } void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { - Unit* target = GetTarget(); - - target->RemoveAura(SPELL_DK_IMPROVED_UNHOLY_PRESENCE_TRIGGERED); - - if (!target->HasAura(SPELL_DK_UNHOLY_PRESENCE)) - target->RemoveAura(SPELL_DK_UNHOLY_PRESENCE_TRIGGERED); + GetTarget()->RemoveAura(SPELL_DK_IMPROVED_UNHOLY_PRESENCE_TRIGGERED); } void Register() override @@ -933,6 +908,34 @@ class spell_dk_improved_unholy_presence : public SpellScriptLoader } }; +// 73975 - Necrotic Strike +class spell_dk_necrotic_strike : public SpellScriptLoader +{ + public: + spell_dk_necrotic_strike() : SpellScriptLoader("spell_dk_necrotic_strike") { } + + class spell_dk_necrotic_strike_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dk_necrotic_strike_AuraScript); + + void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool & /*canBeRecalculated*/) + { + if (Unit* caster = GetCaster()) + amount = int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.7f); + } + + void Register() override + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_necrotic_strike_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_HEAL_ABSORB); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_dk_necrotic_strike_AuraScript(); + } +}; + // 48266 - Blood Presence // 48263 - Frost Presence // 48265 - Unholy Presence @@ -953,10 +956,9 @@ class spell_dk_presence : public SpellScriptLoader || !sSpellMgr->GetSpellInfo(SPELL_DK_IMPROVED_BLOOD_PRESENCE_R1) || !sSpellMgr->GetSpellInfo(SPELL_DK_IMPROVED_FROST_PRESENCE_R1) || !sSpellMgr->GetSpellInfo(SPELL_DK_IMPROVED_UNHOLY_PRESENCE_R1) - || !sSpellMgr->GetSpellInfo(SPELL_DK_IMPROVED_BLOOD_PRESENCE_TRIGGERED) + || !sSpellMgr->GetSpellInfo(SPELL_DK_BLOOD_PRESENCE_TRIGGERED) || !sSpellMgr->GetSpellInfo(SPELL_DK_IMPROVED_UNHOLY_PRESENCE_TRIGGERED) - || !sSpellMgr->GetSpellInfo(SPELL_DK_FROST_PRESENCE_TRIGGERED) - || !sSpellMgr->GetSpellInfo(SPELL_DK_UNHOLY_PRESENCE_TRIGGERED)) + || !sSpellMgr->GetSpellInfo(SPELL_DK_IMPROVED_FROST_PRESENCE_TRIGGERED)) return false; return true; @@ -964,53 +966,57 @@ class spell_dk_presence : public SpellScriptLoader void HandleImprovedBloodPresence(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) { + /// @todo: rune regg (effect 2) Unit* target = GetTarget(); + if (Aura const* aura = target->GetAuraOfRankedSpell(SPELL_DK_IMPROVED_BLOOD_PRESENCE_R1)) + { + CustomSpellValues val; + if (GetSpellInfo()->Id == SPELL_DK_BLOOD_PRESENCE) + { + if (AuraEffect const* impAurEff = aura->GetEffect(EFFECT_1)) + val.AddSpellMod(SPELLVALUE_BASE_POINT1, impAurEff->GetAmount()); + } + else + { + if (AuraEffect const* impAurEff = aura->GetEffect(EFFECT_0)) + val.AddSpellMod(SPELLVALUE_BASE_POINT0, -impAurEff->GetAmount()); + } - if (GetId() == SPELL_DK_BLOOD_PRESENCE) - target->CastSpell(target, SPELL_DK_IMPROVED_BLOOD_PRESENCE_TRIGGERED, true); - else if (AuraEffect const* impAurEff = target->GetAuraEffectOfRankedSpell(SPELL_DK_IMPROVED_BLOOD_PRESENCE_R1, EFFECT_0)) - if (!target->HasAura(SPELL_DK_IMPROVED_BLOOD_PRESENCE_TRIGGERED)) - target->CastCustomSpell(SPELL_DK_IMPROVED_BLOOD_PRESENCE_TRIGGERED, SPELLVALUE_BASE_POINT1, impAurEff->GetAmount(), target, true, NULL, aurEff); + if (!target->HasAura(SPELL_DK_BLOOD_PRESENCE_TRIGGERED)) + target->CastCustomSpell(SPELL_DK_BLOOD_PRESENCE_TRIGGERED, val, target, TRIGGERED_FULL_MASK, NULL, aurEff); + } + else if (GetSpellInfo()->Id == SPELL_DK_BLOOD_PRESENCE) + target->CastSpell(target, SPELL_DK_BLOOD_PRESENCE_TRIGGERED, true, NULL, aurEff); } void HandleImprovedFrostPresence(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) { - Unit* target = GetTarget(); + if (GetSpellInfo()->Id != SPELL_DK_BLOOD_PRESENCE && GetSpellInfo()->Id != SPELL_DK_UNHOLY_PRESENCE) + return; - if (GetId() == SPELL_DK_FROST_PRESENCE) - target->CastSpell(target, SPELL_DK_FROST_PRESENCE_TRIGGERED, true); - else if (AuraEffect const* impAurEff = target->GetAuraEffectOfRankedSpell(SPELL_DK_IMPROVED_FROST_PRESENCE_R1, EFFECT_0)) - if (!target->HasAura(SPELL_DK_FROST_PRESENCE_TRIGGERED)) - target->CastCustomSpell(SPELL_DK_FROST_PRESENCE_TRIGGERED, SPELLVALUE_BASE_POINT0, impAurEff->GetAmount(), target, true, NULL, aurEff); + Unit* target = GetTarget(); + if (AuraEffect const* impAurEff = target->GetAuraEffectOfRankedSpell(SPELL_DK_IMPROVED_FROST_PRESENCE_R1, EFFECT_0)) + if (!target->HasAura(SPELL_DK_IMPROVED_FROST_PRESENCE_TRIGGERED)) + target->CastCustomSpell(SPELL_DK_IMPROVED_FROST_PRESENCE_TRIGGERED, SPELLVALUE_BASE_POINT0, impAurEff->GetAmount(), target, true, NULL, aurEff); } void HandleImprovedUnholyPresence(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) { - Unit* target = GetTarget(); - - if (GetId() == SPELL_DK_UNHOLY_PRESENCE) - target->CastSpell(target, SPELL_DK_UNHOLY_PRESENCE_TRIGGERED, true); + if (GetSpellInfo()->Id != SPELL_DK_BLOOD_PRESENCE && GetSpellInfo()->Id != SPELL_DK_FROST_PRESENCE) + return; + Unit* target = GetTarget(); if (AuraEffect const* impAurEff = target->GetAuraEffectOfRankedSpell(SPELL_DK_IMPROVED_UNHOLY_PRESENCE_R1, EFFECT_0)) - { - if (GetId() == SPELL_DK_UNHOLY_PRESENCE) - { - // Not listed as any effect, only base points set - int32 bp = impAurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue(); - target->CastCustomSpell(target, SPELL_DK_IMPROVED_UNHOLY_PRESENCE_TRIGGERED, &bp, &bp, &bp, true, NULL, aurEff); - } - else if (!target->HasAura(SPELL_DK_UNHOLY_PRESENCE_TRIGGERED)) - target->CastCustomSpell(SPELL_DK_UNHOLY_PRESENCE_TRIGGERED, SPELLVALUE_BASE_POINT0, impAurEff->GetAmount(), target, true, NULL, aurEff); - } + if (!target->HasAura(SPELL_DK_IMPROVED_UNHOLY_PRESENCE_TRIGGERED)) + target->CastCustomSpell(SPELL_DK_IMPROVED_UNHOLY_PRESENCE_TRIGGERED, SPELLVALUE_BASE_POINT0, impAurEff->GetAmount(), target, true, NULL, aurEff); } void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { Unit* target = GetTarget(); - target->RemoveAura(SPELL_DK_IMPROVED_BLOOD_PRESENCE_TRIGGERED); + target->RemoveAura(SPELL_DK_BLOOD_PRESENCE_TRIGGERED); + target->RemoveAura(SPELL_DK_IMPROVED_FROST_PRESENCE_TRIGGERED); target->RemoveAura(SPELL_DK_IMPROVED_UNHOLY_PRESENCE_TRIGGERED); - target->RemoveAura(SPELL_DK_FROST_PRESENCE_TRIGGERED); - target->RemoveAura(SPELL_DK_UNHOLY_PRESENCE_TRIGGERED); } void Register() override @@ -1030,27 +1036,28 @@ class spell_dk_presence : public SpellScriptLoader class RaiseDeadCheck { - public: - explicit RaiseDeadCheck(Player const* caster) : _caster(caster) { } +public: + explicit RaiseDeadCheck(Player const* caster) : _caster(caster) { } - bool operator()(WorldObject* obj) const + bool operator()(WorldObject* obj) const + { + if (Unit* target = obj->ToUnit()) { - if (Unit* target = obj->ToUnit()) - { - if (!target->IsAlive() - && _caster->isHonorOrXPTarget(target) - && target->GetCreatureType() == CREATURE_TYPE_HUMANOID - && target->GetDisplayId() == target->GetNativeDisplayId()) - return false; - } - - return true; + if (!target->IsAlive() + && _caster->isHonorOrXPTarget(target) + && target->GetCreatureType() == CREATURE_TYPE_HUMANOID + && target->GetDisplayId() == target->GetNativeDisplayId()) + return false; } - private: - Player const* _caster; + return true; + } + +private: + Player const* _caster; }; + // 46584 - Raise Dead class spell_dk_raise_dead : public SpellScriptLoader { @@ -1228,16 +1235,16 @@ class spell_dk_scent_of_blood : public SpellScriptLoader return true; } - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + void OnProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) { PreventDefaultAction(); GetTarget()->CastSpell(GetTarget(), SPELL_DK_SCENT_OF_BLOOD, true, NULL, aurEff); - GetTarget()->RemoveAuraFromStack(GetSpellInfo()->Id); + GetTarget()->RemoveAuraFromStack(GetId()); } void Register() override { - OnEffectProc += AuraEffectProcFn(spell_dk_scent_of_blood_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + OnEffectProc += AuraEffectProcFn(spell_dk_scent_of_blood_AuraScript::OnProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); } }; @@ -1310,50 +1317,6 @@ class spell_dk_scourge_strike : public SpellScriptLoader } }; -// 49145 - Spell Deflection -class spell_dk_spell_deflection : public SpellScriptLoader -{ - public: - spell_dk_spell_deflection() : SpellScriptLoader("spell_dk_spell_deflection") { } - - class spell_dk_spell_deflection_AuraScript : public AuraScript - { - PrepareAuraScript(spell_dk_spell_deflection_AuraScript); - - uint32 absorbPct; - - bool Load() override - { - absorbPct = GetSpellInfo()->Effects[EFFECT_0].CalcValue(GetCaster()); - return true; - } - - void CalculateAmount(AuraEffect const* /*aurEff*/, int32 & amount, bool & /*canBeRecalculated*/) - { - // Set absorbtion amount to unlimited - amount = -1; - } - - void Absorb(AuraEffect* /*aurEff*/, DamageInfo & dmgInfo, uint32 & absorbAmount) - { - // You have a chance equal to your Parry chance - if ((dmgInfo.GetDamageType() == SPELL_DIRECT_DAMAGE) && roll_chance_f(GetTarget()->GetUnitParryChance())) - absorbAmount = CalculatePct(dmgInfo.GetDamage(), absorbPct); - } - - void Register() override - { - DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_spell_deflection_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB); - OnEffectAbsorb += AuraEffectAbsorbFn(spell_dk_spell_deflection_AuraScript::Absorb, EFFECT_0); - } - }; - - AuraScript* GetAuraScript() const override - { - return new spell_dk_spell_deflection_AuraScript(); - } -}; - // 55233 - Vampiric Blood class spell_dk_vampiric_blood : public SpellScriptLoader { @@ -1381,7 +1344,7 @@ class spell_dk_vampiric_blood : public SpellScriptLoader } }; -// 52284 - Will of the Necropolis +// -52284 - Will of the Necropolis class spell_dk_will_of_the_necropolis : public SpellScriptLoader { public: @@ -1391,55 +1354,38 @@ class spell_dk_will_of_the_necropolis : public SpellScriptLoader { PrepareAuraScript(spell_dk_will_of_the_necropolis_AuraScript); - bool Validate(SpellInfo const* spellInfo) override + bool Validate(SpellInfo const* /*spellInfo*/) override { - SpellInfo const* firstRankSpellInfo = sSpellMgr->GetSpellInfo(SPELL_DK_WILL_OF_THE_NECROPOLIS_AURA_R1); - if (!firstRankSpellInfo) - return false; - - // can't use other spell than will of the necropolis due to spell_ranks dependency - if (!spellInfo->IsRankOf(firstRankSpellInfo)) - return false; - - uint8 rank = spellInfo->GetRank(); - if (!sSpellMgr->GetSpellWithRank(SPELL_DK_WILL_OF_THE_NECROPOLIS_TALENT_R1, rank, true)) + if (!sSpellMgr->GetSpellInfo(SPELL_DK_WILL_OF_THE_NECROPOLIS)) return false; - return true; } - uint32 absorbPct; - - bool Load() override + bool CheckProc(ProcEventInfo& eventInfo) { - absorbPct = GetSpellInfo()->Effects[EFFECT_0].CalcValue(GetCaster()); - return true; - } + //! HACK due to currenct proc system implementation + if (Player* player = GetTarget()->ToPlayer()) + if (player->HasSpellCooldown(GetId())) + return false; - void CalculateAmount(AuraEffect const* /*aurEff*/, int32 & amount, bool & /*canBeRecalculated*/) - { - // Set absorbtion amount to unlimited - amount = -1; + return GetTarget()->HealthBelowPctDamaged(30, eventInfo.GetDamageInfo()->GetDamage()); } - void Absorb(AuraEffect* /*aurEff*/, DamageInfo & dmgInfo, uint32 & absorbAmount) + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) { - // min pct of hp is stored in effect 0 of talent spell - uint8 rank = GetSpellInfo()->GetRank(); - SpellInfo const* talentProto = sSpellMgr->EnsureSpellInfo(sSpellMgr->GetSpellWithRank(SPELL_DK_WILL_OF_THE_NECROPOLIS_TALENT_R1, rank)); + GetTarget()->CastSpell(GetTarget(), SPELL_DK_WILL_OF_THE_NECROPOLIS, true, NULL, aurEff); - int32 remainingHp = int32(GetTarget()->GetHealth() - dmgInfo.GetDamage()); - int32 minHp = int32(GetTarget()->CountPctFromMaxHealth(talentProto->Effects[EFFECT_0].CalcValue(GetCaster()))); - - // Damage that would take you below [effect0] health or taken while you are at [effect0] - if (remainingHp < minHp) - absorbAmount = CalculatePct(dmgInfo.GetDamage(), absorbPct); + if (Player* player = GetTarget()->ToPlayer()) + { + player->RemoveSpellCooldown(SPELL_DK_RUNE_TAP, true); + player->AddSpellCooldown(GetId(), 0, time(NULL) + 45); + } } void Register() override { - DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_will_of_the_necropolis_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB); - OnEffectAbsorb += AuraEffectAbsorbFn(spell_dk_will_of_the_necropolis_AuraScript::Absorb, EFFECT_0); + DoCheckProc += AuraCheckProcFn(spell_dk_will_of_the_necropolis_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_dk_will_of_the_necropolis_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE); } }; @@ -1456,23 +1402,24 @@ void AddSC_deathknight_spell_scripts() new spell_dk_anti_magic_zone(); new spell_dk_blood_boil(); new spell_dk_blood_gorged(); - new spell_dk_corpse_explosion(); + new spell_dk_butchery(); new spell_dk_death_coil(); new spell_dk_death_gate(); new spell_dk_death_grip(); new spell_dk_death_pact(); new spell_dk_death_strike(); + new spell_dk_death_strike_enabler(); new spell_dk_ghoul_explode(); new spell_dk_icebound_fortitude(); new spell_dk_improved_blood_presence(); new spell_dk_improved_frost_presence(); new spell_dk_improved_unholy_presence(); + new spell_dk_necrotic_strike(); new spell_dk_presence(); new spell_dk_raise_dead(); new spell_dk_rune_tap_party(); new spell_dk_scent_of_blood(); new spell_dk_scourge_strike(); - new spell_dk_spell_deflection(); new spell_dk_vampiric_blood(); new spell_dk_will_of_the_necropolis(); } diff --git a/src/server/scripts/Spells/spell_druid.cpp b/src/server/scripts/Spells/spell_druid.cpp index e466c15d417..a352ebb41ae 100644 --- a/src/server/scripts/Spells/spell_druid.cpp +++ b/src/server/scripts/Spells/spell_druid.cpp @@ -29,24 +29,41 @@ enum DruidSpells { + SPELL_DRUID_WRATH = 5176, + SPELL_DRUID_STARFIRE = 2912, + SPELL_DRUID_STARSURGE = 78674, + SPELL_DRUID_ECLIPSE_GENERAL_ENERGIZE = 89265, + SPELL_DRUID_STARSURGE_ENERGIZE = 86605, + SPELL_DRUID_LUNAR_ECLIPSE_MARKER = 67484, // Will make the yellow arrow on eclipse bar point to the blue side (lunar) + SPELL_DRUID_SOLAR_ECLIPSE_MARKER = 67483, // Will make the yellow arrow on eclipse bar point to the yellow side (solar) + SPELL_DRUID_SOLAR_ECLIPSE = 48517, + SPELL_DRUID_LUNAR_ECLIPSE = 48518, SPELL_DRUID_ENRAGE_MOD_DAMAGE = 51185, + SPELL_DRUID_FERAL_CHARGE_BEAR = 16979, + SPELL_DRUID_FERAL_CHARGE_CAT = 49376, + SPELL_DRUID_GLYPH_OF_INNERVATE = 54833, + SPELL_DRUID_GLYPH_OF_STARFIRE = 54846, SPELL_DRUID_GLYPH_OF_TYPHOON = 62135, SPELL_DRUID_IDOL_OF_FERAL_SHADOWS = 34241, SPELL_DRUID_IDOL_OF_WORSHIP = 60774, SPELL_DRUID_INCREASED_MOONFIRE_DURATION = 38414, + SPELL_DRUID_ITEM_T8_BALANCE_RELIC = 64950, SPELL_DRUID_KING_OF_THE_JUNGLE = 48492, SPELL_DRUID_LIFEBLOOM_ENERGIZE = 64372, SPELL_DRUID_LIFEBLOOM_FINAL_HEAL = 33778, SPELL_DRUID_LIVING_SEED_HEAL = 48503, SPELL_DRUID_LIVING_SEED_PROC = 48504, - SPELL_DRUID_NATURES_SPLENDOR = 57865, + SPELL_DRUID_NATURES_GRACE = 16880, + SPELL_DRUID_NATURES_GRACE_TRIGGER = 16886, SPELL_DRUID_SURVIVAL_INSTINCTS = 50322, SPELL_DRUID_SAVAGE_ROAR = 62071, - SPELL_DRUID_TIGER_S_FURY_ENERGIZE = 51178, - SPELL_DRUID_ITEM_T8_BALANCE_RELIC = 64950, + SPELL_DRUID_STAMPEDE_BAER_RANK_1 = 81016, + SPELL_DRUID_STAMPEDE_CAT_RANK_1 = 81021, + SPELL_DRUID_STAMPEDE_CAT_STATE = 109881, + SPELL_DRUID_TIGER_S_FURY_ENERGIZE = 51178 }; -// -1850 - Dash +// 1850 - Dash class spell_dru_dash : public SpellScriptLoader { public: @@ -75,6 +92,162 @@ class spell_dru_dash : public SpellScriptLoader } }; +// 48517 - Eclipse (Solar) +// 48518 - Eclipse (Lunar) +class spell_dru_eclipse : public SpellScriptLoader +{ + public: + spell_dru_eclipse(char const* scriptName) : SpellScriptLoader(scriptName) { } + + class spell_dru_eclipse_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dru_eclipse_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_DRUID_NATURES_GRACE) || + !sSpellMgr->GetSpellInfo(SPELL_DRUID_NATURES_GRACE_TRIGGER)) + return false; + return true; + } + + bool Load() override + { + return GetCaster() && GetCaster()->GetTypeId() == TYPEID_PLAYER; + } + + void ApplyEffect(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* caster = GetCaster(); + if (!caster) + return; + + if (caster->ToPlayer()->GetAuraOfRankedSpell(SPELL_DRUID_NATURES_GRACE)) + caster->ToPlayer()->RemoveSpellCooldown(SPELL_DRUID_NATURES_GRACE_TRIGGER, true); + } + + void Register() override + { + OnEffectApply += AuraEffectApplyFn(spell_dru_eclipse_AuraScript::ApplyEffect, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_dru_eclipse_AuraScript(); + } +}; + +// 2912, 5176, 78674 - Starfire, Wrath, and Starsurge +class spell_dru_eclipse_energize : public SpellScriptLoader +{ + public: + spell_dru_eclipse_energize() : SpellScriptLoader("spell_dru_eclipse_energize") { } + + class spell_dru_eclipse_energize_SpellScript : public SpellScript + { + PrepareSpellScript(spell_dru_eclipse_energize_SpellScript); + + int32 energizeAmount; + + bool Load() override + { + if (GetCaster()->GetTypeId() != TYPEID_PLAYER) + return false; + + if (GetCaster()->ToPlayer()->getClass() != CLASS_DRUID) + return false; + + energizeAmount = 0; + + return true; + } + + void HandleEnergize(SpellEffIndex effIndex) + { + Player* caster = GetCaster()->ToPlayer(); + + // No boomy, no deal. + if (caster->GetPrimaryTalentTree(caster->GetActiveSpec()) != TALENT_TREE_DRUID_BALANCE) + return; + + switch (GetSpellInfo()->Id) + { + case SPELL_DRUID_WRATH: + { + energizeAmount = -GetSpellInfo()->Effects[effIndex].BasePoints; // -13 + // If we are set to fill the lunar side or we've just logged in with 0 power.. + if ((!caster->HasAura(SPELL_DRUID_SOLAR_ECLIPSE_MARKER) && caster->HasAura(SPELL_DRUID_LUNAR_ECLIPSE_MARKER)) + || caster->GetPower(POWER_ECLIPSE) == 0) + { + caster->CastCustomSpell(caster, SPELL_DRUID_ECLIPSE_GENERAL_ENERGIZE, &energizeAmount, 0, 0, true); + // If the energize was due to 0 power, cast the eclipse marker aura + if (!caster->HasAura(SPELL_DRUID_LUNAR_ECLIPSE_MARKER)) + caster->CastSpell(caster, SPELL_DRUID_LUNAR_ECLIPSE_MARKER, true); + } + // The energizing effect brought us out of the solar eclipse, remove the aura + if (caster->HasAura(SPELL_DRUID_SOLAR_ECLIPSE) && caster->GetPower(POWER_ECLIPSE) <= 0) + caster->RemoveAurasDueToSpell(SPELL_DRUID_SOLAR_ECLIPSE); + break; + } + case SPELL_DRUID_STARFIRE: + { + energizeAmount = GetSpellInfo()->Effects[effIndex].BasePoints; // 20 + // If we are set to fill the solar side or we've just logged in with 0 power.. + if ((!caster->HasAura(SPELL_DRUID_LUNAR_ECLIPSE_MARKER) && caster->HasAura(SPELL_DRUID_SOLAR_ECLIPSE_MARKER)) + || caster->GetPower(POWER_ECLIPSE) == 0) + { + caster->CastCustomSpell(caster, SPELL_DRUID_ECLIPSE_GENERAL_ENERGIZE, &energizeAmount, 0, 0, true); + // If the energize was due to 0 power, cast the eclipse marker aura + if (!caster->HasAura(SPELL_DRUID_SOLAR_ECLIPSE_MARKER)) + caster->CastSpell(caster, SPELL_DRUID_SOLAR_ECLIPSE_MARKER, true); + } + // The energizing effect brought us out of the lunar eclipse, remove the aura + if (caster->HasAura(SPELL_DRUID_LUNAR_ECLIPSE) && caster->GetPower(POWER_ECLIPSE) >= 0) + caster->RemoveAura(SPELL_DRUID_LUNAR_ECLIPSE); + break; + } + case SPELL_DRUID_STARSURGE: + { + // If we are set to fill the solar side or we've just logged in with 0 power (confirmed with sniffs) + if ((!caster->HasAura(SPELL_DRUID_LUNAR_ECLIPSE_MARKER) && caster->HasAura(SPELL_DRUID_SOLAR_ECLIPSE_MARKER)) + || caster->GetPower(POWER_ECLIPSE) == 0) + { + energizeAmount = GetSpellInfo()->Effects[effIndex].BasePoints; // 15 + caster->CastCustomSpell(caster, SPELL_DRUID_STARSURGE_ENERGIZE, &energizeAmount, 0, 0, true); + + // If the energize was due to 0 power, cast the eclipse marker aura + if (!caster->HasAura(SPELL_DRUID_SOLAR_ECLIPSE_MARKER)) + caster->CastSpell(caster, SPELL_DRUID_SOLAR_ECLIPSE_MARKER, true); + } + else if (!caster->HasAura(SPELL_DRUID_SOLAR_ECLIPSE_MARKER) && caster->HasAura(SPELL_DRUID_LUNAR_ECLIPSE_MARKER)) + { + energizeAmount = -GetSpellInfo()->Effects[effIndex].BasePoints; // -15 + caster->CastCustomSpell(caster, SPELL_DRUID_STARSURGE_ENERGIZE, &energizeAmount, 0, 0, true); + } + // The energizing effect brought us out of the lunar eclipse, remove the aura + if (caster->HasAura(SPELL_DRUID_LUNAR_ECLIPSE) && caster->GetPower(POWER_ECLIPSE) >= 0) + caster->RemoveAura(SPELL_DRUID_LUNAR_ECLIPSE); + // The energizing effect brought us out of the solar eclipse, remove the aura + else if (caster->HasAura(SPELL_DRUID_SOLAR_ECLIPSE) && caster->GetPower(POWER_ECLIPSE) <= 0) + caster->RemoveAura(SPELL_DRUID_SOLAR_ECLIPSE); + break; + } + } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_dru_eclipse_energize_SpellScript::HandleEnergize, EFFECT_1, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_dru_eclipse_energize_SpellScript; + } +}; + // 5229 - Enrage class spell_dru_enrage : public SpellScriptLoader { @@ -111,6 +284,48 @@ class spell_dru_enrage : public SpellScriptLoader } }; +// 54832 - Glyph of Innervate +class spell_dru_glyph_of_innervate : public SpellScriptLoader +{ + public: + spell_dru_glyph_of_innervate() : SpellScriptLoader("spell_dru_glyph_of_innervate") { } + + class spell_dru_glyph_of_innervate_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dru_glyph_of_innervate_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_DRUID_GLYPH_OF_INNERVATE)) + return false; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + // Not proc from self Innervate + return GetTarget() != eventInfo.GetProcTarget(); + } + + void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + GetTarget()->CastSpell(GetTarget(), SPELL_DRUID_GLYPH_OF_INNERVATE, true, NULL, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_dru_glyph_of_innervate_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_dru_glyph_of_innervate_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_dru_glyph_of_innervate_AuraScript(); + } +}; + // 54846 - Glyph of Starfire class spell_dru_glyph_of_starfire : public SpellScriptLoader { @@ -123,7 +338,7 @@ class spell_dru_glyph_of_starfire : public SpellScriptLoader bool Validate(SpellInfo const* /*spellInfo*/) override { - if (!sSpellMgr->GetSpellInfo(SPELL_DRUID_INCREASED_MOONFIRE_DURATION) || !sSpellMgr->GetSpellInfo(SPELL_DRUID_NATURES_SPLENDOR)) + if (!sSpellMgr->GetSpellInfo(SPELL_DRUID_INCREASED_MOONFIRE_DURATION)) return false; return true; } @@ -132,7 +347,7 @@ class spell_dru_glyph_of_starfire : public SpellScriptLoader { Unit* caster = GetCaster(); if (Unit* unitTarget = GetHitUnit()) - if (AuraEffect const* aurEff = unitTarget->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_DRUID, 0x00000002, 0, 0, caster->GetGUID())) + if (AuraEffect const* aurEff = unitTarget->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_DRUID, 0x2, 0, 0, caster->GetGUID())) { Aura* aura = aurEff->GetBase(); @@ -140,8 +355,6 @@ class spell_dru_glyph_of_starfire : public SpellScriptLoader uint32 countMax = aura->GetSpellInfo()->GetMaxDuration() + 9000; if (caster->HasAura(SPELL_DRUID_INCREASED_MOONFIRE_DURATION)) countMax += 3000; - if (caster->HasAura(SPELL_DRUID_NATURES_SPLENDOR)) - countMax += 3000; if (countMin < countMax) { @@ -163,6 +376,41 @@ class spell_dru_glyph_of_starfire : public SpellScriptLoader } }; +// 54845 - Glyph of Starfire +class spell_dru_glyph_of_starfire_proc : public SpellScriptLoader +{ + public: + spell_dru_glyph_of_starfire_proc() : SpellScriptLoader("spell_dru_glyph_of_starfire_proc") { } + + class spell_dru_glyph_of_starfire_proc_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dru_glyph_of_starfire_proc_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_DRUID_GLYPH_OF_STARFIRE)) + return false; + return true; + } + + void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + GetTarget()->CastSpell(eventInfo.GetProcTarget(), SPELL_DRUID_GLYPH_OF_STARFIRE, true, NULL, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_dru_glyph_of_starfire_proc_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_dru_glyph_of_starfire_proc_AuraScript(); + } +}; + // 34246 - Idol of the Emerald Queen // 60779 - Idol of Lush Moss class spell_dru_idol_lifebloom : public SpellScriptLoader @@ -226,7 +474,7 @@ class spell_dru_innervate : public SpellScriptLoader } }; -// -5570 - Insect Swarm +// 5570 - Insect Swarm class spell_dru_insect_swarm : public SpellScriptLoader { public: @@ -255,7 +503,7 @@ class spell_dru_insect_swarm : public SpellScriptLoader } }; -// -33763 - Lifebloom +// 33763 - Lifebloom class spell_dru_lifebloom : public SpellScriptLoader { public: @@ -408,77 +656,6 @@ class spell_dru_living_seed_proc : public SpellScriptLoader } }; -// 69366 - Moonkin Form passive -class spell_dru_moonkin_form_passive : public SpellScriptLoader -{ - public: - spell_dru_moonkin_form_passive() : SpellScriptLoader("spell_dru_moonkin_form_passive") { } - - class spell_dru_moonkin_form_passive_AuraScript : public AuraScript - { - PrepareAuraScript(spell_dru_moonkin_form_passive_AuraScript); - - uint32 absorbPct; - - bool Load() override - { - absorbPct = GetSpellInfo()->Effects[EFFECT_0].CalcValue(GetCaster()); - return true; - } - - void CalculateAmount(AuraEffect const* /*aurEff*/, int32 & amount, bool & /*canBeRecalculated*/) - { - // Set absorbtion amount to unlimited - amount = -1; - } - - void Absorb(AuraEffect* /*aurEff*/, DamageInfo & dmgInfo, uint32 & absorbAmount) - { - // reduces all damage taken while Stunned in Moonkin Form - if (GetTarget()->GetUInt32Value(UNIT_FIELD_FLAGS) & (UNIT_FLAG_STUNNED) && GetTarget()->HasAuraWithMechanic(1<<MECHANIC_STUN)) - absorbAmount = CalculatePct(dmgInfo.GetDamage(), absorbPct); - } - - void Register() override - { - DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dru_moonkin_form_passive_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB); - OnEffectAbsorb += AuraEffectAbsorbFn(spell_dru_moonkin_form_passive_AuraScript::Absorb, EFFECT_0); - } - }; - - AuraScript* GetAuraScript() const override - { - return new spell_dru_moonkin_form_passive_AuraScript(); - } -}; - -// 48391 - Owlkin Frenzy -class spell_dru_owlkin_frenzy : public SpellScriptLoader -{ - public: - spell_dru_owlkin_frenzy() : SpellScriptLoader("spell_dru_owlkin_frenzy") { } - - class spell_dru_owlkin_frenzy_AuraScript : public AuraScript - { - PrepareAuraScript(spell_dru_owlkin_frenzy_AuraScript); - - void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/) - { - amount = CalculatePct(GetUnitOwner()->GetCreatePowers(POWER_MANA), amount); - } - - void Register() override - { - DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dru_owlkin_frenzy_AuraScript::CalculateAmount, EFFECT_2, SPELL_AURA_PERIODIC_ENERGIZE); - } - }; - - AuraScript* GetAuraScript() const override - { - return new spell_dru_owlkin_frenzy_AuraScript(); - } -}; - // -16972 - Predatory Strikes class spell_dru_predatory_strikes : public SpellScriptLoader { @@ -508,51 +685,7 @@ class spell_dru_predatory_strikes : public SpellScriptLoader } }; -// 33851 - Primal Tenacity -class spell_dru_primal_tenacity : public SpellScriptLoader -{ - public: - spell_dru_primal_tenacity() : SpellScriptLoader("spell_dru_primal_tenacity") { } - - class spell_dru_primal_tenacity_AuraScript : public AuraScript - { - PrepareAuraScript(spell_dru_primal_tenacity_AuraScript); - - uint32 absorbPct; - - bool Load() override - { - absorbPct = GetSpellInfo()->Effects[EFFECT_1].CalcValue(GetCaster()); - return true; - } - - void CalculateAmount(AuraEffect const* /*aurEff*/, int32 & amount, bool & /*canBeRecalculated*/) - { - // Set absorbtion amount to unlimited - amount = -1; - } - - void Absorb(AuraEffect* /*aurEff*/, DamageInfo & dmgInfo, uint32 & absorbAmount) - { - // reduces all damage taken while Stunned in Cat Form - if (GetTarget()->GetShapeshiftForm() == FORM_CAT && GetTarget()->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED) && GetTarget()->HasAuraWithMechanic(1<<MECHANIC_STUN)) - absorbAmount = CalculatePct(dmgInfo.GetDamage(), absorbPct); - } - - void Register() override - { - DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dru_primal_tenacity_AuraScript::CalculateAmount, EFFECT_1, SPELL_AURA_SCHOOL_ABSORB); - OnEffectAbsorb += AuraEffectAbsorbFn(spell_dru_primal_tenacity_AuraScript::Absorb, EFFECT_1); - } - }; - - AuraScript* GetAuraScript() const override - { - return new spell_dru_primal_tenacity_AuraScript(); - } -}; - -// -1079 - Rip +// 1079 - Rip class spell_dru_rip : public SpellScriptLoader { public: @@ -672,7 +805,7 @@ class spell_dru_savage_roar : public SpellScriptLoader { PrepareAuraScript(spell_dru_savage_roar_AuraScript); - bool Validate(SpellInfo const* /*spell*/) override + bool Validate(SpellInfo const* /*spellInfo*/) override { if (!sSpellMgr->GetSpellInfo(SPELL_DRUID_SAVAGE_ROAR)) return false; @@ -708,34 +841,7 @@ class spell_dru_savage_roar : public SpellScriptLoader } }; -// -50294 - Starfall (AOE) -class spell_dru_starfall_aoe : public SpellScriptLoader -{ - public: - spell_dru_starfall_aoe() : SpellScriptLoader("spell_dru_starfall_aoe") { } - - class spell_dru_starfall_aoe_SpellScript : public SpellScript - { - PrepareSpellScript(spell_dru_starfall_aoe_SpellScript); - - void FilterTargets(std::list<WorldObject*>& targets) - { - targets.remove(GetExplTargetUnit()); - } - - void Register() override - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_dru_starfall_aoe_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY); - } - }; - - SpellScript* GetSpellScript() const override - { - return new spell_dru_starfall_aoe_SpellScript(); - } -}; - -// -50286 - Starfall (Dummy) +// 50286 - Starfall (Dummy) class spell_dru_starfall_dummy : public SpellScriptLoader { public: @@ -781,6 +887,59 @@ class spell_dru_starfall_dummy : public SpellScriptLoader } }; +// -78892 - Stampede +class spell_dru_stampede : public SpellScriptLoader +{ + public: + spell_dru_stampede() : SpellScriptLoader("spell_dru_stampede") { } + + class spell_dru_stampede_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dru_stampede_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_DRUID_STAMPEDE_BAER_RANK_1) || + !sSpellMgr->GetSpellInfo(SPELL_DRUID_STAMPEDE_CAT_RANK_1) || + !sSpellMgr->GetSpellInfo(SPELL_DRUID_STAMPEDE_CAT_STATE) || + !sSpellMgr->GetSpellInfo(SPELL_DRUID_FERAL_CHARGE_CAT) || + !sSpellMgr->GetSpellInfo(SPELL_DRUID_FERAL_CHARGE_BEAR)) + return false; + return true; + } + + void HandleEffectCatProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + if (GetTarget()->GetShapeshiftForm() != FORM_CAT || eventInfo.GetDamageInfo()->GetSpellInfo()->Id != SPELL_DRUID_FERAL_CHARGE_CAT) + return; + + GetTarget()->CastSpell(GetTarget(), sSpellMgr->GetSpellWithRank(SPELL_DRUID_STAMPEDE_CAT_RANK_1, GetSpellInfo()->GetRank()), true, NULL, aurEff); + GetTarget()->CastSpell(GetTarget(), SPELL_DRUID_STAMPEDE_CAT_STATE, true, NULL, aurEff); + } + + void HandleEffectBearProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + if (GetTarget()->GetShapeshiftForm() != FORM_BEAR || eventInfo.GetDamageInfo()->GetSpellInfo()->Id != SPELL_DRUID_FERAL_CHARGE_BEAR) + return; + + GetTarget()->CastSpell(GetTarget(), sSpellMgr->GetSpellWithRank(SPELL_DRUID_STAMPEDE_BAER_RANK_1, GetSpellInfo()->GetRank()), true, NULL, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_dru_stampede_AuraScript::HandleEffectCatProc, EFFECT_0, SPELL_AURA_DUMMY); + OnEffectProc += AuraEffectProcFn(spell_dru_stampede_AuraScript::HandleEffectBearProc, EFFECT_1, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_dru_stampede_AuraScript(); + } +}; + // 61336 - Survival Instincts class spell_dru_survival_instincts : public SpellScriptLoader { @@ -865,7 +1024,7 @@ class spell_dru_swift_flight_passive : public SpellScriptLoader void CalculateAmount(AuraEffect const* /*aurEff*/, int32 & amount, bool & /*canBeRecalculated*/) { if (Player* caster = GetCaster()->ToPlayer()) - if (caster->Has310Flyer(false)) + if (caster->GetSkillValue(SKILL_RIDING) >= 375) amount = 310; } @@ -881,7 +1040,7 @@ class spell_dru_swift_flight_passive : public SpellScriptLoader } }; -// -5217 - Tiger's Fury +// 5217 - Tiger's Fury class spell_dru_tiger_s_fury : public SpellScriptLoader { public: @@ -909,7 +1068,7 @@ class spell_dru_tiger_s_fury : public SpellScriptLoader } }; -// -61391 - Typhoon +// 61391 - Typhoon class spell_dru_typhoon : public SpellScriptLoader { public: @@ -1010,7 +1169,7 @@ class RaidCheck Unit const* _caster; }; -// -48438 - Wild Growth +// 48438 - Wild Growth class spell_dru_wild_growth : public SpellScriptLoader { public: @@ -1066,23 +1225,25 @@ class spell_dru_wild_growth : public SpellScriptLoader void AddSC_druid_spell_scripts() { new spell_dru_dash(); + new spell_dru_eclipse("spell_dru_eclipse_lunar"); + new spell_dru_eclipse("spell_dru_eclipse_solar"); + new spell_dru_eclipse_energize(); new spell_dru_enrage(); + new spell_dru_glyph_of_innervate(); new spell_dru_glyph_of_starfire(); + new spell_dru_glyph_of_starfire_proc(); new spell_dru_idol_lifebloom(); new spell_dru_innervate(); new spell_dru_insect_swarm(); new spell_dru_lifebloom(); new spell_dru_living_seed(); new spell_dru_living_seed_proc(); - new spell_dru_moonkin_form_passive(); - new spell_dru_owlkin_frenzy(); new spell_dru_predatory_strikes(); - new spell_dru_primal_tenacity(); new spell_dru_rip(); new spell_dru_savage_defense(); new spell_dru_savage_roar(); - new spell_dru_starfall_aoe(); new spell_dru_starfall_dummy(); + new spell_dru_stampede(); new spell_dru_survival_instincts(); new spell_dru_swift_flight_passive(); new spell_dru_tiger_s_fury(); diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index 4c72d790059..0dd38c74fef 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -164,6 +164,67 @@ class spell_gen_adaptive_warding : public SpellScriptLoader } }; +enum AlchemistStone +{ + ALECHEMIST_STONE_HEAL = 21399, + ALECHEMIST_STONE_MANA = 21400, +}; + +// 17619 - Alchemist Stone +class spell_gen_alchemist_stone : public SpellScriptLoader +{ + public: + spell_gen_alchemist_stone() : SpellScriptLoader("spell_gen_alchemist_stone") { } + + class spell_gen_alchemist_stone_AuraScript : public AuraScript + { + PrepareAuraScript(spell_gen_alchemist_stone_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(ALECHEMIST_STONE_HEAL) || + !sSpellMgr->GetSpellInfo(ALECHEMIST_STONE_MANA)) + return false; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + return eventInfo.GetDamageInfo()->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_POTION; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + uint32 spellId = 0; + int32 bp = int32(eventInfo.GetDamageInfo()->GetDamage() * 0.4f); + + if (eventInfo.GetDamageInfo()->GetSpellInfo()->HasEffect(SPELL_EFFECT_HEAL)) + spellId = ALECHEMIST_STONE_HEAL; + else if (eventInfo.GetDamageInfo()->GetSpellInfo()->HasEffect(SPELL_EFFECT_ENERGIZE)) + spellId = ALECHEMIST_STONE_MANA; + + if (!spellId) + return; + + GetTarget()->CastCustomSpell(spellId, SPELLVALUE_BASE_POINT0, bp, GetTarget(), true, NULL, aurEff); + } + + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_gen_alchemist_stone_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_gen_alchemist_stone_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_gen_alchemist_stone_AuraScript(); + } +}; + class spell_gen_allow_cast_from_item_only : public SpellScriptLoader { public: @@ -699,6 +760,11 @@ class spell_gen_chaos_blast : public SpellScriptLoader } }; +enum Clone +{ + SPELL_NIGHTMARE_FIGMENT_MIRROR_IMAGE = 57528 +}; + class spell_gen_clone : public SpellScriptLoader { public: @@ -716,8 +782,16 @@ class spell_gen_clone : public SpellScriptLoader 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); + if (m_scriptSpellId == SPELL_NIGHTMARE_FIGMENT_MIRROR_IMAGE) + { + OnEffectHitTarget += SpellEffectFn(spell_gen_clone_SpellScript::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_gen_clone_SpellScript::HandleScriptEffect, EFFECT_2, SPELL_EFFECT_DUMMY); + } + else + { + 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); + } } }; @@ -1080,63 +1154,6 @@ class spell_gen_dalaran_disguise : public SpellScriptLoader } }; -enum DamageReductionAura -{ - SPELL_BLESSING_OF_SANCTUARY = 20911, - SPELL_GREATER_BLESSING_OF_SANCTUARY = 25899, - SPELL_RENEWED_HOPE = 63944, - SPELL_VIGILANCE = 50720, - SPELL_DAMAGE_REDUCTION_AURA = 68066 -}; - -class spell_gen_damage_reduction_aura : public SpellScriptLoader -{ - 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 - { - if (!sSpellMgr->GetSpellInfo(SPELL_DAMAGE_REDUCTION_AURA)) - return false; - return true; - } - - 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); - } - } - - 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); - } - - }; - - AuraScript* GetAuraScript() const override - { - return new spell_gen_damage_reduction_AuraScript(); - } -}; - enum DefendVisuals { SPELL_VISUAL_SHIELD_1 = 63130, @@ -1674,6 +1691,48 @@ class spell_gen_gunship_portal : public SpellScriptLoader } }; + +enum Interrupt +{ + SPELL_GEN_THROW_INTERRUPT = 32747 +}; + +// 32748 - Deadly Throw Interrupt +// 44835 - Maim Interrupt +class spell_gen_interrupt : public SpellScriptLoader +{ + public: + spell_gen_interrupt() : SpellScriptLoader("spell_gen_interrupt") { } + + class spell_gen_interrupt_AuraScript : public AuraScript + { + PrepareAuraScript(spell_gen_interrupt_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_GEN_THROW_INTERRUPT)) + return false; + return true; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + GetTarget()->CastSpell(eventInfo.GetProcTarget(), SPELL_GEN_THROW_INTERRUPT, true, NULL, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_gen_interrupt_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_gen_interrupt_AuraScript(); + } +}; + enum Launch { SPELL_LAUNCH_NO_FALLING_DAMAGE = 66251 @@ -1726,31 +1785,32 @@ class spell_gen_launch : public SpellScriptLoader } }; - -class spell_gen_lifeblood : public SpellScriptLoader +class spell_gen_increase_stats_buff : public SpellScriptLoader { public: - spell_gen_lifeblood() : SpellScriptLoader("spell_gen_lifeblood") { } + spell_gen_increase_stats_buff(char const* scriptName) : SpellScriptLoader(scriptName) { } - class spell_gen_lifeblood_AuraScript : public AuraScript + class spell_gen_increase_stats_buff_SpellScript : public SpellScript { - PrepareAuraScript(spell_gen_lifeblood_AuraScript); + PrepareSpellScript(spell_gen_increase_stats_buff_SpellScript); - void CalculateAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/) + void HandleDummy(SpellEffIndex /*effIndex*/) { - if (Unit* owner = GetUnitOwner()) - amount += int32(CalculatePct(owner->GetMaxHealth(), 1.5f / aurEff->GetTotalTicks())); + if (GetHitUnit()->IsInRaidWith(GetCaster())) + GetCaster()->CastSpell(GetCaster(), GetEffectValue() + 1, true); // raid buff + else + GetCaster()->CastSpell(GetHitUnit(), GetEffectValue(), true); // single-target buff } void Register() override { - DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_lifeblood_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_PERIODIC_HEAL); + OnEffectHitTarget += SpellEffectFn(spell_gen_increase_stats_buff_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; - AuraScript* GetAuraScript() const override + SpellScript* GetSpellScript() const override { - return new spell_gen_lifeblood_AuraScript(); + return new spell_gen_increase_stats_buff_SpellScript(); } }; @@ -1810,233 +1870,6 @@ class spell_gen_lifebloom : public SpellScriptLoader uint32 _spellId; }; -enum MagicRoosterSpells -{ - SPELL_MAGIC_ROOSTER_NORMAL = 66122, - SPELL_MAGIC_ROOSTER_DRAENEI_MALE = 66123, - SPELL_MAGIC_ROOSTER_TAUREN_MALE = 66124 -}; - -class spell_gen_magic_rooster : public SpellScriptLoader -{ - public: - spell_gen_magic_rooster() : SpellScriptLoader("spell_gen_magic_rooster") { } - - class spell_gen_magic_rooster_SpellScript : public SpellScript - { - 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); - } - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_gen_magic_rooster_SpellScript::HandleScript, EFFECT_2, SPELL_EFFECT_SCRIPT_EFFECT); - } - }; - - SpellScript* GetSpellScript() const override - { - return new spell_gen_magic_rooster_SpellScript(); - } -}; - -enum Mounts -{ - SPELL_COLD_WEATHER_FLYING = 54197, - - // Magic Broom - SPELL_MAGIC_BROOM_60 = 42680, - SPELL_MAGIC_BROOM_100 = 42683, - SPELL_MAGIC_BROOM_150 = 42667, - SPELL_MAGIC_BROOM_280 = 42668, - - // Headless Horseman's Mount - SPELL_HEADLESS_HORSEMAN_MOUNT_60 = 51621, - SPELL_HEADLESS_HORSEMAN_MOUNT_100 = 48024, - SPELL_HEADLESS_HORSEMAN_MOUNT_150 = 51617, - SPELL_HEADLESS_HORSEMAN_MOUNT_280 = 48023, - - // Winged Steed of the Ebon Blade - SPELL_WINGED_STEED_150 = 54726, - SPELL_WINGED_STEED_280 = 54727, - - // Big Love Rocket - SPELL_BIG_LOVE_ROCKET_0 = 71343, - SPELL_BIG_LOVE_ROCKET_60 = 71344, - SPELL_BIG_LOVE_ROCKET_100 = 71345, - SPELL_BIG_LOVE_ROCKET_150 = 71346, - SPELL_BIG_LOVE_ROCKET_310 = 71347, - - // Invincible - SPELL_INVINCIBLE_60 = 72281, - SPELL_INVINCIBLE_100 = 72282, - SPELL_INVINCIBLE_150 = 72283, - SPELL_INVINCIBLE_310 = 72284, - - // Blazing Hippogryph - SPELL_BLAZING_HIPPOGRYPH_150 = 74854, - SPELL_BLAZING_HIPPOGRYPH_280 = 74855, - - // Celestial Steed - SPELL_CELESTIAL_STEED_60 = 75619, - SPELL_CELESTIAL_STEED_100 = 75620, - SPELL_CELESTIAL_STEED_150 = 75617, - SPELL_CELESTIAL_STEED_280 = 75618, - SPELL_CELESTIAL_STEED_310 = 76153, - - // X-53 Touring Rocket - SPELL_X53_TOURING_ROCKET_150 = 75957, - SPELL_X53_TOURING_ROCKET_280 = 75972, - SPELL_X53_TOURING_ROCKET_310 = 76154 -}; - -class spell_gen_mount : public SpellScriptLoader -{ - public: - spell_gen_mount(const char* name, uint32 mount0 = 0, uint32 mount60 = 0, uint32 mount100 = 0, uint32 mount150 = 0, uint32 mount280 = 0, uint32 mount310 = 0) : SpellScriptLoader(name), - _mount0(mount0), _mount60(mount60), _mount100(mount100), _mount150(mount150), _mount280(mount280), _mount310(mount310) { } - - class spell_gen_mount_SpellScript : public SpellScript - { - PrepareSpellScript(spell_gen_mount_SpellScript); - - public: - spell_gen_mount_SpellScript(uint32 mount0, uint32 mount60, uint32 mount100, uint32 mount150, uint32 mount280, uint32 mount310) : SpellScript(), - _mount0(mount0), _mount60(mount60), _mount100(mount100), _mount150(mount150), _mount280(mount280), _mount310(mount310) { } - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - if (_mount0 && !sSpellMgr->GetSpellInfo(_mount0)) - return false; - if (_mount60 && !sSpellMgr->GetSpellInfo(_mount60)) - return false; - if (_mount100 && !sSpellMgr->GetSpellInfo(_mount100)) - return false; - if (_mount150 && !sSpellMgr->GetSpellInfo(_mount150)) - return false; - if (_mount280 && !sSpellMgr->GetSpellInfo(_mount280)) - return false; - if (_mount310 && !sSpellMgr->GetSpellInfo(_mount310)) - return false; - return true; - } - - void HandleMount(SpellEffIndex effIndex) - { - PreventHitDefaultEffect(effIndex); - - if (Player* target = GetHitPlayer()) - { - // Prevent stacking of mounts and client crashes upon dismounting - target->RemoveAurasByType(SPELL_AURA_MOUNTED, 0, GetHitAura()); - - // Triggered spell id dependent on riding skill and zone - bool canFly = false; - uint32 map = GetVirtualMapForMapAndZone(target->GetMapId(), target->GetZoneId()); - if (map == 530 || (map == 571 && target->HasSpell(SPELL_COLD_WEATHER_FLYING))) - canFly = true; - - float x, y, z; - target->GetPosition(x, y, z); - uint32 areaFlag = target->GetBaseMap()->GetAreaFlag(x, y, z); - AreaTableEntry const* area = sAreaStore.LookupEntry(areaFlag); - if (!area || (canFly && (area->flags & AREA_FLAG_NO_FLY_ZONE))) - canFly = false; - - uint32 mount = 0; - switch (target->GetBaseSkillValue(SKILL_RIDING)) - { - case 0: - mount = _mount0; - break; - case 75: - mount = _mount60; - break; - case 150: - mount = _mount100; - break; - case 225: - if (canFly) - mount = _mount150; - else - mount = _mount100; - break; - case 300: - if (canFly) - { - if (_mount310 && target->Has310Flyer(false)) - mount = _mount310; - else - mount = _mount280; - } - else - mount = _mount100; - break; - default: - break; - } - - if (mount) - { - PreventHitAura(); - target->CastSpell(target, mount, true); - } - } - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_gen_mount_SpellScript::HandleMount, EFFECT_2, SPELL_EFFECT_SCRIPT_EFFECT); - } - - private: - uint32 _mount0; - uint32 _mount60; - uint32 _mount100; - uint32 _mount150; - uint32 _mount280; - uint32 _mount310; - }; - - SpellScript* GetSpellScript() const override - { - return new spell_gen_mount_SpellScript(_mount0, _mount60, _mount100, _mount150, _mount280, _mount310); - } - - private: - uint32 _mount0; - uint32 _mount60; - uint32 _mount100; - uint32 _mount150; - uint32 _mount280; - uint32 _mount310; -}; - /* DOCUMENTATION: Charge spells Charge spells can be classified in four groups: @@ -2800,7 +2633,7 @@ class spell_gen_parachute_ic : public SpellScriptLoader void HandleTriggerSpell(AuraEffect const* /*aurEff*/) { if (Player* target = GetTarget()->ToPlayer()) - if (target->m_movementInfo.fallTime > 2000) + if (target->m_movementInfo.jump.fallTime > 2000) target->CastSpell(target, SPELL_PARACHUTE_IC, true); } @@ -3058,6 +2891,160 @@ class spell_gen_replenishment : public SpellScriptLoader } }; + +enum RunningWildMountIds +{ + RUNNING_WILD_MODEL_MALE = 29422, + RUNNING_WILD_MODEL_FEMALE = 29423, + SPELL_ALTERED_FORM = 97709 +}; + +class spell_gen_running_wild : public SpellScriptLoader +{ + public: + spell_gen_running_wild() : SpellScriptLoader("spell_gen_running_wild") { } + + class spell_gen_running_wild_AuraScript : public AuraScript + { + PrepareAuraScript(spell_gen_running_wild_AuraScript); + + bool Validate(SpellInfo const* /*spell*/) override + { + if (!sCreatureDisplayInfoStore.LookupEntry(RUNNING_WILD_MODEL_MALE)) + return false; + if (!sCreatureDisplayInfoStore.LookupEntry(RUNNING_WILD_MODEL_FEMALE)) + return false; + return true; + } + + void HandleMount(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + PreventDefaultAction(); + + target->Mount(target->getGender() == GENDER_FEMALE ? RUNNING_WILD_MODEL_FEMALE : RUNNING_WILD_MODEL_MALE, 0, 0); + + // cast speed aura + if (MountCapabilityEntry const* mountCapability = sMountCapabilityStore.LookupEntry(aurEff->GetAmount())) + target->CastSpell(target, mountCapability->SpeedModSpell, TRIGGERED_FULL_MASK); + } + + void Register() override + { + OnEffectApply += AuraEffectApplyFn(spell_gen_running_wild_AuraScript::HandleMount, EFFECT_1, SPELL_AURA_MOUNTED, AURA_EFFECT_HANDLE_REAL); + } + }; + + class spell_gen_running_wild_SpellScript : public SpellScript + { + PrepareSpellScript(spell_gen_running_wild_SpellScript); + + bool Validate(SpellInfo const* /*spell*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_ALTERED_FORM)) + return false; + return true; + } + + bool Load() override + { + // Definitely not a good thing, but currently the only way to do something at cast start + // Should be replaced as soon as possible with a new hook: BeforeCastStart + GetCaster()->CastSpell(GetCaster(), SPELL_ALTERED_FORM, TRIGGERED_FULL_MASK); + return false; + } + + void Register() override + { + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_gen_running_wild_AuraScript(); + } + + SpellScript* GetSpellScript() const override + { + return new spell_gen_running_wild_SpellScript(); + } +}; + +class spell_gen_two_forms : public SpellScriptLoader +{ + public: + spell_gen_two_forms() : SpellScriptLoader("spell_gen_two_forms") { } + + class spell_gen_two_forms_SpellScript : public SpellScript + { + PrepareSpellScript(spell_gen_two_forms_SpellScript); + + SpellCastResult CheckCast() + { + if (GetCaster()->IsInCombat()) + { + SetCustomCastResultMessage(SPELL_CUSTOM_ERROR_CANT_TRANSFORM); + return SPELL_FAILED_CUSTOM_ERROR; + } + + // Player cannot transform to human form if he is forced to be worgen for some reason (Darkflight) + if (GetCaster()->GetAuraEffectsByType(SPELL_AURA_WORGEN_ALTERED_FORM).size() > 1) + { + SetCustomCastResultMessage(SPELL_CUSTOM_ERROR_CANT_TRANSFORM); + return SPELL_FAILED_CUSTOM_ERROR; + } + + return SPELL_CAST_OK; + } + + void HandleTransform(SpellEffIndex effIndex) + { + Unit* target = GetHitUnit(); + PreventHitDefaultEffect(effIndex); + if (target->HasAuraType(SPELL_AURA_WORGEN_ALTERED_FORM)) + target->RemoveAurasByType(SPELL_AURA_WORGEN_ALTERED_FORM); + else // Basepoints 1 for this aura control whether to trigger transform transition animation or not. + target->CastCustomSpell(SPELL_ALTERED_FORM, SPELLVALUE_BASE_POINT0, 1, target, TRIGGERED_FULL_MASK); + } + + void Register() override + { + OnCheckCast += SpellCheckCastFn(spell_gen_two_forms_SpellScript::CheckCast); + OnEffectHitTarget += SpellEffectFn(spell_gen_two_forms_SpellScript::HandleTransform, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_gen_two_forms_SpellScript(); + } +}; + +class spell_gen_darkflight : public SpellScriptLoader +{ + public: + spell_gen_darkflight() : SpellScriptLoader("spell_gen_darkflight") { } + + class spell_gen_darkflight_SpellScript : public SpellScript + { + PrepareSpellScript(spell_gen_darkflight_SpellScript); + + void TriggerTransform() + { + GetCaster()->CastSpell(GetCaster(), SPELL_ALTERED_FORM, TRIGGERED_FULL_MASK); + } + + void Register() override + { + AfterCast += SpellCastFn(spell_gen_darkflight_SpellScript::TriggerTransform); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_gen_darkflight_SpellScript(); + } +}; enum SeaforiumSpells { SPELL_PLANT_CHARGES_CREDIT_ACHIEVEMENT = 60937 @@ -3734,6 +3721,7 @@ void AddSC_generic_spell_scripts() { new spell_gen_absorb0_hitlimit1(); new spell_gen_adaptive_warding(); + new spell_gen_alchemist_stone(); new spell_gen_allow_cast_from_item_only(); new spell_gen_animal_blood(); new spell_gen_aura_of_anger(); @@ -3755,7 +3743,6 @@ void AddSC_generic_spell_scripts() new 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(); @@ -3767,25 +3754,22 @@ void AddSC_generic_spell_scripts() new spell_gen_gift_of_naaru(); new spell_gen_gnomish_transporter(); new spell_gen_gunship_portal(); + new spell_gen_increase_stats_buff("spell_pal_blessing_of_kings"); + new spell_gen_increase_stats_buff("spell_pal_blessing_of_might"); + new spell_gen_increase_stats_buff("spell_dru_mark_of_the_wild"); + new spell_gen_increase_stats_buff("spell_pri_power_word_fortitude"); + new spell_gen_increase_stats_buff("spell_pri_shadow_protection"); + new spell_gen_increase_stats_buff("spell_mage_arcane_brilliance"); + new spell_gen_increase_stats_buff("spell_mage_dalaran_brilliance"); + new spell_gen_interrupt(); new spell_gen_launch(); - new 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(); - 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); - new spell_gen_mount("spell_big_love_rocket", SPELL_BIG_LOVE_ROCKET_0, SPELL_BIG_LOVE_ROCKET_60, SPELL_BIG_LOVE_ROCKET_100, SPELL_BIG_LOVE_ROCKET_150, SPELL_BIG_LOVE_ROCKET_310); - new spell_gen_mount("spell_invincible", 0, SPELL_INVINCIBLE_60, SPELL_INVINCIBLE_100, SPELL_INVINCIBLE_150, SPELL_INVINCIBLE_310); - 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_netherbloom(); - new spell_gen_nightmare_vine(); new spell_gen_obsidian_armor(); new spell_gen_on_tournament_mount(); new spell_gen_oracle_wolvar_reputation(); @@ -3796,6 +3780,11 @@ void AddSC_generic_spell_scripts() new spell_gen_profession_research(); new spell_gen_remove_flight_auras(); new spell_gen_replenishment(); + // Running Wild + new spell_gen_running_wild(); + new spell_gen_two_forms(); + new spell_gen_darkflight(); + /* */ new spell_gen_seaforium_blast(); new spell_gen_spectator_cheer_trigger(); new spell_gen_spirit_healer_res(); diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp index 725312eafce..eb03b47e6fe 100644 --- a/src/server/scripts/Spells/spell_hunter.cpp +++ b/src/server/scripts/Spells/spell_hunter.cpp @@ -32,16 +32,14 @@ enum HunterSpells { - SPELL_HUNTER_ASPECT_OF_THE_BEAST_PET = 61669, - SPELL_HUNTER_ASPECT_OF_THE_VIPER = 34074, - SPELL_HUNTER_ASPECT_OF_THE_VIPER_ENERGIZE = 34075, SPELL_HUNTER_BESTIAL_WRATH = 19574, - SPELL_HUNTER_CHIMERA_SHOT_SERPENT = 53353, - SPELL_HUNTER_CHIMERA_SHOT_VIPER = 53358, - SPELL_HUNTER_CHIMERA_SHOT_SCORPID = 53359, - SPELL_HUNTER_GLYPH_OF_ASPECT_OF_THE_VIPER = 56851, + SPELL_HUNTER_CHIMERA_SHOT_HEAL = 53353, + SPELL_HUNTER_FIRE = 82926, + SPELL_HUNTER_GENERIC_ENERGIZE_FOCUS = 91954, SPELL_HUNTER_IMPROVED_MEND_PET = 24406, + SPELL_HUNTER_INSANITY = 95809, SPELL_HUNTER_INVIGORATION_TRIGGERED = 53398, + SPELL_HUNTER_LOCK_AND_LOAD = 56453, SPELL_HUNTER_MASTERS_CALL_TRIGGERED = 62305, SPELL_HUNTER_MISDIRECTION_PROC = 35079, SPELL_HUNTER_PET_LAST_STAND_TRIGGERED = 53479, @@ -49,214 +47,156 @@ enum HunterSpells SPELL_HUNTER_PET_HEART_OF_THE_PHOENIX_TRIGGERED = 54114, SPELL_HUNTER_PET_HEART_OF_THE_PHOENIX_DEBUFF = 55711, SPELL_HUNTER_PET_CARRION_FEEDER_TRIGGERED = 54045, + SPELL_HUNTER_RAPID_RECUPERATION = 58883, SPELL_HUNTER_READINESS = 23989, + SPELL_HUNTER_SERPENT_STING = 1978, SPELL_HUNTER_SNIPER_TRAINING_R1 = 53302, SPELL_HUNTER_SNIPER_TRAINING_BUFF_R1 = 64418, - SPELL_HUNTER_VICIOUS_VIPER = 61609, - SPELL_HUNTER_VIPER_ATTACK_SPEED = 60144, - SPELL_DRAENEI_GIFT_OF_THE_NAARU = 59543 + SPELL_HUNTER_STEADY_SHOT_FOCUS = 77443, + SPELL_HUNTER_THRILL_OF_THE_HUNT = 34720 }; -// 13161 - Aspect of the Beast -class spell_hun_aspect_of_the_beast : public SpellScriptLoader +enum MiscSpells +{ + SPELL_DRAENEI_GIFT_OF_THE_NAARU = 59543, + SPELL_MAGE_TEMPORAL_DISPLACEMENT = 80354, + SPELL_SHAMAN_EXHAUSTION = 57723, + SPELL_SHAMAN_SATED = 57724 +}; + +// 90355 - Ancient Hysteria +class spell_hun_ancient_hysteria : public SpellScriptLoader { public: - spell_hun_aspect_of_the_beast() : SpellScriptLoader("spell_hun_aspect_of_the_beast") { } + spell_hun_ancient_hysteria() : SpellScriptLoader("spell_hun_ancient_hysteria") { } - class spell_hun_aspect_of_the_beast_AuraScript : public AuraScript + class spell_hun_ancient_hysteria_SpellScript : public SpellScript { - PrepareAuraScript(spell_hun_aspect_of_the_beast_AuraScript); - - bool Load() override - { - return GetCaster()->GetTypeId() == TYPEID_PLAYER; - } + PrepareSpellScript(spell_hun_ancient_hysteria_SpellScript); bool Validate(SpellInfo const* /*spellInfo*/) override { - if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_ASPECT_OF_THE_BEAST_PET)) + if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_INSANITY) + || !sSpellMgr->GetSpellInfo(SPELL_MAGE_TEMPORAL_DISPLACEMENT) + || !sSpellMgr->GetSpellInfo(SPELL_SHAMAN_EXHAUSTION) + || !sSpellMgr->GetSpellInfo(SPELL_SHAMAN_SATED)) return false; return true; } - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + void RemoveInvalidTargets(std::list<WorldObject*>& targets) { - if (Player* caster = GetCaster()->ToPlayer()) - if (Pet* pet = caster->GetPet()) - pet->RemoveAurasDueToSpell(SPELL_HUNTER_ASPECT_OF_THE_BEAST_PET); + targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_HUNTER_INSANITY)); + targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_MAGE_TEMPORAL_DISPLACEMENT)); + targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_SHAMAN_EXHAUSTION)); + targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_SHAMAN_SATED)); } - void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + void ApplyDebuff() { - if (Player* caster = GetCaster()->ToPlayer()) - if (caster->GetPet()) - caster->CastSpell(caster, SPELL_HUNTER_ASPECT_OF_THE_BEAST_PET, true); + if (Unit* target = GetHitUnit()) + target->CastSpell(target, SPELL_HUNTER_INSANITY, true); } void Register() override { - AfterEffectApply += AuraEffectApplyFn(spell_hun_aspect_of_the_beast_AuraScript::OnApply, EFFECT_0, SPELL_AURA_UNTRACKABLE, AURA_EFFECT_HANDLE_REAL); - AfterEffectRemove += AuraEffectRemoveFn(spell_hun_aspect_of_the_beast_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_UNTRACKABLE, AURA_EFFECT_HANDLE_REAL); + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_hun_ancient_hysteria_SpellScript::RemoveInvalidTargets, EFFECT_ALL, TARGET_UNIT_CASTER_AREA_RAID); + AfterHit += SpellHitFn(spell_hun_ancient_hysteria_SpellScript::ApplyDebuff); } }; - AuraScript* GetAuraScript() const override + SpellScript* GetSpellScript() const override { - return new spell_hun_aspect_of_the_beast_AuraScript(); + return new spell_hun_ancient_hysteria_SpellScript(); } }; -// 34074 - Aspect of the Viper -class spell_hun_ascpect_of_the_viper : public SpellScriptLoader +// 53209 - Chimera Shot +class spell_hun_chimera_shot : public SpellScriptLoader { public: - spell_hun_ascpect_of_the_viper() : SpellScriptLoader("spell_hun_ascpect_of_the_viper") { } + spell_hun_chimera_shot() : SpellScriptLoader("spell_hun_chimera_shot") { } - class spell_hun_ascpect_of_the_viper_AuraScript : public AuraScript + class spell_hun_chimera_shot_SpellScript : public SpellScript { - PrepareAuraScript(spell_hun_ascpect_of_the_viper_AuraScript); + PrepareSpellScript(spell_hun_chimera_shot_SpellScript); bool Validate(SpellInfo const* /*spellInfo*/) override { - if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_ASPECT_OF_THE_VIPER_ENERGIZE) || - !sSpellMgr->GetSpellInfo(SPELL_HUNTER_GLYPH_OF_ASPECT_OF_THE_VIPER) || - !sSpellMgr->GetSpellInfo(SPELL_HUNTER_VIPER_ATTACK_SPEED) || - !sSpellMgr->GetSpellInfo(SPELL_HUNTER_VICIOUS_VIPER)) + if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_CHIMERA_SHOT_HEAL) || + !sSpellMgr->GetSpellInfo(SPELL_HUNTER_SERPENT_STING)) return false; return true; } - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + bool Load() override { - PreventDefaultAction(); - - uint32 maxMana = GetTarget()->GetMaxPower(POWER_MANA); - int32 mana = CalculatePct(maxMana, GetTarget()->GetAttackTime(RANGED_ATTACK) / 1000.0f); - - if (AuraEffect const* glyph = GetTarget()->GetAuraEffect(SPELL_HUNTER_GLYPH_OF_ASPECT_OF_THE_VIPER, EFFECT_0)) - AddPct(mana, glyph->GetAmount()); - - GetTarget()->CastCustomSpell(SPELL_HUNTER_ASPECT_OF_THE_VIPER_ENERGIZE, SPELLVALUE_BASE_POINT0, mana, GetTarget(), true, NULL, aurEff); + return GetCaster()->GetTypeId() == TYPEID_PLAYER; } - void OnApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) + void HandleScriptEffect(SpellEffIndex /*effIndex*/) { - // Hunter T7 4P Bonus - if (GetTarget()->HasAura(SPELL_HUNTER_VIPER_ATTACK_SPEED)) - GetTarget()->CastSpell(GetTarget(), SPELL_HUNTER_VICIOUS_VIPER, true, NULL, aurEff); - } + GetCaster()->CastSpell(GetCaster(), SPELL_HUNTER_CHIMERA_SHOT_HEAL, true); - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - // Hunter T7 4P Bonus - if (GetTarget()->HasAura(SPELL_HUNTER_VIPER_ATTACK_SPEED)) - GetTarget()->RemoveAurasDueToSpell(SPELL_HUNTER_VICIOUS_VIPER); + if (Aura* aur = GetHitUnit()->GetAura(SPELL_HUNTER_SERPENT_STING, GetCaster()->GetGUID())) + aur->SetDuration(aur->GetSpellInfo()->GetMaxDuration(), true); } void Register() override { - OnEffectProc += AuraEffectProcFn(spell_hun_ascpect_of_the_viper_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_OBS_MOD_POWER); - AfterEffectApply += AuraEffectApplyFn(spell_hun_ascpect_of_the_viper_AuraScript::OnApply, EFFECT_0, SPELL_AURA_OBS_MOD_POWER, AURA_EFFECT_HANDLE_REAL); - AfterEffectRemove += AuraEffectRemoveFn(spell_hun_ascpect_of_the_viper_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_OBS_MOD_POWER, AURA_EFFECT_HANDLE_REAL); + OnEffectHitTarget += SpellEffectFn(spell_hun_chimera_shot_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; - AuraScript* GetAuraScript() const override + SpellScript* GetSpellScript() const override { - return new spell_hun_ascpect_of_the_viper_AuraScript(); + return new spell_hun_chimera_shot_SpellScript(); } }; -// 53209 - Chimera Shot -class spell_hun_chimera_shot : public SpellScriptLoader +// 77767 - Cobra Shot +class spell_hun_cobra_shot : public SpellScriptLoader { public: - spell_hun_chimera_shot() : SpellScriptLoader("spell_hun_chimera_shot") { } + spell_hun_cobra_shot() : SpellScriptLoader("spell_hun_cobra_shot") { } - class spell_hun_chimera_shot_SpellScript : public SpellScript + class spell_hun_cobra_shot_SpellScript : public SpellScript { - PrepareSpellScript(spell_hun_chimera_shot_SpellScript); + PrepareSpellScript(spell_hun_cobra_shot_SpellScript); bool Validate(SpellInfo const* /*spellInfo*/) override { - if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_CHIMERA_SHOT_SERPENT) || !sSpellMgr->GetSpellInfo(SPELL_HUNTER_CHIMERA_SHOT_VIPER) || !sSpellMgr->GetSpellInfo(SPELL_HUNTER_CHIMERA_SHOT_SCORPID)) + if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_GENERIC_ENERGIZE_FOCUS) || + !sSpellMgr->GetSpellInfo(SPELL_HUNTER_SERPENT_STING)) return false; return true; } + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } + void HandleScriptEffect(SpellEffIndex /*effIndex*/) { - Unit* caster = GetCaster(); - if (Unit* unitTarget = GetHitUnit()) + GetCaster()->CastSpell(GetCaster(), SPELL_HUNTER_GENERIC_ENERGIZE_FOCUS, true); + + if (Aura* aur = GetHitUnit()->GetAura(SPELL_HUNTER_SERPENT_STING, GetCaster()->GetGUID())) { - uint32 spellId = 0; - int32 basePoint = 0; - Unit::AuraApplicationMap& Auras = unitTarget->GetAppliedAuras(); - for (Unit::AuraApplicationMap::iterator i = Auras.begin(); i != Auras.end(); ++i) - { - Aura* aura = i->second->GetBase(); - if (aura->GetCasterGUID() != caster->GetGUID()) - continue; - - // Search only Serpent Sting, Viper Sting, Scorpid Sting auras - flag96 familyFlag = aura->GetSpellInfo()->SpellFamilyFlags; - if (!(familyFlag[1] & 0x00000080 || familyFlag[0] & 0x0000C000)) - continue; - if (AuraEffect const* aurEff = aura->GetEffect(0)) - { - // Serpent Sting - Instantly deals 40% of the damage done by your Serpent Sting. - if (familyFlag[0] & 0x4000) - { - int32 TickCount = aurEff->GetTotalTicks(); - spellId = SPELL_HUNTER_CHIMERA_SHOT_SERPENT; - basePoint = caster->SpellDamageBonusDone(unitTarget, aura->GetSpellInfo(), aurEff->GetAmount(), DOT, aura->GetStackAmount()); - ApplyPct(basePoint, TickCount * 40); - basePoint = unitTarget->SpellDamageBonusTaken(caster, aura->GetSpellInfo(), basePoint, DOT, aura->GetStackAmount()); - } - // Viper Sting - Instantly restores mana to you equal to 60% of the total amount drained by your Viper Sting. - else if (familyFlag[1] & 0x00000080) - { - int32 TickCount = aura->GetEffect(0)->GetTotalTicks(); - spellId = SPELL_HUNTER_CHIMERA_SHOT_VIPER; - - // Amount of one aura tick - basePoint = int32(CalculatePct(unitTarget->GetMaxPower(POWER_MANA), aurEff->GetAmount())); - int32 casterBasePoint = aurEff->GetAmount() * unitTarget->GetMaxPower(POWER_MANA) / 50; /// @todo WTF? caster uses unitTarget? - if (basePoint > casterBasePoint) - basePoint = casterBasePoint; - ApplyPct(basePoint, TickCount * 60); - } - // Scorpid Sting - Attempts to Disarm the target for 10 sec. This effect cannot occur more than once per 1 minute. - else if (familyFlag[0] & 0x00008000) - spellId = SPELL_HUNTER_CHIMERA_SHOT_SCORPID; - // ?? nothing say in spell desc (possibly need addition check) - //if (familyFlag & 0x0000010000000000LL || // dot - // familyFlag & 0x0000100000000000LL) // stun - //{ - // spellId = 53366; // 53366 Chimera Shot - Wyvern - //} - - // Refresh aura duration - aura->RefreshDuration(); - } - break; - } - if (spellId) - caster->CastCustomSpell(unitTarget, spellId, &basePoint, 0, 0, true); - if (spellId == SPELL_HUNTER_CHIMERA_SHOT_SCORPID && caster->ToPlayer()) // Scorpid Sting - Add 1 minute cooldown - caster->ToPlayer()->AddSpellCooldown(spellId, 0, uint32(time(NULL) + 60)); + int32 newDuration = aur->GetDuration() + GetEffectValue() * IN_MILLISECONDS; + aur->SetDuration(std::min(newDuration, aur->GetMaxDuration()), true); } } void Register() override { - OnEffectHitTarget += SpellEffectFn(spell_hun_chimera_shot_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_hun_cobra_shot_SpellScript::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); } }; SpellScript* GetSpellScript() const override { - return new spell_hun_chimera_shot_SpellScript(); + return new spell_hun_cobra_shot_SpellScript(); } }; @@ -291,6 +231,42 @@ class spell_hun_disengage : public SpellScriptLoader } }; +// 82926 - Fire! +class spell_hun_fire : public SpellScriptLoader +{ + public: + spell_hun_fire() : SpellScriptLoader("spell_hun_fire") { } + + class spell_hun_fire_AuraScript : public AuraScript + { + PrepareAuraScript(spell_hun_fire_AuraScript); + + void HandleEffectCalcSpellMod(AuraEffect const* aurEff, SpellModifier*& spellMod) + { + if (!spellMod) + { + spellMod = new SpellModifier(GetAura()); + spellMod->op = SPELLMOD_CASTING_TIME; + spellMod->type = SPELLMOD_PCT; + spellMod->spellId = GetId(); + spellMod->mask = GetSpellInfo()->Effects[aurEff->GetEffIndex()].SpellClassMask; + } + + spellMod->value = -aurEff->GetAmount(); + } + + void Register() override + { + DoEffectCalcSpellMod += AuraEffectCalcSpellModFn(spell_hun_fire_AuraScript::HandleEffectCalcSpellMod, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_hun_fire_AuraScript(); + } +}; + // -19572 - Improved Mend Pet class spell_hun_improved_mend_pet : public SpellScriptLoader { @@ -331,6 +307,43 @@ class spell_hun_improved_mend_pet : public SpellScriptLoader return new spell_hun_improved_mend_pet_AuraScript(); } }; + +// -19464 Improved Serpent Sting +class spell_hun_improved_serpent_sting : public SpellScriptLoader +{ + public: + spell_hun_improved_serpent_sting() : SpellScriptLoader("spell_hun_improved_serpent_sting") { } + + class spell_hun_improved_serpent_sting_AuraScript : public AuraScript + { + PrepareAuraScript(spell_hun_improved_serpent_sting_AuraScript); + + void HandleEffectCalcSpellMod(AuraEffect const* aurEff, SpellModifier*& spellMod) + { + if (!spellMod) + { + spellMod = new SpellModifier(GetAura()); + spellMod->op = SpellModOp(aurEff->GetMiscValue()); + spellMod->type = SPELLMOD_PCT; + spellMod->spellId = GetId(); + spellMod->mask = GetSpellInfo()->Effects[aurEff->GetEffIndex()].SpellClassMask; + } + + spellMod->value = aurEff->GetAmount(); + } + + void Register() override + { + DoEffectCalcSpellMod += AuraEffectCalcSpellModFn(spell_hun_improved_serpent_sting_AuraScript::HandleEffectCalcSpellMod, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_hun_improved_serpent_sting_AuraScript(); + } +}; + // 53412 - Invigoration class spell_hun_invigoration : public SpellScriptLoader { @@ -416,7 +429,8 @@ class spell_hun_masters_call : public SpellScriptLoader bool Validate(SpellInfo const* spellInfo) override { - if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_MASTERS_CALL_TRIGGERED) || !sSpellMgr->GetSpellInfo(spellInfo->Effects[EFFECT_0].CalcValue()) || !sSpellMgr->GetSpellInfo(spellInfo->Effects[EFFECT_1].CalcValue())) + if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_MASTERS_CALL_TRIGGERED) || + !sSpellMgr->GetSpellInfo(spellInfo->Effects[EFFECT_0].CalcValue())) return false; return true; } @@ -429,7 +443,6 @@ class spell_hun_masters_call : public SpellScriptLoader { TriggerCastFlags castMask = TriggerCastFlags(TRIGGERED_FULL_MASK & ~TRIGGERED_IGNORE_CASTER_AURASTATE); target->CastSpell(ally, GetEffectValue(), castMask); - target->CastSpell(ally, GetSpellInfo()->Effects[EFFECT_0].CalcValue(), castMask); } } @@ -635,6 +648,54 @@ class spell_hun_pet_heart_of_the_phoenix : public SpellScriptLoader } }; +// -53228 - Rapid Recuperation +class spell_hun_rapid_recuperation : public SpellScriptLoader +{ + public: + spell_hun_rapid_recuperation() : SpellScriptLoader("spell_hun_rapid_recuperation") { } + + class spell_hun_rapid_recuperation_AuraScript : public AuraScript + { + PrepareAuraScript(spell_hun_rapid_recuperation_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_RAPID_RECUPERATION)) + return false; + return true; + } + + void HandleAbilityCast(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) + { + // This effect only from Rapid Fire (ability cast) + if (!(eventInfo.GetDamageInfo()->GetSpellInfo()->SpellFamilyFlags[0] & 0x20)) + PreventDefaultAction(); + } + + void HandleFocusRegen(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + // This effect only from Rapid Killing (focus regen) + if (!(eventInfo.GetDamageInfo()->GetSpellInfo()->SpellFamilyFlags[1] & 0x01000000)) + return; + + int32 focus = aurEff->GetAmount(); + GetTarget()->CastCustomSpell(SPELL_HUNTER_RAPID_RECUPERATION, SPELLVALUE_BASE_POINT0, focus, GetTarget(), true, NULL, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_hun_rapid_recuperation_AuraScript::HandleAbilityCast, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + OnEffectProc += AuraEffectProcFn(spell_hun_rapid_recuperation_AuraScript::HandleFocusRegen, EFFECT_1, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_hun_rapid_recuperation_AuraScript(); + } +}; + // 23989 - Readiness class spell_hun_readiness : public SpellScriptLoader { @@ -684,6 +745,44 @@ class spell_hun_readiness : public SpellScriptLoader } }; +// 82925 - Ready, Set, Aim... +class spell_hun_ready_set_aim : public SpellScriptLoader +{ + public: + spell_hun_ready_set_aim() : SpellScriptLoader("spell_hun_ready_set_aim") { } + + class spell_hun_ready_set_aim_AuraScript : public AuraScript + { + PrepareAuraScript(spell_hun_ready_set_aim_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_FIRE)) + return false; + return true; + } + + void OnApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) + { + if (GetStackAmount() == 5) + { + GetTarget()->CastSpell(GetTarget(), SPELL_HUNTER_FIRE, true, NULL, aurEff); + GetTarget()->RemoveAura(GetId()); + } + } + + void Register() override + { + AfterEffectApply += AuraEffectApplyFn(spell_hun_ready_set_aim_AuraScript::OnApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_hun_ready_set_aim_AuraScript(); + } +}; + // 37506 - Scatter Shot class spell_hun_scatter_shot : public SpellScriptLoader { @@ -732,7 +831,8 @@ class spell_hun_sniper_training : public SpellScriptLoader bool Validate(SpellInfo const* /*spellInfo*/) override { - if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_SNIPER_TRAINING_R1) || !sSpellMgr->GetSpellInfo(SPELL_HUNTER_SNIPER_TRAINING_BUFF_R1)) + if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_SNIPER_TRAINING_R1) || + !sSpellMgr->GetSpellInfo(SPELL_HUNTER_SNIPER_TRAINING_BUFF_R1)) return false; return true; } @@ -744,6 +844,7 @@ class spell_hun_sniper_training : public SpellScriptLoader { Unit* target = GetTarget(); uint32 spellId = SPELL_HUNTER_SNIPER_TRAINING_BUFF_R1 + GetId() - SPELL_HUNTER_SNIPER_TRAINING_R1; + target->CastSpell(target, spellId, true, 0, aurEff); if (Player* playerTarget = GetUnitOwner()->ToPlayer()) { @@ -779,6 +880,45 @@ class spell_hun_sniper_training : public SpellScriptLoader } }; +// 56641 - Steady Shot +class spell_hun_steady_shot : public SpellScriptLoader +{ + public: + spell_hun_steady_shot() : SpellScriptLoader("spell_hun_steady_shot") { } + + class spell_hun_steady_shot_SpellScript : public SpellScript + { + PrepareSpellScript(spell_hun_steady_shot_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_STEADY_SHOT_FOCUS)) + return false; + return true; + } + + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } + + void HandleOnHit() + { + GetCaster()->CastSpell(GetCaster(), SPELL_HUNTER_STEADY_SHOT_FOCUS, true); + } + + void Register() override + { + OnHit += SpellHitFn(spell_hun_steady_shot_SpellScript::HandleOnHit); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_hun_steady_shot_SpellScript(); + } +}; + // 1515 - Tame Beast class spell_hun_tame_beast : public SpellScriptLoader { @@ -831,7 +971,6 @@ class spell_hun_tame_beast : public SpellScriptLoader } }; -// -24604 - Furious Howl // 53434 - Call of the Wild class spell_hun_target_only_pet_and_owner : public SpellScriptLoader { @@ -863,56 +1002,94 @@ class spell_hun_target_only_pet_and_owner : public SpellScriptLoader } }; -// 60144 - Viper Attack Speed -class spell_hun_viper_attack_speed : public SpellScriptLoader +// 34497 - Thrill of the Hunt +class spell_hun_thrill_of_the_hunt : public SpellScriptLoader { public: - spell_hun_viper_attack_speed() : SpellScriptLoader("spell_hun_viper_attack_speed") { } + spell_hun_thrill_of_the_hunt() : SpellScriptLoader("spell_hun_thrill_of_the_hunt") { } - class spell_hun_viper_attack_speed_AuraScript : public AuraScript + class spell_hun_thrill_of_the_hunt_AuraScript : public AuraScript { - PrepareAuraScript(spell_hun_viper_attack_speed_AuraScript); + PrepareAuraScript(spell_hun_thrill_of_the_hunt_AuraScript); bool Validate(SpellInfo const* /*spellInfo*/) override { - if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_ASPECT_OF_THE_VIPER) || - !sSpellMgr->GetSpellInfo(SPELL_HUNTER_VICIOUS_VIPER)) + if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_THRILL_OF_THE_HUNT)) return false; return true; } - void OnApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) + void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) { - if (GetTarget()->HasAura(SPELL_HUNTER_ASPECT_OF_THE_VIPER)) - GetTarget()->CastSpell(GetTarget(), SPELL_HUNTER_VICIOUS_VIPER, true, NULL, aurEff); + PreventDefaultAction(); + int32 focus = eventInfo.GetDamageInfo()->GetSpellInfo()->CalcPowerCost(GetTarget(), SpellSchoolMask(eventInfo.GetDamageInfo()->GetSchoolMask())); + focus = CalculatePct(focus, aurEff->GetAmount()); + + GetTarget()->CastCustomSpell(GetTarget(), SPELL_HUNTER_THRILL_OF_THE_HUNT, &focus, NULL, NULL, true, NULL, aurEff); } - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + void Register() override { - // possible exploit - GetTarget()->RemoveAurasDueToSpell(SPELL_HUNTER_VICIOUS_VIPER); + OnEffectProc += AuraEffectProcFn(spell_hun_thrill_of_the_hunt_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_hun_thrill_of_the_hunt_AuraScript(); + } +}; + +// -56333 - T.N.T. +class spell_hun_tnt : public SpellScriptLoader +{ + public: + spell_hun_tnt() : SpellScriptLoader("spell_hun_tnt") { } + + class spell_hun_tnt_AuraScript : public AuraScript + { + PrepareAuraScript(spell_hun_tnt_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_LOCK_AND_LOAD)) + return false; + return true; + } + + bool CheckProc(ProcEventInfo& /*eventInfo*/) + { + return roll_chance_i(GetEffect(EFFECT_0)->GetAmount()); + } + + void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + GetTarget()->CastSpell(GetTarget(), SPELL_HUNTER_LOCK_AND_LOAD, true, NULL, aurEff); } void Register() override { - AfterEffectApply += AuraEffectApplyFn(spell_hun_viper_attack_speed_AuraScript::OnApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - AfterEffectRemove += AuraEffectRemoveFn(spell_hun_viper_attack_speed_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + DoCheckProc += AuraCheckProcFn(spell_hun_tnt_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_hun_tnt_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY); } }; AuraScript* GetAuraScript() const override { - return new spell_hun_viper_attack_speed_AuraScript(); + return new spell_hun_tnt_AuraScript(); } }; void AddSC_hunter_spell_scripts() { - new spell_hun_aspect_of_the_beast(); - new spell_hun_ascpect_of_the_viper(); + new spell_hun_ancient_hysteria(); new spell_hun_chimera_shot(); + new spell_hun_cobra_shot(); new spell_hun_disengage(); + new spell_hun_fire(); new spell_hun_improved_mend_pet(); + new spell_hun_improved_serpent_sting(); new spell_hun_invigoration(); new spell_hun_last_stand_pet(); new spell_hun_masters_call(); @@ -920,10 +1097,14 @@ void AddSC_hunter_spell_scripts() new spell_hun_misdirection_proc(); new spell_hun_pet_carrion_feeder(); new spell_hun_pet_heart_of_the_phoenix(); + new spell_hun_rapid_recuperation(); new spell_hun_readiness(); + new spell_hun_ready_set_aim(); new spell_hun_scatter_shot(); new spell_hun_sniper_training(); + new spell_hun_steady_shot(); new spell_hun_tame_beast(); new spell_hun_target_only_pet_and_owner(); - new spell_hun_viper_attack_speed(); + new spell_hun_thrill_of_the_hunt(); + new spell_hun_tnt(); } diff --git a/src/server/scripts/Spells/spell_item.cpp b/src/server/scripts/Spells/spell_item.cpp index a17d7dce2ea..c4a521ea41d 100644 --- a/src/server/scripts/Spells/spell_item.cpp +++ b/src/server/scripts/Spells/spell_item.cpp @@ -2483,51 +2483,6 @@ class spell_item_chicken_cover : public SpellScriptLoader } }; -enum Refocus -{ - SPELL_AIMED_SHOT = 19434, - SPELL_MULTISHOT = 2643, - SPELL_VOLLEY = 42243, -}; - -class spell_item_refocus : public SpellScriptLoader -{ - 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(); - - if (!caster || caster->getClass() != CLASS_HUNTER) - return; - - if (caster->HasSpellCooldown(SPELL_AIMED_SHOT)) - caster->RemoveSpellCooldown(SPELL_AIMED_SHOT, true); - - if (caster->HasSpellCooldown(SPELL_MULTISHOT)) - caster->RemoveSpellCooldown(SPELL_MULTISHOT, true); - - if (caster->HasSpellCooldown(SPELL_VOLLEY)) - caster->RemoveSpellCooldown(SPELL_VOLLEY, true); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_item_refocus_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; - - SpellScript* GetSpellScript() const override - { - return new spell_item_refocus_SpellScript(); - } -}; - class spell_item_muisek_vessel : public SpellScriptLoader { public: @@ -2634,7 +2589,6 @@ void AddSC_item_spell_scripts() 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(); diff --git a/src/server/scripts/Spells/spell_mage.cpp b/src/server/scripts/Spells/spell_mage.cpp index edb9cd04b44..55c1edec480 100644 --- a/src/server/scripts/Spells/spell_mage.cpp +++ b/src/server/scripts/Spells/spell_mage.cpp @@ -25,18 +25,31 @@ #include "ScriptMgr.h" #include "SpellScript.h" #include "SpellAuraEffects.h" +#include "Pet.h" +#include "GridNotifiers.h" enum MageSpells { + SPELL_ARCANCE_POTENCY_RANK_1 = 31571, + SPELL_ARCANCE_POTENCY_RANK_2 = 31572, + SPELL_ARCANCE_POTENCY_TRIGGER_RANK_1 = 57529, + SPELL_ARCANCE_POTENCY_TRIGGER_RANK_2 = 57531, + SPELL_MAGE_BLAZING_SPEED = 31643, SPELL_MAGE_BURNOUT = 29077, SPELL_MAGE_COLD_SNAP = 11958, SPELL_MAGE_FOCUS_MAGIC_PROC = 54648, + SPELL_MAGE_FROST_NOVA = 122, SPELL_MAGE_FROST_WARDING_R1 = 11189, SPELL_MAGE_FROST_WARDING_TRIGGERED = 57776, + SPELL_MAGE_IMPROVED_POLYMORPH_RANK_1 = 11210, + SPELL_MAGE_IMPROVED_POLYMORPH_STUN_RANK_1 = 83046, + SPELL_MAGE_IMPROVED_POLYMORPH_MARKER = 87515, SPELL_MAGE_INCANTERS_ABSORBTION_R1 = 44394, SPELL_MAGE_INCANTERS_ABSORBTION_TRIGGERED = 44413, SPELL_MAGE_IGNITE = 12654, SPELL_MAGE_MASTER_OF_ELEMENTS_ENERGIZE = 29077, + SPELL_MAGE_PERMAFROST = 91394, + SPELL_MAGE_SLOW = 31589, SPELL_MAGE_SQUIRREL_FORM = 32813, SPELL_MAGE_GIRAFFE_FORM = 32816, SPELL_MAGE_SERPENT_FORM = 32817, @@ -47,6 +60,95 @@ enum MageSpells SPELL_MAGE_SUMMON_WATER_ELEMENTAL_PERMANENT = 70908, SPELL_MAGE_SUMMON_WATER_ELEMENTAL_TEMPORARY = 70907, SPELL_MAGE_GLYPH_OF_BLAST_WAVE = 62126, + + SPELL_MAGE_FLAMESTRIKE = 2120, + + SPELL_MAGE_CHILLED_R1 = 12484, + SPELL_MAGE_CHILLED_R2 = 12485, + + SPELL_MAGE_CONE_OF_COLD_AURA_R1 = 11190, + SPELL_MAGE_CONE_OF_COLD_AURA_R2 = 12489, + SPELL_MAGE_CONE_OF_COLD_TRIGGER_R1 = 83301, + SPELL_MAGE_CONE_OF_COLD_TRIGGER_R2 = 83302, + + SPELL_MAGE_SHATTERED_BARRIER_R1 = 44745, + SPELL_MAGE_SHATTERED_BARRIER_R2 = 54787, + SPELL_MAGE_SHATTERED_BARRIER_FREEZE_R1 = 55080, + SPELL_MAGE_SHATTERED_BARRIER_FREEZE_R2 = 83073, + + SPELL_MAGE_IMPROVED_MANA_GEM_TRIGGERED = 83098, + + SPELL_MAGE_RING_OF_FROST_SUMMON = 82676, + SPELL_MAGE_RING_OF_FROST_FREEZE = 82691, + SPELL_MAGE_RING_OF_FROST_DUMMY = 91264, + + SPELL_MAGE_FINGERS_OF_FROST = 44544, + SPELL_MAGE_TEMPORAL_DISPLACEMENT = 80354, +}; + +enum MageIcons +{ + ICON_MAGE_SHATTER = 976, + ICON_MAGE_IMPROVED_FLAMESTRIKE = 37, + ICON_MAGE_IMPROVED_FREEZE = 94, + ICON_MAGE_INCANTER_S_ABSORPTION = 2941, + ICON_MAGE_IMPROVED_MANA_GEM = 1036 +}; + +enum MiscSpells +{ + SPELL_HUNTER_INSANITY = 95809, + SPELL_PRIEST_SHADOW_WORD_DEATH = 32409, + SPELL_SHAMAN_EXHAUSTION = 57723, + SPELL_SHAMAN_SATED = 57724 +}; + +// -31571 - Arcane Potency +class spell_mage_arcane_potency : public SpellScriptLoader +{ + public: + spell_mage_arcane_potency () : SpellScriptLoader("spell_mage_arcane_potency") { } + + class spell_mage_arcane_potency_AuraScript : public AuraScript + { + PrepareAuraScript(spell_mage_arcane_potency_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_ARCANCE_POTENCY_RANK_1) || + !sSpellMgr->GetSpellInfo(SPELL_ARCANCE_POTENCY_RANK_2) || + !sSpellMgr->GetSpellInfo(SPELL_ARCANCE_POTENCY_TRIGGER_RANK_1) || + !sSpellMgr->GetSpellInfo(SPELL_ARCANCE_POTENCY_TRIGGER_RANK_2)) + return false; + return true; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + uint32 spellId = 0; + + if (GetSpellInfo()->Id == SPELL_ARCANCE_POTENCY_RANK_1) + spellId = SPELL_ARCANCE_POTENCY_TRIGGER_RANK_1; + else if (GetSpellInfo()->Id == SPELL_ARCANCE_POTENCY_RANK_2) + spellId = SPELL_ARCANCE_POTENCY_TRIGGER_RANK_2; + if (!spellId) + return; + + GetTarget()->CastSpell(GetTarget(), spellId, true, NULL, aurEff); + + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_mage_arcane_potency_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_mage_arcane_potency_AuraScript(); + } }; // Incanter's Absorbtion @@ -74,7 +176,7 @@ class spell_mage_incanters_absorbtion_base_AuraScript : public AuraScript } }; -// -11113 - Blast Wave +// 11113 - Blast Wave class spell_mage_blast_wave : public SpellScriptLoader { public: @@ -86,21 +188,40 @@ class spell_mage_blast_wave : public SpellScriptLoader bool Validate(SpellInfo const* /*spellInfo*/) override { - if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_GLYPH_OF_BLAST_WAVE)) + if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_FLAMESTRIKE)) return false; return true; } - void HandleKnockBack(SpellEffIndex effIndex) + void CountTargets(std::list<WorldObject*>& targetList) { - if (GetCaster()->HasAura(SPELL_MAGE_GLYPH_OF_BLAST_WAVE)) - PreventHitDefaultEffect(effIndex); + _targetCount = targetList.size(); + } + + void HandleImprovedFlamestrike() + { + if (_targetCount >= 2) + if (AuraEffect* aurEff = GetCaster()->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_MAGE, ICON_MAGE_IMPROVED_FLAMESTRIKE, EFFECT_0)) + if (roll_chance_i(aurEff->GetAmount())) + { + float x, y, z; + WorldLocation const* loc = GetExplTargetDest(); + if (!loc) + return; + + loc->GetPosition(x, y, z); + GetCaster()->CastSpell(x, y, z, SPELL_MAGE_FLAMESTRIKE, true); + } } void Register() override { - OnEffectHitTarget += SpellEffectFn(spell_mage_blast_wave_SpellScript::HandleKnockBack, EFFECT_2, SPELL_EFFECT_KNOCK_BACK); + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mage_blast_wave_SpellScript::CountTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY); + AfterCast += SpellCastFn(spell_mage_blast_wave_SpellScript::HandleImprovedFlamestrike); } + + private: + uint32 _targetCount; }; SpellScript* GetSpellScript() const override @@ -109,51 +230,85 @@ class spell_mage_blast_wave : public SpellScriptLoader } }; -// -44449 - Burnout -class spell_mage_burnout : public SpellScriptLoader +// -31641 - Blazing Speed +class spell_mage_blazing_speed : public SpellScriptLoader { public: - spell_mage_burnout() : SpellScriptLoader("spell_mage_burnout") { } + spell_mage_blazing_speed() : SpellScriptLoader("spell_mage_blazing_speed") { } - class spell_mage_burnout_AuraScript : public AuraScript + class spell_mage_blazing_speed_AuraScript : public AuraScript { - PrepareAuraScript(spell_mage_burnout_AuraScript); + PrepareAuraScript(spell_mage_blazing_speed_AuraScript); bool Validate(SpellInfo const* /*spellInfo*/) override { - if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_BURNOUT)) + if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_BLAZING_SPEED)) return false; return true; } - bool CheckProc(ProcEventInfo& eventInfo) - { - return eventInfo.GetDamageInfo()->GetSpellInfo(); // eventInfo.GetSpellInfo() - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + void OnProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) { PreventDefaultAction(); - - int32 mana = int32(eventInfo.GetDamageInfo()->GetSpellInfo()->CalcPowerCost(GetTarget(), eventInfo.GetDamageInfo()->GetSchoolMask())); - mana = CalculatePct(mana, aurEff->GetAmount()); - - GetTarget()->CastCustomSpell(SPELL_MAGE_BURNOUT, SPELLVALUE_BASE_POINT0, mana, GetTarget(), true, NULL, aurEff); + GetTarget()->CastSpell(GetTarget(), SPELL_MAGE_BLAZING_SPEED, true, NULL, aurEff); } void Register() override { - DoCheckProc += AuraCheckProcFn(spell_mage_burnout_AuraScript::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_mage_burnout_AuraScript::HandleProc, EFFECT_1, SPELL_AURA_DUMMY); + OnEffectProc += AuraEffectProcFn(spell_mage_blazing_speed_AuraScript::OnProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); } }; AuraScript* GetAuraScript() const override { - return new spell_mage_burnout_AuraScript(); + return new spell_mage_blazing_speed_AuraScript(); } }; +// 42208 - Blizzard +/// Updated 4.3.4 +class spell_mage_blizzard : public SpellScriptLoader +{ + public: + spell_mage_blizzard() : SpellScriptLoader("spell_mage_blizzard") { } + + class spell_mage_blizzard_SpellScript : public SpellScript + { + PrepareSpellScript(spell_mage_blizzard_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_CHILLED_R1)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_CHILLED_R2)) + return false; + return true; + } + + void AddChillEffect(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + if (Unit* unitTarget = GetHitUnit()) + { + if (caster->IsScriptOverriden(GetSpellInfo(), 836)) + caster->CastSpell(unitTarget, SPELL_MAGE_CHILLED_R1, true); + else if (caster->IsScriptOverriden(GetSpellInfo(), 988)) + caster->CastSpell(unitTarget, SPELL_MAGE_CHILLED_R2, true); + } + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_mage_blizzard_SpellScript::AddChillEffect, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_mage_blizzard_SpellScript(); + } +}; + // 11958 - Cold Snap class spell_mage_cold_snap : public SpellScriptLoader { @@ -201,8 +356,113 @@ class spell_mage_cold_snap : public SpellScriptLoader } }; -// -543 - Fire Ward -// -6143 - Frost Ward +// 120 - Cone of Cold +/// Updated 4.3.4 +class spell_mage_cone_of_cold : public SpellScriptLoader +{ + public: + spell_mage_cone_of_cold() : SpellScriptLoader("spell_mage_cone_of_cold") { } + + class spell_mage_cone_of_cold_SpellScript : public SpellScript + { + PrepareSpellScript(spell_mage_cone_of_cold_SpellScript); + + void HandleConeOfColdScript(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + if (Unit* unitTarget = GetHitUnit()) + { + if (caster->HasAura(SPELL_MAGE_CONE_OF_COLD_AURA_R1)) // Improved Cone of Cold Rank 1 + unitTarget->CastSpell(unitTarget, SPELL_MAGE_CONE_OF_COLD_TRIGGER_R1, true); + else if (caster->HasAura(SPELL_MAGE_CONE_OF_COLD_AURA_R2)) // Improved Cone of Cold Rank 2 + unitTarget->CastSpell(unitTarget, SPELL_MAGE_CONE_OF_COLD_TRIGGER_R2, true); + } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_mage_cone_of_cold_SpellScript::HandleConeOfColdScript, EFFECT_0, SPELL_EFFECT_APPLY_AURA); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_mage_cone_of_cold_SpellScript(); + } +}; + +// 42955 Conjure Refreshment +/// Updated 4.3.4 +struct ConjureRefreshmentData +{ + uint32 minLevel; + uint32 maxLevel; + uint32 spellId; +}; + +uint8 const MAX_CONJURE_REFRESHMENT_SPELLS = 7; +ConjureRefreshmentData const _conjureData[MAX_CONJURE_REFRESHMENT_SPELLS] = +{ + { 33, 43, 92739 }, + { 44, 53, 92799 }, + { 54, 63, 92802 }, + { 64, 73, 92805 }, + { 74, 79, 74625 }, + { 80, 84, 92822 }, + { 85, 85, 92727 } +}; + +// 42955 - Conjure Refreshment +class spell_mage_conjure_refreshment : public SpellScriptLoader +{ + public: + spell_mage_conjure_refreshment() : SpellScriptLoader("spell_mage_conjure_refreshment") { } + + class spell_mage_conjure_refreshment_SpellScript : public SpellScript + { + PrepareSpellScript(spell_mage_conjure_refreshment_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + for (uint8 i = 0; i < MAX_CONJURE_REFRESHMENT_SPELLS; ++i) + if (!sSpellMgr->GetSpellInfo(_conjureData[i].spellId)) + return false; + return true; + } + + bool Load() override + { + if (GetCaster()->GetTypeId() != TYPEID_PLAYER) + return false; + return true; + } + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + uint8 level = GetHitUnit()->getLevel(); + for (uint8 i = 0; i < MAX_CONJURE_REFRESHMENT_SPELLS; ++i) + { + ConjureRefreshmentData const& spellData = _conjureData[i]; + if (level < spellData.minLevel || level > spellData.maxLevel) + continue; + GetHitUnit()->CastSpell(GetHitUnit(), spellData.spellId); + break; + } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_mage_conjure_refreshment_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_mage_conjure_refreshment_SpellScript(); + } +}; + +// 543 - Fire War class spell_mage_fire_frost_ward : public SpellScriptLoader { public: @@ -214,9 +474,8 @@ class spell_mage_fire_frost_ward : public SpellScriptLoader bool Validate(SpellInfo const* /*spellInfo*/) override { - if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_FROST_WARDING_TRIGGERED)) - return false; - if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_FROST_WARDING_R1)) + if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_FROST_WARDING_TRIGGERED) || + !sSpellMgr->GetSpellInfo(SPELL_MAGE_FROST_WARDING_R1)) return false; return true; } @@ -319,97 +578,154 @@ class spell_mage_focus_magic : public SpellScriptLoader } }; -// -11426 - Ice Barrier -class spell_mage_ice_barrier : public SpellScriptLoader +// 116 - Frostbolt +/// Updated 4.3.4 +class spell_mage_frostbolt : public SpellScriptLoader +{ + public: + spell_mage_frostbolt() : SpellScriptLoader("spell_mage_frostbolt") { } + + class spell_mage_frostbolt_SpellScript : public SpellScript + { + PrepareSpellScript(spell_mage_frostbolt_SpellScript); + + void RecalculateDamage(SpellEffIndex /*effIndex*/) + { + if (GetHitUnit() && GetHitUnit()->HasAuraState(AURA_STATE_FROZEN, GetSpellInfo(), GetCaster())) + { + if (AuraEffect* aurEff = GetCaster()->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_MAGE, ICON_MAGE_SHATTER, EFFECT_1)) + { + int32 damage = GetHitDamage(); + AddPct(damage, aurEff->GetAmount()); + SetHitDamage(damage); + } + } + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_mage_frostbolt_SpellScript::RecalculateDamage, EFFECT_1, SPELL_EFFECT_SCHOOL_DAMAGE); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_mage_frostbolt_SpellScript(); + } +}; + +// 56372 - Glyph of Ice Block +class spell_mage_glyph_of_ice_block : public SpellScriptLoader { public: - spell_mage_ice_barrier() : SpellScriptLoader("spell_mage_ice_barrier") { } + spell_mage_glyph_of_ice_block() : SpellScriptLoader("spell_mage_glyph_of_ice_block") { } - class spell_mage_ice_barrier_AuraScript : public spell_mage_incanters_absorbtion_base_AuraScript + class spell_mage_glyph_of_ice_block_AuraScript : public AuraScript { - PrepareAuraScript(spell_mage_ice_barrier_AuraScript); + PrepareAuraScript(spell_mage_glyph_of_ice_block_AuraScript); - void CalculateAmount(AuraEffect const* aurEff, int32& amount, bool& canBeRecalculated) + bool Validate(SpellInfo const* /*spellInfo*/) override { - canBeRecalculated = false; - if (Unit* caster = GetCaster()) - { - // +80.68% from sp bonus - float bonus = 0.8068f; + if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_FROST_NOVA)) + return false; + return true; + } - bonus *= caster->SpellBaseHealingBonusDone(GetSpellInfo()->GetSchoolMask()); + bool CheckProc(ProcEventInfo& /*eventInfo*/) + { + return GetTarget()->GetTypeId() == TYPEID_PLAYER; + } - // Glyph of Ice Barrier: its weird having a SPELLMOD_ALL_EFFECTS here but its blizzards doing :) - // Glyph of Ice Barrier is only applied at the spell damage bonus because it was already applied to the base value in CalculateSpellDamage - bonus = caster->ApplyEffectModifiers(GetSpellInfo(), aurEff->GetEffIndex(), bonus); + void HandleEffectProc(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + // Remove Frost Nova cooldown + GetTarget()->ToPlayer()->RemoveSpellCooldown(SPELL_MAGE_FROST_NOVA, true); + } - bonus *= caster->CalculateLevelPenalty(GetSpellInfo()); + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_mage_glyph_of_ice_block_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_mage_glyph_of_ice_block_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; - amount += int32(bonus); - } + AuraScript* GetAuraScript() const override + { + return new spell_mage_glyph_of_ice_block_AuraScript(); + } +}; + +// 56374 - Glyph of Icy Veins +class spell_mage_glyph_of_icy_veins : public SpellScriptLoader +{ + public: + spell_mage_glyph_of_icy_veins() : SpellScriptLoader("spell_mage_glyph_of_icy_veins") { } + + class spell_mage_glyph_of_icy_veins_AuraScript : public AuraScript + { + PrepareAuraScript(spell_mage_glyph_of_icy_veins_AuraScript); + + void HandleEffectProc(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + + GetTarget()->RemoveAurasByType(SPELL_AURA_HASTE_SPELLS, 0, 0, true, false); + GetTarget()->RemoveAurasByType(SPELL_AURA_MOD_DECREASE_SPEED); } void Register() override { - DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_mage_ice_barrier_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB); - AfterEffectAbsorb += AuraEffectAbsorbFn(spell_mage_ice_barrier_AuraScript::Trigger, EFFECT_0); + OnEffectProc += AuraEffectProcFn(spell_mage_glyph_of_icy_veins_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY); } }; AuraScript* GetAuraScript() const override { - return new spell_mage_ice_barrier_AuraScript(); + return new spell_mage_glyph_of_icy_veins_AuraScript(); } }; -// -11119 - Ignite -class spell_mage_ignite : public SpellScriptLoader +// 56375 - Glyph of Polymorph +class spell_mage_glyph_of_polymorph : public SpellScriptLoader { public: - spell_mage_ignite() : SpellScriptLoader("spell_mage_ignite") { } + spell_mage_glyph_of_polymorph() : SpellScriptLoader("spell_mage_glyph_of_polymorph") { } - class spell_mage_ignite_AuraScript : public AuraScript + class spell_mage_glyph_of_polymorph_AuraScript : public AuraScript { - PrepareAuraScript(spell_mage_ignite_AuraScript); + PrepareAuraScript(spell_mage_glyph_of_polymorph_AuraScript); bool Validate(SpellInfo const* /*spellInfo*/) override { - if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_IGNITE)) + if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_SHADOW_WORD_DEATH)) return false; return true; } - bool CheckProc(ProcEventInfo& eventInfo) - { - return eventInfo.GetProcTarget(); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + void HandleEffectProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) { PreventDefaultAction(); + Unit* target = eventInfo.GetProcTarget(); - SpellInfo const* igniteDot = sSpellMgr->EnsureSpellInfo(SPELL_MAGE_IGNITE); - int32 pct = 8 * GetSpellInfo()->GetRank(); - - int32 amount = int32(CalculatePct(eventInfo.GetDamageInfo()->GetDamage(), pct) / igniteDot->GetMaxTicks()); - amount += eventInfo.GetProcTarget()->GetRemainingPeriodicAmount(eventInfo.GetActor()->GetGUID(), SPELL_MAGE_IGNITE, SPELL_AURA_PERIODIC_DAMAGE); - GetTarget()->CastCustomSpell(SPELL_MAGE_IGNITE, SPELLVALUE_BASE_POINT0, amount, eventInfo.GetProcTarget(), true, NULL, aurEff); + target->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE, 0, target->GetAura(SPELL_PRIEST_SHADOW_WORD_DEATH)); // SW:D shall not be removed. + target->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE_PERCENT); + target->RemoveAurasByType(SPELL_AURA_PERIODIC_LEECH); } void Register() override { - DoCheckProc += AuraCheckProcFn(spell_mage_ignite_AuraScript::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_mage_ignite_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + OnEffectProc += AuraEffectProcFn(spell_mage_glyph_of_polymorph_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY); } }; AuraScript* GetAuraScript() const override { - return new spell_mage_ignite_AuraScript(); + return new spell_mage_glyph_of_polymorph_AuraScript(); } }; -// -44457 - Living Bomb +// 44457 - Living Bomb class spell_mage_living_bomb : public SpellScriptLoader { public: @@ -419,9 +735,9 @@ class spell_mage_living_bomb : public SpellScriptLoader { PrepareAuraScript(spell_mage_living_bomb_AuraScript); - bool Validate(SpellInfo const* spell) override + bool Validate(SpellInfo const* spellInfo) { - if (!sSpellMgr->GetSpellInfo(uint32(spell->Effects[EFFECT_1].CalcValue()))) + if (!sSpellMgr->GetSpellInfo(uint32(spellInfo->Effects[EFFECT_1].CalcValue()))) return false; return true; } @@ -448,44 +764,158 @@ class spell_mage_living_bomb : public SpellScriptLoader } }; -// -1463 - Mana Shield -class spell_mage_mana_shield : public SpellScriptLoader +// 11426 - Ice Barrier +/// Updated 4.3.4 +class spell_mage_ice_barrier : public SpellScriptLoader +{ + public: + spell_mage_ice_barrier() : SpellScriptLoader("spell_mage_ice_barrier") { } + + class spell_mage_ice_barrier_AuraScript : public AuraScript + { + PrepareAuraScript(spell_mage_ice_barrier_AuraScript); + + void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_ENEMY_SPELL) + return; + + if (GetTarget()->HasAura(SPELL_MAGE_SHATTERED_BARRIER_R1)) + GetTarget()->CastSpell(GetTarget(), SPELL_MAGE_SHATTERED_BARRIER_FREEZE_R1, true); + else if (GetTarget()->HasAura(SPELL_MAGE_SHATTERED_BARRIER_R2)) + GetTarget()->CastSpell(GetTarget(), SPELL_MAGE_SHATTERED_BARRIER_FREEZE_R2, true); + } + + void Register() + { + AfterEffectRemove += AuraEffectRemoveFn(spell_mage_ice_barrier_AuraScript::AfterRemove, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_mage_ice_barrier_AuraScript(); + } +}; + +// -11119 - Ignite +class spell_mage_ignite : public SpellScriptLoader { public: - spell_mage_mana_shield() : SpellScriptLoader("spell_mage_mana_shield") { } + spell_mage_ignite() : SpellScriptLoader("spell_mage_ignite") { } - class spell_mage_mana_shield_AuraScript : public spell_mage_incanters_absorbtion_base_AuraScript + class spell_mage_ignite_AuraScript : public AuraScript { - PrepareAuraScript(spell_mage_mana_shield_AuraScript); + PrepareAuraScript(spell_mage_ignite_AuraScript); - void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& canBeRecalculated) + bool Validate(SpellInfo const* /*spellInfo*/) override { - canBeRecalculated = false; - if (Unit* caster = GetCaster()) - { - // +80.53% from sp bonus - float bonus = 0.8053f; + if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_IGNITE)) + return false; + return true; + } - bonus *= caster->SpellBaseHealingBonusDone(GetSpellInfo()->GetSchoolMask()); - bonus *= caster->CalculateLevelPenalty(GetSpellInfo()); + bool CheckProc(ProcEventInfo& eventInfo) + { + return eventInfo.GetProcTarget(); + } - amount += int32(bonus); - } + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + SpellInfo const* igniteDot = sSpellMgr->EnsureSpellInfo(SPELL_MAGE_IGNITE); + int32 pct = 8 * GetSpellInfo()->GetRank(); + + int32 amount = int32(CalculatePct(eventInfo.GetDamageInfo()->GetDamage(), pct) / igniteDot->GetMaxTicks()); + amount += eventInfo.GetProcTarget()->GetRemainingPeriodicAmount(eventInfo.GetActor()->GetGUID(), SPELL_MAGE_IGNITE, SPELL_AURA_PERIODIC_DAMAGE); + GetTarget()->CastCustomSpell(SPELL_MAGE_IGNITE, SPELLVALUE_BASE_POINT0, amount, eventInfo.GetProcTarget(), true, NULL, aurEff); } void Register() override { - DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_mage_mana_shield_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_MANA_SHIELD); - AfterEffectManaShield += AuraEffectManaShieldFn(spell_mage_mana_shield_AuraScript::Trigger, EFFECT_0); + DoCheckProc += AuraCheckProcFn(spell_mage_ignite_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_mage_ignite_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); } }; AuraScript* GetAuraScript() const override { - return new spell_mage_mana_shield_AuraScript(); + return new spell_mage_ignite_AuraScript(); } }; +// 543 - Mage Ward +/// Updated 4.3.4 +class spell_mage_mage_ward : public SpellScriptLoader +{ + public: + spell_mage_mage_ward() : SpellScriptLoader("spell_mage_mage_ward") { } + + class spell_mage_mage_ward_AuraScript : public AuraScript + { + PrepareAuraScript(spell_mage_mage_ward_AuraScript); + + void HandleAbsorb(AuraEffect* /*aurEff*/, DamageInfo & /*dmgInfo*/, uint32 & absorbAmount) + { + if (AuraEffect* aurEff = GetTarget()->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_GENERIC, ICON_MAGE_INCANTER_S_ABSORPTION, EFFECT_0)) + { + int32 bp = CalculatePct(absorbAmount, aurEff->GetAmount()); + GetTarget()->CastCustomSpell(GetTarget(), SPELL_MAGE_INCANTERS_ABSORBTION_TRIGGERED, &bp, NULL, NULL, true); + } + } + + void Register() override + { + AfterEffectAbsorb += AuraEffectAbsorbFn(spell_mage_mage_ward_AuraScript::HandleAbsorb, EFFECT_0); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_mage_mage_ward_AuraScript(); + } +}; + +// 1463 - Mana Shield +/// Updated 4.3.4 +class spell_mage_mana_shield : public SpellScriptLoader +{ + public: + spell_mage_mana_shield() : SpellScriptLoader("spell_mage_mana_shield") { } + + class spell_mage_mana_shield_AuraScript : public AuraScript + { + PrepareAuraScript(spell_mage_mana_shield_AuraScript); + + void HandleAbsorb(AuraEffect* /*aurEff*/, DamageInfo & /*dmgInfo*/, uint32 & absorbAmount) + { + if (AuraEffect* aurEff = GetTarget()->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_GENERIC, ICON_MAGE_INCANTER_S_ABSORPTION, EFFECT_0)) + { + int32 bp = CalculatePct(absorbAmount, aurEff->GetAmount()); + GetTarget()->CastCustomSpell(GetTarget(), SPELL_MAGE_INCANTERS_ABSORBTION_TRIGGERED, &bp, NULL, NULL, true); + } + } + + void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_ENEMY_SPELL) + GetTarget()->CastSpell(GetTarget(), SPELL_MAGE_INCANTERS_ABSORBTION_R1, true); + } + + void Register() override + { + AfterEffectManaShield += AuraEffectManaShieldFn(spell_mage_mana_shield_AuraScript::HandleAbsorb, EFFECT_0); + AfterEffectRemove += AuraEffectRemoveFn(spell_mage_mana_shield_AuraScript::AfterRemove, EFFECT_0, SPELL_AURA_MANA_SHIELD, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_mage_mana_shield_AuraScript(); + } +}; + // -29074 - Master of Elements class spell_mage_master_of_elements : public SpellScriptLoader { @@ -532,9 +962,158 @@ class spell_mage_master_of_elements : public SpellScriptLoader } }; +// 86181 - Nether Vortex +class spell_mage_nether_vortex : public SpellScriptLoader +{ + public: + spell_mage_nether_vortex() : SpellScriptLoader("spell_mage_nether_vortex") { } + + class spell_mage_nether_vortex_AuraScript : public AuraScript + { + PrepareAuraScript(spell_mage_nether_vortex_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_SLOW)) + return false; + return true; + } + + bool DoCheck(ProcEventInfo& eventInfo) + { + if (Aura* aura = eventInfo.GetProcTarget()->GetAura(SPELL_MAGE_SLOW)) + if (aura->GetCasterGUID() != GetTarget()->GetGUID()) + return false; + + return true; + } + + void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + GetTarget()->CastSpell(eventInfo.GetProcTarget(), SPELL_MAGE_SLOW, true, NULL, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_mage_nether_vortex_AuraScript::DoCheck); + OnEffectProc += AuraEffectProcFn(spell_mage_nether_vortex_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_mage_nether_vortex_AuraScript(); + } +}; + +// -11175 - Permafrost +class spell_mage_permafrost : public SpellScriptLoader +{ + public: + spell_mage_permafrost() : SpellScriptLoader("spell_mage_permafrost") { } + + class spell_mage_permafrost_AuraScript : public AuraScript + { + PrepareAuraScript(spell_mage_permafrost_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_PERMAFROST)) + return false; + return true; + } + + bool DoCheck(ProcEventInfo& eventInfo) + { + return GetTarget()->GetGuardianPet() && eventInfo.GetDamageInfo()->GetDamage(); + } + + void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + int32 heal = int32(CalculatePct(eventInfo.GetDamageInfo()->GetDamage(), aurEff->GetAmount())); + GetTarget()->CastCustomSpell(SPELL_MAGE_PERMAFROST, SPELLVALUE_BASE_POINT0, heal, (Unit*)NULL, true, NULL, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_mage_permafrost_AuraScript::DoCheck); + OnEffectProc += AuraEffectProcFn(spell_mage_permafrost_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_mage_permafrost_AuraScript(); + } +}; + +// 118 - Polymorph +class spell_mage_polymorph : public SpellScriptLoader +{ + public: + spell_mage_polymorph() : SpellScriptLoader("spell_mage_polymorph") { } + + class spell_mage_polymorph_AuraScript : public AuraScript + { + PrepareAuraScript(spell_mage_polymorph_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_IMPROVED_POLYMORPH_RANK_1) || + !sSpellMgr->GetSpellInfo(SPELL_MAGE_IMPROVED_POLYMORPH_STUN_RANK_1) || + !sSpellMgr->GetSpellInfo(SPELL_MAGE_IMPROVED_POLYMORPH_MARKER)) + return false; + return true; + } + + bool Load() override + { + _caster = NULL; + return true; + } + + bool DoCheck(ProcEventInfo& eventInfo) + { + _caster = GetCaster(); + return _caster && eventInfo.GetDamageInfo(); + } + + void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + // Improved Polymorph + if (AuraEffect const* improvedPolymorph = _caster->GetAuraEffectOfRankedSpell(SPELL_MAGE_IMPROVED_POLYMORPH_RANK_1, EFFECT_0)) + { + if (_caster->HasAura(SPELL_MAGE_IMPROVED_POLYMORPH_MARKER)) + return; + + GetTarget()->CastSpell(GetTarget(), sSpellMgr->GetSpellWithRank(SPELL_MAGE_IMPROVED_POLYMORPH_STUN_RANK_1, improvedPolymorph->GetSpellInfo()->GetRank()), true, NULL, aurEff); + _caster->CastSpell(_caster, SPELL_MAGE_IMPROVED_POLYMORPH_MARKER, true, NULL, aurEff); + } + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_mage_polymorph_AuraScript::DoCheck); + OnEffectProc += AuraEffectProcFn(spell_mage_polymorph_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_MOD_CONFUSE); + } + + private: + Unit* _caster; + }; + + AuraScript* GetAuraScript() const override + { + return new spell_mage_polymorph_AuraScript(); + } +}; + enum SilvermoonPolymorph { - NPC_AUROSALIA = 18744, + NPC_AUROSALIA = 18744 }; /// @todo move out of here and rename - not a mage spell @@ -553,7 +1132,7 @@ class spell_mage_polymorph_cast_visual : public SpellScriptLoader bool Validate(SpellInfo const* /*spellInfo*/) override { // check if spell ids exist in dbc - for (uint32 i = 0; i < 6; ++i) + for (uint32 i = 0; i < 6; i++) if (!sSpellMgr->GetSpellInfo(PolymorhForms[i])) return false; return true; @@ -568,6 +1147,7 @@ class spell_mage_polymorph_cast_visual : public SpellScriptLoader void Register() override { + // add dummy effect spell handler to Polymorph visual OnEffectHitTarget += SpellEffectFn(spell_mage_polymorph_cast_visual_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -578,7 +1158,7 @@ class spell_mage_polymorph_cast_visual : public SpellScriptLoader } }; -const uint32 spell_mage_polymorph_cast_visual::spell_mage_polymorph_cast_visual_SpellScript::PolymorhForms[6] = +uint32 const spell_mage_polymorph_cast_visual::spell_mage_polymorph_cast_visual_SpellScript::PolymorhForms[6] = { SPELL_MAGE_SQUIRREL_FORM, SPELL_MAGE_GIRAFFE_FORM, @@ -588,57 +1168,322 @@ const uint32 spell_mage_polymorph_cast_visual::spell_mage_polymorph_cast_visual_ SPELL_MAGE_SHEEP_FORM }; -// 31687 - Summon Water Elemental -class spell_mage_summon_water_elemental : public SpellScriptLoader +// 5405 - Replenish Mana (Mana Gem) +/// Updated 4.3.4 +class spell_mage_replenish_mana : public SpellScriptLoader +{ + public: + spell_mage_replenish_mana() : SpellScriptLoader("spell_mage_replenish_mana") { } + + class spell_mage_replenish_mana_SpellScript : public SpellScript + { + PrepareSpellScript(spell_mage_replenish_mana_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_IMPROVED_MANA_GEM_TRIGGERED)) + return false; + return true; + } + + void HandleImprovedManaGem() + { + if (AuraEffect* aurEff = GetCaster()->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_MAGE, ICON_MAGE_IMPROVED_MANA_GEM, EFFECT_0)) + { + int32 bp = CalculatePct(GetCaster()->GetMaxPower(POWER_MANA), aurEff->GetAmount()); + GetCaster()->CastCustomSpell(GetCaster(), SPELL_MAGE_IMPROVED_MANA_GEM_TRIGGERED, &bp, &bp, NULL, true); + } + } + + void Register() + { + AfterCast += SpellCastFn(spell_mage_replenish_mana_SpellScript::HandleImprovedManaGem); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_mage_replenish_mana_SpellScript(); + } +}; + +// 82676 - Ring of Frost +/// Updated 4.3.4 +class spell_mage_ring_of_frost : public SpellScriptLoader { public: - spell_mage_summon_water_elemental() : SpellScriptLoader("spell_mage_summon_water_elemental") { } + spell_mage_ring_of_frost() : SpellScriptLoader("spell_mage_ring_of_frost") { } - class spell_mage_summon_water_elemental_SpellScript : public SpellScript + class spell_mage_ring_of_frost_AuraScript : public AuraScript { - PrepareSpellScript(spell_mage_summon_water_elemental_SpellScript); + PrepareAuraScript(spell_mage_ring_of_frost_AuraScript); bool Validate(SpellInfo const* /*spellInfo*/) override { - if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_GLYPH_OF_ETERNAL_WATER) || !sSpellMgr->GetSpellInfo(SPELL_MAGE_SUMMON_WATER_ELEMENTAL_TEMPORARY) || !sSpellMgr->GetSpellInfo(SPELL_MAGE_SUMMON_WATER_ELEMENTAL_PERMANENT)) + if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_RING_OF_FROST_SUMMON)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_RING_OF_FROST_FREEZE)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_RING_OF_FROST_DUMMY)) return false; return true; } - void HandleDummy(SpellEffIndex /*effIndex*/) + bool Load() override { - Unit* caster = GetCaster(); - // Glyph of Eternal Water - if (caster->HasAura(SPELL_MAGE_GLYPH_OF_ETERNAL_WATER)) - caster->CastSpell(caster, SPELL_MAGE_SUMMON_WATER_ELEMENTAL_PERMANENT, true); - else - caster->CastSpell(caster, SPELL_MAGE_SUMMON_WATER_ELEMENTAL_TEMPORARY, true); + ringOfFrost = NULL; + return true; + } + + void HandleEffectPeriodic(AuraEffect const* /*aurEff*/) + { + if (ringOfFrost) + if (GetMaxDuration() - (int32)ringOfFrost->GetTimer() >= sSpellMgr->GetSpellInfo(SPELL_MAGE_RING_OF_FROST_DUMMY)->GetDuration()) + GetTarget()->CastSpell(ringOfFrost->GetPositionX(), ringOfFrost->GetPositionY(), ringOfFrost->GetPositionZ(), SPELL_MAGE_RING_OF_FROST_FREEZE, true); + } + + void Apply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + std::list<Creature*> MinionList; + GetTarget()->GetAllMinionsByEntry(MinionList, GetSpellInfo()->Effects[EFFECT_0].MiscValue); + + // Get the last summoned RoF, save it and despawn older ones + for (std::list<Creature*>::iterator itr = MinionList.begin(); itr != MinionList.end(); itr++) + { + TempSummon* summon = (*itr)->ToTempSummon(); + + if (ringOfFrost && summon) + { + if (summon->GetTimer() > ringOfFrost->GetTimer()) + { + ringOfFrost->DespawnOrUnsummon(); + ringOfFrost = summon; + } + else + summon->DespawnOrUnsummon(); + } + else if (summon) + ringOfFrost = summon; + } } + TempSummon* ringOfFrost; + void Register() override { - OnEffectHit += SpellEffectFn(spell_mage_summon_water_elemental_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectPeriodic += AuraEffectPeriodicFn(spell_mage_ring_of_frost_AuraScript::HandleEffectPeriodic, EFFECT_1, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + OnEffectApply += AuraEffectApplyFn(spell_mage_ring_of_frost_AuraScript::Apply, EFFECT_1, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_mage_ring_of_frost_AuraScript(); + } +}; + +// 82691 - Ring of Frost (freeze efect) +/// Updated 4.3.4 +class spell_mage_ring_of_frost_freeze : public SpellScriptLoader +{ + public: + spell_mage_ring_of_frost_freeze() : SpellScriptLoader("spell_mage_ring_of_frost_freeze") { } + + class spell_mage_ring_of_frost_freeze_SpellScript : public SpellScript + { + PrepareSpellScript(spell_mage_ring_of_frost_freeze_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_RING_OF_FROST_SUMMON)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_RING_OF_FROST_FREEZE)) + return false; + return true; + } + + void FilterTargets(std::list<WorldObject*>& targets) + { + float outRadius = sSpellMgr->GetSpellInfo(SPELL_MAGE_RING_OF_FROST_SUMMON)->Effects[EFFECT_0].CalcRadius(); + float inRadius = 4.7f; + + for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr) + if (Unit* unit = (*itr)->ToUnit()) + if (unit->HasAura(SPELL_MAGE_RING_OF_FROST_DUMMY) || unit->HasAura(SPELL_MAGE_RING_OF_FROST_FREEZE) || unit->GetExactDist(GetExplTargetDest()) > outRadius || unit->GetExactDist(GetExplTargetDest()) < inRadius) + targets.erase(itr--); + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mage_ring_of_frost_freeze_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY); } }; SpellScript* GetSpellScript() const override { - return new spell_mage_summon_water_elemental_SpellScript(); + return new spell_mage_ring_of_frost_freeze_SpellScript(); } + + class spell_mage_ring_of_frost_freeze_AuraScript : public AuraScript + { + PrepareAuraScript(spell_mage_ring_of_frost_freeze_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_RING_OF_FROST_DUMMY)) + return false; + return true; + } + + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE) + if (GetCaster()) + GetCaster()->CastSpell(GetTarget(), SPELL_MAGE_RING_OF_FROST_DUMMY, true); + } + + void Register() override + { + AfterEffectRemove += AuraEffectRemoveFn(spell_mage_ring_of_frost_freeze_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_MOD_STUN, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_mage_ring_of_frost_freeze_AuraScript(); + } +}; + +// 80353 - Time Warp +class spell_mage_time_warp : public SpellScriptLoader +{ + public: + spell_mage_time_warp() : SpellScriptLoader("spell_mage_time_warp") { } + + class spell_mage_time_warp_SpellScript : public SpellScript + { + PrepareSpellScript(spell_mage_time_warp_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_TEMPORAL_DISPLACEMENT) + || !sSpellMgr->GetSpellInfo(SPELL_HUNTER_INSANITY) + || !sSpellMgr->GetSpellInfo(SPELL_SHAMAN_EXHAUSTION) + || !sSpellMgr->GetSpellInfo(SPELL_SHAMAN_SATED)) + return false; + return true; + } + + void RemoveInvalidTargets(std::list<WorldObject*>& targets) + { + targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_MAGE_TEMPORAL_DISPLACEMENT)); + targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_HUNTER_INSANITY)); + targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_SHAMAN_EXHAUSTION)); + targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_SHAMAN_SATED)); + } + + void ApplyDebuff() + { + if (Unit* target = GetHitUnit()) + target->CastSpell(target, SPELL_MAGE_TEMPORAL_DISPLACEMENT, true); + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mage_time_warp_SpellScript::RemoveInvalidTargets, EFFECT_ALL, TARGET_UNIT_CASTER_AREA_RAID); + AfterHit += SpellHitFn(spell_mage_time_warp_SpellScript::ApplyDebuff); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_mage_time_warp_SpellScript(); + } +}; + +// 33395 Water Elemental's Freeze +/// Updated 4.3.4 +class spell_mage_water_elemental_freeze : public SpellScriptLoader +{ + public: + spell_mage_water_elemental_freeze() : SpellScriptLoader("spell_mage_water_elemental_freeze") { } + + class spell_mage_water_elemental_freeze_SpellScript : public SpellScript + { + PrepareSpellScript(spell_mage_water_elemental_freeze_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_FINGERS_OF_FROST)) + return false; + return true; + } + + void CountTargets(std::list<WorldObject*>& targetList) + { + _didHit = !targetList.empty(); + } + + void HandleImprovedFreeze() + { + if (!_didHit) + return; + + Unit* owner = GetCaster()->GetOwner(); + if (!owner) + return; + + if (AuraEffect* aurEff = owner->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_MAGE, ICON_MAGE_IMPROVED_FREEZE, EFFECT_0)) + { + if (roll_chance_i(aurEff->GetAmount())) + owner->CastCustomSpell(SPELL_MAGE_FINGERS_OF_FROST, SPELLVALUE_AURA_STACK, 2, owner, true); + } + } + + void Register() + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mage_water_elemental_freeze_SpellScript::CountTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY); + AfterCast += SpellCastFn(spell_mage_water_elemental_freeze_SpellScript::HandleImprovedFreeze); + } + + private: + bool _didHit; + }; + + SpellScript* GetSpellScript() const + { + return new spell_mage_water_elemental_freeze_SpellScript(); + } }; void AddSC_mage_spell_scripts() { + new spell_mage_arcane_potency(); new spell_mage_blast_wave(); - new spell_mage_burnout(); + new spell_mage_blazing_speed(); + new spell_mage_blizzard(); new spell_mage_cold_snap(); + new spell_mage_cone_of_cold(); + new spell_mage_conjure_refreshment(); new spell_mage_fire_frost_ward(); new spell_mage_focus_magic(); + new spell_mage_frostbolt(); new spell_mage_ice_barrier(); new spell_mage_ignite(); + new spell_mage_glyph_of_ice_block(); + new spell_mage_glyph_of_icy_veins(); + new spell_mage_glyph_of_polymorph(); new spell_mage_living_bomb(); + new spell_mage_mage_ward(); new spell_mage_mana_shield(); new spell_mage_master_of_elements(); + new spell_mage_nether_vortex(); + new spell_mage_permafrost(); + new spell_mage_polymorph(); new spell_mage_polymorph_cast_visual(); - new spell_mage_summon_water_elemental(); + new spell_mage_replenish_mana(); + new spell_mage_ring_of_frost(); + new spell_mage_ring_of_frost_freeze(); + new spell_mage_time_warp(); + new spell_mage_water_elemental_freeze(); } diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp index 447cb645e76..2efcbd5d35e 100644 --- a/src/server/scripts/Spells/spell_paladin.cpp +++ b/src/server/scripts/Spells/spell_paladin.cpp @@ -29,57 +29,45 @@ enum PaladinSpells { - SPELL_PALADIN_DIVINE_PLEA = 54428, - SPELL_PALADIN_BLESSING_OF_SANCTUARY_BUFF = 67480, - SPELL_PALADIN_BLESSING_OF_SANCTUARY_ENERGIZE = 57319, - - SPELL_PALADIN_HOLY_SHOCK_R1 = 20473, - SPELL_PALADIN_HOLY_SHOCK_R1_DAMAGE = 25912, - SPELL_PALADIN_HOLY_SHOCK_R1_HEALING = 25914, - + SPELL_PALADIN_AVENGERS_SHIELD = 31935, + SPELL_PALADIN_AURA_MASTERY_IMMUNE = 64364, + SPELL_PALADIN_BEACON_OF_LIGHT_MARKER = 53563, + SPELL_PALADIN_BEACON_OF_LIGHT_HEAL = 53652, SPELL_PALADIN_BLESSING_OF_LOWER_CITY_DRUID = 37878, SPELL_PALADIN_BLESSING_OF_LOWER_CITY_PALADIN = 37879, SPELL_PALADIN_BLESSING_OF_LOWER_CITY_PRIEST = 37880, SPELL_PALADIN_BLESSING_OF_LOWER_CITY_SHAMAN = 37881, - + SPELL_PALADIN_CONCENTRACTION_AURA = 19746, + SPELL_PALADIN_DIVINE_PURPOSE_PROC = 90174, + SPELL_PALADIN_DIVINE_SACRIFICE = 64205, SPELL_PALADIN_DIVINE_STORM = 53385, SPELL_PALADIN_DIVINE_STORM_DUMMY = 54171, SPELL_PALADIN_DIVINE_STORM_HEAL = 54172, - + SPELL_PALADIN_EYE_FOR_AN_EYE_RANK_1 = 9799, SPELL_PALADIN_EYE_FOR_AN_EYE_DAMAGE = 25997, - SPELL_PALADIN_FORBEARANCE = 25771, - SPELL_PALADIN_AVENGING_WRATH_MARKER = 61987, - SPELL_PALADIN_IMMUNE_SHIELD_MARKER = 61988, - + SPELL_PALADIN_GLYPH_OF_SALVATION = 63225, SPELL_PALADIN_HAND_OF_SACRIFICE = 6940, - SPELL_PALADIN_DIVINE_SACRIFICE = 64205, - + SPELL_PALADIN_HOLY_LIGHT = 635, + SPELL_PALADIN_HOLY_SHOCK_R1 = 20473, + SPELL_PALADIN_HOLY_SHOCK_R1_DAMAGE = 25912, + SPELL_PALADIN_HOLY_SHOCK_R1_HEALING = 25914, + SPELL_PALADIN_IMMUNE_SHIELD_MARKER = 61988, + SPELL_PALADIN_IMPROVED_CONCENTRACTION_AURA = 63510, + SPELL_PALADIN_IMPROVED_DEVOTION_AURA = 63514, SPELL_PALADIN_ITEM_HEALING_TRANCE = 37706, - SPELL_PALADIN_JUDGEMENT_DAMAGE = 54158, - SPELL_PALADIN_JUDGEMENT_OF_JUSTICE = 20184, - SPELL_PALADIN_JUDGEMENT_OF_LIGHT = 20185, - SPELL_PALADIN_JUDGEMENT_OF_WISDOM = 20186, - - SPELL_PALADIN_GLYPH_OF_SALVATION = 63225, - SPELL_PALADIN_RIGHTEOUS_DEFENSE_TAUNT = 31790, - + SPELL_PALADIN_SANCTIFIED_RETRIBUTION_AURA = 63531, + SPELL_PALADIN_SANCTIFIED_RETRIBUTION_R1 = 31869, SPELL_PALADIN_SANCTIFIED_WRATH = 57318, SPELL_PALADIN_SANCTIFIED_WRATH_TALENT_R1 = 53375, - SPELL_PALADIN_SEAL_OF_RIGHTEOUSNESS = 25742, + SPELL_PALADIN_SWIFT_RETRIBUTION_R1 = 53379 +}; - SPELL_PALADIN_CONCENTRACTION_AURA = 19746, - SPELL_PALADIN_SANCTIFIED_RETRIBUTION_R1 = 31869, - SPELL_PALADIN_SWIFT_RETRIBUTION_R1 = 53379, - - SPELL_PALADIN_IMPROVED_CONCENTRACTION_AURA = 63510, - SPELL_PALADIN_IMPROVED_DEVOTION_AURA = 63514, - SPELL_PALADIN_SANCTIFIED_RETRIBUTION_AURA = 63531, - SPELL_PALADIN_AURA_MASTERY_IMMUNE = 64364, - +enum MiscSpells +{ SPELL_GENERIC_ARENA_DAMPENING = 74410, SPELL_GENERIC_BATTLEGROUND_DAMPENING = 74411 }; @@ -89,6 +77,7 @@ enum PaladinSpellIcons PALADIN_ICON_ID_RETRIBUTION_AURA = 555 }; +/* // 31850 - Ardent Defender class spell_pal_ardent_defender : public SpellScriptLoader { @@ -113,7 +102,7 @@ class spell_pal_ardent_defender : public SpellScriptLoader return GetUnitOwner()->GetTypeId() == TYPEID_PLAYER; } - void CalculateAmount(AuraEffect const* /*aurEff*/, int32 & amount, bool & /*canBeRecalculated*/) + void CalculateAmount(AuraEffect const* aurEff, int32 & amount, bool & canBeRecalculated) { // Set absorbtion amount to unlimited amount = -1; @@ -164,6 +153,7 @@ class spell_pal_ardent_defender : public SpellScriptLoader return new spell_pal_ardent_defender_AuraScript(); } }; +*/ // 31821 - Aura Mastery class spell_pal_aura_mastery : public SpellScriptLoader @@ -285,6 +275,68 @@ class spell_pal_avenging_wrath : public SpellScriptLoader } }; +// 53651 - Beacon of Light +class spell_pal_beacon_of_light : public SpellScriptLoader +{ + public: + spell_pal_beacon_of_light() : SpellScriptLoader("spell_pal_beacon_of_light") { } + + class spell_pal_beacon_of_light_AuraScript : public AuraScript + { + PrepareAuraScript(spell_pal_beacon_of_light_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_PALADIN_BEACON_OF_LIGHT_HEAL)) + return false; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + if (eventInfo.GetActionTarget()->GetAura(SPELL_PALADIN_BEACON_OF_LIGHT_MARKER, GetCasterGUID())) + return false; + return true; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + int32 heal = eventInfo.GetHealInfo()->GetHeal(); + + if (eventInfo.GetDamageInfo()->GetSpellInfo()->Id != SPELL_PALADIN_HOLY_LIGHT) + heal = int32(CalculatePct(heal, aurEff->GetAmount())); + + Unit::AuraList const& auras = GetCaster()->GetSingleCastAuras(); + for (Unit::AuraList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) + { + if ((*itr)->GetId() == SPELL_PALADIN_BEACON_OF_LIGHT_MARKER) + { + std::list<AuraApplication*> applications; + (*itr)->GetApplicationList(applications); + if (applications.empty()) + return; + + GetCaster()->CastCustomSpell(SPELL_PALADIN_BEACON_OF_LIGHT_HEAL, SPELLVALUE_BASE_POINT0, heal, applications.front()->GetTarget(), true, NULL, aurEff); + return; + } + } + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_pal_beacon_of_light_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_pal_beacon_of_light_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_pal_beacon_of_light_AuraScript(); + } +}; + + // 37877 - Blessing of Faith class spell_pal_blessing_of_faith : public SpellScriptLoader { @@ -341,65 +393,6 @@ class spell_pal_blessing_of_faith : public SpellScriptLoader } }; -// 20911 - Blessing of Sanctuary -// 25899 - Greater Blessing of Sanctuary -class spell_pal_blessing_of_sanctuary : public SpellScriptLoader -{ - public: - spell_pal_blessing_of_sanctuary() : SpellScriptLoader("spell_pal_blessing_of_sanctuary") { } - - class spell_pal_blessing_of_sanctuary_AuraScript : public AuraScript - { - PrepareAuraScript(spell_pal_blessing_of_sanctuary_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - if (!sSpellMgr->GetSpellInfo(SPELL_PALADIN_BLESSING_OF_SANCTUARY_BUFF)) - return false; - if (!sSpellMgr->GetSpellInfo(SPELL_PALADIN_BLESSING_OF_SANCTUARY_ENERGIZE)) - return false; - return true; - } - - void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - Unit* target = GetTarget(); - if (Unit* caster = GetCaster()) - caster->CastSpell(target, SPELL_PALADIN_BLESSING_OF_SANCTUARY_BUFF, true); - } - - void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - Unit* target = GetTarget(); - target->RemoveAura(SPELL_PALADIN_BLESSING_OF_SANCTUARY_BUFF, GetCasterGUID()); - } - - bool CheckProc(ProcEventInfo& /*eventInfo*/) - { - return GetTarget()->getPowerType() == POWER_MANA; - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) - { - PreventDefaultAction(); - GetTarget()->CastSpell(GetTarget(), SPELL_PALADIN_BLESSING_OF_SANCTUARY_ENERGIZE, true, NULL, aurEff); - } - - void Register() override - { - AfterEffectApply += AuraEffectApplyFn(spell_pal_blessing_of_sanctuary_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); - AfterEffectRemove += AuraEffectRemoveFn(spell_pal_blessing_of_sanctuary_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); - DoCheckProc += AuraCheckProcFn(spell_pal_blessing_of_sanctuary_AuraScript::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_pal_blessing_of_sanctuary_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } - }; - - AuraScript* GetAuraScript() const override - { - return new spell_pal_blessing_of_sanctuary_AuraScript(); - } -}; - // 64205 - Divine Sacrifice class spell_pal_divine_sacrifice : public SpellScriptLoader { @@ -415,6 +408,7 @@ class spell_pal_divine_sacrifice : public SpellScriptLoader bool Load() override { + if (Unit* caster = GetCaster()) { if (caster->GetTypeId() == TYPEID_PLAYER) @@ -597,17 +591,16 @@ class spell_pal_eye_for_an_eye : public SpellScriptLoader return true; } - void OnProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) { PreventDefaultAction(); - // return damage % to attacker but < 50% own total health - int32 damage = int32(std::min(CalculatePct(eventInfo.GetDamageInfo()->GetDamage(), aurEff->GetAmount()), GetTarget()->GetMaxHealth() / 2)); + int32 damage = CalculatePct(eventInfo.GetDamageInfo()->GetDamage(), aurEff->GetAmount()); GetTarget()->CastCustomSpell(SPELL_PALADIN_EYE_FOR_AN_EYE_DAMAGE, SPELLVALUE_BASE_POINT0, damage, eventInfo.GetProcTarget(), true, NULL, aurEff); } void Register() override { - OnEffectProc += AuraEffectProcFn(spell_pal_eye_for_an_eye_AuraScript::OnProc, EFFECT_0, SPELL_AURA_DUMMY); + OnEffectProc += AuraEffectProcFn(spell_pal_eye_for_an_eye_AuraScript::HandleEffectProc, EFFECT_0, m_scriptSpellId == SPELL_PALADIN_EYE_FOR_AN_EYE_RANK_1 ? SPELL_AURA_DUMMY : SPELL_AURA_PROC_TRIGGER_SPELL); } }; @@ -617,72 +610,76 @@ class spell_pal_eye_for_an_eye : public SpellScriptLoader } }; -// 54968 - Glyph of Holy Light -class spell_pal_glyph_of_holy_light : public SpellScriptLoader +// -75806 - Grand Crusader +class spell_pal_grand_crusader : public SpellScriptLoader { public: - spell_pal_glyph_of_holy_light() : SpellScriptLoader("spell_pal_glyph_of_holy_light") { } + spell_pal_grand_crusader() : SpellScriptLoader("spell_pal_grand_crusader") { } - class spell_pal_glyph_of_holy_light_SpellScript : public SpellScript + class spell_pal_grand_crusader_AuraScript : public AuraScript { - PrepareSpellScript(spell_pal_glyph_of_holy_light_SpellScript); + PrepareAuraScript(spell_pal_grand_crusader_AuraScript); - void FilterTargets(std::list<WorldObject*>& targets) + bool Validate(SpellInfo const* /*spellInfo*/) override { - uint32 const maxTargets = GetSpellInfo()->MaxAffectedTargets; + if (!sSpellMgr->GetSpellInfo(SPELL_PALADIN_AVENGERS_SHIELD)) + return false; + return true; + } - if (targets.size() > maxTargets) - { - targets.sort(Trinity::HealthPctOrderPred()); - targets.resize(maxTargets); - } + bool CheckProc(ProcEventInfo& /*eventInfo*/) + { + return GetTarget()->GetTypeId() == TYPEID_PLAYER; + } + + void HandleEffectProc(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/) + { + GetTarget()->ToPlayer()->RemoveSpellCooldown(SPELL_PALADIN_AVENGERS_SHIELD, true); } void Register() override { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_pal_glyph_of_holy_light_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ALLY); + DoCheckProc += AuraCheckProcFn(spell_pal_grand_crusader_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_pal_grand_crusader_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); } }; - SpellScript* GetSpellScript() const override + AuraScript* GetAuraScript() const override { - return new spell_pal_glyph_of_holy_light_SpellScript(); + return new spell_pal_grand_crusader_AuraScript(); } }; -// 63521 - Guarded by The Light -class spell_pal_guarded_by_the_light : public SpellScriptLoader +// 54968 - Glyph of Holy Light +class spell_pal_glyph_of_holy_light : public SpellScriptLoader { public: - spell_pal_guarded_by_the_light() : SpellScriptLoader("spell_pal_guarded_by_the_light") { } + spell_pal_glyph_of_holy_light() : SpellScriptLoader("spell_pal_glyph_of_holy_light") { } - class spell_pal_guarded_by_the_light_SpellScript : public SpellScript + class spell_pal_glyph_of_holy_light_SpellScript : public SpellScript { - PrepareSpellScript(spell_pal_guarded_by_the_light_SpellScript); + PrepareSpellScript(spell_pal_glyph_of_holy_light_SpellScript); - bool Validate(SpellInfo const* /*spellInfo*/) override + void FilterTargets(std::list<WorldObject*>& targets) { - if (!sSpellMgr->GetSpellInfo(SPELL_PALADIN_DIVINE_PLEA)) - return false; - return true; - } + uint32 const maxTargets = GetSpellInfo()->MaxAffectedTargets; - void HandleScriptEffect(SpellEffIndex /*effIndex*/) - { - // Divine Plea - if (Aura* aura = GetCaster()->GetAura(SPELL_PALADIN_DIVINE_PLEA)) - aura->RefreshDuration(); + if (targets.size() > maxTargets) + { + targets.sort(Trinity::HealthPctOrderPred()); + targets.resize(maxTargets); + } } void Register() override { - OnEffectHitTarget += SpellEffectFn(spell_pal_guarded_by_the_light_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_pal_glyph_of_holy_light_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ALLY); } }; SpellScript* GetSpellScript() const override { - return new spell_pal_guarded_by_the_light_SpellScript(); + return new spell_pal_glyph_of_holy_light_SpellScript(); } }; @@ -730,40 +727,7 @@ class spell_pal_hand_of_sacrifice : public SpellScriptLoader } }; -// 1038 - Hand of Salvation -class spell_pal_hand_of_salvation : public SpellScriptLoader -{ - public: - spell_pal_hand_of_salvation() : SpellScriptLoader("spell_pal_hand_of_salvation") { } - - class spell_pal_hand_of_salvation_AuraScript : public AuraScript - { - PrepareAuraScript(spell_pal_hand_of_salvation_AuraScript); - - void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/) - { - if (Unit* caster = GetCaster()) - { - // Glyph of Salvation - if (caster->GetGUID() == GetUnitOwner()->GetGUID()) - if (AuraEffect const* aurEff = caster->GetAuraEffect(SPELL_PALADIN_GLYPH_OF_SALVATION, EFFECT_0)) - amount -= aurEff->GetAmount(); - } - } - - void Register() override - { - DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_pal_hand_of_salvation_AuraScript::CalculateAmount, EFFECT_1, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN); - } - }; - - AuraScript* GetAuraScript() const override - { - return new spell_pal_hand_of_salvation_AuraScript(); - } -}; - -// -20473 - Holy Shock +// 20473 - Holy Shock class spell_pal_holy_shock : public SpellScriptLoader { public: @@ -835,71 +799,6 @@ class spell_pal_holy_shock : public SpellScriptLoader } }; -// Maybe this is incorrect -// These spells should always be cast on login, regardless of whether the player has the talent or not - -// -20254 - Improved Concentration Aura -// -20138 - Improved Devotion Aura -// 31869 - Sanctified Retribution -// -53379 - Swift Retribution -class spell_pal_improved_aura : public SpellScriptLoader -{ - public: - spell_pal_improved_aura(char const* name, uint32 spellId) : SpellScriptLoader(name), _spellId(spellId) { } - - class spell_pal_improved_aura_AuraScript : public AuraScript - { - PrepareAuraScript(spell_pal_improved_aura_AuraScript); - - public: - spell_pal_improved_aura_AuraScript(uint32 spellId) : AuraScript(), _spellId(spellId) { } - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - if (!sSpellMgr->GetSpellInfo(_spellId) - || !sSpellMgr->GetSpellInfo(SPELL_PALADIN_SANCTIFIED_RETRIBUTION_R1) - || !sSpellMgr->GetSpellInfo(SPELL_PALADIN_SWIFT_RETRIBUTION_R1)) - return false; - return true; - } - - void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - Unit* target = GetTarget(); - GetTarget()->RemoveOwnedAura(_spellId, GetCasterGUID()); // need to remove to reapply spellmods - target->CastSpell(target, _spellId, true); - } - - void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - uint32 spellId = GetSpellInfo()->GetFirstRankSpell()->Id; - - if ((spellId == SPELL_PALADIN_SANCTIFIED_RETRIBUTION_R1 && GetTarget()->GetAuraOfRankedSpell(SPELL_PALADIN_SWIFT_RETRIBUTION_R1)) - || (spellId == SPELL_PALADIN_SWIFT_RETRIBUTION_R1 && GetTarget()->GetAuraOfRankedSpell(SPELL_PALADIN_SANCTIFIED_RETRIBUTION_R1))) - return; - - GetTarget()->RemoveOwnedAura(_spellId, GetCasterGUID()); - } - - void Register() override - { - AfterEffectApply += AuraEffectApplyFn(spell_pal_improved_aura_AuraScript::HandleEffectApply, EFFECT_FIRST_FOUND, SPELL_AURA_ADD_FLAT_MODIFIER, AURA_EFFECT_HANDLE_REAL); - AfterEffectRemove += AuraEffectRemoveFn(spell_pal_improved_aura_AuraScript::HandleEffectRemove, EFFECT_FIRST_FOUND, SPELL_AURA_ADD_FLAT_MODIFIER, AURA_EFFECT_HANDLE_REAL); - } - - private: - uint32 _spellId; - }; - - AuraScript* GetAuraScript() const override - { - return new spell_pal_improved_aura_AuraScript(_spellId); - } - - private: - uint32 _spellId; -}; - // 63510 - Improved Concentraction Aura (Area Aura) // 63514 - Improved Devotion Aura (Area Aura) // 63531 - Sanctified Retribution (Area Aura) @@ -977,32 +876,27 @@ class spell_pal_item_healing_discount : public SpellScriptLoader } }; -// 53407 - Judgement of Justice -// 20271 - Judgement of Light -// 53408 - Judgement of Wisdom +// 20271 - Judgement +/// Updated 4.3.4 class spell_pal_judgement : public SpellScriptLoader { public: - spell_pal_judgement(char const* scriptName, uint32 spellId) : SpellScriptLoader(scriptName), _spellId(spellId) { } + spell_pal_judgement() : SpellScriptLoader("spell_pal_judgement") { } class spell_pal_judgement_SpellScript : public SpellScript { PrepareSpellScript(spell_pal_judgement_SpellScript); - public: - spell_pal_judgement_SpellScript(uint32 spellId) : SpellScript(), _spellId(spellId) { } - bool Validate(SpellInfo const* /*spellInfo*/) override { - if (!sSpellMgr->GetSpellInfo(SPELL_PALADIN_JUDGEMENT_DAMAGE) - || !sSpellMgr->GetSpellInfo(_spellId)) + if (!sSpellMgr->GetSpellInfo(SPELL_PALADIN_JUDGEMENT_DAMAGE)) return false; return true; } void HandleScriptEffect(SpellEffIndex /*effIndex*/) { - uint32 spellId2 = SPELL_PALADIN_JUDGEMENT_DAMAGE; + uint32 spellId = SPELL_PALADIN_JUDGEMENT_DAMAGE; // some seals have SPELL_AURA_DUMMY in EFFECT_2 Unit::AuraEffectList const& auras = GetCaster()->GetAuraEffectsByType(SPELL_AURA_DUMMY); @@ -1011,63 +905,27 @@ class spell_pal_judgement : public SpellScriptLoader if ((*i)->GetSpellInfo()->GetSpellSpecific() == SPELL_SPECIFIC_SEAL && (*i)->GetEffIndex() == EFFECT_2) if (sSpellMgr->GetSpellInfo((*i)->GetAmount())) { - spellId2 = (*i)->GetAmount(); + spellId = (*i)->GetAmount(); break; } } - GetCaster()->CastSpell(GetHitUnit(), _spellId, true); - GetCaster()->CastSpell(GetHitUnit(), spellId2, true); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_pal_judgement_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - } - - private: - uint32 const _spellId; - }; - - SpellScript* GetSpellScript() const override - { - return new spell_pal_judgement_SpellScript(_spellId); - } - - private: - uint32 const _spellId; -}; - -// 20425 - Judgement of Command -class spell_pal_judgement_of_command : public SpellScriptLoader -{ - public: - spell_pal_judgement_of_command() : SpellScriptLoader("spell_pal_judgement_of_command") { } - - class spell_pal_judgement_of_command_SpellScript : public SpellScript - { - PrepareSpellScript(spell_pal_judgement_of_command_SpellScript); - - void HandleDummy(SpellEffIndex /*effIndex*/) - { - if (Unit* unitTarget = GetHitUnit()) - if (SpellInfo const* spell_proto = sSpellMgr->GetSpellInfo(GetEffectValue())) - GetCaster()->CastSpell(unitTarget, spell_proto, true, NULL); + GetCaster()->CastSpell(GetHitUnit(), spellId, true); } void Register() override { - OnEffectHitTarget += SpellEffectFn(spell_pal_judgement_of_command_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_pal_judgement_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_DUMMY); } }; SpellScript* GetSpellScript() const override { - return new spell_pal_judgement_of_command_SpellScript(); + return new spell_pal_judgement_SpellScript(); } }; -// -633 - Lay on Hands +// 633 - Lay on Hands class spell_pal_lay_on_hands : public SpellScriptLoader { public: @@ -1079,11 +937,8 @@ class spell_pal_lay_on_hands : public SpellScriptLoader bool Validate(SpellInfo const* /*spell*/) override { - if (!sSpellMgr->GetSpellInfo(SPELL_PALADIN_FORBEARANCE)) - return false; - if (!sSpellMgr->GetSpellInfo(SPELL_PALADIN_AVENGING_WRATH_MARKER)) - return false; - if (!sSpellMgr->GetSpellInfo(SPELL_PALADIN_IMMUNE_SHIELD_MARKER)) + if (!sSpellMgr->GetSpellInfo(SPELL_PALADIN_FORBEARANCE) || + !sSpellMgr->GetSpellInfo(SPELL_PALADIN_IMMUNE_SHIELD_MARKER)) return false; return true; } @@ -1093,8 +948,11 @@ class spell_pal_lay_on_hands : public SpellScriptLoader Unit* caster = GetCaster(); if (Unit* target = GetExplTargetUnit()) if (caster == target) - if (target->HasAura(SPELL_PALADIN_FORBEARANCE) || target->HasAura(SPELL_PALADIN_AVENGING_WRATH_MARKER) || target->HasAura(SPELL_PALADIN_IMMUNE_SHIELD_MARKER)) + if (target->HasAura(SPELL_PALADIN_FORBEARANCE) || + target->HasAura(SPELL_PALADIN_IMMUNE_SHIELD_MARKER)) + { return SPELL_FAILED_TARGET_AURASTATE; + } return SPELL_CAST_OK; } @@ -1105,7 +963,6 @@ class spell_pal_lay_on_hands : public SpellScriptLoader if (caster == GetHitUnit()) { caster->CastSpell(caster, SPELL_PALADIN_FORBEARANCE, true); - caster->CastSpell(caster, SPELL_PALADIN_AVENGING_WRATH_MARKER, true); caster->CastSpell(caster, SPELL_PALADIN_IMMUNE_SHIELD_MARKER, true); } } @@ -1187,47 +1044,105 @@ class spell_pal_righteous_defense : public SpellScriptLoader } }; -// 58597 - Sacred Shield +// 85285 - Sacred Shield class spell_pal_sacred_shield : public SpellScriptLoader { public: spell_pal_sacred_shield() : SpellScriptLoader("spell_pal_sacred_shield") { } - class spell_pal_sacred_shield_AuraScript : public AuraScript + class spell_pal_sacred_shield_SpellScript : public SpellScript { - PrepareAuraScript(spell_pal_sacred_shield_AuraScript); + PrepareSpellScript(spell_pal_sacred_shield_SpellScript); - void CalculateAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/) + SpellCastResult CheckCast() { - if (Unit* caster = GetCaster()) - { - // +75.00% from sp bonus - float bonus = CalculatePct(caster->SpellBaseHealingBonusDone(GetSpellInfo()->GetSchoolMask()), 75.0f); + Unit* caster = GetCaster(); + if (caster->GetTypeId() != TYPEID_PLAYER) + return SPELL_FAILED_DONT_REPORT; - // Divine Guardian is only applied at the spell healing bonus because it was already applied to the base value in CalculateSpellDamage - bonus = caster->ApplyEffectModifiers(GetSpellInfo(), aurEff->GetEffIndex(), bonus); - bonus *= caster->CalculateLevelPenalty(GetSpellInfo()); + if (!caster->HealthBelowPct(30)) + return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW; - amount += int32(bonus); + return SPELL_CAST_OK; + } - // Arena - Dampening - if (AuraEffect const* dampening = caster->GetAuraEffect(SPELL_GENERIC_ARENA_DAMPENING, EFFECT_0)) - AddPct(amount, dampening->GetAmount()); - // Battleground - Dampening - else if (AuraEffect const* dampening = caster->GetAuraEffect(SPELL_GENERIC_BATTLEGROUND_DAMPENING, EFFECT_0)) - AddPct(amount, dampening->GetAmount()); + void Register() override + { + OnCheckCast += SpellCheckCastFn(spell_pal_sacred_shield_SpellScript::CheckCast); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_pal_sacred_shield_SpellScript(); + } +}; + +// 85256 - Templar's Verdict +/// Updated 4.3.4 +class spell_pal_templar_s_verdict : public SpellScriptLoader +{ + public: + spell_pal_templar_s_verdict() : SpellScriptLoader("spell_pal_templar_s_verdict") { } + + class spell_pal_templar_s_verdict_SpellScript : public SpellScript + { + PrepareSpellScript(spell_pal_templar_s_verdict_SpellScript); + + bool Validate (SpellInfo const* /*spellEntry*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_PALADIN_DIVINE_PURPOSE_PROC)) + return false; + + return true; + } + + bool Load() override + { + if (GetCaster()->GetTypeId() != TYPEID_PLAYER) + return false; + + if (GetCaster()->ToPlayer()->getClass() != CLASS_PALADIN) + return false; + + return true; + } + + void ChangeDamage(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + int32 damage = GetHitDamage(); + + if (caster->HasAura(SPELL_PALADIN_DIVINE_PURPOSE_PROC)) + damage *= 7.5; // 7.5*30% = 225% + else + { + switch (caster->GetPower(POWER_HOLY_POWER)) + { + case 0: // 1 Holy Power + damage = damage; + break; + case 1: // 2 Holy Power + damage *= 3; // 3*30 = 90% + break; + case 2: // 3 Holy Power + damage *= 7.5; // 7.5*30% = 225% + break; + } } + + SetHitDamage(damage); } void Register() override { - DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_pal_sacred_shield_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB); + OnEffectHitTarget += SpellEffectFn(spell_pal_templar_s_verdict_SpellScript::ChangeDamage, EFFECT_0, SPELL_EFFECT_WEAPON_PERCENT_DAMAGE); } }; - AuraScript* GetAuraScript() const override + SpellScript* GetSpellScript() const override { - return new spell_pal_sacred_shield_AuraScript(); + return new spell_pal_templar_s_verdict_SpellScript(); } }; @@ -1277,38 +1192,32 @@ class spell_pal_seal_of_righteousness : public SpellScriptLoader } }; + void AddSC_paladin_spell_scripts() { - new spell_pal_ardent_defender(); + //new spell_pal_ardent_defender(); new spell_pal_aura_mastery(); new spell_pal_aura_mastery_immune(); new spell_pal_avenging_wrath(); + new spell_pal_beacon_of_light(); new spell_pal_blessing_of_faith(); - new spell_pal_blessing_of_sanctuary(); new spell_pal_divine_sacrifice(); new spell_pal_divine_storm(); new spell_pal_divine_storm_dummy(); new spell_pal_exorcism_and_holy_wrath_damage(); new spell_pal_eye_for_an_eye(); new spell_pal_glyph_of_holy_light(); - new spell_pal_guarded_by_the_light(); + new spell_pal_grand_crusader(); new spell_pal_hand_of_sacrifice(); - new spell_pal_hand_of_salvation(); new spell_pal_holy_shock(); - new spell_pal_improved_aura("spell_pal_improved_concentraction_aura", SPELL_PALADIN_IMPROVED_CONCENTRACTION_AURA); - new spell_pal_improved_aura("spell_pal_improved_devotion_aura", SPELL_PALADIN_IMPROVED_DEVOTION_AURA); - new spell_pal_improved_aura("spell_pal_sanctified_retribution", SPELL_PALADIN_SANCTIFIED_RETRIBUTION_AURA); - new spell_pal_improved_aura("spell_pal_swift_retribution", SPELL_PALADIN_SANCTIFIED_RETRIBUTION_AURA); new spell_pal_improved_aura_effect("spell_pal_improved_concentraction_aura_effect"); new spell_pal_improved_aura_effect("spell_pal_improved_devotion_aura_effect"); new spell_pal_improved_aura_effect("spell_pal_sanctified_retribution_effect"); new spell_pal_item_healing_discount(); - new spell_pal_judgement("spell_pal_judgement_of_justice", SPELL_PALADIN_JUDGEMENT_OF_JUSTICE); - new spell_pal_judgement("spell_pal_judgement_of_light", SPELL_PALADIN_JUDGEMENT_OF_LIGHT); - new spell_pal_judgement("spell_pal_judgement_of_wisdom", SPELL_PALADIN_JUDGEMENT_OF_WISDOM); - new spell_pal_judgement_of_command(); + new spell_pal_judgement(); new spell_pal_lay_on_hands(); new spell_pal_righteous_defense(); new spell_pal_sacred_shield(); + new spell_pal_templar_s_verdict(); new spell_pal_seal_of_righteousness(); } diff --git a/src/server/scripts/Spells/spell_pet.cpp b/src/server/scripts/Spells/spell_pet.cpp index 775f9f505f9..f8466eb1f74 100644 --- a/src/server/scripts/Spells/spell_pet.cpp +++ b/src/server/scripts/Spells/spell_pet.cpp @@ -536,7 +536,6 @@ public: } }; - class spell_warl_pet_scaling_04 : public SpellScriptLoader { public: @@ -813,7 +812,6 @@ public: } }; - class spell_sha_pet_scaling_04 : public SpellScriptLoader { public: @@ -1347,24 +1345,6 @@ public: return; if (GetCaster()->GetOwner()->ToPlayer()) { - // Pet's base damage changes depending on happiness - if (GetCaster()->IsPet() && GetCaster()->ToPet()->IsHunterPet()) - { - switch (GetCaster()->ToPet()->GetHappinessState()) - { - case HAPPY: - // 125% of normal damage - amount += 25.0f; - break; - case CONTENT: - // 100% of normal damage, nothing to modify - break; - case UNHAPPY: - // 75% of normal damage - amount += -25.0f; - break; - } - } // Cobra Reflexes if (AuraEffect* cobraReflexes = GetCaster()->GetAuraEffectOfRankedSpell(61682, EFFECT_0)) amount -= cobraReflexes->GetAmount(); @@ -1424,7 +1404,6 @@ public: } }; - class spell_dk_avoidance_passive : public SpellScriptLoader { public: diff --git a/src/server/scripts/Spells/spell_priest.cpp b/src/server/scripts/Spells/spell_priest.cpp index dea67b5222d..d804c0cfc8b 100644 --- a/src/server/scripts/Spells/spell_priest.cpp +++ b/src/server/scripts/Spells/spell_priest.cpp @@ -29,29 +29,51 @@ enum PriestSpells { + SPELL_PRIEST_ABSOLUTION = 33167, + SPELL_PRIEST_BODY_AND_SOUL_DISPEL = 64136, + SPELL_PRIEST_BODY_AND_SOUL_SPEED = 65081, + SPELL_PRIEST_CURE_DISEASE = 528, + SPELL_PRIEST_DISPEL_MAGIC_FRIENDLY = 97690, + SPELL_PRIEST_DISPEL_MAGIC_HOSTILE = 97691, SPELL_PRIEST_DIVINE_AEGIS = 47753, - SPELL_PRIEST_EMPOWERED_RENEW = 63544, + SPELL_PRIEST_DIVINE_TOUCH = 63544, SPELL_PRIEST_GLYPH_OF_CIRCLE_OF_HEALING = 55675, + SPELL_PRIEST_GLYPH_OF_DISPEL_MAGIC = 55677, + SPELL_PRIEST_GLYPH_OF_DISPEL_MAGIC_HEAL = 56131, SPELL_PRIEST_GLYPH_OF_LIGHTWELL = 55673, SPELL_PRIEST_GLYPH_OF_PRAYER_OF_HEALING_HEAL = 56161, + SPELL_PRIEST_GLYPH_OF_SHADOW = 107906, SPELL_PRIEST_GUARDIAN_SPIRIT_HEAL = 48153, SPELL_PRIEST_ITEM_EFFICIENCY = 37595, + SPELL_PRIEST_LEAP_OF_FAITH = 73325, + SPELL_PRIEST_LEAP_OF_FAITH_EFFECT = 92832, + SPELL_PRIEST_LEAP_OF_FAITH_EFFECT_TRIGGER = 92833, + SPELL_PRIEST_LEAP_OF_FAITH_TRIGGERED = 92572, SPELL_PRIEST_MANA_LEECH_PROC = 34650, SPELL_PRIEST_PENANCE_R1 = 47540, SPELL_PRIEST_PENANCE_R1_DAMAGE = 47758, SPELL_PRIEST_PENANCE_R1_HEAL = 47757, - SPELL_PRIEST_REFLECTIVE_SHIELD_TRIGGERED = 33619, SPELL_PRIEST_REFLECTIVE_SHIELD_R1 = 33201, + SPELL_PRIEST_REFLECTIVE_SHIELD_TRIGGERED = 33619, + SPELL_PRIEST_SHADOWFORM_VISUAL_WITHOUT_GLYPH = 107903, + SPELL_PRIEST_SHADOWFORM_VISUAL_WITH_GLYPH = 107904, SPELL_PRIEST_SHADOW_WORD_DEATH = 32409, + SPELL_PRIEST_TWIN_DISCIPLINES_RANK_1 = 47586, SPELL_PRIEST_T9_HEALING_2P = 67201, - SPELL_PRIEST_VAMPIRIC_TOUCH_DISPEL = 64085, + SPELL_PRIEST_VAMPIRIC_EMBRACE_HEAL = 15290, + SPELL_PRIEST_VAMPIRIC_TOUCH_DISPEL = 64085 }; enum PriestSpellIcons { PRIEST_ICON_ID_BORROWED_TIME = 2899, - PRIEST_ICON_ID_EMPOWERED_RENEW_TALENT = 3021, - PRIEST_ICON_ID_PAIN_AND_SUFFERING = 2874, + PRIEST_ICON_ID_DIVINE_TOUCH_TALENT = 3021, + PRIEST_ICON_ID_PAIN_AND_SUFFERING = 2874 +}; + +enum MiscSpells +{ + SPELL_GEN_REPLENISHMENT = 57669 }; class PowerCheck @@ -88,7 +110,58 @@ class RaidCheck Unit const* _caster; }; -// -34861 - Circle of Healing +class spell_pri_body_and_soul : public SpellScriptLoader +{ + public: + spell_pri_body_and_soul() : SpellScriptLoader("spell_pri_body_and_soul") { } + + class spell_pri_body_and_soul_AuraScript : public AuraScript + { + PrepareAuraScript(spell_pri_body_and_soul_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_CURE_DISEASE) || + !sSpellMgr->GetSpellInfo(SPELL_PRIEST_BODY_AND_SOUL_DISPEL)) + return false; + return true; + } + + void HandleEffectSpeedProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + // Proc only with Power Word: Shield or Leap of Faith + if (!(eventInfo.GetDamageInfo()->GetSpellInfo()->SpellFamilyFlags[0] & 0x1 || eventInfo.GetDamageInfo()->GetSpellInfo()->SpellFamilyFlags[2] & 0x80000)) + return; + + GetTarget()->CastCustomSpell(SPELL_PRIEST_BODY_AND_SOUL_SPEED, SPELLVALUE_BASE_POINT0, aurEff->GetAmount(), eventInfo.GetProcTarget(), true, NULL, aurEff); + } + + void HandleEffectDispelProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + // Proc only with Cure Disease + if (eventInfo.GetDamageInfo()->GetSpellInfo()->Id != SPELL_PRIEST_CURE_DISEASE || eventInfo.GetProcTarget() != GetTarget()) + return; + + if (roll_chance_i(aurEff->GetAmount())) + GetTarget()->CastSpell(eventInfo.GetProcTarget(), SPELL_PRIEST_BODY_AND_SOUL_DISPEL, true, NULL, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_pri_body_and_soul_AuraScript::HandleEffectSpeedProc, EFFECT_0, SPELL_AURA_DUMMY); + OnEffectProc += AuraEffectProcFn(spell_pri_body_and_soul_AuraScript::HandleEffectDispelProc, EFFECT_1, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_pri_body_and_soul_AuraScript(); + } +}; + +// 34861 - Circle of Healing class spell_pri_circle_of_healing : public SpellScriptLoader { public: @@ -130,6 +203,65 @@ class spell_pri_circle_of_healing : public SpellScriptLoader } }; +// 527 - Dispel magic +class spell_pri_dispel_magic : public SpellScriptLoader +{ +public: + spell_pri_dispel_magic() : SpellScriptLoader("spell_pri_dispel_magic") { } + + class spell_pri_dispel_magic_SpellScript : public SpellScript + { + PrepareSpellScript(spell_pri_dispel_magic_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_ABSOLUTION)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_GLYPH_OF_DISPEL_MAGIC_HEAL)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_GLYPH_OF_DISPEL_MAGIC)) + return false; + return true; + } + + SpellCastResult CheckCast() + { + Unit* caster = GetCaster(); + Unit* target = GetExplTargetUnit(); + + if (!target || (!caster->HasAura(SPELL_PRIEST_ABSOLUTION) && caster != target && target->IsFriendlyTo(caster))) + return SPELL_FAILED_BAD_TARGETS; + return SPELL_CAST_OK; + } + + void AfterEffectHit(SpellEffIndex /*effIndex*/) + { + if (GetHitUnit()->IsFriendlyTo(GetCaster())) + { + GetCaster()->CastSpell(GetHitUnit(), SPELL_PRIEST_DISPEL_MAGIC_FRIENDLY, true); + if (AuraEffect const* aurEff = GetHitUnit()->GetAuraEffect(SPELL_PRIEST_GLYPH_OF_DISPEL_MAGIC, EFFECT_0)) + { + int32 heal = GetHitUnit()->CountPctFromMaxHealth(aurEff->GetAmount()); + GetCaster()->CastCustomSpell(SPELL_PRIEST_GLYPH_OF_DISPEL_MAGIC_HEAL, SPELLVALUE_BASE_POINT0, heal, GetHitUnit()); + } + } + else + GetCaster()->CastSpell(GetHitUnit(), SPELL_PRIEST_DISPEL_MAGIC_HOSTILE, true); + } + + void Register() + { + OnCheckCast += SpellCheckCastFn(spell_pri_dispel_magic_SpellScript::CheckCast); + OnEffectHitTarget += SpellEffectFn(spell_pri_dispel_magic_SpellScript::AfterEffectHit, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_pri_dispel_magic_SpellScript(); + } +}; + // -47509 - Divine Aegis class spell_pri_divine_aegis : public SpellScriptLoader { @@ -253,6 +385,76 @@ class spell_pri_glyph_of_prayer_of_healing : public SpellScriptLoader } }; +class spell_pri_improved_power_word_shield : public SpellScriptLoader +{ + public: + spell_pri_improved_power_word_shield() : SpellScriptLoader("spell_pri_improved_power_word_shield") { } + + class spell_pri_improved_power_word_shield_AuraScript : public AuraScript + { + PrepareAuraScript(spell_pri_improved_power_word_shield_AuraScript); + + void HandleEffectCalcSpellMod(AuraEffect const* aurEff, SpellModifier*& spellMod) + { + if (!spellMod) + { + spellMod = new SpellModifier(GetAura()); + spellMod->op = SpellModOp(aurEff->GetMiscValue()); + spellMod->type = SPELLMOD_PCT; + spellMod->spellId = GetId(); + spellMod->mask = GetSpellInfo()->Effects[aurEff->GetEffIndex()].SpellClassMask; + } + + spellMod->value = aurEff->GetAmount(); + } + + void Register() override + { + DoEffectCalcSpellMod += AuraEffectCalcSpellModFn(spell_pri_improved_power_word_shield_AuraScript::HandleEffectCalcSpellMod, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_pri_improved_power_word_shield_AuraScript(); + } +}; + +// 37594 - Greater Heal Refund +class spell_pri_item_greater_heal_refund : public SpellScriptLoader +{ + public: + spell_pri_item_greater_heal_refund() : SpellScriptLoader("spell_pri_item_greater_heal_refund") { } + + class spell_pri_item_greater_heal_refund_AuraScript : public AuraScript + { + PrepareAuraScript(spell_pri_item_greater_heal_refund_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_ITEM_EFFICIENCY)) + return false; + return true; + } + + void OnProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + GetTarget()->CastSpell(GetTarget(), SPELL_PRIEST_ITEM_EFFICIENCY, true, NULL, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_pri_item_greater_heal_refund_AuraScript::OnProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_pri_item_greater_heal_refund_AuraScript(); + } +}; + // 47788 - Guardian Spirit class spell_pri_guardian_spirit : public SpellScriptLoader { @@ -346,42 +548,46 @@ class spell_pri_hymn_of_hope : public SpellScriptLoader } }; -// 37594 - Greater Heal Refund -class spell_pri_item_greater_heal_refund : public SpellScriptLoader +// 92833 - Leap of Faith +class spell_pri_leap_of_faith_effect_trigger : public SpellScriptLoader { public: - spell_pri_item_greater_heal_refund() : SpellScriptLoader("spell_pri_item_greater_heal_refund") { } + spell_pri_leap_of_faith_effect_trigger() : SpellScriptLoader("spell_pri_leap_of_faith_effect_trigger") { } - class spell_pri_item_greater_heal_refund_AuraScript : public AuraScript + class spell_pri_leap_of_faith_effect_trigger_SpellScript : public SpellScript { - PrepareAuraScript(spell_pri_item_greater_heal_refund_AuraScript); + PrepareSpellScript(spell_pri_leap_of_faith_effect_trigger_SpellScript); bool Validate(SpellInfo const* /*spellInfo*/) override { - if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_ITEM_EFFICIENCY)) + if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_LEAP_OF_FAITH_EFFECT)) return false; return true; } - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + void HandleEffectDummy(SpellEffIndex /*effIndex*/) { - PreventDefaultAction(); - GetTarget()->CastSpell(GetTarget(), SPELL_PRIEST_ITEM_EFFICIENCY, true, NULL, aurEff); + Position destPos = GetHitDest()->GetPosition(); + + SpellCastTargets targets; + targets.SetDst(destPos); + targets.SetUnitTarget(GetCaster()); + GetHitUnit()->CastSpell(targets, sSpellMgr->GetSpellInfo(GetEffectValue()), NULL); } void Register() override { - OnEffectProc += AuraEffectProcFn(spell_pri_item_greater_heal_refund_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + OnEffectHitTarget += SpellEffectFn(spell_pri_leap_of_faith_effect_trigger_SpellScript::HandleEffectDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; - AuraScript* GetAuraScript() const override + SpellScript* GetSpellScript() const override { - return new spell_pri_item_greater_heal_refund_AuraScript(); + return new spell_pri_leap_of_faith_effect_trigger_SpellScript(); } }; -// -7001 - Lightwell Renew +// 7001 - Lightwell Renew class spell_pri_lightwell_renew : public SpellScriptLoader { public: @@ -492,7 +698,7 @@ class spell_pri_mana_leech : public SpellScriptLoader } }; -// -49821 - Mind Sear +// 49821 - Mind Sear class spell_pri_mind_sear : public SpellScriptLoader { public: @@ -549,7 +755,7 @@ class spell_pri_pain_and_suffering_proc : public SpellScriptLoader } }; -// -47540 - Penance +// 47540 - Penance class spell_pri_penance : public SpellScriptLoader { public: @@ -622,7 +828,41 @@ class spell_pri_penance : public SpellScriptLoader } }; -// -17 - Power Word: Shield +// -47569 - Phantasm +class spell_pri_phantasm : public SpellScriptLoader +{ + public: + spell_pri_phantasm() : SpellScriptLoader("spell_pri_phantasm") { } + + class spell_pri_phantasm_AuraScript : public AuraScript + { + PrepareAuraScript(spell_pri_phantasm_AuraScript); + + bool CheckProc(ProcEventInfo& /*eventInfo*/) + { + return roll_chance_i(GetEffect(EFFECT_0)->GetAmount()); + } + + void HandleEffectProc(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + GetTarget()->RemoveMovementImpairingAuras(); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_pri_phantasm_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_pri_phantasm_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_pri_phantasm_AuraScript(); + } +}; + +// 17 - Power Word: Shield class spell_pri_power_word_shield : public SpellScriptLoader { public: @@ -646,8 +886,8 @@ class spell_pri_power_word_shield : public SpellScriptLoader canBeRecalculated = false; if (Unit* caster = GetCaster()) { - // +80.68% from sp bonus - float bonus = 0.8068f; + // +87% from sp bonus + float bonus = 0.87f; // Borrowed Time if (AuraEffect const* borrowedTime = caster->GetDummyAuraEffect(SPELLFAMILY_PRIEST, PRIEST_ICON_ID_BORROWED_TIME, EFFECT_1)) @@ -663,7 +903,7 @@ class spell_pri_power_word_shield : public SpellScriptLoader amount += int32(bonus); // Twin Disciplines - if (AuraEffect const* twinDisciplines = caster->GetAuraEffect(SPELL_AURA_ADD_PCT_MODIFIER, SPELLFAMILY_PRIEST, 0x400000, 0, 0, GetCasterGUID())) + if (AuraEffect const* twinDisciplines = caster->GetAuraEffectOfRankedSpell(SPELL_PRIEST_TWIN_DISCIPLINES_RANK_1, EFFECT_1)) AddPct(amount, twinDisciplines->GetAmount()); // Focused Power @@ -677,7 +917,7 @@ class spell_pri_power_word_shield : public SpellScriptLoader if (dmgInfo.GetAttacker() == target) return; - if (AuraEffect* talentAurEff = target->GetAuraEffectOfRankedSpell(SPELL_PRIEST_REFLECTIVE_SHIELD_R1, EFFECT_0)) + if (AuraEffect const* talentAurEff = target->GetAuraEffectOfRankedSpell(SPELL_PRIEST_REFLECTIVE_SHIELD_R1, EFFECT_0)) { int32 bp = CalculatePct(absorbAmount, talentAurEff->GetAmount()); target->CastCustomSpell(dmgInfo.GetAttacker(), SPELL_PRIEST_REFLECTIVE_SHIELD_TRIGGERED, &bp, NULL, NULL, true, NULL, aurEff); @@ -732,7 +972,7 @@ class spell_pri_prayer_of_mending_heal : public SpellScriptLoader } }; -// -139 - Renew +// 139 - Renew class spell_pri_renew : public SpellScriptLoader { public: @@ -742,6 +982,13 @@ class spell_pri_renew : public SpellScriptLoader { PrepareAuraScript(spell_pri_renew_AuraScript); + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_DIVINE_TOUCH)) + return false; + return true; + } + bool Load() override { return GetCaster() && GetCaster()->GetTypeId() == TYPEID_PLAYER; @@ -751,14 +998,13 @@ class spell_pri_renew : public SpellScriptLoader { if (Unit* caster = GetCaster()) { - // Empowered Renew - if (AuraEffect const* empoweredRenewAurEff = caster->GetDummyAuraEffect(SPELLFAMILY_PRIEST, PRIEST_ICON_ID_EMPOWERED_RENEW_TALENT, EFFECT_1)) + // Divine Touch + if (AuraEffect const* empoweredRenewAurEff = caster->GetDummyAuraEffect(SPELLFAMILY_PRIEST, PRIEST_ICON_ID_DIVINE_TOUCH_TALENT, EFFECT_0)) { - uint32 heal = caster->SpellHealingBonusDone(GetTarget(), GetSpellInfo(), GetEffect(EFFECT_0)->GetAmount(), DOT); + uint32 heal = caster->SpellHealingBonusDone(GetTarget(), GetSpellInfo(), aurEff->GetAmount(), DOT); heal = GetTarget()->SpellHealingBonusTaken(caster, GetSpellInfo(), heal, DOT); - - int32 basepoints0 = empoweredRenewAurEff->GetAmount() * GetEffect(EFFECT_0)->GetTotalTicks() * int32(heal) / 100; - caster->CastCustomSpell(GetTarget(), SPELL_PRIEST_EMPOWERED_RENEW, &basepoints0, NULL, NULL, true, NULL, aurEff); + int32 basepoints0 = CalculatePct(int32(heal) * aurEff->GetTotalTicks(), empoweredRenewAurEff->GetAmount()); + caster->CastCustomSpell(GetTarget(), SPELL_PRIEST_DIVINE_TOUCH, &basepoints0, NULL, NULL, true, NULL, aurEff); } } } @@ -775,7 +1021,7 @@ class spell_pri_renew : public SpellScriptLoader } }; -// -32379 - Shadow Word Death +// 32379 - Shadow Word Death class spell_pri_shadow_word_death : public SpellScriptLoader { public: @@ -808,7 +1054,120 @@ class spell_pri_shadow_word_death : public SpellScriptLoader } }; -// -34914 - Vampiric Touch +// 15473 - Shadowform +class spell_pri_shadowform : public SpellScriptLoader +{ + public: + spell_pri_shadowform() : SpellScriptLoader("spell_pri_shadowform") { } + + class spell_pri_shadowform_AuraScript : public AuraScript + { + PrepareAuraScript(spell_pri_shadowform_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_SHADOWFORM_VISUAL_WITHOUT_GLYPH) || + !sSpellMgr->GetSpellInfo(SPELL_PRIEST_SHADOWFORM_VISUAL_WITH_GLYPH)) + return false; + return true; + } + + void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->CastSpell(GetTarget(), GetTarget()->HasAura(SPELL_PRIEST_GLYPH_OF_SHADOW) ? SPELL_PRIEST_SHADOWFORM_VISUAL_WITH_GLYPH : SPELL_PRIEST_SHADOWFORM_VISUAL_WITHOUT_GLYPH, true); + } + + void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->RemoveAurasDueToSpell(GetTarget()->HasAura(SPELL_PRIEST_GLYPH_OF_SHADOW) ? SPELL_PRIEST_SHADOWFORM_VISUAL_WITH_GLYPH : SPELL_PRIEST_SHADOWFORM_VISUAL_WITHOUT_GLYPH); + } + + void Register() override + { + AfterEffectApply += AuraEffectApplyFn(spell_pri_shadowform_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_MOD_SHAPESHIFT, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); + AfterEffectRemove += AuraEffectRemoveFn(spell_pri_shadowform_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_MOD_SHAPESHIFT, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_pri_shadowform_AuraScript(); + } +}; + +// 15286 - Vampiric Embrace +class spell_pri_vampiric_embrace : public SpellScriptLoader +{ + public: + spell_pri_vampiric_embrace() : SpellScriptLoader("spell_pri_vampiric_embrace") { } + + class spell_pri_vampiric_embrace_AuraScript : public AuraScript + { + PrepareAuraScript(spell_pri_vampiric_embrace_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_VAMPIRIC_EMBRACE_HEAL)) + return false; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + // Not proc from Mind Sear + return !(eventInfo.GetDamageInfo()->GetSpellInfo()->SpellFamilyFlags[1] & 0x80000); + } + + void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + int32 self = int32(CalculatePct(eventInfo.GetDamageInfo()->GetDamage(), aurEff->GetAmount())); + int32 team = int32(CalculatePct(eventInfo.GetDamageInfo()->GetDamage(), aurEff->GetAmount() / 2)); + + GetTarget()->CastCustomSpell((Unit*)NULL, SPELL_PRIEST_VAMPIRIC_EMBRACE_HEAL, &team, &self, NULL, true, NULL, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_pri_vampiric_embrace_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_pri_vampiric_embrace_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_pri_vampiric_embrace_AuraScript(); + } +}; + +// 15290 - Vampiric Embrace (heal) +class spell_pri_vampiric_embrace_target : public SpellScriptLoader +{ + public: + spell_pri_vampiric_embrace_target() : SpellScriptLoader("spell_pri_vampiric_embrace_target") { } + + class spell_pri_vampiric_embrace_target_SpellScript : public SpellScript + { + PrepareSpellScript(spell_pri_vampiric_embrace_target_SpellScript); + + void FilterTargets(std::list<WorldObject*>& unitList) + { + unitList.remove(GetCaster()); + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_pri_vampiric_embrace_target_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_PARTY); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_pri_vampiric_embrace_target_SpellScript(); + } +}; + +// 34914 - Vampiric Touch class spell_pri_vampiric_touch : public SpellScriptLoader { public: @@ -820,7 +1179,8 @@ class spell_pri_vampiric_touch : public SpellScriptLoader bool Validate(SpellInfo const* /*spellInfo*/) override { - if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_VAMPIRIC_TOUCH_DISPEL)) + if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_VAMPIRIC_TOUCH_DISPEL) || + !sSpellMgr->GetSpellInfo(SPELL_GEN_REPLENISHMENT)) return false; return true; } @@ -837,9 +1197,21 @@ class spell_pri_vampiric_touch : public SpellScriptLoader } } + bool CheckProc(ProcEventInfo& eventInfo) + { + return eventInfo.GetProcTarget() == GetCaster(); + } + + void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + eventInfo.GetProcTarget()->CastSpell((Unit*)NULL, SPELL_GEN_REPLENISHMENT, true, NULL, aurEff); + } + void Register() override { AfterDispel += AuraDispelFn(spell_pri_vampiric_touch_AuraScript::HandleDispel); + DoCheckProc += AuraCheckProcFn(spell_pri_vampiric_touch_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_pri_vampiric_touch_AuraScript::HandleEffectProc, EFFECT_2, SPELL_AURA_DUMMY); } }; @@ -851,22 +1223,30 @@ class spell_pri_vampiric_touch : public SpellScriptLoader void AddSC_priest_spell_scripts() { + new spell_pri_body_and_soul(); new spell_pri_circle_of_healing(); + new spell_pri_dispel_magic(); new spell_pri_divine_aegis(); new spell_pri_divine_hymn(); new spell_pri_glyph_of_prayer_of_healing(); - new spell_pri_guardian_spirit(); new spell_pri_hymn_of_hope(); + new spell_pri_improved_power_word_shield(); new spell_pri_item_greater_heal_refund(); + new spell_pri_guardian_spirit(); + new spell_pri_leap_of_faith_effect_trigger(); new spell_pri_lightwell_renew(); new spell_pri_mana_burn(); new spell_pri_mana_leech(); new spell_pri_mind_sear(); new spell_pri_pain_and_suffering_proc(); new spell_pri_penance(); + new spell_pri_phantasm(); new spell_pri_power_word_shield(); new spell_pri_prayer_of_mending_heal(); new spell_pri_renew(); new spell_pri_shadow_word_death(); + new spell_pri_shadowform(); + new spell_pri_vampiric_embrace(); + new spell_pri_vampiric_embrace_target(); new spell_pri_vampiric_touch(); } diff --git a/src/server/scripts/Spells/spell_rogue.cpp b/src/server/scripts/Spells/spell_rogue.cpp index bf413aef6a3..98fe019bcc6 100644 --- a/src/server/scripts/Spells/spell_rogue.cpp +++ b/src/server/scripts/Spells/spell_rogue.cpp @@ -29,17 +29,31 @@ enum RogueSpells { - SPELL_ROGUE_BLADE_FLURRY_EXTRA_ATTACK = 22482, - SPELL_ROGUE_CHEAT_DEATH_COOLDOWN = 31231, - SPELL_ROGUE_GLYPH_OF_PREPARATION = 56819, - SPELL_ROGUE_KILLING_SPREE = 51690, - SPELL_ROGUE_KILLING_SPREE_TELEPORT = 57840, - SPELL_ROGUE_KILLING_SPREE_WEAPON_DMG = 57841, - SPELL_ROGUE_KILLING_SPREE_DMG_BUFF = 61851, - SPELL_ROGUE_PREY_ON_THE_WEAK = 58670, - SPELL_ROGUE_SHIV_TRIGGERED = 5940, - SPELL_ROGUE_TRICKS_OF_THE_TRADE_DMG_BOOST = 57933, - SPELL_ROGUE_TRICKS_OF_THE_TRADE_PROC = 59628, + SPELL_ROGUE_BLADE_FLURRY = 13877, + SPELL_ROGUE_BLADE_FLURRY_EXTRA_ATTACK = 22482, + SPELL_ROGUE_CHEAT_DEATH_COOLDOWN = 31231, + SPELL_ROGUE_CRIPPLING_POISON = 3409, + SPELL_ROGUE_GLYPH_OF_PREPARATION = 56819, + SPELL_ROGUE_KILLING_SPREE = 51690, + SPELL_ROGUE_KILLING_SPREE_TELEPORT = 57840, + SPELL_ROGUE_KILLING_SPREE_WEAPON_DMG = 57841, + SPELL_ROGUE_KILLING_SPREE_DMG_BUFF = 61851, + SPELL_ROGUE_MASTER_OF_SUBTLETY_DAMAGE_PERCENT = 31665, + SPELL_ROGUE_MASTER_OF_SUBTLETY_PASSIVE = 31223, + SPELL_ROGUE_MASTER_OF_SUBTLETY_PERIODIC = 31666, + SPELL_ROGUE_OVERKILL_TALENT = 58426, + SPELL_ROGUE_OVERKILL_PERIODIC = 58428, + SPELL_ROGUE_OVERKILL_POWER_REGEN = 58427, + SPELL_ROGUE_PREY_ON_THE_WEAK = 58670, + SPELL_ROGUE_SHIV_TRIGGERED = 5940, + SPELL_ROGUE_SILCE_AND_DICE = 5171, + SPELL_ROGUE_TRICKS_OF_THE_TRADE_DMG_BOOST = 57933, + SPELL_ROGUE_TRICKS_OF_THE_TRADE_PROC = 59628 +}; + +enum RogueSpellIcons +{ + ICON_ROGUE_IMPROVED_RECUPERATE = 4819 }; // 13877, 33735, (check 51211, 65956) - Blade Flurry @@ -67,24 +81,27 @@ class spell_rog_blade_flurry : public SpellScriptLoader bool CheckProc(ProcEventInfo& eventInfo) { - _procTarget = eventInfo.GetActor()->SelectNearbyTarget(eventInfo.GetProcTarget()); - return _procTarget; + _procTarget = GetTarget()->SelectNearbyTarget(eventInfo.GetProcTarget()); + return _procTarget && eventInfo.GetDamageInfo(); } void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) { PreventDefaultAction(); - if (eventInfo.GetDamageInfo()) - { - int32 damage = eventInfo.GetDamageInfo()->GetDamage(); - GetTarget()->CastCustomSpell(SPELL_ROGUE_BLADE_FLURRY_EXTRA_ATTACK, SPELLVALUE_BASE_POINT0, damage, _procTarget, true, NULL, aurEff); - } + + TC_LOG_ERROR("misc", "damage: %u procSpell: %u", + eventInfo.GetDamageInfo()->GetDamage(), eventInfo.GetDamageInfo()->GetSpellInfo() ? eventInfo.GetDamageInfo()->GetSpellInfo()->Id : 0); + + GetTarget()->CastCustomSpell(SPELL_ROGUE_BLADE_FLURRY_EXTRA_ATTACK, SPELLVALUE_BASE_POINT0, eventInfo.GetDamageInfo()->GetDamage(), _procTarget, true, NULL, aurEff); } void Register() override { DoCheckProc += AuraCheckProcFn(spell_rog_blade_flurry_AuraScript::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_rog_blade_flurry_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_MOD_MELEE_HASTE); + if (m_scriptSpellId == SPELL_ROGUE_BLADE_FLURRY) + OnEffectProc += AuraEffectProcFn(spell_rog_blade_flurry_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_MOD_POWER_REGEN_PERCENT); + else + OnEffectProc += AuraEffectProcFn(spell_rog_blade_flurry_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_MOD_MELEE_HASTE); } private: @@ -97,7 +114,7 @@ class spell_rog_blade_flurry : public SpellScriptLoader } }; -// -31228 - Cheat Death +// 31228 - Cheat Death class spell_rog_cheat_death : public SpellScriptLoader { public: @@ -160,7 +177,71 @@ class spell_rog_cheat_death : public SpellScriptLoader } }; -// -2818 - Deadly Poison +// -51625 - Deadly Brew +class spell_rog_crippling_poison : public SpellScriptLoader +{ + public: + spell_rog_crippling_poison() : SpellScriptLoader("spell_rog_crippling_poison") { } + + class spell_rog_crippling_poison_AuraScript : public AuraScript + { + PrepareAuraScript(spell_rog_crippling_poison_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_ROGUE_CRIPPLING_POISON)) + return false; + return true; + } + + void OnProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + GetTarget()->CastSpell(eventInfo.GetProcTarget(), SPELL_ROGUE_CRIPPLING_POISON, true, NULL, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_rog_crippling_poison_AuraScript::OnProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_rog_crippling_poison_AuraScript(); + } +}; + +// -51664 - Cut to the Chase +class spell_rog_cut_to_the_chase : public SpellScriptLoader +{ + public: + spell_rog_cut_to_the_chase () : SpellScriptLoader("spell_rog_cut_to_the_chase") { } + + class spell_rog_cut_to_the_chase_AuraScript : public AuraScript + { + PrepareAuraScript(spell_rog_cut_to_the_chase_AuraScript); + + void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + if (Aura* aur = GetTarget()->GetAura(SPELL_ROGUE_SILCE_AND_DICE)) + aur->SetDuration(aur->GetSpellInfo()->GetMaxDuration(), true); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_rog_cut_to_the_chase_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_rog_cut_to_the_chase_AuraScript(); + } +}; + +// 2818 - Deadly Poison class spell_rog_deadly_poison : public SpellScriptLoader { public: @@ -206,6 +287,9 @@ class spell_rog_deadly_poison : public SpellScriptLoader // item combat enchantments for (uint8 slot = 0; slot < MAX_ENCHANTMENT_SLOT; ++slot) { + if (slot > PRISMATIC_ENCHANTMENT_SLOT && slot < PROP_ENCHANTMENT_SLOT_0) // not holding enchantment id + continue; + SpellItemEnchantmentEntry const* enchant = sSpellItemEnchantmentStore.LookupEntry(item->GetEnchantmentId(EnchantmentSlot(slot))); if (!enchant) continue; @@ -354,7 +438,44 @@ class spell_rog_killing_spree : public SpellScriptLoader } }; -// -31130 - Nerves of Steel +// 31666 - Master of Subtlety +class spell_rog_master_of_subtlety : public SpellScriptLoader +{ + public: + spell_rog_master_of_subtlety() : SpellScriptLoader("spell_rog_master_of_subtlety") { } + + class spell_rog_master_of_subtlety_AuraScript : public AuraScript + { + PrepareAuraScript(spell_rog_master_of_subtlety_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_ROGUE_MASTER_OF_SUBTLETY_DAMAGE_PERCENT)) + return false; + return true; + } + + void HandleEffectPeriodic(AuraEffect const* /*aurEff*/) + { + Unit* target = GetTarget(); + + if (!target->HasAuraType(SPELL_AURA_MOD_STEALTH)) + target->RemoveAurasDueToSpell(SPELL_ROGUE_MASTER_OF_SUBTLETY_DAMAGE_PERCENT); + } + + void Register() + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_rog_master_of_subtlety_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_rog_master_of_subtlety_AuraScript(); + } +}; + +// 31130 - Nerves of Steel class spell_rog_nerves_of_steel : public SpellScriptLoader { public: @@ -398,6 +519,43 @@ class spell_rog_nerves_of_steel : public SpellScriptLoader } }; +// 58428 - Overkill +class spell_rog_overkill : public SpellScriptLoader +{ + public: + spell_rog_overkill() : SpellScriptLoader("spell_rog_overkill") { } + + class spell_rog_overkill_AuraScript : public AuraScript + { + PrepareAuraScript(spell_rog_overkill_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_ROGUE_OVERKILL_POWER_REGEN)) + return false; + return true; + } + + void HandleEffectPeriodic(AuraEffect const* /*aurEff*/) + { + Unit* target = GetTarget(); + + if (!target->HasAuraType(SPELL_AURA_MOD_STEALTH)) + target->RemoveAurasDueToSpell(SPELL_ROGUE_OVERKILL_POWER_REGEN); + } + + void Register() + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_rog_overkill_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_rog_overkill_AuraScript(); + } +}; + // 14185 - Preparation class spell_rog_preparation : public SpellScriptLoader { @@ -424,29 +582,25 @@ class spell_rog_preparation : public SpellScriptLoader { Player* caster = GetCaster()->ToPlayer(); - //immediately finishes the cooldown on certain Rogue abilities - const SpellCooldowns& cm = caster->GetSpellCooldownMap(); + // immediately finishes the cooldown on certain Rogue abilities + SpellCooldowns const& cm = caster->GetSpellCooldownMap(); for (SpellCooldowns::const_iterator itr = cm.begin(); itr != cm.end();) { SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(itr->first); + if (spellInfo->SpellFamilyName != SPELLFAMILY_ROGUE) + { + ++itr; + continue; + } - if (spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE) + if ((spellInfo->SpellFamilyFlags[1] & SPELLFAMILYFLAG1_ROGUE_SHADOWSTEP || // Shadowstep + spellInfo->SpellFamilyFlags[0] & SPELLFAMILYFLAG0_ROGUE_VAN_SPRINT) || // Vanish, Sprint + // Glyph of Preparation + (caster->HasAura(SPELL_ROGUE_GLYPH_OF_PREPARATION) && + (spellInfo->SpellFamilyFlags[1] & SPELLFAMILYFLAG1_ROGUE_DISMANTLE_SMOKE_BOMB || // Dismantle, Smoke Bomb + spellInfo->SpellFamilyFlags[0] & SPELLFAMILYFLAG0_ROGUE_KICK))) // Kick { - if (spellInfo->SpellFamilyFlags[1] & SPELLFAMILYFLAG1_ROGUE_COLDB_SHADOWSTEP || // Cold Blood, Shadowstep - spellInfo->SpellFamilyFlags[0] & SPELLFAMILYFLAG_ROGUE_VAN_EVAS_SPRINT) // Vanish, Evasion, Sprint - caster->RemoveSpellCooldown((itr++)->first, true); - else if (caster->HasAura(SPELL_ROGUE_GLYPH_OF_PREPARATION)) - { - if (spellInfo->SpellFamilyFlags[1] & SPELLFAMILYFLAG1_ROGUE_DISMANTLE || // Dismantle - spellInfo->SpellFamilyFlags[0] & SPELLFAMILYFLAG_ROGUE_KICK || // Kick - (spellInfo->SpellFamilyFlags[0] & SPELLFAMILYFLAG_ROGUE_BLADE_FLURRY && // Blade Flurry - spellInfo->SpellFamilyFlags[1] & SPELLFAMILYFLAG1_ROGUE_BLADE_FLURRY)) - caster->RemoveSpellCooldown((itr++)->first, true); - else - ++itr; - } - else - ++itr; + caster->RemoveSpellCooldown((itr++)->first, true); } else ++itr; @@ -465,7 +619,7 @@ class spell_rog_preparation : public SpellScriptLoader } }; -// -51685 - Prey on the Weak +// 51685 - Prey on the Weak class spell_rog_prey_on_the_weak : public SpellScriptLoader { public: @@ -510,7 +664,56 @@ class spell_rog_prey_on_the_weak : public SpellScriptLoader } }; -// -1943 - Rupture +// 73651 - Recuperate +class spell_rog_recuperate : public SpellScriptLoader +{ + public: + spell_rog_recuperate() : SpellScriptLoader("spell_rog_recuperate") { } + + class spell_rog_recuperate_AuraScript : public AuraScript + { + PrepareAuraScript(spell_rog_recuperate_AuraScript); + + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } + + void OnPeriodic(AuraEffect const* /*aurEff*/) + { + if (Unit* caster = GetCaster()) + if (AuraEffect* effect = GetAura()->GetEffect(EFFECT_0)) + effect->RecalculateAmount(caster); + } + + void CalculateBonus(AuraEffect const* /*aurEff*/, int32& amount, bool& canBeRecalculated) + { + canBeRecalculated = false; + if (Unit* caster = GetCaster()) + { + int32 baseAmount = GetSpellInfo()->Effects[EFFECT_0].CalcValue(caster) * 1000; + // Improved Recuperate + if (AuraEffect const* auraEffect = caster->GetDummyAuraEffect(SPELLFAMILY_ROGUE, ICON_ROGUE_IMPROVED_RECUPERATE, EFFECT_0)) + baseAmount += auraEffect->GetAmount(); + + amount = CalculatePct(caster->GetMaxHealth(), float(baseAmount) / 1000.0f); + } + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_rog_recuperate_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_HEAL); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_rog_recuperate_AuraScript::CalculateBonus, EFFECT_0, SPELL_AURA_PERIODIC_HEAL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_rog_recuperate_AuraScript(); + } +}; + +// 1943 - Rupture class spell_rog_rupture : public SpellScriptLoader { public: @@ -603,6 +806,70 @@ class spell_rog_shiv : public SpellScriptLoader } }; +// 1784 - Stealth +class spell_rog_stealth : public SpellScriptLoader +{ + public: + spell_rog_stealth() : SpellScriptLoader("spell_rog_stealth") { } + + class spell_rog_stealth_AuraScript : public AuraScript + { + PrepareAuraScript(spell_rog_stealth_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_ROGUE_MASTER_OF_SUBTLETY_PASSIVE) || + !sSpellMgr->GetSpellInfo(SPELL_ROGUE_MASTER_OF_SUBTLETY_DAMAGE_PERCENT) || + !sSpellMgr->GetSpellInfo(SPELL_ROGUE_MASTER_OF_SUBTLETY_PERIODIC) || + !sSpellMgr->GetSpellInfo(SPELL_ROGUE_OVERKILL_TALENT) || + !sSpellMgr->GetSpellInfo(SPELL_ROGUE_OVERKILL_POWER_REGEN) || + !sSpellMgr->GetSpellInfo(SPELL_ROGUE_OVERKILL_PERIODIC)) + return false; + return true; + } + + void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + + // Master of Subtlety + if (AuraEffect const* aurEff = target->GetAuraEffect(SPELL_ROGUE_MASTER_OF_SUBTLETY_PASSIVE, EFFECT_0)) + { + int32 basepoints0 = aurEff->GetAmount(); + target->CastCustomSpell(target, SPELL_ROGUE_MASTER_OF_SUBTLETY_DAMAGE_PERCENT, &basepoints0, NULL, NULL, true); + } + + // Overkill + if (target->HasAura(SPELL_ROGUE_OVERKILL_TALENT)) + target->CastSpell(target, SPELL_ROGUE_OVERKILL_POWER_REGEN, true); + } + + void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + + // Master of subtlety + if (target->HasAura(SPELL_ROGUE_MASTER_OF_SUBTLETY_PASSIVE)) + target->CastSpell(target, SPELL_ROGUE_MASTER_OF_SUBTLETY_PERIODIC, true); + + // Overkill + if (target->HasAura(SPELL_ROGUE_OVERKILL_TALENT)) + target->CastSpell(target, SPELL_ROGUE_OVERKILL_PERIODIC, true); + } + + void Register() + { + AfterEffectApply += AuraEffectApplyFn(spell_rog_stealth_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_MOD_SHAPESHIFT, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); + AfterEffectRemove += AuraEffectRemoveFn(spell_rog_stealth_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_MOD_SHAPESHIFT, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_rog_stealth_AuraScript(); + } +}; + // 57934 - Tricks of the Trade class spell_rog_tricks_of_the_trade : public SpellScriptLoader { @@ -698,13 +965,19 @@ void AddSC_rogue_spell_scripts() { new spell_rog_blade_flurry(); new spell_rog_cheat_death(); + new spell_rog_crippling_poison(); + new spell_rog_cut_to_the_chase(); new spell_rog_deadly_poison(); new spell_rog_killing_spree(); + new spell_rog_master_of_subtlety(); new spell_rog_nerves_of_steel(); + new spell_rog_overkill(); new spell_rog_preparation(); new spell_rog_prey_on_the_weak(); + new spell_rog_recuperate(); new spell_rog_rupture(); new spell_rog_shiv(); + new spell_rog_stealth(); new spell_rog_tricks_of_the_trade(); new spell_rog_tricks_of_the_trade_proc(); } diff --git a/src/server/scripts/Spells/spell_shaman.cpp b/src/server/scripts/Spells/spell_shaman.cpp index 61ff79c505e..bc568904b80 100644 --- a/src/server/scripts/Spells/spell_shaman.cpp +++ b/src/server/scripts/Spells/spell_shaman.cpp @@ -30,132 +30,138 @@ enum ShamanSpells { + SPELL_SHAMAN_ANCESTRAL_AWAKENING = 52759, SPELL_SHAMAN_ANCESTRAL_AWAKENING_PROC = 52752, SPELL_SHAMAN_BIND_SIGHT = 6277, - SPELL_SHAMAN_CLEANSING_TOTEM_EFFECT = 52025, SPELL_SHAMAN_EARTH_SHIELD_HEAL = 379, + SPELL_SHAMAN_ELEMENTAL_MASTERY = 16166, SPELL_SHAMAN_EXHAUSTION = 57723, - SPELL_SHAMAN_FIRE_NOVA_R1 = 1535, SPELL_SHAMAN_FIRE_NOVA_TRIGGERED_R1 = 8349, + SPELL_SHAMAN_FLAME_SHOCK = 8050, + SPELL_SHAMAN_FOCUSED_INSIGHT = 77800, SPELL_SHAMAN_GLYPH_OF_EARTH_SHIELD = 63279, SPELL_SHAMAN_GLYPH_OF_HEALING_STREAM_TOTEM = 55456, + SPELL_SHAMAN_GLYPH_OF_HEALING_WAVE = 55533, SPELL_SHAMAN_GLYPH_OF_MANA_TIDE = 55441, SPELL_SHAMAN_GLYPH_OF_THUNDERSTORM = 62132, + SPELL_SHAMAN_LAVA_BURST = 51505, + SPELL_SHAMAN_LAVA_FLOWS_R1 = 51480, + SPELL_SHAMAN_LAVA_FLOWS_TRIGGERED_R1 = 65264, + SPELL_SHAMAN_LAVA_SURGE = 77762, SPELL_SHAMAN_ITEM_LIGHTNING_SHIELD = 23552, SPELL_SHAMAN_ITEM_LIGHTNING_SHIELD_DAMAGE = 27635, SPELL_SHAMAN_ITEM_MANA_SURGE = 23571, - SPELL_SHAMAN_LAVA_FLOWS_R1 = 51480, - SPELL_SHAMAN_LAVA_FLOWS_TRIGGERED_R1 = 64694, - SPELL_SHAMAN_MANA_SPRING_TOTEM_ENERGIZE = 52032, - SPELL_SHAMAN_MANA_TIDE_TOTEM = 39609, + SPELL_SHAMAN_LIGHTNING_SHIELD = 324, + SPELL_SHAMAN_NATURE_GUARDIAN = 31616, SPELL_SHAMAN_SATED = 57724, SPELL_SHAMAN_STORM_EARTH_AND_FIRE = 51483, + SPELL_SHAMAN_TELLURIC_CURRENTS = 82987, SPELL_SHAMAN_TOTEM_EARTHBIND_EARTHGRAB = 64695, SPELL_SHAMAN_TOTEM_EARTHBIND_TOTEM = 6474, SPELL_SHAMAN_TOTEM_EARTHEN_POWER = 59566, - SPELL_SHAMAN_TOTEM_HEALING_STREAM_HEAL = 52042 + SPELL_SHAMAN_TOTEM_HEALING_STREAM_HEAL = 52042, + SPELL_SHAMAN_TIDAL_WAVES = 53390 }; enum ShamanSpellIcons { - SHAMAN_ICON_ID_RESTORATIVE_TOTEMS = 338, + SHAMAN_ICON_ID_SOOTHING_RAIN = 2011, SHAMAN_ICON_ID_SHAMAN_LAVA_FLOW = 3087 }; -// 52759 - Ancestral Awakening (Proc) -class spell_sha_ancestral_awakening_proc : public SpellScriptLoader +enum MiscSpells +{ + SPELL_HUNTER_INSANITY = 95809, + SPELL_MAGE_TEMPORAL_DISPLACEMENT = 80354 +}; + +// -51556 - Ancestral Awakening +class spell_sha_ancestral_awakening : public SpellScriptLoader { public: - spell_sha_ancestral_awakening_proc() : SpellScriptLoader("spell_sha_ancestral_awakening_proc") { } + spell_sha_ancestral_awakening() : SpellScriptLoader("spell_sha_ancestral_awakening") { } - class spell_sha_ancestral_awakening_proc_SpellScript : public SpellScript + class spell_sha_ancestral_awakening_AuraScript : public AuraScript { - PrepareSpellScript(spell_sha_ancestral_awakening_proc_SpellScript); + PrepareAuraScript(spell_sha_ancestral_awakening_AuraScript); bool Validate(SpellInfo const* /*spellInfo*/) override { - if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_ANCESTRAL_AWAKENING_PROC)) + if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_TIDAL_WAVES)) return false; return true; } - void FilterTargets(std::list<WorldObject*>& targets) + void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) { - if (targets.size() < 2) - return; - - targets.sort(Trinity::HealthPctOrderPred()); - - WorldObject* target = targets.front(); - targets.clear(); - targets.push_back(target); - } + PreventDefaultAction(); + int32 heal = int32(CalculatePct(eventInfo.GetHealInfo()->GetHeal(), aurEff->GetAmount())); - void HandleDummy(SpellEffIndex /*effIndex*/) - { - int32 damage = GetEffectValue(); - if (GetHitUnit()) - GetCaster()->CastCustomSpell(GetHitUnit(), SPELL_SHAMAN_ANCESTRAL_AWAKENING_PROC, &damage, NULL, NULL, true); + GetTarget()->CastCustomSpell(SPELL_SHAMAN_ANCESTRAL_AWAKENING, SPELLVALUE_BASE_POINT0, heal, (Unit*)NULL, true, NULL, aurEff); } void Register() override { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sha_ancestral_awakening_proc_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_RAID); - OnEffectHitTarget += SpellEffectFn(spell_sha_ancestral_awakening_proc_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectProc += AuraEffectProcFn(spell_sha_ancestral_awakening_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY); } }; - SpellScript* GetSpellScript() const override + AuraScript* GetAuraScript() const override { - return new spell_sha_ancestral_awakening_proc_SpellScript(); + return new spell_sha_ancestral_awakening_AuraScript(); } }; -// 51474 - Astral Shift -class spell_sha_astral_shift : public SpellScriptLoader +// 52759 - Ancestral Awakening +/// Updated 4.3.4 +class spell_sha_ancestral_awakening_proc : public SpellScriptLoader { public: - spell_sha_astral_shift() : SpellScriptLoader("spell_sha_astral_shift") { } + spell_sha_ancestral_awakening_proc() : SpellScriptLoader("spell_sha_ancestral_awakening_proc") { } - class spell_sha_astral_shift_AuraScript : public AuraScript + class spell_sha_ancestral_awakening_proc_SpellScript : public SpellScript { - PrepareAuraScript(spell_sha_astral_shift_AuraScript); - - uint32 absorbPct; + PrepareSpellScript(spell_sha_ancestral_awakening_proc_SpellScript); - bool Load() override + bool Validate(SpellInfo const* /*spellInfo*/) override { - absorbPct = GetSpellInfo()->Effects[EFFECT_0].CalcValue(GetCaster()); + if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_ANCESTRAL_AWAKENING_PROC)) + return false; return true; } - void CalculateAmount(AuraEffect const* /*aurEff*/, int32 & amount, bool & /*canBeRecalculated*/) + void FilterTargets(std::list<WorldObject*>& targets) { - // Set absorbtion amount to unlimited - amount = -1; + if (targets.size() < 2) + return; + + targets.sort(Trinity::HealthPctOrderPred()); + + WorldObject* target = targets.front(); + targets.clear(); + targets.push_back(target); } - void Absorb(AuraEffect* /*aurEff*/, DamageInfo & dmgInfo, uint32 & absorbAmount) + void HandleDummy(SpellEffIndex /*effIndex*/) { - // reduces all damage taken while stun, fear or silence - if (GetTarget()->GetUInt32Value(UNIT_FIELD_FLAGS) & (UNIT_FLAG_FLEEING | UNIT_FLAG_SILENCED) || (GetTarget()->GetUInt32Value(UNIT_FIELD_FLAGS) & (UNIT_FLAG_STUNNED) && GetTarget()->HasAuraWithMechanic(1<<MECHANIC_STUN))) - absorbAmount = CalculatePct(dmgInfo.GetDamage(), absorbPct); + GetCaster()->CastCustomSpell(SPELL_SHAMAN_ANCESTRAL_AWAKENING_PROC, SPELLVALUE_BASE_POINT0, GetEffectValue(), GetHitUnit(), true); } void Register() override { - DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_sha_astral_shift_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB); - OnEffectAbsorb += AuraEffectAbsorbFn(spell_sha_astral_shift_AuraScript::Absorb, EFFECT_0); + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sha_ancestral_awakening_proc_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_RAID); + OnEffectHitTarget += SpellEffectFn(spell_sha_ancestral_awakening_proc_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; - AuraScript* GetAuraScript() const override + SpellScript* GetSpellScript() const override { - return new spell_sha_astral_shift_AuraScript(); + return new spell_sha_ancestral_awakening_proc_SpellScript(); } }; // 2825 - Bloodlust +/// Updated 4.3.4 class spell_sha_bloodlust : public SpellScriptLoader { public: @@ -167,7 +173,9 @@ class spell_sha_bloodlust : public SpellScriptLoader bool Validate(SpellInfo const* /*spellInfo*/) override { - if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_SATED)) + if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_SATED) + || !sSpellMgr->GetSpellInfo(SPELL_HUNTER_INSANITY) + || !sSpellMgr->GetSpellInfo(SPELL_MAGE_TEMPORAL_DISPLACEMENT)) return false; return true; } @@ -175,6 +183,8 @@ class spell_sha_bloodlust : public SpellScriptLoader void RemoveInvalidTargets(std::list<WorldObject*>& targets) { targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_SHAMAN_SATED)); + targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_HUNTER_INSANITY)); + targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_MAGE_TEMPORAL_DISPLACEMENT)); } void ApplyDebuff() @@ -198,7 +208,8 @@ class spell_sha_bloodlust : public SpellScriptLoader } }; -// -1064 - Chain Heal +// 1064 - Chain Heal +/// Updated 4.3.4 class spell_sha_chain_heal : public SpellScriptLoader { public: @@ -212,6 +223,7 @@ class spell_sha_chain_heal : public SpellScriptLoader { firstHeal = true; riptide = false; + amount = 0; return true; } @@ -223,6 +235,7 @@ class spell_sha_chain_heal : public SpellScriptLoader if (AuraEffect* aurEff = GetHitUnit()->GetAuraEffect(SPELL_AURA_PERIODIC_HEAL, SPELLFAMILY_SHAMAN, 0, 0, 0x10, GetCaster()->GetGUID())) { riptide = true; + amount = aurEff->GetSpellInfo()->Effects[EFFECT_2].CalcValue(); // Consume it GetHitUnit()->RemoveAura(aurEff->GetBase()); } @@ -230,7 +243,10 @@ class spell_sha_chain_heal : public SpellScriptLoader } // Riptide increases the Chain Heal effect by 25% if (riptide) - SetHitHeal(GetHitHeal() * 1.25f); + { + uint32 bonus = CalculatePct(GetHitHeal(), amount); + SetHitHeal(GetHitHeal() + bonus); + } } void Register() override @@ -240,6 +256,7 @@ class spell_sha_chain_heal : public SpellScriptLoader bool firstHeal; bool riptide; + uint32 amount; }; SpellScript* GetSpellScript() const override @@ -248,43 +265,7 @@ class spell_sha_chain_heal : public SpellScriptLoader } }; -// 8171 - Cleansing Totem (Pulse) -class spell_sha_cleansing_totem_pulse : public SpellScriptLoader -{ - public: - spell_sha_cleansing_totem_pulse() : SpellScriptLoader("spell_sha_cleansing_totem_pulse") { } - - class spell_sha_cleansing_totem_pulse_SpellScript : public SpellScript - { - PrepareSpellScript(spell_sha_cleansing_totem_pulse_SpellScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_CLEANSING_TOTEM_EFFECT)) - return false; - return true; - } - - void HandleDummy(SpellEffIndex /*effIndex*/) - { - int32 bp = 1; - if (GetCaster() && GetHitUnit() && GetOriginalCaster()) - GetCaster()->CastCustomSpell(GetHitUnit(), SPELL_SHAMAN_CLEANSING_TOTEM_EFFECT, NULL, &bp, NULL, true, NULL, NULL, GetOriginalCaster()->GetGUID()); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_sha_cleansing_totem_pulse_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; - - SpellScript* GetSpellScript() const override - { - return new spell_sha_cleansing_totem_pulse_SpellScript(); - } -}; - -// -974 - Earth Shield +// 974 - Earth Shield class spell_sha_earth_shield : public SpellScriptLoader { public: @@ -296,9 +277,8 @@ class spell_sha_earth_shield : public SpellScriptLoader bool Validate(SpellInfo const* /*spellInfo*/) override { - if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_EARTH_SHIELD_HEAL)) - return false; - if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_GLYPH_OF_EARTH_SHIELD)) + if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_EARTH_SHIELD_HEAL) || + !sSpellMgr->GetSpellInfo(SPELL_SHAMAN_GLYPH_OF_EARTH_SHIELD)) return false; return true; } @@ -352,7 +332,8 @@ class spell_sha_earth_shield : public SpellScriptLoader } }; -// 6474 - Earthbind Totem - Fix Talent: Earthen Power +// 6474 - Earthbind Totem - Fix Talent:Earthen Power, Earth's Grasp +/// Updated 4.3.4 class spell_sha_earthbind_totem : public SpellScriptLoader { public: @@ -364,7 +345,8 @@ class spell_sha_earthbind_totem : public SpellScriptLoader bool Validate(SpellInfo const* /*spellInfo*/) override { - if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_TOTEM_EARTHBIND_TOTEM) || !sSpellMgr->GetSpellInfo(SPELL_SHAMAN_TOTEM_EARTHEN_POWER)) + if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_TOTEM_EARTHBIND_TOTEM) || + !sSpellMgr->GetSpellInfo(SPELL_SHAMAN_TOTEM_EARTHEN_POWER)) return false; return true; } @@ -386,7 +368,7 @@ class spell_sha_earthbind_totem : public SpellScriptLoader Player* owner = GetCaster()->GetCharmerOrOwnerPlayerOrPlayerItself(); if (!owner) return; - // Storm, Earth and Fire + // Earth's Grasp if (AuraEffect* aurEff = owner->GetAuraEffectOfRankedSpell(SPELL_SHAMAN_STORM_EARTH_AND_FIRE, EFFECT_1)) { if (roll_chance_i(aurEff->GetAmount())) @@ -451,54 +433,68 @@ class spell_sha_earthen_power : public SpellScriptLoader } }; -// -1535 - Fire Nova -class spell_sha_fire_nova : public SpellScriptLoader +// 86185 Feedback +class spell_sha_feedback : public SpellScriptLoader { public: - spell_sha_fire_nova() : SpellScriptLoader("spell_sha_fire_nova") { } + spell_sha_feedback() : SpellScriptLoader("spell_sha_feedback") { } - class spell_sha_fire_nova_SpellScript : public SpellScript + class spell_sha_feedback_AuraScript : public AuraScript { - PrepareSpellScript(spell_sha_fire_nova_SpellScript); + PrepareAuraScript(spell_sha_feedback_AuraScript); - bool Validate(SpellInfo const* spellInfo) override + bool Validate(SpellInfo const* /*spellInfo*/) override { - SpellInfo const* firstRankSpellInfo = sSpellMgr->GetSpellInfo(SPELL_SHAMAN_FIRE_NOVA_R1); - if (!firstRankSpellInfo || !spellInfo->IsRankOf(firstRankSpellInfo)) - return false; - - uint8 rank = spellInfo->GetRank(); - if (!sSpellMgr->GetSpellWithRank(SPELL_SHAMAN_FIRE_NOVA_TRIGGERED_R1, rank, true)) + if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_ELEMENTAL_MASTERY)) return false; return true; } - SpellCastResult CheckFireTotem() + void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) { - // fire totem - if (!GetCaster()->m_SummonSlot[1]) - { - SetCustomCastResultMessage(SPELL_CUSTOM_ERROR_MUST_HAVE_FIRE_TOTEM); - return SPELL_FAILED_CUSTOM_ERROR; - } + PreventDefaultAction(); // will prevent default effect execution + if (Player* target = GetTarget()->ToPlayer()) + target->ModifySpellCooldown(SPELL_SHAMAN_ELEMENTAL_MASTERY, aurEff->GetBaseAmount()); + } - return SPELL_CAST_OK; + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_sha_feedback_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY); } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_sha_feedback_AuraScript(); + } +}; + +// 1535 Fire Nova +/// Updated 4.3.4 +class spell_sha_fire_nova : public SpellScriptLoader +{ + public: + spell_sha_fire_nova() : SpellScriptLoader("spell_sha_fire_nova") { } + + class spell_sha_fire_nova_SpellScript : public SpellScript + { + PrepareSpellScript(spell_sha_fire_nova_SpellScript); void HandleDummy(SpellEffIndex /*effIndex*/) { Unit* caster = GetCaster(); - if (Creature* totem = caster->GetMap()->GetCreature(caster->m_SummonSlot[1])) + if (Unit* target = GetHitUnit()) { - uint8 rank = GetSpellInfo()->GetRank(); - if (totem->IsTotem()) - caster->CastSpell(totem, sSpellMgr->GetSpellWithRank(SPELL_SHAMAN_FIRE_NOVA_TRIGGERED_R1, rank), true); + if (target->HasAura(SPELL_SHAMAN_FLAME_SHOCK)) + { + caster->CastSpell(target, SPELL_SHAMAN_FIRE_NOVA_TRIGGERED_R1, true); + target->RemoveAurasDueToSpell(SPELL_SHAMAN_FLAME_SHOCK); + } } } void Register() override { - OnCheckCast += SpellCheckCastFn(spell_sha_fire_nova_SpellScript::CheckFireTotem); OnEffectHitTarget += SpellEffectFn(spell_sha_fire_nova_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -509,7 +505,8 @@ class spell_sha_fire_nova : public SpellScriptLoader } }; -// -8050 - Flame Shock +// 8050 -Flame Shock +/// Updated 4.3.4 class spell_sha_flame_shock : public SpellScriptLoader { public: @@ -521,9 +518,8 @@ class spell_sha_flame_shock : public SpellScriptLoader bool Validate(SpellInfo const* /*spell*/) override { - if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_LAVA_FLOWS_R1)) - return false; - if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_LAVA_FLOWS_TRIGGERED_R1)) + if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_LAVA_FLOWS_R1) || + !sSpellMgr->GetSpellInfo(SPELL_SHAMAN_LAVA_FLOWS_TRIGGERED_R1)) return false; return true; } @@ -531,6 +527,7 @@ class spell_sha_flame_shock : public SpellScriptLoader void HandleDispel(DispelInfo* /*dispelInfo*/) { if (Unit* caster = GetCaster()) + { // Lava Flows if (AuraEffect const* aurEff = caster->GetDummyAuraEffect(SPELLFAMILY_SHAMAN, SHAMAN_ICON_ID_SHAMAN_LAVA_FLOW, EFFECT_0)) { @@ -538,9 +535,10 @@ class spell_sha_flame_shock : public SpellScriptLoader if (!aurEff->GetSpellInfo()->IsRankOf(firstRankSpellInfo)) return; - uint8 rank = aurEff->GetSpellInfo()->GetRank(); - caster->CastSpell(caster, sSpellMgr->GetSpellWithRank(SPELL_SHAMAN_LAVA_FLOWS_TRIGGERED_R1, rank), true); + int32 basepoints = aurEff->GetAmount(); + caster->CastCustomSpell(caster, SPELL_SHAMAN_LAVA_FLOWS_TRIGGERED_R1, &basepoints, NULL, NULL, true); } + } } void Register() override @@ -555,7 +553,90 @@ class spell_sha_flame_shock : public SpellScriptLoader } }; -// 52041, 52046, 52047, 52048, 52049, 52050, 58759, 58760, 58761 - Healing Stream Totem +// 77794 - Focused Insight +class spell_sha_focused_insight : public SpellScriptLoader +{ + public: + spell_sha_focused_insight() : SpellScriptLoader("spell_sha_focused_insight") { } + + class spell_sha_focused_insight_AuraScript : public AuraScript + { + PrepareAuraScript(spell_sha_focused_insight_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_FOCUSED_INSIGHT)) + return false; + return true; + } + + void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + int32 basePoints0 = aurEff->GetAmount(); + int32 basePoints1 = aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue(); + + GetTarget()->CastCustomSpell(GetTarget(), SPELL_SHAMAN_FOCUSED_INSIGHT, &basePoints0, &basePoints1, &basePoints1, true, NULL, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_sha_focused_insight_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_sha_focused_insight_AuraScript(); + } +}; + +// 55440 - Glyph of Healing Wave +class spell_sha_glyph_of_healing_wave : public SpellScriptLoader +{ + public: + spell_sha_glyph_of_healing_wave() : SpellScriptLoader("spell_sha_glyph_of_healing_wave") { } + + class spell_sha_glyph_of_healing_wave_AuraScript : public AuraScript + { + PrepareAuraScript(spell_sha_glyph_of_healing_wave_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_GLYPH_OF_HEALING_WAVE)) + return false; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + // Not proc from self heals + return GetTarget() != eventInfo.GetProcTarget(); + } + + void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + int32 heal = CalculatePct(int32(eventInfo.GetHealInfo()->GetHeal()), aurEff->GetAmount()); + + GetTarget()->CastCustomSpell(SPELL_SHAMAN_GLYPH_OF_HEALING_WAVE, SPELLVALUE_BASE_POINT0, heal, (Unit*)NULL, true, NULL, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_sha_glyph_of_healing_wave_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_sha_glyph_of_healing_wave_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_sha_glyph_of_healing_wave_AuraScript(); + } +}; + +// 52041 - Healing Stream Totem +/// Updated 4.3.4 class spell_sha_healing_stream_totem : public SpellScriptLoader { public: @@ -567,12 +648,10 @@ class spell_sha_healing_stream_totem : public SpellScriptLoader bool Validate(SpellInfo const* /*spellInfo*/) override { - if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_GLYPH_OF_HEALING_STREAM_TOTEM) || !sSpellMgr->GetSpellInfo(SPELL_SHAMAN_TOTEM_HEALING_STREAM_HEAL)) - return false; - return true; + return sSpellMgr->GetSpellInfo(SPELL_SHAMAN_TOTEM_HEALING_STREAM_HEAL); } - void HandleDummy(SpellEffIndex /*effIndex*/) + void HandleDummy(SpellEffIndex /* effIndex */) { int32 damage = GetEffectValue(); SpellInfo const* triggeringSpell = GetTriggeringSpell(); @@ -584,14 +663,10 @@ class spell_sha_healing_stream_totem : public SpellScriptLoader if (triggeringSpell) damage = int32(owner->SpellHealingBonusDone(target, triggeringSpell, damage, HEAL)); - // Restorative Totems - if (AuraEffect* dummy = owner->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_SHAMAN, SHAMAN_ICON_ID_RESTORATIVE_TOTEMS, 1)) + // Soothing Rains + if (AuraEffect* dummy = owner->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_SHAMAN, SHAMAN_ICON_ID_SOOTHING_RAIN, EFFECT_0)) AddPct(damage, dummy->GetAmount()); - // Glyph of Healing Stream Totem - if (AuraEffect const* aurEff = owner->GetAuraEffect(SPELL_SHAMAN_GLYPH_OF_HEALING_STREAM_TOTEM, EFFECT_0)) - AddPct(damage, aurEff->GetAmount()); - damage = int32(target->SpellHealingBonusTaken(owner, triggeringSpell, damage, HEAL)); } caster->CastCustomSpell(target, SPELL_SHAMAN_TOTEM_HEALING_STREAM_HEAL, &damage, 0, 0, true, 0, 0, GetOriginalCaster()->GetGUID()); @@ -611,6 +686,7 @@ class spell_sha_healing_stream_totem : public SpellScriptLoader }; // 32182 - Heroism +/// Updated 4.3.4 class spell_sha_heroism : public SpellScriptLoader { public: @@ -622,7 +698,9 @@ class spell_sha_heroism : public SpellScriptLoader bool Validate(SpellInfo const* /*spellInfo*/) override { - if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_EXHAUSTION)) + if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_EXHAUSTION) + || !sSpellMgr->GetSpellInfo(SPELL_HUNTER_INSANITY) + || !sSpellMgr->GetSpellInfo(SPELL_MAGE_TEMPORAL_DISPLACEMENT)) return false; return true; } @@ -630,6 +708,8 @@ class spell_sha_heroism : public SpellScriptLoader void RemoveInvalidTargets(std::list<WorldObject*>& targets) { targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_SHAMAN_EXHAUSTION)); + targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_HUNTER_INSANITY)); + targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_MAGE_TEMPORAL_DISPLACEMENT)); } void ApplyDebuff() @@ -670,7 +750,7 @@ class spell_sha_item_lightning_shield : public SpellScriptLoader return true; } - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + void OnProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) { PreventDefaultAction(); GetTarget()->CastSpell(eventInfo.GetProcTarget(), SPELL_SHAMAN_ITEM_LIGHTNING_SHIELD, true, NULL, aurEff); @@ -678,7 +758,7 @@ class spell_sha_item_lightning_shield : public SpellScriptLoader void Register() override { - OnEffectProc += AuraEffectProcFn(spell_sha_item_lightning_shield_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + OnEffectProc += AuraEffectProcFn(spell_sha_item_lightning_shield_AuraScript::OnProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); } }; @@ -705,7 +785,7 @@ class spell_sha_item_lightning_shield_trigger : public SpellScriptLoader return true; } - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + void OnProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) { PreventDefaultAction(); GetTarget()->CastSpell(GetTarget(), SPELL_SHAMAN_ITEM_LIGHTNING_SHIELD_DAMAGE, true, NULL, aurEff); @@ -713,7 +793,7 @@ class spell_sha_item_lightning_shield_trigger : public SpellScriptLoader void Register() override { - OnEffectProc += AuraEffectProcFn(spell_sha_item_lightning_shield_trigger_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + OnEffectProc += AuraEffectProcFn(spell_sha_item_lightning_shield_trigger_AuraScript::OnProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); } }; @@ -740,24 +820,18 @@ class spell_sha_item_mana_surge : public SpellScriptLoader return true; } - bool CheckProc(ProcEventInfo& eventInfo) - { - return eventInfo.GetDamageInfo()->GetSpellInfo(); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + void OnProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) { PreventDefaultAction(); - int32 mana = eventInfo.GetDamageInfo()->GetSpellInfo()->CalcPowerCost(GetTarget(), eventInfo.GetSchoolMask()); - int32 damage = CalculatePct(mana, 35); + int32 mana = eventInfo.GetDamageInfo()->GetSpellInfo()->CalcPowerCost(GetTarget(), SpellSchoolMask(eventInfo.GetDamageInfo()->GetSchoolMask())); + mana = int32(CalculatePct(mana, 35)); - GetTarget()->CastCustomSpell(SPELL_SHAMAN_ITEM_MANA_SURGE, SPELLVALUE_BASE_POINT0, damage, GetTarget(), true, NULL, aurEff); + GetTarget()->CastCustomSpell(SPELL_SHAMAN_ITEM_MANA_SURGE, SPELLVALUE_BASE_POINT0, mana, GetTarget(), true, NULL, aurEff); } void Register() override { - DoCheckProc += AuraCheckProcFn(spell_sha_item_mana_surge_AuraScript::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_sha_item_mana_surge_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + OnEffectProc += AuraEffectProcFn(spell_sha_item_mana_surge_AuraScript::OnProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); } }; @@ -768,6 +842,7 @@ class spell_sha_item_mana_surge : public SpellScriptLoader }; // 60103 - Lava Lash +/// Updated 4.3.4 class spell_sha_lava_lash : public SpellScriptLoader { public: @@ -811,139 +886,240 @@ class spell_sha_lava_lash : public SpellScriptLoader } }; -// 52031, 52033, 52034, 52035, 52036, 58778, 58779, 58780 - Mana Spring Totem -class spell_sha_mana_spring_totem : public SpellScriptLoader +class spell_sha_lava_surge : public SpellScriptLoader { public: - spell_sha_mana_spring_totem() : SpellScriptLoader("spell_sha_mana_spring_totem") { } + spell_sha_lava_surge() : SpellScriptLoader("spell_sha_lava_surge") { } - class spell_sha_mana_spring_totem_SpellScript : public SpellScript + class spell_sha_lava_surge_AuraScript : public AuraScript { - PrepareSpellScript(spell_sha_mana_spring_totem_SpellScript); + PrepareAuraScript(spell_sha_lava_surge_AuraScript); bool Validate(SpellInfo const* /*spellInfo*/) override { - if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_MANA_SPRING_TOTEM_ENERGIZE)) + if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_LAVA_SURGE)) return false; return true; } + void HandleEffectProc(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + GetTarget()->CastSpell(GetTarget(), SPELL_SHAMAN_LAVA_SURGE, true); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_sha_lava_surge_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_sha_lava_surge_AuraScript(); + } +}; + +class spell_sha_lava_surge_proc : public SpellScriptLoader +{ + public: + spell_sha_lava_surge_proc() : SpellScriptLoader("spell_sha_lava_surge_proc") { } + + class spell_sha_lava_surge_proc_SpellScript : public SpellScript + { + PrepareSpellScript(spell_sha_lava_surge_proc_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_LAVA_BURST)) + return false; + return true; + } + + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } + void HandleDummy(SpellEffIndex /*effIndex*/) { - int32 damage = GetEffectValue(); - if (Unit* target = GetHitUnit()) - if (Unit* caster = GetCaster()) - if (target->getPowerType() == POWER_MANA) - caster->CastCustomSpell(target, SPELL_SHAMAN_MANA_SPRING_TOTEM_ENERGIZE, &damage, 0, 0, true, 0, 0, GetOriginalCaster()->GetGUID()); + GetCaster()->ToPlayer()->RemoveSpellCooldown(SPELL_SHAMAN_LAVA_BURST, true); } void Register() override { - OnEffectHitTarget += SpellEffectFn(spell_sha_mana_spring_totem_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_sha_lava_surge_proc_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; SpellScript* GetSpellScript() const override { - return new spell_sha_mana_spring_totem_SpellScript(); + return new spell_sha_lava_surge_proc_SpellScript(); } }; -// 39610 - Mana Tide Totem +// 16191 - Mana Tide +/// Updated 4.3.4 class spell_sha_mana_tide_totem : public SpellScriptLoader { public: spell_sha_mana_tide_totem() : SpellScriptLoader("spell_sha_mana_tide_totem") { } - class spell_sha_mana_tide_totem_SpellScript : public SpellScript + class spell_sha_mana_tide_totem_AuraScript : public AuraScript + { + PrepareAuraScript(spell_sha_mana_tide_totem_AuraScript); + + void CalculateAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/) + { + ///@TODO: Exclude the "short term" buffs from the stat value + if (Unit* caster = GetCaster()) + if (Unit* owner = caster->GetOwner()) + amount = CalculatePct(owner->GetStat(STAT_SPIRIT), aurEff->GetAmount()); + } + + void Register() override + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_sha_mana_tide_totem_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_MOD_STAT); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_sha_mana_tide_totem_AuraScript(); + } +}; + +// -30881 - Nature's Guardian +class spell_sha_nature_guardian : public SpellScriptLoader +{ + public: + spell_sha_nature_guardian() : SpellScriptLoader("spell_sha_nature_guardian") { } + + class spell_sha_nature_guardian_AuraScript : public AuraScript { - PrepareSpellScript(spell_sha_mana_tide_totem_SpellScript); + PrepareAuraScript(spell_sha_nature_guardian_AuraScript); bool Validate(SpellInfo const* /*spellInfo*/) override { - if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_GLYPH_OF_MANA_TIDE) || !sSpellMgr->GetSpellInfo(SPELL_SHAMAN_MANA_TIDE_TOTEM)) + if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_NATURE_GUARDIAN)) return false; return true; } - void HandleDummy(SpellEffIndex /*effIndex*/) + bool CheckProc(ProcEventInfo& eventInfo) { - if (Unit* caster = GetCaster()) - if (Unit* unitTarget = GetHitUnit()) - { - if (unitTarget->getPowerType() == POWER_MANA) - { - int32 effValue = GetEffectValue(); - // Glyph of Mana Tide - if (Unit* owner = caster->GetOwner()) - if (AuraEffect* dummy = owner->GetAuraEffect(SPELL_SHAMAN_GLYPH_OF_MANA_TIDE, 0)) - effValue += dummy->GetAmount(); - // Regenerate 6% of Total Mana Every 3 secs - int32 effBasePoints0 = int32(CalculatePct(unitTarget->GetMaxPower(POWER_MANA), effValue)); - caster->CastCustomSpell(unitTarget, SPELL_SHAMAN_MANA_TIDE_TOTEM, &effBasePoints0, NULL, NULL, true, NULL, NULL, GetOriginalCaster()->GetGUID()); - } - } + //! HACK due to currenct proc system implementation + if (Player* player = GetTarget()->ToPlayer()) + if (player->HasSpellCooldown(GetSpellInfo()->Id)) + return false; + + return GetTarget()->HealthBelowPctDamaged(30, eventInfo.GetDamageInfo()->GetDamage()); + } + + void OnProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + int32 basePoints0 = GetTarget()->CountPctFromMaxHealth(aurEff->GetAmount()); + + GetTarget()->CastCustomSpell(GetTarget(), SPELL_SHAMAN_NATURE_GUARDIAN, &basePoints0, NULL, NULL, true); + + if (eventInfo.GetProcTarget() && eventInfo.GetProcTarget()->IsAlive()) + eventInfo.GetProcTarget()->getThreatManager().modifyThreatPercent(GetTarget(), -10); + + if (Player* player = GetTarget()->ToPlayer()) + player->AddSpellCooldown(GetSpellInfo()->Id, 0, time(NULL) + aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue()); } void Register() override { - OnEffectHitTarget += SpellEffectFn(spell_sha_mana_tide_totem_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + DoCheckProc += AuraCheckProcFn(spell_sha_nature_guardian_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_sha_nature_guardian_AuraScript::OnProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); } }; - SpellScript* GetSpellScript() const override + AuraScript* GetAuraScript() const override { - return new spell_sha_mana_tide_totem_SpellScript(); + return new spell_sha_nature_guardian_AuraScript(); } }; -// 6495 - Sentry Totem -class spell_sha_sentry_totem : public SpellScriptLoader +// 88756 - Rolling Thunder +class spell_sha_rolling_thunder : public SpellScriptLoader { public: - spell_sha_sentry_totem() : SpellScriptLoader("spell_sha_sentry_totem") { } + spell_sha_rolling_thunder() : SpellScriptLoader("spell_sha_rolling_thunder") { } - class spell_sha_sentry_totem_AuraScript : public AuraScript + class spell_sha_rolling_thunder_AuraScript : public AuraScript { - PrepareAuraScript(spell_sha_sentry_totem_AuraScript); + PrepareAuraScript(spell_sha_rolling_thunder_AuraScript); - bool Validate(SpellInfo const* /*spell*/) override + bool Validate(SpellInfo const* /*spellInfo*/) override { - if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_BIND_SIGHT)) + if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_LIGHTNING_SHIELD)) return false; return true; } - void AfterApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) { - if (Unit* caster = GetCaster()) - if (Creature* totem = caster->GetMap()->GetCreature(caster->m_SummonSlot[4])) - if (totem->IsTotem()) - caster->CastSpell(totem, SPELL_SHAMAN_BIND_SIGHT, true); + if (Aura* aura = GetTarget()->GetAura(SPELL_SHAMAN_LIGHTNING_SHIELD)) + { + aura->SetCharges(std::min(aura->GetCharges() + 1, aurEff->GetAmount())); + aura->RefreshDuration(); + } } - void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + void Register() override { - if (Unit* caster = GetCaster()) - if (caster->GetTypeId() == TYPEID_PLAYER) - caster->ToPlayer()->StopCastingBindSight(); + OnEffectProc += AuraEffectProcFn(spell_sha_rolling_thunder_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_sha_rolling_thunder_AuraScript(); + } +}; + +// 82984 - Telluric Currents +class spell_sha_telluric_currents : public SpellScriptLoader +{ + public: + spell_sha_telluric_currents() : SpellScriptLoader("spell_sha_telluric_currents") { } + + class spell_sha_telluric_currents_AuraScript : public AuraScript + { + PrepareAuraScript(spell_sha_telluric_currents_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_TELLURIC_CURRENTS)) + return false; + return true; + } + + void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + int32 basePoints0 = CalculatePct(eventInfo.GetDamageInfo()->GetDamage(), aurEff->GetAmount()); + + GetTarget()->CastCustomSpell(GetTarget(), SPELL_SHAMAN_TELLURIC_CURRENTS, &basePoints0, NULL, NULL, true); } void Register() override { - AfterEffectApply += AuraEffectApplyFn(spell_sha_sentry_totem_AuraScript::AfterApply, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - AfterEffectRemove += AuraEffectRemoveFn(spell_sha_sentry_totem_AuraScript::AfterRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + OnEffectProc += AuraEffectProcFn(spell_sha_telluric_currents_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY); } }; AuraScript* GetAuraScript() const override { - return new spell_sha_sentry_totem_AuraScript(); + return new spell_sha_telluric_currents_AuraScript(); } }; -// -51490 - Thunderstorm +// 51490 - Thunderstorm class spell_sha_thunderstorm : public SpellScriptLoader { public: @@ -972,26 +1148,70 @@ class spell_sha_thunderstorm : public SpellScriptLoader } }; +// 51562 - Tidal Waves +class spell_sha_tidal_waves : public SpellScriptLoader +{ + public: + spell_sha_tidal_waves() : SpellScriptLoader("spell_sha_tidal_waves") { } + + class spell_sha_tidal_waves_AuraScript : public AuraScript + { + PrepareAuraScript(spell_sha_tidal_waves_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_TIDAL_WAVES)) + return false; + return true; + } + + void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + int32 basePoints0 = -aurEff->GetAmount(); + int32 basePoints1 = aurEff->GetAmount(); + + GetTarget()->CastCustomSpell(GetTarget(), SPELL_SHAMAN_TIDAL_WAVES, &basePoints0, &basePoints1, NULL, true, NULL, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_sha_tidal_waves_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_sha_tidal_waves_AuraScript(); + } +}; + void AddSC_shaman_spell_scripts() { + new spell_sha_ancestral_awakening(); new spell_sha_ancestral_awakening_proc(); - new spell_sha_astral_shift(); new spell_sha_bloodlust(); new spell_sha_chain_heal(); - new spell_sha_cleansing_totem_pulse(); new spell_sha_earth_shield(); new spell_sha_earthbind_totem(); new spell_sha_earthen_power(); + new spell_sha_feedback(); new spell_sha_fire_nova(); new spell_sha_flame_shock(); + new spell_sha_focused_insight(); + new spell_sha_glyph_of_healing_wave(); new spell_sha_healing_stream_totem(); new spell_sha_heroism(); new spell_sha_item_lightning_shield(); new spell_sha_item_lightning_shield_trigger(); new spell_sha_item_mana_surge(); new spell_sha_lava_lash(); - new spell_sha_mana_spring_totem(); + new spell_sha_lava_surge(); + new spell_sha_lava_surge_proc(); new spell_sha_mana_tide_totem(); - new spell_sha_sentry_totem(); + new spell_sha_nature_guardian(); + new spell_sha_rolling_thunder(); + new spell_sha_telluric_currents(); new spell_sha_thunderstorm(); + new spell_sha_tidal_waves(); } diff --git a/src/server/scripts/Spells/spell_warlock.cpp b/src/server/scripts/Spells/spell_warlock.cpp index 18979d24ecb..2b0a5506a83 100644 --- a/src/server/scripts/Spells/spell_warlock.cpp +++ b/src/server/scripts/Spells/spell_warlock.cpp @@ -25,33 +25,55 @@ #include "ScriptMgr.h" #include "SpellScript.h" #include "SpellAuraEffects.h" +#include "SpellAuras.h" enum WarlockSpells { + SPELL_WARLOCK_AFTERMATH_STUN = 85387, + SPELL_WARLOCK_BANE_OF_DOOM_EFFECT = 18662, + SPELL_WARLOCK_CREATE_HEALTHSTONE = 34130, SPELL_WARLOCK_CURSE_OF_DOOM_EFFECT = 18662, + SPELL_WARLOCK_DEMONIC_CIRCLE_ALLOW_CAST = 62388, SPELL_WARLOCK_DEMONIC_CIRCLE_SUMMON = 48018, SPELL_WARLOCK_DEMONIC_CIRCLE_TELEPORT = 48020, - SPELL_WARLOCK_DEMONIC_CIRCLE_ALLOW_CAST = 62388, - SPELL_WARLOCK_DEMONIC_EMPOWERMENT_SUCCUBUS = 54435, - SPELL_WARLOCK_DEMONIC_EMPOWERMENT_VOIDWALKER = 54443, SPELL_WARLOCK_DEMONIC_EMPOWERMENT_FELGUARD = 54508, SPELL_WARLOCK_DEMONIC_EMPOWERMENT_FELHUNTER = 54509, SPELL_WARLOCK_DEMONIC_EMPOWERMENT_IMP = 54444, + SPELL_WARLOCK_DEMONIC_EMPOWERMENT_SUCCUBUS = 54435, + SPELL_WARLOCK_DEMONIC_EMPOWERMENT_VOIDWALKER = 54443, + SPELL_WARLOCK_DEMON_SOUL_IMP = 79459, + SPELL_WARLOCK_DEMON_SOUL_FELHUNTER = 79460, + SPELL_WARLOCK_DEMON_SOUL_FELGUARD = 79452, + SPELL_WARLOCK_DEMON_SOUL_SUCCUBUS = 79453, + SPELL_WARLOCK_DEMON_SOUL_VOIDWALKER = 79454, SPELL_WARLOCK_FEL_SYNERGY_HEAL = 54181, SPELL_WARLOCK_GLYPH_OF_SHADOWFLAME = 63311, SPELL_WARLOCK_GLYPH_OF_SIPHON_LIFE = 63106, + SPELL_WARLOCK_GLYPH_OF_SOUL_SWAP = 56226, + SPELL_WARLOCK_GLYPH_OF_SUCCUBUS = 56250, SPELL_WARLOCK_HAUNT = 48181, SPELL_WARLOCK_HAUNT_HEAL = 48210, - SPELL_WARLOCK_IMPROVED_HEALTHSTONE_R1 = 18692, - SPELL_WARLOCK_IMPROVED_HEALTHSTONE_R2 = 18693, - SPELL_WARLOCK_IMPROVED_HEALTH_FUNNEL_R1 = 18703, - SPELL_WARLOCK_IMPROVED_HEALTH_FUNNEL_R2 = 18704, + SPELL_WARLOCK_IMMOLATE = 348, SPELL_WARLOCK_IMPROVED_HEALTH_FUNNEL_BUFF_R1 = 60955, SPELL_WARLOCK_IMPROVED_HEALTH_FUNNEL_BUFF_R2 = 60956, + SPELL_WARLOCK_IMPROVED_HEALTH_FUNNEL_R1 = 18703, + SPELL_WARLOCK_IMPROVED_HEALTH_FUNNEL_R2 = 18704, + SPELL_WARLOCK_IMPROVED_SOUL_FIRE_PCT = 85383, + SPELL_WARLOCK_IMPROVED_SOUL_FIRE_STATE = 85385, SPELL_WARLOCK_LIFE_TAP_ENERGIZE = 31818, SPELL_WARLOCK_LIFE_TAP_ENERGIZE_2 = 32553, - SPELL_WARLOCK_SOULSHATTER = 32835, + SPELL_WARLOCK_NETHER_WARD = 91711, + SPELL_WARLOCK_NETHER_TALENT = 91713, + SPELL_WARLOCK_RAIN_OF_FIRE = 42223, + SPELL_WARLOCK_SHADOW_TRANCE = 17941, SPELL_WARLOCK_SIPHON_LIFE_HEAL = 63106, + SPELL_WARLOCK_SHADOW_WARD = 6229, + SPELL_WARLOCK_SOULSHATTER = 32835, + SPELL_WARLOCK_SOUL_SWAP_CD_MARKER = 94229, + SPELL_WARLOCK_SOUL_SWAP_OVERRIDE = 86211, + SPELL_WARLOCK_SOUL_SWAP_MOD_COST = 92794, + SPELL_WARLOCK_SOUL_SWAP_DOT_MARKER = 92795, + SPELL_WARLOCK_UNSTABLE_AFFLICTION = 30108, SPELL_WARLOCK_UNSTABLE_AFFLICTION_DISPEL = 31117 }; @@ -61,7 +83,53 @@ enum WarlockSpellIcons WARLOCK_ICON_ID_MANA_FEED = 1982 }; -// -710 - Banish +enum MiscSpells +{ + SPELL_GEN_REPLENISHMENT = 57669, + SPELL_PRIEST_SHADOW_WORD_DEATH = 32409 +}; + +// -85113 - Aftermath +class spell_warl_aftermath : public SpellScriptLoader +{ + public: + spell_warl_aftermath() : SpellScriptLoader("spell_warl_aftermath") { } + + class spell_warl_aftermath_AuraScript : public AuraScript + { + PrepareAuraScript(spell_warl_aftermath_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_AFTERMATH_STUN)) + return false; + return true; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + if (eventInfo.GetDamageInfo()->GetSpellInfo()->Id == SPELL_WARLOCK_RAIN_OF_FIRE) + { + PreventDefaultAction(); + + if (eventInfo.GetProcTarget() && roll_chance_i(aurEff->GetAmount())) + GetTarget()->CastSpell(eventInfo.GetProcTarget(), SPELL_WARLOCK_AFTERMATH_STUN, true, NULL, aurEff); + } + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_warl_aftermath_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_warl_aftermath_AuraScript(); + } +}; + +// 710 - Banish class spell_warl_banish : public SpellScriptLoader { public: @@ -79,6 +147,8 @@ class spell_warl_banish : public SpellScriptLoader void HandleBanish() { + /// Casting Banish on a banished target will cancel the effect + /// Check if the target already has Banish, if so, do nothing. if (Unit* target = GetHitUnit()) { if (target->GetAuraEffect(SPELL_AURA_SCHOOL_IMMUNITY, SPELLFAMILY_WARLOCK, 0, 0x08000000, 0)) @@ -113,7 +183,42 @@ class spell_warl_banish : public SpellScriptLoader } }; -// 6201 - Create Healthstone (and ranks) +// 17962 - Conflagrate - Updated to 4.3.4 +class spell_warl_conflagrate : public SpellScriptLoader +{ + public: + spell_warl_conflagrate() : SpellScriptLoader("spell_warl_conflagrate") { } + + class spell_warl_conflagrate_SpellScript : public SpellScript + { + PrepareSpellScript(spell_warl_conflagrate_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_IMMOLATE)) + return false; + return true; + } + + void HandleHit(SpellEffIndex /*effIndex*/) + { + if (AuraEffect const* aurEff = GetHitUnit()->GetAuraEffect(SPELL_WARLOCK_IMMOLATE, EFFECT_2, GetCaster()->GetGUID())) + SetHitDamage(CalculatePct(aurEff->GetAmount(), GetSpellInfo()->Effects[EFFECT_1].CalcValue(GetCaster()))); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_warl_conflagrate_SpellScript::HandleHit, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_warl_conflagrate_SpellScript(); + } +}; + +// 6201 - Create Healthstone class spell_warl_create_healthstone : public SpellScriptLoader { public: @@ -123,59 +228,26 @@ class spell_warl_create_healthstone : public SpellScriptLoader { PrepareSpellScript(spell_warl_create_healthstone_SpellScript); - static uint32 const iTypes[8][3]; - bool Validate(SpellInfo const* /*spellInfo*/) override { - if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_IMPROVED_HEALTHSTONE_R1) || !sSpellMgr->GetSpellInfo(SPELL_WARLOCK_IMPROVED_HEALTHSTONE_R2)) + if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_CREATE_HEALTHSTONE)) return false; return true; } - SpellCastResult CheckCast() + bool Load() override { - if (Player* caster = GetCaster()->ToPlayer()) - { - uint8 spellRank = GetSpellInfo()->GetRank(); - ItemPosCountVec dest; - InventoryResult msg = caster->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, iTypes[spellRank - 1][0], 1, NULL); - if (msg != EQUIP_ERR_OK) - return SPELL_FAILED_TOO_MANY_OF_ITEM; - } - return SPELL_CAST_OK; + return GetCaster()->GetTypeId() == TYPEID_PLAYER; } - void HandleScriptEffect(SpellEffIndex effIndex) + void HandleScriptEffect(SpellEffIndex /*effIndex*/) { - if (Unit* unitTarget = GetHitUnit()) - { - uint32 rank = 0; - // Improved Healthstone - if (AuraEffect const* aurEff = unitTarget->GetDummyAuraEffect(SPELLFAMILY_WARLOCK, 284, 0)) - { - switch (aurEff->GetId()) - { - case SPELL_WARLOCK_IMPROVED_HEALTHSTONE_R1: - rank = 1; - break; - case SPELL_WARLOCK_IMPROVED_HEALTHSTONE_R2: - rank = 2; - break; - default: - TC_LOG_ERROR("spells", "Unknown rank of Improved Healthstone id: %d", aurEff->GetId()); - break; - } - } - uint8 spellRank = GetSpellInfo()->GetRank(); - if (spellRank > 0 && spellRank <= 8) - CreateItem(effIndex, iTypes[spellRank - 1][rank]); - } + GetCaster()->CastSpell(GetCaster(), SPELL_WARLOCK_CREATE_HEALTHSTONE, true); } void Register() override { OnEffectHitTarget += SpellEffectFn(spell_warl_create_healthstone_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - OnCheckCast += SpellCheckCastFn(spell_warl_create_healthstone_SpellScript::CheckCast); } }; @@ -185,22 +257,12 @@ class spell_warl_create_healthstone : public SpellScriptLoader } }; -uint32 const spell_warl_create_healthstone::spell_warl_create_healthstone_SpellScript::iTypes[8][3] = { - { 5512, 19004, 19005}, // Minor Healthstone - { 5511, 19006, 19007}, // Lesser Healthstone - { 5509, 19008, 19009}, // Healthstone - { 5510, 19010, 19011}, // Greater Healthstone - { 9421, 19012, 19013}, // Major Healthstone - {22103, 22104, 22105}, // Master Healthstone - {36889, 36890, 36891}, // Demonic Healthstone - {36892, 36893, 36894} // Fel Healthstone -}; - -// -603 - Curse of Doom -class spell_warl_curse_of_doom : public SpellScriptLoader +// 603 - Bane of Doom +/// Updated 4.3.4 +class spell_warl_bane_of_doom : public SpellScriptLoader { public: - spell_warl_curse_of_doom() : SpellScriptLoader("spell_warl_curse_of_doom") { } + spell_warl_bane_of_doom() : SpellScriptLoader("spell_warl_bane_of_doom") { } class spell_warl_curse_of_doom_AuraScript : public AuraScript { @@ -208,7 +270,7 @@ class spell_warl_curse_of_doom : public SpellScriptLoader bool Validate(SpellInfo const* /*spellInfo*/) override { - if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_CURSE_OF_DOOM_EFFECT)) + if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_BANE_OF_DOOM_EFFECT)) return false; return true; } @@ -228,7 +290,7 @@ class spell_warl_curse_of_doom : public SpellScriptLoader return; if (GetCaster()->ToPlayer()->isHonorOrXPTarget(GetTarget())) - GetCaster()->CastSpell(GetTarget(), SPELL_WARLOCK_CURSE_OF_DOOM_EFFECT, true, NULL, aurEff); + GetCaster()->CastSpell(GetTarget(), SPELL_WARLOCK_BANE_OF_DOOM_EFFECT, true, NULL, aurEff); } void Register() override @@ -244,6 +306,7 @@ class spell_warl_curse_of_doom : public SpellScriptLoader }; // 48018 - Demonic Circle: Summon +/// Updated 4.3.4 class spell_warl_demonic_circle_summon : public SpellScriptLoader { public: @@ -296,6 +359,7 @@ class spell_warl_demonic_circle_summon : public SpellScriptLoader }; // 48020 - Demonic Circle: Teleport +/// Updated 4.3.4 class spell_warl_demonic_circle_teleport : public SpellScriptLoader { public: @@ -329,7 +393,75 @@ class spell_warl_demonic_circle_teleport : public SpellScriptLoader } }; +// 77801 - Demon Soul - Updated to 4.3.4 +class spell_warl_demon_soul : public SpellScriptLoader +{ + public: + spell_warl_demon_soul() : SpellScriptLoader("spell_warl_demon_soul") { } + + class spell_warl_demon_soul_SpellScript : public SpellScript + { + PrepareSpellScript(spell_warl_demon_soul_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_DEMON_SOUL_IMP)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_DEMON_SOUL_FELHUNTER)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_DEMON_SOUL_FELGUARD)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_DEMON_SOUL_SUCCUBUS)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_DEMON_SOUL_VOIDWALKER)) + return false; + return true; + } + + void OnHitTarget(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + if (Creature* targetCreature = GetHitCreature()) + { + if (targetCreature->IsPet()) + { + CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(targetCreature->GetEntry()); + switch (ci->family) + { + case CREATURE_FAMILY_SUCCUBUS: + caster->CastSpell(caster, SPELL_WARLOCK_DEMON_SOUL_SUCCUBUS); + break; + case CREATURE_FAMILY_VOIDWALKER: + caster->CastSpell(caster, SPELL_WARLOCK_DEMON_SOUL_VOIDWALKER); + break; + case CREATURE_FAMILY_FELGUARD: + caster->CastSpell(caster, SPELL_WARLOCK_DEMON_SOUL_FELGUARD); + break; + case CREATURE_FAMILY_FELHUNTER: + caster->CastSpell(caster, SPELL_WARLOCK_DEMON_SOUL_FELHUNTER); + break; + case CREATURE_FAMILY_IMP: + caster->CastSpell(caster, SPELL_WARLOCK_DEMON_SOUL_IMP); + break; + } + } + } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_warl_demon_soul_SpellScript::OnHitTarget, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_warl_demon_soul_SpellScript; + } +}; + // 47193 - Demonic Empowerment +/// Updated 4.3.4 class spell_warl_demonic_empowerment : public SpellScriptLoader { public: @@ -364,7 +496,6 @@ class spell_warl_demonic_empowerment : public SpellScriptLoader SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(SPELL_WARLOCK_DEMONIC_EMPOWERMENT_VOIDWALKER); int32 hp = int32(targetCreature->CountPctFromMaxHealth(GetCaster()->CalculateSpellDamage(targetCreature, spellInfo, 0))); targetCreature->CastCustomSpell(targetCreature, SPELL_WARLOCK_DEMONIC_EMPOWERMENT_VOIDWALKER, &hp, NULL, NULL, true); - //unitTarget->CastSpell(unitTarget, 54441, true); break; } case CREATURE_FAMILY_FELGUARD: @@ -394,6 +525,7 @@ class spell_warl_demonic_empowerment : public SpellScriptLoader }; // 47422 - Everlasting Affliction +/// Updated 4.3.4 class spell_warl_everlasting_affliction : public SpellScriptLoader { public: @@ -407,8 +539,8 @@ class spell_warl_everlasting_affliction : public SpellScriptLoader { if (Unit* unitTarget = GetHitUnit()) // Refresh corruption on target - if (AuraEffect* aur = unitTarget->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_WARLOCK, 0x2, 0, 0, GetCaster()->GetGUID())) - aur->GetBase()->RefreshDuration(); + if (AuraEffect* aurEff = unitTarget->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_WARLOCK, 0x2, 0, 0, GetCaster()->GetGUID())) + aurEff->GetBase()->RefreshDuration(); } void Register() override @@ -423,6 +555,43 @@ class spell_warl_everlasting_affliction : public SpellScriptLoader } }; +// 77799 - Fel Flame - Updated to 4.3.4 +class spell_warl_fel_flame : public SpellScriptLoader +{ + public: + spell_warl_fel_flame() : SpellScriptLoader("spell_warl_fel_flame") { } + + class spell_warl_fel_flame_SpellScript : public SpellScript + { + PrepareSpellScript(spell_warl_fel_flame_SpellScript); + + void OnHitTarget(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + Unit* target = GetHitUnit(); + Aura* aura = target->GetAura(SPELL_WARLOCK_UNSTABLE_AFFLICTION, caster->GetGUID()); + if (!aura) + aura = target->GetAura(SPELL_WARLOCK_IMMOLATE, caster->GetGUID()); + + if (!aura) + return; + + int32 newDuration = aura->GetDuration() + GetSpellInfo()->Effects[EFFECT_1].CalcValue() * 1000; + aura->SetDuration(std::min(newDuration, aura->GetMaxDuration())); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_warl_fel_flame_SpellScript::OnHitTarget, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_warl_fel_flame_SpellScript; + } +}; + // -47230 - Fel Synergy class spell_warl_fel_synergy : public SpellScriptLoader { @@ -483,7 +652,7 @@ class spell_warl_glyph_of_shadowflame : public SpellScriptLoader return true; } - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + void OnProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) { PreventDefaultAction(); GetTarget()->CastSpell(eventInfo.GetProcTarget(), SPELL_WARLOCK_GLYPH_OF_SHADOWFLAME, true, NULL, aurEff); @@ -491,7 +660,7 @@ class spell_warl_glyph_of_shadowflame : public SpellScriptLoader void Register() override { - OnEffectProc += AuraEffectProcFn(spell_warl_glyph_of_shadowflame_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + OnEffectProc += AuraEffectProcFn(spell_warl_glyph_of_shadowflame_AuraScript::OnProc, EFFECT_0, SPELL_AURA_DUMMY); } }; @@ -501,7 +670,8 @@ class spell_warl_glyph_of_shadowflame : public SpellScriptLoader } }; -// -48181 - Haunt +// 48181 - Haunt +/// Updated 4.3.4 class spell_warl_haunt : public SpellScriptLoader { public: @@ -561,7 +731,8 @@ class spell_warl_haunt : public SpellScriptLoader } }; -// -755 - Health Funnel +// 755 - Health Funnel +/// Updated 4.3.4 class spell_warl_health_funnel : public SpellScriptLoader { public: @@ -591,10 +762,28 @@ class spell_warl_health_funnel : public SpellScriptLoader target->RemoveAurasDueToSpell(SPELL_WARLOCK_IMPROVED_HEALTH_FUNNEL_BUFF_R2); } + void OnPeriodic(AuraEffect const* aurEff) + { + Unit* caster = GetCaster(); + if (!caster) + return; + //! HACK for self damage, is not blizz :/ + uint32 damage = caster->CountPctFromMaxHealth(aurEff->GetBaseAmount()); + + if (Player* modOwner = caster->GetSpellModOwner()) + modOwner->ApplySpellMod(GetId(), SPELLMOD_COST, damage); + + SpellNonMeleeDamage damageInfo(caster, caster, GetSpellInfo()->Id, GetSpellInfo()->SchoolMask); + damageInfo.damage = damage; + caster->SendSpellNonMeleeDamageLog(&damageInfo); + caster->DealSpellDamage(&damageInfo, false); + } + void Register() override { - OnEffectRemove += AuraEffectRemoveFn(spell_warl_health_funnel_AuraScript::RemoveEffect, EFFECT_0, SPELL_AURA_PERIODIC_HEAL, AURA_EFFECT_HANDLE_REAL); - OnEffectApply += AuraEffectApplyFn(spell_warl_health_funnel_AuraScript::ApplyEffect, EFFECT_0, SPELL_AURA_PERIODIC_HEAL, AURA_EFFECT_HANDLE_REAL); + OnEffectApply += AuraEffectApplyFn(spell_warl_health_funnel_AuraScript::ApplyEffect, EFFECT_0, SPELL_AURA_OBS_MOD_HEALTH, AURA_EFFECT_HANDLE_REAL); + OnEffectRemove += AuraEffectRemoveFn(spell_warl_health_funnel_AuraScript::RemoveEffect, EFFECT_0, SPELL_AURA_OBS_MOD_HEALTH, AURA_EFFECT_HANDLE_REAL); + OnEffectPeriodic += AuraEffectPeriodicFn(spell_warl_health_funnel_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_OBS_MOD_HEALTH); } }; @@ -604,7 +793,73 @@ class spell_warl_health_funnel : public SpellScriptLoader } }; -// -1454 - Life Tap +// 6262 - Healthstone +class spell_warl_healthstone_heal : public SpellScriptLoader +{ + public: + spell_warl_healthstone_heal() : SpellScriptLoader("spell_warl_healthstone_heal") { } + + class spell_warl_healthstone_heal_SpellScript : public SpellScript + { + PrepareSpellScript(spell_warl_healthstone_heal_SpellScript); + + void HandleOnHit() + { + int32 heal = int32(CalculatePct(GetCaster()->GetCreateHealth(), GetHitHeal())); + SetHitHeal(heal); + } + + void Register() override + { + OnHit += SpellHitFn(spell_warl_healthstone_heal_SpellScript::HandleOnHit); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_warl_healthstone_heal_SpellScript(); + } +}; + +// -18119 - Improved Soul Fire +class spell_warl_improved_soul_fire : public SpellScriptLoader +{ + public: + spell_warl_improved_soul_fire() : SpellScriptLoader("spell_warl_improved_soul_fire") { } + + class spell_warl_improved_soul_fire_AuraScript : public AuraScript + { + PrepareAuraScript(spell_warl_improved_soul_fire_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_IMPROVED_SOUL_FIRE_PCT) || + !sSpellMgr->GetSpellInfo(SPELL_WARLOCK_IMPROVED_SOUL_FIRE_STATE)) + return false; + return true; + } + + void OnProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + GetTarget()->CastCustomSpell(SPELL_WARLOCK_IMPROVED_SOUL_FIRE_PCT, SPELLVALUE_BASE_POINT0, aurEff->GetAmount(), GetTarget(), true, NULL, aurEff); + GetTarget()->CastSpell(GetTarget(), SPELL_WARLOCK_IMPROVED_SOUL_FIRE_STATE, true, NULL, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_warl_improved_soul_fire_AuraScript::OnProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_warl_improved_soul_fire_AuraScript(); + } +}; + +// 1454 - Life Tap +/// Updated 4.3.4 class spell_warl_life_tap : public SpellScriptLoader { public: @@ -619,9 +874,10 @@ class spell_warl_life_tap : public SpellScriptLoader return GetCaster()->GetTypeId() == TYPEID_PLAYER; } - bool Validate(SpellInfo const* /*spell*/) override + bool Validate(SpellInfo const* /*spellInfo*/) override { - if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_LIFE_TAP_ENERGIZE) || !sSpellMgr->GetSpellInfo(SPELL_WARLOCK_LIFE_TAP_ENERGIZE_2)) + if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_LIFE_TAP_ENERGIZE) || + !sSpellMgr->GetSpellInfo(SPELL_WARLOCK_LIFE_TAP_ENERGIZE_2)) return false; return true; } @@ -631,8 +887,8 @@ class spell_warl_life_tap : public SpellScriptLoader Player* caster = GetCaster()->ToPlayer(); if (Unit* target = GetHitUnit()) { - int32 damage = GetEffectValue(); - int32 mana = int32(damage + (caster->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS+SPELL_SCHOOL_SHADOW) * 0.5f)); + int32 damage = caster->CountPctFromMaxHealth(GetSpellInfo()->Effects[EFFECT_2].CalcValue()); + int32 mana = CalculatePct(damage, GetSpellInfo()->Effects[EFFECT_1].CalcValue()); // Shouldn't Appear in Combat Log target->ModifyHealth(-damage); @@ -644,12 +900,9 @@ class spell_warl_life_tap : public SpellScriptLoader caster->CastCustomSpell(target, SPELL_WARLOCK_LIFE_TAP_ENERGIZE, &mana, NULL, NULL, false); // Mana Feed - int32 manaFeedVal = 0; if (AuraEffect const* aurEff = caster->GetAuraEffect(SPELL_AURA_ADD_FLAT_MODIFIER, SPELLFAMILY_WARLOCK, WARLOCK_ICON_ID_MANA_FEED, 0)) - manaFeedVal = aurEff->GetAmount(); - - if (manaFeedVal > 0) { + int32 manaFeedVal = aurEff->GetAmount(); ApplyPct(manaFeedVal, mana); caster->CastCustomSpell(caster, SPELL_WARLOCK_LIFE_TAP_ENERGIZE_2, &manaFeedVal, NULL, NULL, true, NULL); } @@ -658,7 +911,7 @@ class spell_warl_life_tap : public SpellScriptLoader SpellCastResult CheckCast() { - if ((int32(GetCaster()->GetHealth()) > int32(GetSpellInfo()->Effects[EFFECT_0].CalcValue() + (6.3875 * GetSpellInfo()->BaseLevel)))) + if (int32(GetCaster()->GetHealth()) > int32(GetCaster()->CountPctFromMaxHealth(GetSpellInfo()->Effects[EFFECT_2].CalcValue()))) return SPELL_CAST_OK; return SPELL_FAILED_FIZZLE; } @@ -676,35 +929,92 @@ class spell_warl_life_tap : public SpellScriptLoader } }; -// 18541 - Ritual of Doom Effect -class spell_warl_ritual_of_doom_effect : public SpellScriptLoader +// 687 - Demon Armor +// 28176 - Fel Armor +class spell_warl_nether_ward_overrride : public SpellScriptLoader { public: - spell_warl_ritual_of_doom_effect() : SpellScriptLoader("spell_warl_ritual_of_doom_effect") { } + spell_warl_nether_ward_overrride() : SpellScriptLoader("spell_warl_nether_ward_overrride") { } - class spell_warl_ritual_of_doom_effect_SpellScript : public SpellScript + class spell_warl_nether_ward_overrride_AuraScript : public AuraScript { - PrepareSpellScript(spell_warl_ritual_of_doom_effect_SpellScript); + PrepareAuraScript(spell_warl_nether_ward_overrride_AuraScript); - void HandleDummy(SpellEffIndex /*effIndex*/) + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_NETHER_TALENT) || + !sSpellMgr->GetSpellInfo(SPELL_WARLOCK_NETHER_WARD) || + !sSpellMgr->GetSpellInfo(SPELL_WARLOCK_SHADOW_WARD)) + return false; + return true; + } + + void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/) + { + if (GetUnitOwner()->HasAura(SPELL_WARLOCK_NETHER_TALENT)) + amount = SPELL_WARLOCK_NETHER_WARD; + else + amount = SPELL_WARLOCK_SHADOW_WARD; + } + + void Register() override + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_nether_ward_overrride_AuraScript::CalculateAmount, EFFECT_2, SPELL_AURA_OVERRIDE_ACTIONBAR_SPELLS); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_warl_nether_ward_overrride_AuraScript(); + } +}; + +// 6358 - Seduction (Special Ability) +class spell_warl_seduction : public SpellScriptLoader +{ + public: + spell_warl_seduction() : SpellScriptLoader("spell_warl_seduction") { } + + class spell_warl_seduction_SpellScript : public SpellScript + { + PrepareSpellScript(spell_warl_seduction_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_GLYPH_OF_SUCCUBUS) || + !sSpellMgr->GetSpellInfo(SPELL_PRIEST_SHADOW_WORD_DEATH)) + return false; + return true; + } + + void HandleScriptEffect(SpellEffIndex /*effIndex*/) { Unit* caster = GetCaster(); - caster->CastSpell(caster, GetEffectValue(), true); + if (Unit* target = GetHitUnit()) + { + if (caster->GetOwner() && caster->GetOwner()->HasAura(SPELL_WARLOCK_GLYPH_OF_SUCCUBUS)) + { + target->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE, 0, target->GetAura(SPELL_PRIEST_SHADOW_WORD_DEATH)); // SW:D shall not be removed. + target->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE_PERCENT); + target->RemoveAurasByType(SPELL_AURA_PERIODIC_LEECH); + } + } } void Register() override { - OnEffectHit += SpellEffectFn(spell_warl_ritual_of_doom_effect_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_warl_seduction_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_APPLY_AURA); } }; SpellScript* GetSpellScript() const override { - return new spell_warl_ritual_of_doom_effect_SpellScript(); + return new spell_warl_seduction_SpellScript(); } }; -// -27285 - Seed of Corruption +// 27285 - Seed of Corruption +/// Updated 4.3.4 class spell_warl_seed_of_corruption : public SpellScriptLoader { public: @@ -732,6 +1042,42 @@ class spell_warl_seed_of_corruption : public SpellScriptLoader } }; +// -18094 - Nightfall +// 56218 - Glyph of Corruption +class spell_warl_shadow_trance_proc : public SpellScriptLoader +{ + public: + spell_warl_shadow_trance_proc() : SpellScriptLoader("spell_warl_shadow_trance_proc") { } + + class spell_warl_shadow_trance_proc_AuraScript : public AuraScript + { + PrepareAuraScript(spell_warl_shadow_trance_proc_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_SHADOW_TRANCE)) + return false; + return true; + } + + void OnProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + GetTarget()->CastSpell(GetTarget(), SPELL_WARLOCK_SHADOW_TRANCE, true, NULL, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_warl_shadow_trance_proc_AuraScript::OnProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_warl_shadow_trance_proc_AuraScript(); + } +}; + // -7235 - Shadow Ward class spell_warl_shadow_ward : public SpellScriptLoader { @@ -769,56 +1115,246 @@ class spell_warl_shadow_ward : public SpellScriptLoader } }; -// 63108 - Siphon Life -class spell_warl_siphon_life : public SpellScriptLoader +// -30293 - Soul Leech +class spell_warl_soul_leech : public SpellScriptLoader { public: - spell_warl_siphon_life() : SpellScriptLoader("spell_warl_siphon_life") { } + spell_warl_soul_leech() : SpellScriptLoader("spell_warl_soul_leech") { } - class spell_warl_siphon_life_AuraScript : public AuraScript + class spell_warl_soul_leech_AuraScript : public AuraScript { - PrepareAuraScript(spell_warl_siphon_life_AuraScript); + PrepareAuraScript(spell_warl_soul_leech_AuraScript); bool Validate(SpellInfo const* /*spellInfo*/) override { - if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_SIPHON_LIFE_HEAL)) - return false; - if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_GLYPH_OF_SIPHON_LIFE)) + if (!sSpellMgr->GetSpellInfo(SPELL_GEN_REPLENISHMENT)) return false; return true; } - bool CheckProc(ProcEventInfo& eventInfo) + void OnProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) { - return eventInfo.GetDamageInfo()->GetDamage() && GetTarget()->IsAlive(); + GetTarget()->CastSpell((Unit*)NULL, SPELL_GEN_REPLENISHMENT, true, NULL, aurEff); } - void OnProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + void Register() override { - PreventDefaultAction(); + OnEffectProc += AuraEffectProcFn(spell_warl_soul_leech_AuraScript::OnProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE); + } + }; - int32 amount = int32(CalculatePct(eventInfo.GetDamageInfo()->GetDamage(), aurEff->GetAmount())); - // Glyph of Siphon Life - if (AuraEffect const* glyph = GetTarget()->GetAuraEffect(SPELL_WARLOCK_GLYPH_OF_SIPHON_LIFE, EFFECT_0)) - AddPct(amount, glyph->GetAmount()); + AuraScript* GetAuraScript() const override + { + return new spell_warl_soul_leech_AuraScript(); + } +}; + +// 86121 - Soul Swap +class spell_warl_soul_swap : public SpellScriptLoader +{ + public: + spell_warl_soul_swap() : SpellScriptLoader("spell_warl_soul_swap") { } + + class spell_warl_soul_swap_SpellScript : public SpellScript + { + PrepareSpellScript(spell_warl_soul_swap_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_GLYPH_OF_SOUL_SWAP) || + !sSpellMgr->GetSpellInfo(SPELL_WARLOCK_SOUL_SWAP_CD_MARKER) || + !sSpellMgr->GetSpellInfo(SPELL_WARLOCK_SOUL_SWAP_OVERRIDE)) + return false; + return true; + } - GetTarget()->CastCustomSpell(SPELL_WARLOCK_SIPHON_LIFE_HEAL, SPELLVALUE_BASE_POINT0, amount, GetTarget(), true, NULL, aurEff); + void HandleHit(SpellEffIndex /*effIndex*/) + { + GetCaster()->CastSpell(GetCaster(), SPELL_WARLOCK_SOUL_SWAP_OVERRIDE, true); + GetHitUnit()->CastSpell(GetCaster(), SPELL_WARLOCK_SOUL_SWAP_DOT_MARKER, true); } void Register() override { - DoCheckProc += AuraCheckProcFn(spell_warl_siphon_life_AuraScript::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_warl_siphon_life_AuraScript::OnProc, EFFECT_0, SPELL_AURA_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_warl_soul_swap_SpellScript::HandleHit, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); } }; + SpellScript* GetSpellScript() const override + { + return new spell_warl_soul_swap_SpellScript(); + } +}; + +// 86211 - Soul Swap Override - Also acts as a dot container +class spell_warl_soul_swap_override : public SpellScriptLoader +{ + public: + spell_warl_soul_swap_override() : SpellScriptLoader("spell_warl_soul_swap_override") { } + + class spell_warl_soul_swap_override_AuraScript : public AuraScript + { + PrepareAuraScript(spell_warl_soul_swap_override_AuraScript); + + bool Load() override + { + _swapCaster = NULL; + return true; + } + + //! Forced to, pure virtual functions must have a body when linking + void Register() override { } + + public: + void AddDot(uint32 id) { _dotList.push_back(id); } + std::list<uint32> const GetDotList() const { return _dotList; } + Unit* GetOriginalSwapSource() const { return _swapCaster; } + void SetOriginalSwapSource(Unit* victim) { _swapCaster = victim; } + + private: + std::list<uint32> _dotList; + Unit* _swapCaster; + }; + AuraScript* GetAuraScript() const override { - return new spell_warl_siphon_life_AuraScript(); + return new spell_warl_soul_swap_override_AuraScript(); } }; +typedef spell_warl_soul_swap_override::spell_warl_soul_swap_override_AuraScript SoulSwapOverrideAuraScript; + +//! Soul Swap Copy Spells - 92795 - Simply copies spell IDs. +class spell_warl_soul_swap_dot_marker : public SpellScriptLoader +{ + public: + spell_warl_soul_swap_dot_marker() : SpellScriptLoader("spell_warl_soul_swap_dot_marker") { } + + class spell_warl_soul_swap_dot_marker_SpellScript : public SpellScript + { + PrepareSpellScript(spell_warl_soul_swap_dot_marker_SpellScript); + + void HandleHit(SpellEffIndex effIndex) + { + Unit* swapVictim = GetCaster(); + Unit* warlock = GetHitUnit(); + if (!warlock || !swapVictim) + return; + + flag96 classMask = GetSpellInfo()->Effects[effIndex].SpellClassMask; + + Unit::AuraApplicationMap const& appliedAuras = swapVictim->GetAppliedAuras(); + SoulSwapOverrideAuraScript* swapSpellScript = NULL; + if (Aura* swapOverrideAura = warlock->GetAura(SPELL_WARLOCK_SOUL_SWAP_OVERRIDE)) + swapSpellScript = dynamic_cast<SoulSwapOverrideAuraScript*>(swapOverrideAura->GetScriptByName("spell_warl_soul_swap_override")); + + if (swapSpellScript == NULL) + return; + + for (Unit::AuraApplicationMap::const_iterator itr = appliedAuras.begin(); itr != appliedAuras.end(); ++itr) + { + SpellInfo const* spellProto = itr->second->GetBase()->GetSpellInfo(); + if (itr->second->GetBase()->GetCaster() == warlock) + if (spellProto->SpellFamilyName == SPELLFAMILY_WARLOCK && (spellProto->SpellFamilyFlags & classMask)) + swapSpellScript->AddDot(itr->first); + } + + swapSpellScript->SetOriginalSwapSource(swapVictim); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_warl_soul_swap_dot_marker_SpellScript::HandleHit, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_warl_soul_swap_dot_marker_SpellScript(); + } +}; + +// 86213 - Soul Swap Exhale +class spell_warl_soul_swap_exhale : public SpellScriptLoader +{ +public: + spell_warl_soul_swap_exhale() : SpellScriptLoader("spell_warl_soul_swap_exhale") { } + + class spell_warl_soul_swap_exhale_SpellScript : public SpellScript + { + PrepareSpellScript(spell_warl_soul_swap_exhale_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_SOUL_SWAP_MOD_COST) || + !sSpellMgr->GetSpellInfo(SPELL_WARLOCK_SOUL_SWAP_OVERRIDE)) + return false; + return true; + } + + SpellCastResult CheckCast() + { + Unit* currentTarget = GetExplTargetUnit(); + Unit* swapTarget = NULL; + if (Aura const* swapOverride = GetCaster()->GetAura(SPELL_WARLOCK_SOUL_SWAP_OVERRIDE)) + if (SoulSwapOverrideAuraScript* swapScript = dynamic_cast<SoulSwapOverrideAuraScript*>(swapOverride->GetScriptByName("spell_warl_soul_swap_override"))) + swapTarget = swapScript->GetOriginalSwapSource(); + + // Soul Swap Exhale can't be cast on the same target than Soul Swap + if (swapTarget && currentTarget && swapTarget == currentTarget) + return SPELL_FAILED_BAD_TARGETS; + + return SPELL_CAST_OK; + } + + void OnEffectHit(SpellEffIndex /*effIndex*/) + { + GetCaster()->CastSpell(GetCaster(), SPELL_WARLOCK_SOUL_SWAP_MOD_COST, true); + bool hasGlyph = GetCaster()->HasAura(SPELL_WARLOCK_GLYPH_OF_SOUL_SWAP); + + std::list<uint32> dotList; + Unit* swapSource = NULL; + if (Aura const* swapOverride = GetCaster()->GetAura(SPELL_WARLOCK_SOUL_SWAP_OVERRIDE)) + { + SoulSwapOverrideAuraScript* swapScript = dynamic_cast<SoulSwapOverrideAuraScript*>(swapOverride->GetScriptByName("spell_warl_soul_swap_override")); + if (!swapScript) + return; + dotList = swapScript->GetDotList(); + swapSource = swapScript->GetOriginalSwapSource(); + } + + if (dotList.empty()) + return; + + for (std::list<uint32>::const_iterator itr = dotList.begin(); itr != dotList.end(); ++itr) + { + GetCaster()->AddAura(*itr, GetHitUnit()); + if (!hasGlyph && swapSource) + swapSource->RemoveAurasDueToSpell(*itr); + } + + // Remove Soul Swap Exhale buff + GetCaster()->RemoveAurasDueToSpell(SPELL_WARLOCK_SOUL_SWAP_OVERRIDE); + + if (hasGlyph) // Add a cooldown on Soul Swap if caster has the glyph + GetCaster()->CastSpell(GetCaster(), SPELL_WARLOCK_SOUL_SWAP_CD_MARKER, false); + } + + void Register() override + { + OnCheckCast += SpellCheckCastFn(spell_warl_soul_swap_exhale_SpellScript::CheckCast); + OnEffectHitTarget += SpellEffectFn(spell_warl_soul_swap_exhale_SpellScript::OnEffectHit, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_warl_soul_swap_exhale_SpellScript(); + } +}; + // 29858 - Soulshatter +/// Updated 4.3.4 class spell_warl_soulshatter : public SpellScriptLoader { public: @@ -839,10 +1375,8 @@ class spell_warl_soulshatter : public SpellScriptLoader { Unit* caster = GetCaster(); if (Unit* target = GetHitUnit()) - { if (target->CanHaveThreatList() && target->getThreatManager().getThreat(caster) > 0.0f) caster->CastSpell(target, SPELL_WARLOCK_SOULSHATTER, true); - } } void Register() override @@ -857,7 +1391,8 @@ class spell_warl_soulshatter : public SpellScriptLoader } }; -// -30108 - Unstable Affliction +// 30108, 34438, 34439, 35183 - Unstable Affliction +/// Updated 4.3.4 class spell_warl_unstable_affliction : public SpellScriptLoader { public: @@ -877,7 +1412,7 @@ class spell_warl_unstable_affliction : public SpellScriptLoader void HandleDispel(DispelInfo* dispelInfo) { if (Unit* caster = GetCaster()) - if (AuraEffect const* aurEff = GetEffect(EFFECT_0)) + if (AuraEffect const* aurEff = GetEffect(EFFECT_1)) { int32 damage = aurEff->GetAmount() * 9; // backfire damage and silence @@ -899,22 +1434,34 @@ class spell_warl_unstable_affliction : public SpellScriptLoader void AddSC_warlock_spell_scripts() { + new spell_warl_aftermath(); + new spell_warl_bane_of_doom(); new spell_warl_banish(); + new spell_warl_conflagrate(); new spell_warl_create_healthstone(); - new spell_warl_curse_of_doom(); new spell_warl_demonic_circle_summon(); new spell_warl_demonic_circle_teleport(); new spell_warl_demonic_empowerment(); + new spell_warl_demon_soul(); new spell_warl_everlasting_affliction(); + new spell_warl_fel_flame(); new spell_warl_fel_synergy(); new spell_warl_glyph_of_shadowflame(); new spell_warl_haunt(); new spell_warl_health_funnel(); + new spell_warl_healthstone_heal(); + new spell_warl_improved_soul_fire(); new spell_warl_life_tap(); - new spell_warl_ritual_of_doom_effect(); + new spell_warl_nether_ward_overrride(); + new spell_warl_seduction(); new spell_warl_seed_of_corruption(); + new spell_warl_shadow_trance_proc(); new spell_warl_shadow_ward(); - new spell_warl_siphon_life(); + new spell_warl_soul_leech(); + new spell_warl_soul_swap(); + new spell_warl_soul_swap_dot_marker(); + new spell_warl_soul_swap_exhale(); + new spell_warl_soul_swap_override(); new spell_warl_soulshatter(); new spell_warl_unstable_affliction(); } diff --git a/src/server/scripts/Spells/spell_warrior.cpp b/src/server/scripts/Spells/spell_warrior.cpp index fd1c785cf50..529d62b5297 100644 --- a/src/server/scripts/Spells/spell_warrior.cpp +++ b/src/server/scripts/Spells/spell_warrior.cpp @@ -32,19 +32,26 @@ enum WarriorSpells SPELL_WARRIOR_BLOODTHIRST = 23885, SPELL_WARRIOR_BLOODTHIRST_DAMAGE = 23881, SPELL_WARRIOR_CHARGE = 34846, - SPELL_WARRIOR_DAMAGE_SHIELD_DAMAGE = 59653, + SPELL_WARRIOR_COLOSSUS_SMASH = 86346, SPELL_WARRIOR_DEEP_WOUNDS_RANK_1 = 12162, SPELL_WARRIOR_DEEP_WOUNDS_RANK_2 = 12850, SPELL_WARRIOR_DEEP_WOUNDS_RANK_3 = 12868, SPELL_WARRIOR_DEEP_WOUNDS_RANK_PERIODIC = 12721, SPELL_WARRIOR_EXECUTE = 20647, SPELL_WARRIOR_GLYPH_OF_EXECUTION = 58367, - SPELL_WARRIOR_GLYPH_OF_VIGILANCE = 63326, SPELL_WARRIOR_JUGGERNAUT_CRIT_BONUS_BUFF = 65156, SPELL_WARRIOR_JUGGERNAUT_CRIT_BONUS_TALENT = 64976, SPELL_WARRIOR_LAST_STAND_TRIGGERED = 12976, + SPELL_WARRIOR_MORTAL_STRIKE = 12294, + SPELL_WARRIOR_RALLYING_CRY = 97463, + SPELL_WARRIOR_REND = 94009, SPELL_WARRIOR_RETALIATION_DAMAGE = 22858, - SPELL_WARRIOR_SLAM = 50783, + SPELL_WARRIOR_SECOUND_WIND_PROC_RANK_1 = 29834, + SPELL_WARRIOR_SECOUND_WIND_PROC_RANK_2 = 29838, + SPELL_WARRIOR_SECOUND_WIND_TRIGGER_RANK_1 = 29841, + SPELL_WARRIOR_SECOUND_WIND_TRIGGER_RANK_2 = 29842, + SPELL_WARRIOR_SHIELD_SLAM = 23922, + SPELL_WARRIOR_SLAM = 50782, SPELL_WARRIOR_SUNDER_ARMOR = 58567, SPELL_WARRIOR_SWEEPING_STRIKES_EXTRA_ATTACK_1 = 12723, SPELL_WARRIOR_SWEEPING_STRIKES_EXTRA_ATTACK_2 = 26654, @@ -54,7 +61,7 @@ enum WarriorSpells SPELL_WARRIOR_UNRELENTING_ASSAULT_TRIGGER_1 = 64849, SPELL_WARRIOR_UNRELENTING_ASSAULT_TRIGGER_2 = 64850, SPELL_WARRIOR_VIGILANCE_PROC = 50725, - SPELL_WARRIOR_VIGILANCE_REDIRECT_THREAT = 59665 + SPELL_WARRIOR_VENGEANCE = 76691 }; enum WarriorSpellIcons @@ -62,15 +69,15 @@ enum WarriorSpellIcons WARRIOR_ICON_ID_SUDDEN_DEATH = 1989 }; + enum MiscSpells { SPELL_PALADIN_BLESSING_OF_SANCTUARY = 20911, SPELL_PALADIN_GREATER_BLESSING_OF_SANCTUARY = 25899, - SPELL_PRIEST_RENEWED_HOPE = 63944, - SPELL_GEN_DAMAGE_REDUCTION_AURA = 68066, + SPELL_PRIEST_RENEWED_HOPE = 63944 }; -// 23881 - Bloodthirst +/// Updated 4.3.4 class spell_warr_bloodthirst : public SpellScriptLoader { public: @@ -112,7 +119,7 @@ class spell_warr_bloodthirst : public SpellScriptLoader } }; -// 23880 - Bloodthirst (Heal) +/// Updated 4.3.4 class spell_warr_bloodthirst_heal : public SpellScriptLoader { public: @@ -125,7 +132,7 @@ class spell_warr_bloodthirst_heal : public SpellScriptLoader void HandleHeal(SpellEffIndex /*effIndex*/) { if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(SPELL_WARRIOR_BLOODTHIRST_DAMAGE)) - SetHitHeal(GetCaster()->CountPctFromMaxHealth(spellInfo->Effects[EFFECT_1].CalcValue(GetCaster()))); + SetHitHeal(GetCaster()->CountPctFromMaxHealth(spellInfo->Effects[EFFECT_1].CalcValue(GetCaster())) / 100); } void Register() override @@ -140,7 +147,7 @@ class spell_warr_bloodthirst_heal : public SpellScriptLoader } }; -// -100 - Charge +/// Updated 4.3.4 class spell_warr_charge : public SpellScriptLoader { public: @@ -152,7 +159,9 @@ class spell_warr_charge : public SpellScriptLoader bool Validate(SpellInfo const* /*spellInfo*/) override { - if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_JUGGERNAUT_CRIT_BONUS_TALENT) || !sSpellMgr->GetSpellInfo(SPELL_WARRIOR_JUGGERNAUT_CRIT_BONUS_BUFF) || !sSpellMgr->GetSpellInfo(SPELL_WARRIOR_CHARGE)) + if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_JUGGERNAUT_CRIT_BONUS_TALENT) || + !sSpellMgr->GetSpellInfo(SPELL_WARRIOR_JUGGERNAUT_CRIT_BONUS_BUFF) || + !sSpellMgr->GetSpellInfo(SPELL_WARRIOR_CHARGE)) return false; return true; } @@ -180,7 +189,7 @@ class spell_warr_charge : public SpellScriptLoader } }; -// 12809 - Concussion Blow +/// Updated 4.3.4 class spell_warr_concussion_blow : public SpellScriptLoader { public: @@ -207,44 +216,6 @@ class spell_warr_concussion_blow : public SpellScriptLoader } }; -// -58872 - Damage Shield -class spell_warr_damage_shield : public SpellScriptLoader -{ - public: - spell_warr_damage_shield() : SpellScriptLoader("spell_warr_damage_shield") { } - - class spell_warr_damage_shield_AuraScript : public AuraScript - { - PrepareAuraScript(spell_warr_damage_shield_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_DAMAGE_SHIELD_DAMAGE)) - return false; - return true; - } - - void OnProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - // % of amount blocked - int32 damage = CalculatePct(int32(GetTarget()->GetShieldBlockValue()), aurEff->GetAmount()); - GetTarget()->CastCustomSpell(SPELL_WARRIOR_DAMAGE_SHIELD_DAMAGE, SPELLVALUE_BASE_POINT0, damage, eventInfo.GetProcTarget(), true, NULL, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_warr_damage_shield_AuraScript::OnProc, EFFECT_0, SPELL_AURA_DUMMY); - } - }; - - AuraScript* GetAuraScript() const override - { - return new spell_warr_damage_shield_AuraScript(); - } -}; - // -12162 - Deep Wounds class spell_warr_deep_wounds : public SpellScriptLoader { @@ -257,7 +228,10 @@ class spell_warr_deep_wounds : public SpellScriptLoader bool Validate(SpellInfo const* /*spellInfo*/) override { - if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_DEEP_WOUNDS_RANK_1) || !sSpellMgr->GetSpellInfo(SPELL_WARRIOR_DEEP_WOUNDS_RANK_2) || !sSpellMgr->GetSpellInfo(SPELL_WARRIOR_DEEP_WOUNDS_RANK_3)) + if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_DEEP_WOUNDS_RANK_1) || + !sSpellMgr->GetSpellInfo(SPELL_WARRIOR_DEEP_WOUNDS_RANK_2) || + !sSpellMgr->GetSpellInfo(SPELL_WARRIOR_DEEP_WOUNDS_RANK_3) || + !sSpellMgr->GetSpellInfo(SPELL_WARRIOR_DEEP_WOUNDS_RANK_PERIODIC)) return false; return true; } @@ -300,7 +274,7 @@ class spell_warr_deep_wounds : public SpellScriptLoader } }; -// -5308 - Execute +/// Updated 4.3.4 class spell_warr_execute : public SpellScriptLoader { public: @@ -310,43 +284,35 @@ class spell_warr_execute : public SpellScriptLoader { PrepareSpellScript(spell_warr_execute_SpellScript); - bool Validate(SpellInfo const* /*spellInfo*/) override - { - if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_EXECUTE) || !sSpellMgr->GetSpellInfo(SPELL_WARRIOR_GLYPH_OF_EXECUTION)) - return false; - return true; - } - - void HandleEffect(SpellEffIndex effIndex) + void HandleEffect(SpellEffIndex /*effIndex*/) { Unit* caster = GetCaster(); - if (Unit* target = GetHitUnit()) + if (GetHitUnit()) { SpellInfo const* spellInfo = GetSpellInfo(); - int32 rageUsed = std::min<int32>(300 - spellInfo->CalcPowerCost(caster, SpellSchoolMask(spellInfo->SchoolMask)), caster->GetPower(POWER_RAGE)); + int32 rageUsed = std::min<int32>(200 - spellInfo->CalcPowerCost(caster, SpellSchoolMask(spellInfo->SchoolMask)), caster->GetPower(POWER_RAGE)); int32 newRage = std::max<int32>(0, caster->GetPower(POWER_RAGE) - rageUsed); // Sudden Death rage save if (AuraEffect* aurEff = caster->GetAuraEffect(SPELL_AURA_PROC_TRIGGER_SPELL, SPELLFAMILY_GENERIC, WARRIOR_ICON_ID_SUDDEN_DEATH, EFFECT_0)) { - int32 ragesave = aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue() * 10; + int32 ragesave = aurEff->GetSpellInfo()->Effects[EFFECT_0].CalcValue() * 10; newRage = std::max(newRage, ragesave); } caster->SetPower(POWER_RAGE, uint32(newRage)); - // Glyph of Execution bonus - if (AuraEffect* aurEff = caster->GetAuraEffect(SPELL_WARRIOR_GLYPH_OF_EXECUTION, EFFECT_0)) - rageUsed += aurEff->GetAmount() * 10; - - int32 bp = GetEffectValue() + int32(rageUsed * spellInfo->Effects[effIndex].DamageMultiplier + caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.2f); - caster->CastCustomSpell(target, SPELL_WARRIOR_EXECUTE, &bp, NULL, NULL, true, NULL, NULL, GetOriginalCaster()->GetGUID()); + /// Formula taken from the DBC: "${10+$AP*0.437*$m1/100}" + int32 baseDamage = int32(10 + caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.437f * GetEffectValue() / 100.0f); + /// Formula taken from the DBC: "${$ap*0.874*$m1/100-1} = 20 rage" + int32 moreDamage = int32(rageUsed * (caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.874f * GetEffectValue() / 100.0f - 1) / 200); + SetHitDamage(baseDamage + moreDamage); } } void Register() override { - OnEffectHitTarget += SpellEffectFn(spell_warr_execute_SpellScript::HandleEffect, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_warr_execute_SpellScript::HandleEffect, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); } }; @@ -448,6 +414,44 @@ class spell_warr_intimidating_shout : public SpellScriptLoader } }; +// -84583 Lambs to the Slaughter +class spell_warr_lambs_to_the_slaughter : public SpellScriptLoader +{ + public: + spell_warr_lambs_to_the_slaughter() : SpellScriptLoader("spell_warr_lambs_to_the_slaughter") { } + + class spell_warr_lambs_to_the_slaughter_AuraScript : public AuraScript + { + PrepareAuraScript(spell_warr_lambs_to_the_slaughter_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_MORTAL_STRIKE) || + !sSpellMgr->GetSpellInfo(SPELL_WARRIOR_REND)) + return false; + return true; + } + + void OnProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) + { + if (Aura* aur = eventInfo.GetProcTarget()->GetAura(SPELL_WARRIOR_REND, GetTarget()->GetGUID())) + aur->SetDuration(aur->GetSpellInfo()->GetMaxDuration(), true); + + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_warr_lambs_to_the_slaughter_AuraScript::OnProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_warr_lambs_to_the_slaughter_AuraScript(); + } +}; + +/// Updated 4.3.4 // 12975 - Last Stand class spell_warr_last_stand : public SpellScriptLoader { @@ -474,6 +478,7 @@ class spell_warr_last_stand : public SpellScriptLoader void Register() override { + // add dummy effect spell handler to Last Stand OnEffectHit += SpellEffectFn(spell_warr_last_stand_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -484,7 +489,7 @@ class spell_warr_last_stand : public SpellScriptLoader } }; -// 7384, 7887, 11584, 11585 - Overpower +// 7384 - Overpower class spell_warr_overpower : public SpellScriptLoader { public: @@ -522,7 +527,48 @@ class spell_warr_overpower : public SpellScriptLoader } }; -// -772 - Rend +// 97462 - Rallying Cry +class spell_warr_rallying_cry : public SpellScriptLoader +{ + public: + spell_warr_rallying_cry() : SpellScriptLoader("spell_warr_rallying_cry") { } + + class spell_warr_rallying_cry_SpellScript : public SpellScript + { + PrepareSpellScript(spell_warr_rallying_cry_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_RALLYING_CRY)) + return false; + return true; + } + + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + int32 basePoints0 = int32(GetHitUnit()->CountPctFromMaxHealth(GetEffectValue())); + + GetCaster()->CastCustomSpell(GetHitUnit(), SPELL_WARRIOR_RALLYING_CRY, &basePoints0, NULL, NULL, true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_warr_rallying_cry_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_warr_rallying_cry_SpellScript(); + } +}; + +// 94009 - Rend class spell_warr_rend : public SpellScriptLoader { public: @@ -538,21 +584,13 @@ class spell_warr_rend : public SpellScriptLoader { canBeRecalculated = false; - // $0.2 * (($MWB + $mwb) / 2 + $AP / 14 * $MWS) bonus per tick + // $0.25 * (($MWB + $mwb) / 2 + $AP / 14 * $MWS) bonus per tick float ap = caster->GetTotalAttackPowerValue(BASE_ATTACK); int32 mws = caster->GetAttackTime(BASE_ATTACK); float mwbMin = caster->GetWeaponDamageRange(BASE_ATTACK, MINDAMAGE); float mwbMax = caster->GetWeaponDamageRange(BASE_ATTACK, MAXDAMAGE); - float mwb = ((mwbMin + mwbMax) / 2 + ap * mws / 14000) * 0.2f; + float mwb = ((mwbMin + mwbMax) / 2 + ap * mws / 14000) * 0.25f; amount += int32(caster->ApplyEffectModifiers(GetSpellInfo(), aurEff->GetEffIndex(), mwb)); - - // "If used while your target is above 75% health, Rend does 35% more damage." - // as for 3.1.3 only ranks above 9 (wrong tooltip?) - if (GetSpellInfo()->GetRank() >= 9) - { - if (GetUnitOwner()->HasAuraState(AURA_STATE_HEALTH_ABOVE_75_PERCENT, GetSpellInfo(), caster)) - AddPct(amount, GetSpellInfo()->Effects[EFFECT_2].CalcValue(caster)); - } } } @@ -588,7 +626,7 @@ class spell_warr_retaliation : public SpellScriptLoader bool CheckProc(ProcEventInfo& eventInfo) { // check attack comes not from behind and warrior is not stunned - return GetTarget()->isInFront(eventInfo.GetActor(), M_PI) && !GetTarget()->HasUnitState(UNIT_STATE_STUNNED); + return GetTarget()->isInFront(eventInfo.GetProcTarget(), M_PI) && !GetTarget()->HasUnitState(UNIT_STATE_STUNNED); } void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) @@ -641,7 +679,7 @@ class spell_warr_shattering_throw : public SpellScriptLoader } }; -// -1464 - Slam +/// Updated 4.3.4 class spell_warr_slam : public SpellScriptLoader { public: @@ -676,6 +714,126 @@ class spell_warr_slam : public SpellScriptLoader } }; +class spell_warr_second_wind_proc : public SpellScriptLoader +{ + public: + spell_warr_second_wind_proc() : SpellScriptLoader("spell_warr_second_wind_proc") { } + + class spell_warr_second_wind_proc_AuraScript : public AuraScript + { + PrepareAuraScript(spell_warr_second_wind_proc_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_SECOUND_WIND_PROC_RANK_1) || + !sSpellMgr->GetSpellInfo(SPELL_WARRIOR_SECOUND_WIND_PROC_RANK_2) || + !sSpellMgr->GetSpellInfo(SPELL_WARRIOR_SECOUND_WIND_TRIGGER_RANK_1) || + !sSpellMgr->GetSpellInfo(SPELL_WARRIOR_SECOUND_WIND_TRIGGER_RANK_2)) + return false; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + if (eventInfo.GetProcTarget() == GetTarget()) + return false; + if (!eventInfo.GetDamageInfo()->GetSpellInfo() || !(eventInfo.GetDamageInfo()->GetSpellInfo()->GetAllEffectsMechanicMask() & ((1 << MECHANIC_ROOT) | (1 << MECHANIC_STUN)))) + return false; + return true; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + uint32 spellId = 0; + + if (GetSpellInfo()->Id == SPELL_WARRIOR_SECOUND_WIND_PROC_RANK_1) + spellId = SPELL_WARRIOR_SECOUND_WIND_TRIGGER_RANK_1; + else if (GetSpellInfo()->Id == SPELL_WARRIOR_SECOUND_WIND_PROC_RANK_2) + spellId = SPELL_WARRIOR_SECOUND_WIND_TRIGGER_RANK_2; + if (!spellId) + return; + + GetTarget()->CastSpell(GetTarget(), spellId, true, NULL, aurEff); + + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_warr_second_wind_proc_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_warr_second_wind_proc_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + + }; + + AuraScript* GetAuraScript() const override + { + return new spell_warr_second_wind_proc_AuraScript(); + } +}; + +class spell_warr_second_wind_trigger : public SpellScriptLoader +{ + public: + spell_warr_second_wind_trigger() : SpellScriptLoader("spell_warr_second_wind_trigger") { } + + class spell_warr_second_wind_trigger_AuraScript : public AuraScript + { + PrepareAuraScript(spell_warr_second_wind_trigger_AuraScript); + + void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/) + { + amount = int32(GetUnitOwner()->CountPctFromMaxHealth(amount)); + } + + void Register() override + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warr_second_wind_trigger_AuraScript::CalculateAmount, EFFECT_1, SPELL_AURA_PERIODIC_HEAL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_warr_second_wind_trigger_AuraScript(); + } +}; + +// 52437 - Sudden Death +class spell_warr_sudden_death : public SpellScriptLoader +{ + public: + spell_warr_sudden_death() : SpellScriptLoader("spell_warr_sudden_death") { } + + class spell_warr_sudden_death_AuraScript : public AuraScript + { + PrepareAuraScript(spell_warr_sudden_death_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_COLOSSUS_SMASH)) + return false; + return true; + } + + void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + // Remove cooldown on Colossus Smash + if (Player* player = GetTarget()->ToPlayer()) + player->RemoveSpellCooldown(SPELL_WARRIOR_COLOSSUS_SMASH, true); + } + + void Register() override + { + AfterEffectApply += AuraEffectRemoveFn(spell_warr_sudden_death_AuraScript::HandleApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); // correct? + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_warr_sudden_death_AuraScript(); + } +}; + // 12328, 18765, 35429 - Sweeping Strikes class spell_warr_sweeping_strikes : public SpellScriptLoader { @@ -740,88 +898,123 @@ class spell_warr_sweeping_strikes : public SpellScriptLoader } }; -// 50720 - Vigilance -class spell_warr_vigilance : public SpellScriptLoader +// -46951 - Sword and Board +class spell_warr_sword_and_board : public SpellScriptLoader { public: - spell_warr_vigilance() : SpellScriptLoader("spell_warr_vigilance") { } + spell_warr_sword_and_board() : SpellScriptLoader("spell_warr_sword_and_board") { } - class spell_warr_vigilance_AuraScript : public AuraScript + class spell_warr_sword_and_board_AuraScript : public AuraScript { - PrepareAuraScript(spell_warr_vigilance_AuraScript); + PrepareAuraScript(spell_warr_sword_and_board_AuraScript); bool Validate(SpellInfo const* /*spellInfo*/) override { - if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_GLYPH_OF_VIGILANCE)) - return false; - if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_VIGILANCE_PROC)) - return false; - if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_VIGILANCE_REDIRECT_THREAT)) - return false; - if (!sSpellMgr->GetSpellInfo(SPELL_GEN_DAMAGE_REDUCTION_AURA)) + if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_SHIELD_SLAM)) return false; return true; } - bool Load() override + void OnProc(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/) { - _procTarget = NULL; - return true; + // Remove cooldown on Shield Slam + if (Player* player = GetTarget()->ToPlayer()) + player->RemoveSpellCooldown(SPELL_WARRIOR_SHIELD_SLAM, true); } - void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + void Register() override { - Unit* target = GetTarget(); - target->CastSpell(target, SPELL_GEN_DAMAGE_REDUCTION_AURA, true); + OnEffectProc += AuraEffectProcFn(spell_warr_sword_and_board_AuraScript::OnProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } + }; - if (Unit* caster = GetCaster()) - target->CastSpell(caster, SPELL_WARRIOR_VIGILANCE_REDIRECT_THREAT, true); + AuraScript* GetAuraScript() const override + { + return new spell_warr_sword_and_board_AuraScript(); + } +}; + +// 32216 - Victorious +// 82368 - Victorious +class spell_warr_victorious : public SpellScriptLoader +{ + public: + spell_warr_victorious() : SpellScriptLoader("spell_warr_victorious") { } + + class spell_warr_victorious_AuraScript : public AuraScript + { + PrepareAuraScript(spell_warr_victorious_AuraScript); + + void HandleEffectProc(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + GetTarget()->RemoveAura(GetId()); } - void HandleAfterApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + void Register() override { - //! WORKAROUND - //! this glyph is a proc - if (Unit* caster = GetCaster()) - { - if (AuraEffect const* glyph = caster->GetAuraEffect(SPELL_WARRIOR_GLYPH_OF_VIGILANCE, EFFECT_0)) - GetTarget()->ModifyRedirectThreat(glyph->GetAmount()); - } + OnEffectProc += AuraEffectProcFn(spell_warr_victorious_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY); } + }; - void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + AuraScript* GetAuraScript() const override + { + return new spell_warr_victorious_AuraScript(); + } +}; + +// 50720 - Vigilance +class spell_warr_vigilance : public SpellScriptLoader +{ + public: + spell_warr_vigilance() : SpellScriptLoader("spell_warr_vigilance") { } + + class spell_warr_vigilance_AuraScript : public AuraScript + { + PrepareAuraScript(spell_warr_vigilance_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override { - Unit* target = GetTarget(); - if (target->HasAura(SPELL_GEN_DAMAGE_REDUCTION_AURA) && - !(target->HasAura(SPELL_PALADIN_BLESSING_OF_SANCTUARY) || - target->HasAura(SPELL_PALADIN_GREATER_BLESSING_OF_SANCTUARY) || - target->HasAura(SPELL_PRIEST_RENEWED_HOPE))) - { - target->RemoveAurasDueToSpell(SPELL_GEN_DAMAGE_REDUCTION_AURA); - } + if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_VENGEANCE)) + return false; + return true; + } - target->ResetRedirectThreat(); + bool Load() override + { + _procTarget = NULL; + return true; } - bool CheckProc(ProcEventInfo& /*eventInfo*/) + bool CheckProc(ProcEventInfo& eventInfo) { _procTarget = GetCaster(); - return _procTarget; + return _procTarget && eventInfo.GetDamageInfo(); } - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) { PreventDefaultAction(); + int32 damage = int32(CalculatePct(eventInfo.GetDamageInfo()->GetDamage(), aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue())); + GetTarget()->CastSpell(_procTarget, SPELL_WARRIOR_VIGILANCE_PROC, true, NULL, aurEff); + _procTarget->CastCustomSpell(_procTarget, SPELL_WARRIOR_VENGEANCE, &damage, &damage, &damage, true, NULL, aurEff); + } + + void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Unit* caster = GetCaster()) + { + if (caster->HasAura(SPELL_WARRIOR_VENGEANCE)) + caster->RemoveAurasDueToSpell(SPELL_WARRIOR_VENGEANCE); + } } void Register() override { - OnEffectApply += AuraEffectApplyFn(spell_warr_vigilance_AuraScript::HandleApply, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); - AfterEffectApply += AuraEffectApplyFn(spell_warr_vigilance_AuraScript::HandleAfterApply, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); - OnEffectRemove += AuraEffectRemoveFn(spell_warr_vigilance_AuraScript::HandleRemove, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); DoCheckProc += AuraCheckProcFn(spell_warr_vigilance_AuraScript::CheckProc); OnEffectProc += AuraEffectProcFn(spell_warr_vigilance_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + OnEffectRemove += AuraEffectRemoveFn(spell_warr_vigilance_AuraScript::HandleRemove, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL); } private: @@ -834,7 +1027,7 @@ class spell_warr_vigilance : public SpellScriptLoader } }; -// 50725 - Vigilance +// 50725 Vigilance class spell_warr_vigilance_trigger : public SpellScriptLoader { public: @@ -871,19 +1064,25 @@ void AddSC_warrior_spell_scripts() new spell_warr_bloodthirst_heal(); new spell_warr_charge(); new spell_warr_concussion_blow(); - new spell_warr_damage_shield(); new spell_warr_deep_wounds(); new spell_warr_execute(); new spell_warr_glyph_of_sunder_armor(); new spell_warr_improved_spell_reflection(); new spell_warr_intimidating_shout(); + new spell_warr_lambs_to_the_slaughter(); new spell_warr_last_stand(); new spell_warr_overpower(); + new spell_warr_rallying_cry(); new spell_warr_rend(); new spell_warr_retaliation(); + new spell_warr_second_wind_proc(); + new spell_warr_second_wind_trigger(); new spell_warr_shattering_throw(); new spell_warr_slam(); + new spell_warr_sudden_death(); new spell_warr_sweeping_strikes(); + new spell_warr_sword_and_board(); + new spell_warr_victorious(); new spell_warr_vigilance(); new spell_warr_vigilance_trigger(); } diff --git a/src/server/scripts/World/go_scripts.cpp b/src/server/scripts/World/go_scripts.cpp index ca00b0fc352..9dbcb91dc1a 100644 --- a/src/server/scripts/World/go_scripts.cpp +++ b/src/server/scripts/World/go_scripts.cpp @@ -869,23 +869,6 @@ public: ## go_soulwell ######*/ -enum SoulWellData -{ - GO_SOUL_WELL_R1 = 181621, - GO_SOUL_WELL_R2 = 193169, - - SPELL_IMPROVED_HEALTH_STONE_R1 = 18692, - SPELL_IMPROVED_HEALTH_STONE_R2 = 18693, - - SPELL_CREATE_MASTER_HEALTH_STONE_R0 = 34130, - SPELL_CREATE_MASTER_HEALTH_STONE_R1 = 34149, - SPELL_CREATE_MASTER_HEALTH_STONE_R2 = 34150, - - SPELL_CREATE_FEL_HEALTH_STONE_R0 = 58890, - SPELL_CREATE_FEL_HEALTH_STONE_R1 = 58896, - SPELL_CREATE_FEL_HEALTH_STONE_R2 = 58898, -}; - class go_soulwell : public GameObjectScript { public: @@ -895,39 +878,6 @@ class go_soulwell : public GameObjectScript { go_soulwellAI(GameObject* go) : GameObjectAI(go) { - _stoneSpell = 0; - _stoneId = 0; - switch (go->GetEntry()) - { - case GO_SOUL_WELL_R1: - _stoneSpell = SPELL_CREATE_MASTER_HEALTH_STONE_R0; - if (Unit* owner = go->GetOwner()) - { - if (owner->HasAura(SPELL_IMPROVED_HEALTH_STONE_R1)) - _stoneSpell = SPELL_CREATE_MASTER_HEALTH_STONE_R1; - else if (owner->HasAura(SPELL_CREATE_MASTER_HEALTH_STONE_R2)) - _stoneSpell = SPELL_CREATE_MASTER_HEALTH_STONE_R2; - } - break; - case GO_SOUL_WELL_R2: - _stoneSpell = SPELL_CREATE_FEL_HEALTH_STONE_R0; - if (Unit* owner = go->GetOwner()) - { - if (owner->HasAura(SPELL_IMPROVED_HEALTH_STONE_R1)) - _stoneSpell = SPELL_CREATE_FEL_HEALTH_STONE_R1; - else if (owner->HasAura(SPELL_CREATE_MASTER_HEALTH_STONE_R2)) - _stoneSpell = SPELL_CREATE_FEL_HEALTH_STONE_R2; - } - break; - } - if (_stoneSpell == 0) // Should never happen - return; - - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(_stoneSpell); - if (!spellInfo) - return; - - _stoneId = spellInfo->Effects[EFFECT_0].ItemType; } /// Due to the fact that this GameObject triggers CMSG_GAMEOBJECT_USE @@ -937,31 +887,10 @@ class go_soulwell : public GameObjectScript bool GossipHello(Player* player) override { Unit* owner = go->GetOwner(); - if (_stoneSpell == 0 || _stoneId == 0) - return true; - if (!owner || owner->GetTypeId() != TYPEID_PLAYER || !player->IsInSameRaidWith(owner->ToPlayer())) return true; - - // Don't try to add a stone if we already have one. - if (player->HasItemCount(_stoneId)) - { - if (SpellInfo const* spell = sSpellMgr->GetSpellInfo(_stoneSpell)) - Spell::SendCastResult(player, spell, 0, SPELL_FAILED_TOO_MANY_OF_ITEM); - return true; - } - - owner->CastSpell(player, _stoneSpell, true); - // Item has to actually be created to remove a charge on the well. - if (player->HasItemCount(_stoneId)) - go->AddUse(); - return false; } - - private: - uint32 _stoneSpell; - uint32 _stoneId; }; GameObjectAI* GetAI(GameObject* go) const override diff --git a/src/server/scripts/World/item_scripts.cpp b/src/server/scripts/World/item_scripts.cpp index 4cf2ef971eb..c53fe254db3 100644 --- a/src/server/scripts/World/item_scripts.cpp +++ b/src/server/scripts/World/item_scripts.cpp @@ -76,7 +76,7 @@ public: return false; // error - player->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW, item, NULL); + player->SendEquipError(EQUIP_ERR_CLIENT_LOCKED_OUT, item, NULL); return true; } }; @@ -119,7 +119,7 @@ public: targets.GetUnitTarget()->GetEntry() == 20748 && !targets.GetUnitTarget()->HasAura(32578)) return false; - player->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW, item, NULL); + player->SendEquipError(EQUIP_ERR_CLIENT_LOCKED_OUT, item, NULL); return true; } }; @@ -268,15 +268,13 @@ class item_petrov_cluster_bombs : public ItemScript public: item_petrov_cluster_bombs() : ItemScript("item_petrov_cluster_bombs") { } - bool OnUse(Player* player, Item* item, const SpellCastTargets & /*targets*/) override + bool OnUse(Player* player, Item* /*item*/, const SpellCastTargets & /*targets*/) override { if (player->GetZoneId() != ZONE_ID_HOWLING) return false; if (!player->GetTransport() || player->GetAreaId() != AREA_ID_SHATTERED_STRAITS) { - player->SendEquipError(EQUIP_ERR_NONE, item, NULL); - if (const SpellInfo* spellInfo = sSpellMgr->GetSpellInfo(SPELL_PETROV_BOMB)) Spell::SendCastResult(player, spellInfo, 1, SPELL_FAILED_NOT_HERE); @@ -381,7 +379,7 @@ public: } else player->SendEquipError(EQUIP_ERR_OUT_OF_RANGE, item, NULL); } else - player->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW, item, NULL); + player->SendEquipError(EQUIP_ERR_CLIENT_LOCKED_OUT, item, NULL); return true; } }; @@ -407,7 +405,7 @@ public: player->SendEquipError(EQUIP_ERR_OUT_OF_RANGE, item, NULL); } else - player->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW, item, NULL); + player->SendEquipError(EQUIP_ERR_CLIENT_LOCKED_OUT, item, NULL); return true; } }; diff --git a/src/server/scripts/World/npc_professions.cpp b/src/server/scripts/World/npc_professions.cpp index 21489c714e2..08bc408f114 100644 --- a/src/server/scripts/World/npc_professions.cpp +++ b/src/server/scripts/World/npc_professions.cpp @@ -214,7 +214,7 @@ int32 DoLowUnlearnCost(Player* player) //blacksmith void ProcessCastaction(Player* player, Creature* creature, uint32 spellId, uint32 triggeredSpellId, int32 cost) { - if (!(spellId && player->HasSpell(spellId)) && player->HasEnoughMoney(cost)) + if (!(spellId && player->HasSpell(spellId)) && player->HasEnoughMoney((int64)cost)) { player->CastSpell(player, triggeredSpellId, true); player->ModifyMoney(-cost); @@ -352,11 +352,11 @@ void ProcessUnlearnAction(Player* player, Creature* creature, uint32 spellId, ui { if (EquippedOk(player, spellId)) { - if (player->HasEnoughMoney(cost)) + if (player->HasEnoughMoney(int64(cost))) { player->CastSpell(player, spellId, true); ProfessionUnlearnSpells(player, spellId); - player->ModifyMoney(-cost); + player->ModifyMoney(-int64(cost)); if (alternativeSpellId) creature->CastSpell(player, alternativeSpellId, true); } @@ -364,7 +364,7 @@ void ProcessUnlearnAction(Player* player, Creature* creature, uint32 spellId, ui player->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, creature, 0, 0); } else - player->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW, NULL, NULL); + player->SendEquipError(EQUIP_ERR_CLIENT_LOCKED_OUT, NULL, NULL); player->CLOSE_GOSSIP_MENU(); } diff --git a/src/server/scripts/World/npcs_special.cpp b/src/server/scripts/World/npcs_special.cpp index c32edff09bc..321c3d67dc5 100644 --- a/src/server/scripts/World/npcs_special.cpp +++ b/src/server/scripts/World/npcs_special.cpp @@ -441,9 +441,6 @@ public: me->Relocate(x, y, z + 0.94f); me->SetDisableGravity(true); me->HandleEmoteCommand(EMOTE_ONESHOT_DANCE); - WorldPacket data; //send update position to client - me->BuildHeartBeatMsg(&data); - me->SendMessageToSet(&data, true); } void UpdateAI(uint32 diff) override @@ -470,9 +467,6 @@ public: me->SetInFront(player); Active = false; - WorldPacket data; - me->BuildHeartBeatMsg(&data); - me->SendMessageToSet(&data, true); switch (emote) { case TEXT_EMOTE_KISS: @@ -1218,6 +1212,11 @@ public: player->SEND_GOSSIP_MENU(10239, creature->GetGUID()); else canBuy = true; break; + case 48510: //Kall Worthaton + if (player->GetReputationRank(1133) != REP_EXALTED && race != RACE_GOBLIN) + player->SEND_GOSSIP_MENU(17494, creature->GetGUID()); + else canBuy = true; + break; } if (canBuy) @@ -1239,7 +1238,6 @@ public: } }; - /*###### ## npc_sayge ######*/ @@ -1963,11 +1961,11 @@ public: } if (doSwitch) { - if (!player->HasEnoughMoney(EXP_COST)) + if (!player->HasEnoughMoney(uint64(EXP_COST))) player->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, 0, 0, 0); else if (noXPGain) { - player->ModifyMoney(-EXP_COST); + player->ModifyMoney(-int64(EXP_COST)); player->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_NO_XP_GAIN); } else if (!noXPGain) |