diff options
| author | Nay <dnpd.dd@gmail.com> | 2013-01-28 01:04:37 +0000 |
|---|---|---|
| committer | Nay <dnpd.dd@gmail.com> | 2013-01-28 01:04:37 +0000 |
| commit | b404e0bec1d39a90a516ed935d882faa47e54a04 (patch) | |
| tree | 575ae3ed3c0a631dc8a1b2ca2f824161c65e73b1 /src/server/scripts | |
| parent | a3d07b5e6ac45c23ec4116028c4bccae9307083b (diff) | |
| parent | da080ac4e796be6039a239b7e035ead02e73b333 (diff) | |
Merge remote-tracking branch 'origin/master' into 4.3.4
Conflicts:
dep/PackageList.txt
src/server/game/Battlegrounds/Battleground.cpp
src/server/game/Combat/ThreatManager.cpp
src/server/game/Entities/Object/Object.cpp
src/server/game/Entities/Player/Player.cpp
src/server/game/Entities/Unit/Unit.cpp
src/server/game/Handlers/BattleGroundHandler.cpp
src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp
src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp
src/server/game/Movement/Spline/MoveSplineInit.cpp
src/server/game/Spells/Auras/SpellAuraEffects.cpp
src/server/game/Spells/SpellEffects.cpp
src/server/game/World/World.cpp
src/server/game/World/World.h
src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp
src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp
src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h
src/server/scripts/Spells/spell_druid.cpp
src/server/scripts/Spells/spell_mage.cpp
src/server/scripts/Spells/spell_paladin.cpp
src/server/scripts/Spells/spell_priest.cpp
src/server/scripts/Spells/spell_rogue.cpp
src/server/scripts/Spells/spell_shaman.cpp
src/server/scripts/Spells/spell_warlock.cpp
src/server/scripts/Spells/spell_warrior.cpp
src/tools/map_extractor/CMakeLists.txt
src/tools/map_extractor/System.cpp
src/tools/map_extractor/loadlib.cpp
src/tools/map_extractor/mpq_libmpq.cpp
src/tools/map_extractor/mpq_libmpq04.h
src/tools/vmap4_assembler/CMakeLists.txt
src/tools/vmap4_extractor/CMakeLists.txt
src/tools/vmap4_extractor/mpq_libmpq.cpp
src/tools/vmap4_extractor/mpq_libmpq04.h
Diffstat (limited to 'src/server/scripts')
26 files changed, 3688 insertions, 197 deletions
diff --git a/src/server/scripts/CMakeLists.txt b/src/server/scripts/CMakeLists.txt index 5ccd244ef7f..a32a42b8172 100644 --- a/src/server/scripts/CMakeLists.txt +++ b/src/server/scripts/CMakeLists.txt @@ -45,6 +45,8 @@ message("") include_directories( ${CMAKE_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour + ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Recast ${CMAKE_SOURCE_DIR}/dep/g3dlite/include ${CMAKE_SOURCE_DIR}/dep/SFMT ${CMAKE_SOURCE_DIR}/dep/zlib diff --git a/src/server/scripts/Commands/CMakeLists.txt b/src/server/scripts/Commands/CMakeLists.txt index 97e9b35e6cd..7b9e2444952 100644 --- a/src/server/scripts/Commands/CMakeLists.txt +++ b/src/server/scripts/Commands/CMakeLists.txt @@ -42,6 +42,7 @@ set(scripts_STAT_SRCS Commands/cs_server.cpp Commands/cs_titles.cpp Commands/cs_wp.cpp + Commands/cs_mmaps.cpp # Commands/cs_pdump.cpp # Commands/cs_channel.cpp # Commands/cs_pet.cpp diff --git a/src/server/scripts/Commands/cs_disable.cpp b/src/server/scripts/Commands/cs_disable.cpp index 37e282cac8e..34738777c85 100644 --- a/src/server/scripts/Commands/cs_disable.cpp +++ b/src/server/scripts/Commands/cs_disable.cpp @@ -48,6 +48,7 @@ public: { "achievement_criteria", SEC_ADMINISTRATOR, true, &HandleRemoveDisableAchievementCriteriaCommand, "", NULL }, { "outdoorpvp", SEC_ADMINISTRATOR, true, &HandleRemoveDisableOutdoorPvPCommand, "", NULL }, { "vmap", SEC_ADMINISTRATOR, true, &HandleRemoveDisableVmapCommand, "", NULL }, + { "mmap", SEC_ADMINISTRATOR, true, &HandleRemoveDisableMMapCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; static ChatCommand addDisableCommandTable[] = @@ -59,6 +60,7 @@ public: { "achievement_criteria", SEC_ADMINISTRATOR, true, &HandleAddDisableAchievementCriteriaCommand, "", NULL }, { "outdoorpvp", SEC_ADMINISTRATOR, true, &HandleAddDisableOutdoorPvPCommand, "", NULL }, { "vmap", SEC_ADMINISTRATOR, true, &HandleAddDisableVmapCommand, "", NULL }, + { "mmap", SEC_ADMINISTRATOR, true, &HandleAddDisableMMapCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; static ChatCommand disableCommandTable[] = @@ -172,6 +174,17 @@ public: disableTypeStr = "vmap"; break; } + case DISABLE_TYPE_MMAP: + { + if (!sMapStore.LookupEntry(entry)) + { + handler->PSendSysMessage(LANG_COMMAND_NOMAPFOUND); + handler->SetSentErrorMessage(true); + return false; + } + disableTypeStr = "mmap"; + break; + } default: break; } @@ -256,6 +269,14 @@ public: return HandleAddDisables(handler, args, DISABLE_TYPE_VMAP); } + static bool HandleAddDisableMMapCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + return HandleAddDisables(handler, args, DISABLE_TYPE_MMAP); + } + static bool HandleRemoveDisables(ChatHandler* handler, char const* args, uint8 disableType) { char* entryStr = strtok((char*)args, " "); @@ -289,6 +310,9 @@ public: case DISABLE_TYPE_VMAP: disableTypeStr = "vmap"; break; + case DISABLE_TYPE_MMAP: + disableTypeStr = "mmap"; + break; } PreparedStatement* stmt = NULL; @@ -367,6 +391,14 @@ public: return HandleRemoveDisables(handler, args, DISABLE_TYPE_VMAP); } + + static bool HandleRemoveDisableMMapCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + return HandleRemoveDisables(handler, args, DISABLE_TYPE_MMAP); + } }; void AddSC_disable_commandscript() diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index a1098cff5d3..18dbeba8f89 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -33,6 +33,8 @@ #include "ace/INET_Addr.h" #include "Player.h" #include "Pet.h" +#include "LFG.h" +#include "GroupMgr.h" class misc_commandscript : public CommandScript { @@ -46,6 +48,8 @@ public: { "leader", SEC_ADMINISTRATOR, false, &HandleGroupLeaderCommand, "", NULL }, { "disband", SEC_ADMINISTRATOR, false, &HandleGroupDisbandCommand, "", NULL }, { "remove", SEC_ADMINISTRATOR, false, &HandleGroupRemoveCommand, "", NULL }, + { "join", SEC_ADMINISTRATOR, false, &HandleGroupJoinCommand, "", NULL }, + { "list", SEC_ADMINISTRATOR, false, &HandleGroupListCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; static ChatCommand petCommandTable[] = @@ -1734,6 +1738,29 @@ public: else handler->PSendSysMessage(LANG_PINFO_MAP_OFFLINE, map->name, areaName.c_str()); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_MEMBER_EXTENDED); + stmt->setUInt32(0, GUID_LOPART(targetGuid)); + + result = CharacterDatabase.Query(stmt); + if (result) + { + uint32 guildId = 0; + std::string guildName = ""; + std::string guildRank = ""; + std::string note = ""; + std::string officeNote = ""; + + Field* fields = result->Fetch(); + guildId = fields[0].GetUInt32(); + guildName = fields[1].GetString(); + //rankId = fields[2].GetUInt8(); + guildRank = fields[3].GetString(); + note = fields[4].GetString(); + officeNote = fields[5].GetString(); + + handler->PSendSysMessage(LANG_PINFO_GUILD_INFO, guildName.c_str(), guildId, guildRank.c_str(), note.c_str(), officeNote.c_str()); + } + return true; } @@ -2723,6 +2750,133 @@ public: return true; } + static bool HandleGroupJoinCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + Player* playerSource = NULL; + Player* playerTarget = NULL; + Group* groupSource = NULL; + Group* groupTarget = NULL; + uint64 guidSource = 0; + uint64 guidTarget = 0; + char* nameplgrStr = strtok((char*)args, " "); + char* nameplStr = strtok(NULL, " "); + + if (handler->GetPlayerGroupAndGUIDByName(nameplgrStr, playerSource, groupSource, guidSource, true)) + { + if (groupSource) + { + if (handler->GetPlayerGroupAndGUIDByName(nameplStr, playerTarget, groupTarget, guidTarget, true)) + { + if (!groupTarget && playerTarget->GetGroup() != groupSource) + { + if (!groupSource->IsFull()) + { + groupSource->AddMember(playerTarget); + groupSource->BroadcastGroupUpdate(); + handler->PSendSysMessage(LANG_GROUP_PLAYER_JOINED, playerTarget->GetName().c_str(), playerSource->GetName().c_str()); + return true; + } + else + { + // group is full + handler->PSendSysMessage(LANG_GROUP_FULL); + return true; + } + } + else + { + // group is full or target player already in a group + handler->PSendSysMessage(LANG_GROUP_ALREADY_IN_GROUP, playerTarget->GetName().c_str()); + return true; + } + } + } + else + { + // specified source player is not in a group + handler->PSendSysMessage(LANG_GROUP_NOT_IN_GROUP, playerSource->GetName().c_str()); + return true; + } + } + + return true; + } + + static bool HandleGroupListCommand(ChatHandler* handler, char const* args) + { + Player* playerTarget; + uint64 guidTarget; + std::string nameTarget; + + uint32 parseGUID = MAKE_NEW_GUID(atol((char*)args), 0, HIGHGUID_PLAYER); + + if (sObjectMgr->GetPlayerNameByGUID(parseGUID, nameTarget)) + { + playerTarget = sObjectMgr->GetPlayerByLowGUID(parseGUID); + guidTarget = parseGUID; + } + else if (!handler->extractPlayerTarget((char*)args, &playerTarget, &guidTarget, &nameTarget)) + return false; + + Group* groupTarget = NULL; + if (playerTarget) + groupTarget = playerTarget->GetGroup(); + + if (!groupTarget) + { + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GROUP_MEMBER); + stmt->setUInt32(0, guidTarget); + PreparedQueryResult resultGroup = CharacterDatabase.Query(stmt); + if (resultGroup) + groupTarget = sGroupMgr->GetGroupByDbStoreId((*resultGroup)[0].GetUInt32()); + } + + if (groupTarget) + { + handler->PSendSysMessage(LANG_GROUP_TYPE, (groupTarget->isRaidGroup() ? "raid" : "party")); + Group::MemberSlotList const& members = groupTarget->GetMemberSlots(); + Group::MemberSlotList::const_iterator itr; + for (itr = members.begin(); itr != members.end(); ++itr) + { + std::ostringstream flags, roles; + if ((*itr).flags & MEMBER_FLAG_ASSISTANT) + flags << "Assistant "; + if ((*itr).flags & MEMBER_FLAG_MAINTANK) + flags << "MainTank "; + if ((*itr).flags & MEMBER_FLAG_MAINASSIST) + flags << "MainAssist "; + + if ((*itr).roles & PLAYER_ROLE_LEADER) + roles << "Leader "; + if ((*itr).roles & PLAYER_ROLE_TANK) + roles << "Tank "; + if ((*itr).roles & PLAYER_ROLE_HEALER) + roles << "Healer "; + if ((*itr).roles & PLAYER_ROLE_DAMAGE) + roles << "Damage "; + + Player* p = ObjectAccessor::FindPlayer((*itr).guid); + const char* onlineState = (p && p->IsInWorld()) ? "online" : "offline"; + + std::string flagsStr = (flags.str().empty()) ? "None" : flags.str(); + std::string rolesStr = (roles.str().empty()) ? "None" : roles.str(); + + handler->PSendSysMessage(LANG_GROUP_PLAYER_NAME_GUID, (*itr).name.c_str(), onlineState, GUID_LOPART((*itr).guid), flagsStr.c_str(), rolesStr.c_str()); + } + return true; + } + else + { + handler->PSendSysMessage(LANG_GROUP_NOT_IN_GROUP, nameTarget.c_str()); + return true; + } + + return true; + } + static bool HandlePlayAllCommand(ChatHandler* handler, char const* args) { if (!*args) diff --git a/src/server/scripts/Commands/cs_mmaps.cpp b/src/server/scripts/Commands/cs_mmaps.cpp new file mode 100644 index 00000000000..97861133983 --- /dev/null +++ b/src/server/scripts/Commands/cs_mmaps.cpp @@ -0,0 +1,294 @@ +/* + * 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 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 +* @brief .mmap related commands +* +* This file contains the CommandScripts for all +* mmap sub-commands +*/ + +#include "ScriptMgr.h" +#include "Chat.h" +#include "ObjectMgr.h" +#include "Player.h" +#include "PointMovementGenerator.h" +#include "PathGenerator.h" +#include "MMapFactory.h" +#include "Map.h" +#include "TargetedMovementGenerator.h" +#include "GridNotifiers.h" +#include "GridNotifiersImpl.h" +#include "CellImpl.h" + +class mmaps_commandscript : public CommandScript +{ +public: + mmaps_commandscript() : CommandScript("mmaps_commandscript") { } + + ChatCommand* GetCommands() const + { + static ChatCommand mmapCommandTable[] = + { + { "path", SEC_ADMINISTRATOR, false, &HandleMmapPathCommand, "", NULL }, + { "loc", SEC_ADMINISTRATOR, false, &HandleMmapLocCommand, "", NULL }, + { "loadedtiles", SEC_ADMINISTRATOR, false, &HandleMmapLoadedTilesCommand, "", NULL }, + { "stats", SEC_ADMINISTRATOR, false, &HandleMmapStatsCommand, "", NULL }, + { "testarea", SEC_ADMINISTRATOR, false, &HandleMmapTestArea, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + + static ChatCommand commandTable[] = + { + { "mmap", SEC_ADMINISTRATOR, true, NULL, "", mmapCommandTable }, + { NULL, 0, false, NULL, "", NULL } + }; + return commandTable; + } + + static bool HandleMmapPathCommand(ChatHandler* handler, char const* args) + { + if (!MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(handler->GetSession()->GetPlayer()->GetMapId())) + { + handler->PSendSysMessage("NavMesh not loaded for current map."); + return true; + } + + handler->PSendSysMessage("mmap path:"); + + // units + Player* player = handler->GetSession()->GetPlayer(); + Unit* target = handler->getSelectedUnit(); + if (!player || !target) + { + handler->PSendSysMessage("Invalid target/source selection."); + return true; + } + + char* para = strtok((char*)args, " "); + + bool useStraightPath = false; + if (para && strcmp(para, "true") == 0) + useStraightPath = true; + + // unit locations + float x, y, z; + player->GetPosition(x, y, z); + + // path + PathGenerator path(target); + path.SetUseStraightPath(useStraightPath); + bool result = path.CalculatePath(x, y, z); + + PointsArray pointPath = path.GetPath(); + handler->PSendSysMessage("%s's path to %s:", target->GetName().c_str(), player->GetName().c_str()); + handler->PSendSysMessage("Building: %s", useStraightPath ? "StraightPath" : "SmoothPath"); + handler->PSendSysMessage("Result: %s - Length: "SIZEFMTD" - Type: %u", (result ? "true" : "false"), pointPath.size(), path.GetPathType()); + + Vector3 start = path.GetStartPosition(); + Vector3 end = path.GetEndPosition(); + Vector3 actualEnd = path.GetActualEndPosition(); + + handler->PSendSysMessage("StartPosition (%.3f, %.3f, %.3f)", start.x, start.y, start.z); + handler->PSendSysMessage("EndPosition (%.3f, %.3f, %.3f)", end.x, end.y, end.z); + handler->PSendSysMessage("ActualEndPosition (%.3f, %.3f, %.3f)", actualEnd.x, actualEnd.y, actualEnd.z); + + if (!player->isGameMaster()) + handler->PSendSysMessage("Enable GM mode to see the path points."); + + for (uint32 i = 0; i < pointPath.size(); ++i) + player->SummonCreature(VISUAL_WAYPOINT, pointPath[i].x, pointPath[i].y, pointPath[i].z, 0, TEMPSUMMON_TIMED_DESPAWN, 9000); + + return true; + } + + static bool HandleMmapLocCommand(ChatHandler* handler, char const* /*args*/) + { + handler->PSendSysMessage("mmap tileloc:"); + + // grid tile location + Player* player = handler->GetSession()->GetPlayer(); + + int32 gx = 32 - player->GetPositionX() / SIZE_OF_GRIDS; + int32 gy = 32 - player->GetPositionY() / SIZE_OF_GRIDS; + + handler->PSendSysMessage("%03u%02i%02i.mmtile", player->GetMapId(), gy, gx); + handler->PSendSysMessage("gridloc [%i,%i]", gx, gy); + + // calculate navmesh tile location + dtNavMesh const* navmesh = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(handler->GetSession()->GetPlayer()->GetMapId()); + dtNavMeshQuery const* navmeshquery = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMeshQuery(handler->GetSession()->GetPlayer()->GetMapId(), player->GetInstanceId()); + if (!navmesh || !navmeshquery) + { + handler->PSendSysMessage("NavMesh not loaded for current map."); + return true; + } + + 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}; + + int32 tilex = int32((y - min[0]) / SIZE_OF_GRIDS); + int32 tiley = int32((x - min[2]) / SIZE_OF_GRIDS); + + handler->PSendSysMessage("Calc [%02i,%02i]", tilex, tiley); + + // navmesh poly -> navmesh tile location + dtQueryFilter filter = dtQueryFilter(); + dtPolyRef polyRef = INVALID_POLYREF; + navmeshquery->findNearestPoly(location, extents, &filter, &polyRef, NULL); + + if (polyRef == INVALID_POLYREF) + handler->PSendSysMessage("Dt [??,??] (invalid poly, probably no tile loaded)"); + else + { + dtMeshTile const* tile; + dtPoly const* poly; + navmesh->getTileAndPolyByRef(polyRef, &tile, &poly); + if (tile) + handler->PSendSysMessage("Dt [%02i,%02i]", tile->header->x, tile->header->y); + else + handler->PSendSysMessage("Dt [??,??] (no tile loaded)"); + } + + return true; + } + + static bool HandleMmapLoadedTilesCommand(ChatHandler* handler, char const* /*args*/) + { + uint32 mapid = handler->GetSession()->GetPlayer()->GetMapId(); + dtNavMesh const* navmesh = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(mapid); + dtNavMeshQuery const* navmeshquery = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMeshQuery(mapid, handler->GetSession()->GetPlayer()->GetInstanceId()); + if (!navmesh || !navmeshquery) + { + handler->PSendSysMessage("NavMesh not loaded for current map."); + return true; + } + + handler->PSendSysMessage("mmap loadedtiles:"); + + for (int32 i = 0; i < navmesh->getMaxTiles(); ++i) + { + dtMeshTile const* tile = navmesh->getTile(i); + if (!tile || !tile->header) + continue; + + handler->PSendSysMessage("[%02i,%02i]", tile->header->x, tile->header->y); + } + + return true; + } + + static bool HandleMmapStatsCommand(ChatHandler* handler, char const* /*args*/) + { + uint32 mapId = handler->GetSession()->GetPlayer()->GetMapId(); + handler->PSendSysMessage("mmap stats:"); + handler->PSendSysMessage(" global mmap pathfinding is %sabled", MMAP::MMapFactory::IsPathfindingEnabled(mapId) ? "en" : "dis"); + + MMAP::MMapManager* manager = MMAP::MMapFactory::createOrGetMMapManager(); + handler->PSendSysMessage(" %u maps loaded with %u tiles overall", manager->getLoadedMapsCount(), manager->getLoadedTilesCount()); + + dtNavMesh const* navmesh = manager->GetNavMesh(handler->GetSession()->GetPlayer()->GetMapId()); + if (!navmesh) + { + handler->PSendSysMessage("NavMesh not loaded for current map."); + return true; + } + + uint32 tileCount = 0; + uint32 nodeCount = 0; + uint32 polyCount = 0; + uint32 vertCount = 0; + uint32 triCount = 0; + uint32 triVertCount = 0; + uint32 dataSize = 0; + for (int32 i = 0; i < navmesh->getMaxTiles(); ++i) + { + dtMeshTile const* tile = navmesh->getTile(i); + if (!tile || !tile->header) + continue; + + tileCount++; + nodeCount += tile->header->bvNodeCount; + polyCount += tile->header->polyCount; + vertCount += tile->header->vertCount; + triCount += tile->header->detailTriCount; + triVertCount += tile->header->detailVertCount; + dataSize += tile->dataSize; + } + + handler->PSendSysMessage("Navmesh stats:"); + handler->PSendSysMessage(" %u tiles loaded", tileCount); + handler->PSendSysMessage(" %u BVTree nodes", nodeCount); + handler->PSendSysMessage(" %u polygons (%u vertices)", polyCount, vertCount); + handler->PSendSysMessage(" %u triangles (%u vertices)", triCount, triVertCount); + handler->PSendSysMessage(" %.2f MB of data (not including pointers)", ((float)dataSize / sizeof(unsigned char)) / 1048576); + + return true; + } + + static bool HandleMmapTestArea(ChatHandler* handler, char const* /*args*/) + { + float radius = 40.0f; + WorldObject* object = handler->GetSession()->GetPlayer(); + + CellCoord pair(Trinity::ComputeCellCoord(object->GetPositionX(), object->GetPositionY())); + Cell cell(pair); + cell.SetNoCreate(); + + std::list<Creature*> creatureList; + + Trinity::AnyUnitInObjectRangeCheck go_check(object, radius); + Trinity::CreatureListSearcher<Trinity::AnyUnitInObjectRangeCheck> go_search(object, creatureList, go_check); + TypeContainerVisitor<Trinity::CreatureListSearcher<Trinity::AnyUnitInObjectRangeCheck>, GridTypeMapContainer> go_visit(go_search); + + // Get Creatures + cell.Visit(pair, go_visit, *(object->GetMap()), *object, radius); + + if (!creatureList.empty()) + { + handler->PSendSysMessage("Found "SIZEFMTD" Creatures.", creatureList.size()); + + uint32 paths = 0; + uint32 uStartTime = getMSTime(); + + float gx, gy, gz; + object->GetPosition(gx, gy, gz); + for (std::list<Creature*>::iterator itr = creatureList.begin(); itr != creatureList.end(); ++itr) + { + PathGenerator path(*itr); + path.CalculatePath(gx, gy, gz); + ++paths; + } + + uint32 uPathLoadTime = getMSTimeDiff(uStartTime, getMSTime()); + handler->PSendSysMessage("Generated %i paths in %i ms", paths, uPathLoadTime); + } + else + handler->PSendSysMessage("No creatures in %f yard range.", radius); + + return true; + } +}; + +void AddSC_mmaps_commandscript() +{ + new mmaps_commandscript(); +} diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp index 0217aea1149..6653439b703 100644 --- a/src/server/scripts/Commands/cs_npc.cpp +++ b/src/server/scripts/Commands/cs_npc.cpp @@ -33,6 +33,42 @@ EndScriptData */ #include "Player.h" #include "Pet.h" +struct NpcFlagText +{ + uint32 flag; + int32 text; +}; + +#define NPCFLAG_COUNT 24 + +const NpcFlagText npcFlagTexts[NPCFLAG_COUNT] = +{ + { UNIT_NPC_FLAG_AUCTIONEER, LANG_NPCINFO_AUCTIONEER }, + { UNIT_NPC_FLAG_BANKER, LANG_NPCINFO_BANKER }, + { UNIT_NPC_FLAG_BATTLEMASTER, LANG_NPCINFO_BATTLEMASTER }, + { UNIT_NPC_FLAG_FLIGHTMASTER, LANG_NPCINFO_FLIGHTMASTER }, + { UNIT_NPC_FLAG_GOSSIP, LANG_NPCINFO_GOSSIP }, + { UNIT_NPC_FLAG_GUILD_BANKER, LANG_NPCINFO_GUILD_BANKER }, + { UNIT_NPC_FLAG_INNKEEPER, LANG_NPCINFO_INNKEEPER }, + { UNIT_NPC_FLAG_PETITIONER, LANG_NPCINFO_PETITIONER }, + { UNIT_NPC_FLAG_PLAYER_VEHICLE, LANG_NPCINFO_PLAYER_VEHICLE }, + { UNIT_NPC_FLAG_QUESTGIVER, LANG_NPCINFO_QUESTGIVER }, + { UNIT_NPC_FLAG_REPAIR, LANG_NPCINFO_REPAIR }, + { UNIT_NPC_FLAG_SPELLCLICK, LANG_NPCINFO_SPELLCLICK }, + { UNIT_NPC_FLAG_SPIRITGUIDE, LANG_NPCINFO_SPIRITGUIDE }, + { UNIT_NPC_FLAG_SPIRITHEALER, LANG_NPCINFO_SPIRITHEALER }, + { UNIT_NPC_FLAG_STABLEMASTER, LANG_NPCINFO_STABLEMASTER }, + { UNIT_NPC_FLAG_TABARDDESIGNER, LANG_NPCINFO_TABARDDESIGNER }, + { UNIT_NPC_FLAG_TRAINER, LANG_NPCINFO_TRAINER }, + { UNIT_NPC_FLAG_TRAINER_CLASS, LANG_NPCINFO_TRAINER_CLASS }, + { UNIT_NPC_FLAG_TRAINER_PROFESSION, LANG_NPCINFO_TRAINER_PROFESSION }, + { UNIT_NPC_FLAG_VENDOR, LANG_NPCINFO_VENDOR }, + { UNIT_NPC_FLAG_VENDOR_AMMO, LANG_NPCINFO_VENDOR_AMMO }, + { UNIT_NPC_FLAG_VENDOR_FOOD, LANG_NPCINFO_VENDOR_FOOD }, + { UNIT_NPC_FLAG_VENDOR_POISON, LANG_NPCINFO_VENDOR_POISON }, + { UNIT_NPC_FLAG_VENDOR_REAGENT, LANG_NPCINFO_VENDOR_REAGENT } +}; + class npc_commandscript : public CommandScript { public: @@ -623,11 +659,9 @@ public: handler->PSendSysMessage(LANG_NPCINFO_POSITION, float(target->GetPositionX()), float(target->GetPositionY()), float(target->GetPositionZ())); handler->PSendSysMessage(LANG_NPCINFO_AIINFO, target->GetAIName().c_str(), target->GetScriptName().c_str()); - if (npcflags & UNIT_NPC_FLAG_VENDOR) - handler->SendSysMessage(LANG_NPCINFO_VENDOR); - - if (npcflags & UNIT_NPC_FLAG_TRAINER) - handler->SendSysMessage(LANG_NPCINFO_TRAINER); + for (uint8 i = 0; i < NPCFLAG_COUNT; i++) + if (npcflags & npcFlagTexts[i].flag) + handler->PSendSysMessage(npcFlagTexts[i].text, npcFlagTexts[i].flag); return true; } diff --git a/src/server/scripts/EasternKingdoms/Scholomance/boss_kirtonos_the_herald.cpp b/src/server/scripts/EasternKingdoms/Scholomance/boss_kirtonos_the_herald.cpp index 58e130ce644..19660cec4af 100644 --- a/src/server/scripts/EasternKingdoms/Scholomance/boss_kirtonos_the_herald.cpp +++ b/src/server/scripts/EasternKingdoms/Scholomance/boss_kirtonos_the_herald.cpp @@ -66,8 +66,8 @@ enum eMisc Position const PosMove[2] = { - { 299.4884f, 92.76137f, 105.6335f }, - { 314.8673f, 90.30210f, 101.6459f } + { 299.4884f, 92.76137f, 105.6335f, 0.0f }, + { 314.8673f, 90.30210f, 101.6459f, 0.0f } }; class boss_kirtonos_the_herald : public CreatureScript diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp index c8caa3976e4..ab0c44aa6d0 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp @@ -46,6 +46,7 @@ enum Spells SPELL_FRENZIED_BLOODTHIRST_VISUAL = 71949, SPELL_VAMPIRIC_BITE = 71726, SPELL_ESSENCE_OF_THE_BLOOD_QUEEN_PLR = 70879, + SPELL_ESSENCE_OF_THE_BLOOD_QUEEN_HEAL = 70872, SPELL_FRENZIED_BLOODTHIRST = 70877, SPELL_UNCONTROLLABLE_FRENZY = 70923, SPELL_PRESENCE_OF_THE_DARKFALLEN = 71952, @@ -698,6 +699,42 @@ class spell_blood_queen_bloodbolt : public SpellScriptLoader } }; +// 70871 - Essence of the Blood Queen +class spell_blood_queen_essence_of_the_blood_queen : public SpellScriptLoader +{ + public: + spell_blood_queen_essence_of_the_blood_queen() : SpellScriptLoader("spell_blood_queen_essence_of_the_blood_queen") { } + + class spell_blood_queen_essence_of_the_blood_queen_AuraScript : public AuraScript + { + PrepareAuraScript(spell_blood_queen_essence_of_the_blood_queen_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_ESSENCE_OF_THE_BLOOD_QUEEN_HEAL)) + return false; + return true; + } + + void OnProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + int32 heal = CalculatePct(int32(eventInfo.GetDamageInfo()->GetDamage()), aurEff->GetAmount()); + GetTarget()->CastCustomSpell(SPELL_ESSENCE_OF_THE_BLOOD_QUEEN_HEAL, SPELLVALUE_BASE_POINT0, heal, GetTarget(), TRIGGERED_FULL_MASK, NULL, aurEff); + } + + void Register() + { + OnEffectProc += AuraEffectProcFn(spell_blood_queen_essence_of_the_blood_queen_AuraScript::OnProc, EFFECT_1, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_blood_queen_essence_of_the_blood_queen_AuraScript(); + } +}; + class spell_blood_queen_pact_of_the_darkfallen : public SpellScriptLoader { public: @@ -849,6 +886,7 @@ void AddSC_boss_blood_queen_lana_thel() new spell_blood_queen_vampiric_bite(); new spell_blood_queen_frenzied_bloodthirst(); new spell_blood_queen_bloodbolt(); + new spell_blood_queen_essence_of_the_blood_queen(); new spell_blood_queen_pact_of_the_darkfallen(); new spell_blood_queen_pact_of_the_darkfallen_dmg(); new spell_blood_queen_pact_of_the_darkfallen_dmg_target(); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp index ce1166663f3..59d69d658cc 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp @@ -415,6 +415,13 @@ class boss_deathbringer_saurfang : public CreatureScript } } + void SpellHit(Unit* /*caster*/, SpellInfo const* spell) + { + if (spell->Id == SPELL_BLOOD_LINK_POWER) + if (Aura* bloodPower = me->GetAura(SPELL_BLOOD_POWER)) + bloodPower->RecalculateAmountOfEffects(); + } + void UpdateAI(uint32 const diff) { if (!UpdateVictim() && !(events.GetPhaseMask() & PHASE_INTRO_MASK)) @@ -1004,8 +1011,6 @@ class spell_deathbringer_blood_link : public SpellScriptLoader void HandleDummy(SpellEffIndex /*effIndex*/) { GetHitUnit()->CastCustomSpell(SPELL_BLOOD_LINK_POWER, SPELLVALUE_BASE_POINT0, GetEffectValue(), GetHitUnit(), true); - if (Aura* bloodPower = GetHitUnit()->GetAura(SPELL_BLOOD_POWER)) - bloodPower->RecalculateAmountOfEffects(); PreventHitDefaultEffect(EFFECT_0); } @@ -1093,13 +1098,6 @@ class spell_deathbringer_blood_power : public SpellScriptLoader DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_deathbringer_blood_power_AuraScript::RecalculateHook, EFFECT_0, SPELL_AURA_MOD_SCALE); DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_deathbringer_blood_power_AuraScript::RecalculateHook, EFFECT_1, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); } - - bool Load() - { - if (GetUnitOwner()->getPowerType() != POWER_ENERGY) - return false; - return true; - } }; SpellScript* GetSpellScript() const diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp index 4c18821d2f7..e3ab6e0941f 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp @@ -53,7 +53,7 @@ enum Spells SPELL_COLDFLAME_SUMMON = 69147, }; -uint32 const boneSpikeSummonId[3] = {69062, 72669, 72670}; +uint32 const BoneSpikeSummonId[3] = {69062, 72669, 72670}; enum Events { @@ -514,6 +514,20 @@ class spell_marrowgar_bone_spike_graveyard : public SpellScriptLoader { PrepareSpellScript(spell_marrowgar_bone_spike_graveyard_SpellScript); + bool Validate(SpellInfo const* /*spell*/) + { + for (uint32 i = 0; i < 3; ++i) + if (!sSpellMgr->GetSpellInfo(BoneSpikeSummonId[i])) + return false; + + return true; + } + + bool Load() + { + return GetCaster()->GetTypeId() == TYPEID_UNIT && GetCaster()->IsAIEnabled; + } + SpellCastResult CheckCast() { return GetCaster()->GetAI()->SelectTarget(SELECT_TARGET_TOPAGGRO, 1, 0.0f, true, -SPELL_IMPALED) ? SPELL_CAST_OK : SPELL_FAILED_NO_VALID_TARGETS; @@ -535,7 +549,7 @@ class spell_marrowgar_bone_spike_graveyard : public SpellScriptLoader break; didHit = true; - target->CastCustomSpell(boneSpikeSummonId[i], SPELLVALUE_BASE_POINT0, 0, target, true); + target->CastCustomSpell(BoneSpikeSummonId[i], SPELLVALUE_BASE_POINT0, 0, target, true); } if (didHit) 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 962e12a2461..2dd4323ad3b 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp @@ -145,6 +145,7 @@ enum Spells SPELL_RESTORE_SOUL = 72595, SPELL_RESTORE_SOULS = 73650, // Heroic SPELL_DARK_HUNGER = 69383, // Passive proc healing + SPELL_DARK_HUNGER_HEAL = 69384, SPELL_DESTROY_SOUL = 74086, // Used when Terenas Menethil dies SPELL_SOUL_RIP = 69397, // Deals increasing damage SPELL_SOUL_RIP_DAMAGE = 69398, @@ -2989,6 +2990,41 @@ class spell_the_lich_king_restore_soul : public SpellScriptLoader } }; +class spell_the_lich_king_dark_hunger : public SpellScriptLoader +{ + public: + spell_the_lich_king_dark_hunger() : SpellScriptLoader("spell_the_lich_king_dark_hunger") { } + + class spell_the_lich_king_dark_hunger_AuraScript : public AuraScript + { + PrepareAuraScript(spell_the_lich_king_dark_hunger_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_DARK_HUNGER_HEAL)) + return false; + return true; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + int32 heal = int32(eventInfo.GetDamageInfo()->GetDamage() / 2); + GetTarget()->CastCustomSpell(SPELL_DARK_HUNGER_HEAL, SPELLVALUE_BASE_POINT0, heal, GetTarget(), true, NULL, aurEff); + } + + void Register() + { + OnEffectProc += AuraEffectProcFn(spell_the_lich_king_dark_hunger_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_the_lich_king_dark_hunger_AuraScript(); + } +}; + class spell_the_lich_king_in_frostmourne_room : public SpellScriptLoader { public: @@ -3234,6 +3270,7 @@ void AddSC_boss_the_lich_king() new spell_the_lich_king_lights_favor(); new spell_the_lich_king_soul_rip(); new spell_the_lich_king_restore_soul(); + new spell_the_lich_king_dark_hunger(); new spell_the_lich_king_in_frostmourne_room(); new spell_the_lich_king_summon_spirit_bomb(); new spell_the_lich_king_trigger_vile_spirit(); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp index 1f96848fa0a..13a4fe23690 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp @@ -343,7 +343,7 @@ class boss_algalon_the_observer : public CreatureScript DoCast(me, SPELL_RIDE_THE_LIGHTNING, true); me->GetMotionMaster()->MovePoint(POINT_ALGALON_LAND, AlgalonLandPos); me->SetHomePosition(AlgalonLandPos); - Movement::MoveSplineInit init(*me); + Movement::MoveSplineInit init(me); init.MoveTo(AlgalonLandPos.GetPositionX(), AlgalonLandPos.GetPositionY(), AlgalonLandPos.GetPositionZ()); init.SetOrientationFixed(true); init.Launch(); diff --git a/src/server/scripts/Outland/zone_shadowmoon_valley.cpp b/src/server/scripts/Outland/zone_shadowmoon_valley.cpp index 0a016f0923c..a1bfc0a090a 100644 --- a/src/server/scripts/Outland/zone_shadowmoon_valley.cpp +++ b/src/server/scripts/Outland/zone_shadowmoon_valley.cpp @@ -661,6 +661,7 @@ class npc_karynaku : public CreatureScript /*#### # npc_overlord_morghor +# this whole script is wrong and needs a rewrite.even the illidan npc used is the wrong one.npc id 23467 may be the correct one ####*/ enum eOverlordData { @@ -766,7 +767,7 @@ public: Player* player = Unit::GetPlayer(*me, PlayerGUID); Creature* Illi = Creature::GetCreature(*me, IllidanGUID); - if (!player || !Illi) + if (!player) { EnterEvadeMode(); return 0; @@ -794,14 +795,21 @@ public: return 2000; break; case 5: - Illi->SetVisible(true); - Illi->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + if (Illi) + { + Illi->SetVisible(true); + Illi->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + Illi->SetDisplayId(21526); + } return 350; break; case 6: - Illi->CastSpell(Illi, SPELL_ONE, true); - Illi->SetTarget(me->GetGUID()); - me->SetTarget(IllidanGUID); + if (Illi) + { + Illi->CastSpell(Illi, SPELL_ONE, true); + Illi->SetTarget(me->GetGUID()); + me->SetTarget(IllidanGUID); + } return 2000; break; case 7: @@ -810,10 +818,15 @@ public: break; case 8: me->SetUInt32Value(UNIT_FIELD_BYTES_1, 8); - return 9000; + return 2500; + break; + case 9: + // missing text "Lord Illidan, this is the Dragonmaw that I, and others, have told you about. He will lead us to victory!" + return 5000; break; case 10: - Illi->AI()->Talk(LORD_ILLIDAN_SAY_1); + if (Illi) + Illi->AI()->Talk(LORD_ILLIDAN_SAY_1); return 5000; break; case 11: @@ -821,42 +834,53 @@ public: return 6000; break; case 12: - Illi->AI()->Talk(LORD_ILLIDAN_SAY_2); + if (Illi) + Illi->AI()->Talk(LORD_ILLIDAN_SAY_2); return 5500; break; case 13: - Illi->AI()->Talk(LORD_ILLIDAN_SAY_3); + if (Illi) + Illi->AI()->Talk(LORD_ILLIDAN_SAY_3); return 4000; break; case 14: - Illi->SetTarget(PlayerGUID); + if (Illi) + Illi->SetTarget(PlayerGUID); return 1500; break; case 15: - Illi->AI()->Talk(LORD_ILLIDAN_SAY_4); + if (Illi) + Illi->AI()->Talk(LORD_ILLIDAN_SAY_4); return 1500; break; case 16: - Illi->CastSpell(player, SPELL_TWO, true); + if (Illi) + Illi->CastSpell(player, SPELL_TWO, true); player->RemoveAurasDueToSpell(SPELL_THREE); player->RemoveAurasDueToSpell(SPELL_FOUR); return 5000; break; case 17: - Illi->AI()->Talk(LORD_ILLIDAN_SAY_5); + if (Illi) + Illi->AI()->Talk(LORD_ILLIDAN_SAY_5); return 5000; break; case 18: - Illi->AI()->Talk(LORD_ILLIDAN_SAY_6); + if (Illi) + Illi->AI()->Talk(LORD_ILLIDAN_SAY_6); return 5000; break; case 19: - Illi->AI()->Talk(LORD_ILLIDAN_SAY_7); + if (Illi) + Illi->AI()->Talk(LORD_ILLIDAN_SAY_7); return 5000; break; case 20: - Illi->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); - Illi->SetDisableGravity(true); + if (Illi) + { + Illi->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); + Illi->SetDisableGravity(true); + } return 500; break; case 21: @@ -864,8 +888,11 @@ public: return 500; break; case 22: - Illi->SetVisible(false); - Illi->setDeathState(JUST_DIED); + if (Illi) + { + Illi->SetVisible(false); + Illi->setDeathState(JUST_DIED); + } return 1000; break; case 23: @@ -886,7 +913,7 @@ public: break; case 27: { - Unit* Yarzill = me->FindNearestCreature(C_YARZILL, 50); + Unit* Yarzill = me->FindNearestCreature(C_YARZILL, 50.0f); if (Yarzill) Yarzill->SetTarget(PlayerGUID); return 500; @@ -921,9 +948,11 @@ public: } break; case 32: - me->GetMotionMaster()->MovePoint(0, -5085.77f, 577.231f, 86.6719f); return 5000; + me->GetMotionMaster()->MovePoint(0, -5085.77f, 577.231f, 86.6719f); + return 5000; break; case 33: + me->SetTarget(0); Reset(); return 100; break; @@ -940,7 +969,7 @@ public: if (ConversationTimer <= diff) { - if (Event && IllidanGUID && PlayerGUID) + if (Event && PlayerGUID) ConversationTimer = NextStep(++Step); } else ConversationTimer -= diff; } diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp index 5b43a46cb1f..f5a6bb61120 100644 --- a/src/server/scripts/Spells/spell_dk.cpp +++ b/src/server/scripts/Spells/spell_dk.cpp @@ -31,12 +31,14 @@ enum DeathKnightSpells SPELL_DK_ANTI_MAGIC_SHELL_TALENT = 51052, SPELL_DK_BLACK_ICE_R1 = 49140, SPELL_DK_BLOOD_BOIL_TRIGGERED = 65658, + SPELL_DK_BLOOD_GORGED_HEAL = 50454, 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_GHOUL_EXPLODE = 47496, + SPELL_DK_GLYPH_OF_ICEBOUND_FORTITUDE = 58625, SPELL_DK_RUNIC_POWER_ENERGIZE = 49088, SPELL_DK_SCOURGE_STRIKE_TRIGGERED = 70890, SPELL_DK_WILL_OF_THE_NECROPOLIS_TALENT_R1 = 49189, @@ -251,6 +253,58 @@ class spell_dk_blood_boil : public SpellScriptLoader } }; +// 50453 - Bloodworms Health Leech +class spell_dk_blood_gorged : public SpellScriptLoader +{ + public: + spell_dk_blood_gorged() : SpellScriptLoader("spell_dk_blood_gorged") { } + + class spell_dk_blood_gorged_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dk_blood_gorged_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_DK_BLOOD_GORGED_HEAL)) + return false; + return true; + } + + bool Load() + { + _procTarget = NULL; + return true; + } + + bool CheckProc(ProcEventInfo& /*eventInfo*/) + { + _procTarget = GetTarget()->GetOwner(); + return _procTarget; + } + + 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); + } + + void Register() + { + DoCheckProc += AuraCheckProcFn(spell_dk_blood_gorged_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_dk_blood_gorged_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + + private: + Unit* _procTarget; + }; + + AuraScript* GetAuraScript() const + { + return new spell_dk_blood_gorged_AuraScript(); + } +}; + // 49158 - Corpse Explosion (51325, 51326, 51327, 51328) class spell_dk_corpse_explosion : public SpellScriptLoader { @@ -584,6 +638,55 @@ class spell_dk_ghoul_explode : public SpellScriptLoader } }; +// 48792 - Icebound Fortitude +class spell_dk_icebound_fortitude : public SpellScriptLoader +{ + public: + spell_dk_icebound_fortitude() : SpellScriptLoader("spell_dk_icebound_fortitude") { } + + class spell_dk_icebound_fortitude_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dk_icebound_fortitude_AuraScript); + + bool Load() + { + Unit* caster = GetCaster(); + return caster && caster->GetTypeId() == TYPEID_PLAYER; + } + + void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/) + { + if (Unit* caster = GetCaster()) + { + int32 value = amount; + uint32 defValue = uint32(caster->ToPlayer()->GetSkillValue(SKILL_DEFENSE) + caster->ToPlayer()->GetRatingBonusValue(CR_DEFENSE_SKILL)); + + if (defValue > 400) + value -= int32((defValue - 400) * 0.15); + + // Glyph of Icebound Fortitude + if (AuraEffect const* aurEff = caster->GetAuraEffect(SPELL_DK_GLYPH_OF_ICEBOUND_FORTITUDE, EFFECT_0)) + { + int32 valMax = -aurEff->GetAmount(); + if (value > valMax) + value = valMax; + } + amount = value; + } + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_icebound_fortitude_AuraScript::CalculateAmount, EFFECT_2, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_dk_icebound_fortitude_AuraScript(); + } +}; + // 50365, 50371 - Improved Blood Presence class spell_dk_improved_blood_presence : public SpellScriptLoader { @@ -677,6 +780,33 @@ class spell_dk_improved_unholy_presence : public SpellScriptLoader } }; +// 59754 Rune Tap - Party +class spell_dk_rune_tap_party : public SpellScriptLoader +{ + public: + spell_dk_rune_tap_party() : SpellScriptLoader("spell_dk_rune_tap_party") { } + + class spell_dk_rune_tap_party_SpellScript : public SpellScript + { + PrepareSpellScript(spell_dk_rune_tap_party_SpellScript); + + void CheckTargets(std::list<WorldObject*>& targets) + { + targets.remove(GetCaster()); + } + + void Register() + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_dk_rune_tap_party_SpellScript::CheckTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_PARTY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_dk_rune_tap_party_SpellScript(); + } +}; + // 55090 - Scourge Strike (55265, 55270, 55271) class spell_dk_scourge_strike : public SpellScriptLoader { @@ -784,6 +914,33 @@ class spell_dk_spell_deflection : public SpellScriptLoader } }; +// 55233 - Vampiric Blood +class spell_dk_vampiric_blood : public SpellScriptLoader +{ + public: + spell_dk_vampiric_blood() : SpellScriptLoader("spell_dk_vampiric_blood") { } + + class spell_dk_vampiric_blood_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dk_vampiric_blood_AuraScript); + + void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/) + { + amount = GetUnitOwner()->CountPctFromMaxHealth(amount); + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_vampiric_blood_AuraScript::CalculateAmount, EFFECT_1, SPELL_AURA_MOD_INCREASE_HEALTH); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_dk_vampiric_blood_AuraScript(); + } +}; + // 52284 - Will of the Necropolis class spell_dk_will_of_the_necropolis : public SpellScriptLoader { @@ -854,6 +1011,7 @@ void AddSC_deathknight_spell_scripts() new spell_dk_anti_magic_shell_self(); new spell_dk_anti_magic_zone(); new spell_dk_blood_boil(); + new spell_dk_blood_gorged(); new spell_dk_corpse_explosion(); new spell_dk_death_coil(); new spell_dk_death_gate(); @@ -861,9 +1019,12 @@ void AddSC_deathknight_spell_scripts() new spell_dk_death_pact(); new spell_dk_death_strike(); new spell_dk_ghoul_explode(); + new spell_dk_icebound_fortitude(); new spell_dk_improved_blood_presence(); new spell_dk_improved_unholy_presence(); + new spell_dk_rune_tap_party(); 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 b5b4937a14c..8fd44544fb8 100644 --- a/src/server/scripts/Spells/spell_druid.cpp +++ b/src/server/scripts/Spells/spell_druid.cpp @@ -39,10 +39,15 @@ enum DruidSpells SPELL_DRUID_SOLAR_ECLIPSE = 48517, SPELL_DRUID_LUNAR_ECLIPSE = 48518, SPELL_DRUID_ENRAGE_MOD_DAMAGE = 51185, + 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_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_SURVIVAL_INSTINCTS = 50322, SPELL_DRUID_SAVAGE_ROAR = 62071, @@ -160,6 +165,35 @@ class spell_dru_eclipse_energize : public SpellScriptLoader } }; +// -1850 - Dash +class spell_dru_dash : public SpellScriptLoader +{ + public: + spell_dru_dash() : SpellScriptLoader("spell_dru_dash") { } + + class spell_dru_dash_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dru_dash_AuraScript); + + void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/) + { + // do not set speed if not in cat form + if (GetUnitOwner()->GetShapeshiftForm() != FORM_CAT) + amount = 0; + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dru_dash_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_MOD_INCREASE_SPEED); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_dru_dash_AuraScript(); + } +}; + // -5229 - Enrage class spell_dru_enrage : public SpellScriptLoader { @@ -240,6 +274,69 @@ class spell_dru_glyph_of_starfire : public SpellScriptLoader } }; +// 34246 - Idol of the Emerald Queen +// 60779 - Idol of Lush Moss +class spell_dru_idol_lifebloom : public SpellScriptLoader +{ + public: + spell_dru_idol_lifebloom() : SpellScriptLoader("spell_dru_idol_lifebloom") { } + + class spell_dru_idol_lifebloom_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dru_idol_lifebloom_AuraScript); + + void HandleEffectCalcSpellMod(AuraEffect const* aurEff, SpellModifier*& spellMod) + { + if (!spellMod) + { + spellMod = new SpellModifier(GetAura()); + spellMod->op = SPELLMOD_DOT; + spellMod->type = SPELLMOD_FLAT; + spellMod->spellId = GetId(); + spellMod->mask = GetSpellInfo()->Effects[aurEff->GetEffIndex()].SpellClassMask; + } + spellMod->value = aurEff->GetAmount() / 7; + } + + void Register() + { + DoEffectCalcSpellMod += AuraEffectCalcSpellModFn(spell_dru_idol_lifebloom_AuraScript::HandleEffectCalcSpellMod, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_dru_idol_lifebloom_AuraScript(); + } +}; + +// 29166 - Innervate +class spell_dru_innervate : public SpellScriptLoader +{ + public: + spell_dru_innervate() : SpellScriptLoader("spell_dru_innervate") { } + + class spell_dru_innervate_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dru_innervate_AuraScript); + + void CalculateAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/) + { + amount = CalculatePct(int32(GetUnitOwner()->GetCreatePowers(POWER_MANA) / aurEff->GetTotalTicks()), amount); + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dru_innervate_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_PERIODIC_ENERGIZE); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_dru_innervate_AuraScript(); + } +}; + // -5570 - Insect Swarm class spell_dru_insect_swarm : public SpellScriptLoader { @@ -351,6 +448,77 @@ class spell_dru_lifebloom : public SpellScriptLoader } }; +// -48496 - Living Seed +class spell_dru_living_seed : public SpellScriptLoader +{ + public: + spell_dru_living_seed() : SpellScriptLoader("spell_dru_living_seed") { } + + class spell_dru_living_seed_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dru_living_seed_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_DRUID_LIVING_SEED_PROC)) + return false; + return true; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + int32 amount = CalculatePct(eventInfo.GetHealInfo()->GetHeal(), aurEff->GetAmount()); + GetTarget()->CastCustomSpell(SPELL_DRUID_LIVING_SEED_PROC, SPELLVALUE_BASE_POINT0, amount, eventInfo.GetProcTarget(), true, NULL, aurEff); + } + + void Register() + { + OnEffectProc += AuraEffectProcFn(spell_dru_living_seed_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_dru_living_seed_AuraScript(); + } +}; + +// 48504 - Living Seed (Proc) +class spell_dru_living_seed_proc : public SpellScriptLoader +{ + public: + spell_dru_living_seed_proc() : SpellScriptLoader("spell_dru_living_seed_proc") { } + + class spell_dru_living_seed_proc_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dru_living_seed_proc_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_DRUID_LIVING_SEED_HEAL)) + return false; + return true; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + GetTarget()->CastCustomSpell(SPELL_DRUID_LIVING_SEED_HEAL, SPELLVALUE_BASE_POINT0, aurEff->GetAmount(), GetTarget(), true, NULL, aurEff); + } + + void Register() + { + OnEffectProc += AuraEffectProcFn(spell_dru_living_seed_proc_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_dru_living_seed_proc_AuraScript(); + } +}; + // 69366 - Moonkin Form passive class spell_dru_moonkin_form_passive : public SpellScriptLoader { @@ -395,6 +563,33 @@ class spell_dru_moonkin_form_passive : public SpellScriptLoader } }; +// 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() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dru_owlkin_frenzy_AuraScript::CalculateAmount, EFFECT_2, SPELL_AURA_PERIODIC_ENERGIZE); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_dru_owlkin_frenzy_AuraScript(); + } +}; + // -16972 - Predatory Strikes class spell_dru_predatory_strikes : public SpellScriptLoader { @@ -468,6 +663,54 @@ class spell_dru_primal_tenacity : public SpellScriptLoader } }; +// -1079 - Rip +class spell_dru_rip : public SpellScriptLoader +{ + public: + spell_dru_rip() : SpellScriptLoader("spell_dru_rip") { } + + class spell_dru_rip_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dru_rip_AuraScript); + + bool Load() + { + Unit* caster = GetCaster(); + return caster && caster->GetTypeId() == TYPEID_PLAYER; + } + + void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& canBeRecalculated) + { + canBeRecalculated = false; + + if (Unit* caster = GetCaster()) + { + // 0.01 * $AP * cp + uint8 cp = caster->ToPlayer()->GetComboPoints(); + + // Idol of Feral Shadows. Can't be handled as SpellMod due its dependency from CPs + if (AuraEffect const* idol = caster->GetAuraEffect(SPELL_DRUID_IDOL_OF_FERAL_SHADOWS, EFFECT_0)) + amount += cp * idol->GetAmount(); + // Idol of Worship. Can't be handled as SpellMod due its dependency from CPs + else if (AuraEffect const* idol = caster->GetAuraEffect(SPELL_DRUID_IDOL_OF_WORSHIP, EFFECT_0)) + amount += cp * idol->GetAmount(); + + amount += int32(CalculatePct(caster->GetTotalAttackPowerValue(BASE_ATTACK), cp)); + } + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dru_rip_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_dru_rip_AuraScript(); + } +}; + // 62606 - Savage Defense class spell_dru_savage_defense : public SpellScriptLoader { @@ -777,6 +1020,35 @@ class spell_dru_tiger_s_fury : public SpellScriptLoader } }; +// -61391 - Typhoon +class spell_dru_typhoon : public SpellScriptLoader +{ + public: + spell_dru_typhoon() : SpellScriptLoader("spell_dru_typhoon") { } + + class spell_dru_typhoon_SpellScript : public SpellScript + { + PrepareSpellScript(spell_dru_typhoon_SpellScript); + + void HandleKnockBack(SpellEffIndex effIndex) + { + // Glyph of Typhoon + if (GetCaster()->HasAura(SPELL_DRUID_GLYPH_OF_TYPHOON)) + PreventHitDefaultEffect(effIndex); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_dru_typhoon_SpellScript::HandleKnockBack, EFFECT_0, SPELL_EFFECT_KNOCK_BACK); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_dru_typhoon_SpellScript(); + } +}; + // 70691 - Item T10 Restoration 4P Bonus class spell_dru_t10_restoration_4p_bonus : public SpellScriptLoader { @@ -834,14 +1106,21 @@ class spell_dru_t10_restoration_4p_bonus : public SpellScriptLoader void AddSC_druid_spell_scripts() { + new spell_dru_dash(); new spell_dru_eclipse_energize(); new spell_dru_enrage(); new spell_dru_glyph_of_starfire(); + 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(); @@ -849,5 +1128,6 @@ void AddSC_druid_spell_scripts() new spell_dru_survival_instincts(); new spell_dru_swift_flight_passive(); new spell_dru_tiger_s_fury(); + new spell_dru_typhoon(); new spell_dru_t10_restoration_4p_bonus(); } diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index d1d4f660172..acaf7f08f36 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -72,6 +72,97 @@ class spell_gen_absorb0_hitlimit1 : public SpellScriptLoader } }; +// 28764 - Adaptive Warding (Frostfire Regalia Set) +enum AdaptiveWarding +{ + SPELL_GEN_ADAPTIVE_WARDING_FIRE = 28765, + SPELL_GEN_ADAPTIVE_WARDING_NATURE = 28768, + SPELL_GEN_ADAPTIVE_WARDING_FROST = 28766, + SPELL_GEN_ADAPTIVE_WARDING_SHADOW = 28769, + SPELL_GEN_ADAPTIVE_WARDING_ARCANE = 28770 +}; + +class spell_gen_adaptive_warding : public SpellScriptLoader +{ + public: + spell_gen_adaptive_warding() : SpellScriptLoader("spell_gen_adaptive_warding") { } + + class spell_gen_adaptive_warding_AuraScript : public AuraScript + { + PrepareAuraScript(spell_gen_adaptive_warding_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_GEN_ADAPTIVE_WARDING_FIRE) || + !sSpellMgr->GetSpellInfo(SPELL_GEN_ADAPTIVE_WARDING_NATURE) || + !sSpellMgr->GetSpellInfo(SPELL_GEN_ADAPTIVE_WARDING_FROST) || + !sSpellMgr->GetSpellInfo(SPELL_GEN_ADAPTIVE_WARDING_SHADOW) || + !sSpellMgr->GetSpellInfo(SPELL_GEN_ADAPTIVE_WARDING_ARCANE)) + return false; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + if (eventInfo.GetDamageInfo()->GetSpellInfo()) // eventInfo.GetSpellInfo() + return false; + + // find Mage Armor + if (!GetTarget()->GetAuraEffect(SPELL_AURA_MOD_MANA_REGEN_INTERRUPT, SPELLFAMILY_MAGE, 0x10000000, 0x0, 0x0)) + return false; + + switch (GetFirstSchoolInMask(eventInfo.GetSchoolMask())) + { + case SPELL_SCHOOL_NORMAL: + case SPELL_SCHOOL_HOLY: + return false; + default: + break; + } + return true; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + uint32 spellId = 0; + switch (GetFirstSchoolInMask(eventInfo.GetSchoolMask())) + { + case SPELL_SCHOOL_FIRE: + spellId = SPELL_GEN_ADAPTIVE_WARDING_FIRE; + break; + case SPELL_SCHOOL_NATURE: + spellId = SPELL_GEN_ADAPTIVE_WARDING_NATURE; + break; + case SPELL_SCHOOL_FROST: + spellId = SPELL_GEN_ADAPTIVE_WARDING_FROST; + break; + case SPELL_SCHOOL_SHADOW: + spellId = SPELL_GEN_ADAPTIVE_WARDING_SHADOW; + break; + case SPELL_SCHOOL_ARCANE: + spellId = SPELL_GEN_ADAPTIVE_WARDING_ARCANE; + break; + default: + return; + } + GetTarget()->CastSpell(GetTarget(), spellId, true, NULL, aurEff); + } + + void Register() + { + DoCheckProc += AuraCheckProcFn(spell_gen_adaptive_warding_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_gen_adaptive_warding_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_gen_adaptive_warding_AuraScript(); + } +}; + // 41337 Aura of Anger class spell_gen_aura_of_anger : public SpellScriptLoader { @@ -226,6 +317,245 @@ class spell_gen_cannibalize : public SpellScriptLoader } }; +// 63845 - Create Lance +enum CreateLanceSpells +{ + SPELL_CREATE_LANCE_ALLIANCE = 63914, + SPELL_CREATE_LANCE_HORDE = 63919 +}; + +class spell_gen_create_lance : public SpellScriptLoader +{ + public: + spell_gen_create_lance() : SpellScriptLoader("spell_gen_create_lance") { } + + class spell_gen_create_lance_SpellScript : public SpellScript + { + PrepareSpellScript(spell_gen_create_lance_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_CREATE_LANCE_ALLIANCE) || !sSpellMgr->GetSpellInfo(SPELL_CREATE_LANCE_HORDE)) + return false; + return true; + } + + void HandleScript(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + + if (Player* target = GetHitPlayer()) + { + if (target->GetTeam() == ALLIANCE) + GetCaster()->CastSpell(target, SPELL_CREATE_LANCE_ALLIANCE, true); + else + GetCaster()->CastSpell(target, SPELL_CREATE_LANCE_HORDE, true); + } + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_gen_create_lance_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_gen_create_lance_SpellScript(); + } +}; + +// 28702 - Netherbloom +enum Netherbloom +{ + SPELL_NETHERBLOOM_POLLEN_1 = 28703 +}; + +class spell_gen_netherbloom : public SpellScriptLoader +{ + public: + spell_gen_netherbloom() : SpellScriptLoader("spell_gen_netherbloom") { } + + class spell_gen_netherbloom_SpellScript : public SpellScript + { + PrepareSpellScript(spell_gen_netherbloom_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + for (uint8 i = 0; i < 5; ++i) + if (!sSpellMgr->GetSpellInfo(SPELL_NETHERBLOOM_POLLEN_1 + i)) + return false; + return true; + } + + void HandleScript(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + + if (Unit* target = GetHitUnit()) + { + // 25% chance of casting a random buff + if (roll_chance_i(75)) + return; + + // triggered spells are 28703 to 28707 + // Note: some sources say, that there was the possibility of + // receiving a debuff. However, this seems to be removed by a patch. + + // don't overwrite an existing aura + for (uint8 i = 0; i < 5; ++i) + if (target->HasAura(SPELL_NETHERBLOOM_POLLEN_1 + i)) + return; + + target->CastSpell(target, SPELL_NETHERBLOOM_POLLEN_1 + urand(0, 4), true); + } + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_gen_netherbloom_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_gen_netherbloom_SpellScript(); + } +}; + +// 28720 - Nightmare Vine +enum NightmareVine +{ + SPELL_NIGHTMARE_POLLEN = 28721 +}; + +class spell_gen_nightmare_vine : public SpellScriptLoader +{ + public: + spell_gen_nightmare_vine() : SpellScriptLoader("spell_gen_nightmare_vine") { } + + class spell_gen_nightmare_vine_SpellScript : public SpellScript + { + PrepareSpellScript(spell_gen_nightmare_vine_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_NIGHTMARE_POLLEN)) + return false; + return true; + } + + void HandleScript(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + + if (Unit* target = GetHitUnit()) + { + // 25% chance of casting Nightmare Pollen + if (roll_chance_i(25)) + target->CastSpell(target, SPELL_NIGHTMARE_POLLEN, true); + } + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_gen_nightmare_vine_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_gen_nightmare_vine_SpellScript(); + } +}; + +// 27539 - Obsidian Armor +enum ObsidianArmor +{ + SPELL_GEN_OBSIDIAN_ARMOR_HOLY = 27536, + SPELL_GEN_OBSIDIAN_ARMOR_FIRE = 27533, + SPELL_GEN_OBSIDIAN_ARMOR_NATURE = 27538, + SPELL_GEN_OBSIDIAN_ARMOR_FROST = 27534, + SPELL_GEN_OBSIDIAN_ARMOR_SHADOW = 27535, + SPELL_GEN_OBSIDIAN_ARMOR_ARCANE = 27540 +}; + +class spell_gen_obsidian_armor : public SpellScriptLoader +{ + public: + spell_gen_obsidian_armor() : SpellScriptLoader("spell_gen_obsidian_armor") { } + + class spell_gen_obsidian_armor_AuraScript : public AuraScript + { + PrepareAuraScript(spell_gen_obsidian_armor_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_GEN_OBSIDIAN_ARMOR_HOLY) || + !sSpellMgr->GetSpellInfo(SPELL_GEN_OBSIDIAN_ARMOR_FIRE) || + !sSpellMgr->GetSpellInfo(SPELL_GEN_OBSIDIAN_ARMOR_NATURE) || + !sSpellMgr->GetSpellInfo(SPELL_GEN_OBSIDIAN_ARMOR_FROST) || + !sSpellMgr->GetSpellInfo(SPELL_GEN_OBSIDIAN_ARMOR_SHADOW) || + !sSpellMgr->GetSpellInfo(SPELL_GEN_OBSIDIAN_ARMOR_ARCANE)) + return false; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + if (eventInfo.GetDamageInfo()->GetSpellInfo()) // eventInfo.GetSpellInfo() + return false; + + if (GetFirstSchoolInMask(eventInfo.GetSchoolMask()) == SPELL_SCHOOL_NORMAL) + return false; + + return true; + } + + void OnProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + uint32 spellId = 0; + switch (GetFirstSchoolInMask(eventInfo.GetSchoolMask())) + { + case SPELL_SCHOOL_HOLY: + spellId = SPELL_GEN_OBSIDIAN_ARMOR_HOLY; + break; + case SPELL_SCHOOL_FIRE: + spellId = SPELL_GEN_OBSIDIAN_ARMOR_FIRE; + break; + case SPELL_SCHOOL_NATURE: + spellId = SPELL_GEN_OBSIDIAN_ARMOR_NATURE; + break; + case SPELL_SCHOOL_FROST: + spellId = SPELL_GEN_OBSIDIAN_ARMOR_FROST; + break; + case SPELL_SCHOOL_SHADOW: + spellId = SPELL_GEN_OBSIDIAN_ARMOR_SHADOW; + break; + case SPELL_SCHOOL_ARCANE: + spellId = SPELL_GEN_OBSIDIAN_ARMOR_ARCANE; + break; + default: + return; + } + GetTarget()->CastSpell(GetTarget(), spellId, true, NULL, aurEff); + } + + void Register() + { + DoCheckProc += AuraCheckProcFn(spell_gen_obsidian_armor_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_gen_obsidian_armor_AuraScript::OnProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_gen_obsidian_armor_AuraScript(); + } +}; + // 45472 Parachute enum ParachuteSpells { @@ -3320,10 +3650,15 @@ class spell_gen_darkflight : public SpellScriptLoader void AddSC_generic_spell_scripts() { new spell_gen_absorb0_hitlimit1(); + new spell_gen_adaptive_warding(); new spell_gen_aura_of_anger(); new spell_gen_av_drekthar_presence(); new spell_gen_burn_brutallus(); new spell_gen_cannibalize(); + new spell_gen_create_lance(); + new spell_gen_netherbloom(); + new spell_gen_nightmare_vine(); + new spell_gen_obsidian_armor(); new spell_gen_parachute(); new spell_gen_pet_summoned(); new spell_gen_remove_flight_auras(); diff --git a/src/server/scripts/Spells/spell_holiday.cpp b/src/server/scripts/Spells/spell_holiday.cpp index d883b4d7da7..dbfc2b44501 100644 --- a/src/server/scripts/Spells/spell_holiday.cpp +++ b/src/server/scripts/Spells/spell_holiday.cpp @@ -303,27 +303,10 @@ class spell_winter_veil_mistletoe : public SpellScriptLoader void HandleScript(SpellEffIndex /*effIndex*/) { - Unit* caster = GetCaster(); - if (Player* target = GetHitPlayer()) { - uint32 spellId = 0; - switch (urand(0, 2)) - { - case 0: - spellId = SPELL_CREATE_MISTLETOE; - break; - case 1: - spellId = SPELL_CREATE_HOLLY; - break; - case 2: - spellId = SPELL_CREATE_SNOWFLAKES; - break; - default: - return; - } - - caster->CastSpell(target, spellId, true); + uint32 spellId = RAND(SPELL_CREATE_HOLLY, SPELL_CREATE_MISTLETOE, SPELL_CREATE_SNOWFLAKES); + GetCaster()->CastSpell(target, spellId, true); } } @@ -339,6 +322,71 @@ class spell_winter_veil_mistletoe : public SpellScriptLoader } }; +// 26275 - PX-238 Winter Wondervolt TRAP +enum PX238WinterWondervolt +{ + SPELL_PX_238_WINTER_WONDERVOLT_TRANSFORM_1 = 26157, + SPELL_PX_238_WINTER_WONDERVOLT_TRANSFORM_2 = 26272, + SPELL_PX_238_WINTER_WONDERVOLT_TRANSFORM_3 = 26273, + SPELL_PX_238_WINTER_WONDERVOLT_TRANSFORM_4 = 26274 +}; + +class spell_winter_veil_px_238_winter_wondervolt : public SpellScriptLoader +{ + public: + spell_winter_veil_px_238_winter_wondervolt() : SpellScriptLoader("spell_winter_veil_px_238_winter_wondervolt") { } + + class spell_winter_veil_px_238_winter_wondervolt_SpellScript : public SpellScript + { + PrepareSpellScript(spell_winter_veil_px_238_winter_wondervolt_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_PX_238_WINTER_WONDERVOLT_TRANSFORM_1) || + !sSpellMgr->GetSpellInfo(SPELL_PX_238_WINTER_WONDERVOLT_TRANSFORM_2) || + !sSpellMgr->GetSpellInfo(SPELL_PX_238_WINTER_WONDERVOLT_TRANSFORM_3) || + !sSpellMgr->GetSpellInfo(SPELL_PX_238_WINTER_WONDERVOLT_TRANSFORM_4)) + return false; + return true; + } + + void HandleScript(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + + uint32 const spells[4] = + { + SPELL_PX_238_WINTER_WONDERVOLT_TRANSFORM_1, + SPELL_PX_238_WINTER_WONDERVOLT_TRANSFORM_2, + SPELL_PX_238_WINTER_WONDERVOLT_TRANSFORM_3, + SPELL_PX_238_WINTER_WONDERVOLT_TRANSFORM_4 + }; + + if (Unit* target = GetHitUnit()) + { + for (uint8 i = 0; i < 4; ++i) + if (target->HasAura(spells[i])) + return; + + GetCaster()->CastSpell(target, spells[urand(0, 3)], true); + } + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_winter_veil_px_238_winter_wondervolt_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + + private: + + }; + + SpellScript* GetSpellScript() const + { + return new spell_winter_veil_px_238_winter_wondervolt_SpellScript(); + } +}; + void AddSC_holiday_spell_scripts() { // Love is in the Air @@ -349,4 +397,5 @@ void AddSC_holiday_spell_scripts() new spell_hallow_end_tricky_treat(); // Winter Veil new spell_winter_veil_mistletoe(); + new spell_winter_veil_px_238_winter_wondervolt(); } diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp index a9b21807899..891a7daaa1f 100644 --- a/src/server/scripts/Spells/spell_hunter.cpp +++ b/src/server/scripts/Spells/spell_hunter.cpp @@ -33,12 +33,15 @@ enum HunterSpells { SPELL_HUNTER_ASPECT_OF_THE_BEAST_PET = 61669, + 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_INVIGORATION_TRIGGERED = 53398, SPELL_HUNTER_MASTERS_CALL_TRIGGERED = 62305, + SPELL_HUNTER_MISDIRECTION_PROC = 35079, SPELL_HUNTER_PET_LAST_STAND_TRIGGERED = 53479, SPELL_HUNTER_PET_HEART_OF_THE_PHOENIX = 55709, SPELL_HUNTER_PET_HEART_OF_THE_PHOENIX_TRIGGERED = 54114, @@ -99,6 +102,50 @@ class spell_hun_aspect_of_the_beast : public SpellScriptLoader } }; +// 34074 - Aspect of the Viper +class spell_hun_ascpect_of_the_viper : public SpellScriptLoader +{ + public: + spell_hun_ascpect_of_the_viper() : SpellScriptLoader("spell_hun_ascpect_of_the_viper") { } + + class spell_hun_ascpect_of_the_viper_AuraScript : public AuraScript + { + PrepareAuraScript(spell_hun_ascpect_of_the_viper_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_ASPECT_OF_THE_VIPER_ENERGIZE)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_GLYPH_OF_ASPECT_OF_THE_VIPER)) + return false; + return true; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + 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); + } + + void Register() + { + OnEffectProc += AuraEffectProcFn(spell_hun_ascpect_of_the_viper_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_OBS_MOD_POWER); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_hun_ascpect_of_the_viper_AuraScript(); + } +}; + // 53209 - Chimera Shot class spell_hun_chimera_shot : public SpellScriptLoader { @@ -358,16 +405,35 @@ class spell_hun_misdirection : public SpellScriptLoader { PrepareAuraScript(spell_hun_misdirection_AuraScript); + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_MISDIRECTION_PROC)) + return false; + return true; + } + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { - if (Unit* caster = GetCaster()) - if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_DEFAULT) - caster->SetReducedThreatPercent(0, 0); + if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_DEFAULT) + GetTarget()->ResetRedirectThreat(); + } + + bool CheckProc(ProcEventInfo& /*eventInfo*/) + { + return GetTarget()->GetRedirectThreatTarget(); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + GetTarget()->CastSpell(GetTarget(), SPELL_HUNTER_MISDIRECTION_PROC, true, NULL, aurEff); } void Register() { AfterEffectRemove += AuraEffectRemoveFn(spell_hun_misdirection_AuraScript::OnRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + DoCheckProc += AuraCheckProcFn(spell_hun_misdirection_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_hun_misdirection_AuraScript::HandleProc, EFFECT_1, SPELL_AURA_DUMMY); } }; @@ -377,7 +443,7 @@ class spell_hun_misdirection : public SpellScriptLoader } }; -// 35079 - Misdirection proc +// 35079 - Misdirection (Proc) class spell_hun_misdirection_proc : public SpellScriptLoader { public: @@ -389,8 +455,7 @@ class spell_hun_misdirection_proc : public SpellScriptLoader void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { - if (GetCaster()) - GetCaster()->SetReducedThreatPercent(0, 0); + GetTarget()->ResetRedirectThreat(); } void Register() @@ -740,6 +805,7 @@ class spell_hun_target_only_pet_and_owner : public SpellScriptLoader void AddSC_hunter_spell_scripts() { new spell_hun_aspect_of_the_beast(); + new spell_hun_ascpect_of_the_viper(); new spell_hun_chimera_shot(); new spell_hun_disengage(); new spell_hun_invigoration(); diff --git a/src/server/scripts/Spells/spell_item.cpp b/src/server/scripts/Spells/spell_item.cpp index b4e06cb6b48..b8e17f4ecca 100644 --- a/src/server/scripts/Spells/spell_item.cpp +++ b/src/server/scripts/Spells/spell_item.cpp @@ -73,6 +73,150 @@ class spell_item_trigger_spell : public SpellScriptLoader } }; +// 26400 - Arcane Shroud +class spell_item_arcane_shroud : public SpellScriptLoader +{ + public: + spell_item_arcane_shroud() : SpellScriptLoader("spell_item_arcane_shroud") { } + + class spell_item_arcane_shroud_AuraScript : public AuraScript + { + PrepareAuraScript(spell_item_arcane_shroud_AuraScript); + + void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/) + { + int32 diff = GetUnitOwner()->getLevel() - 60; + if (diff > 0) + amount += 2 * diff; + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_item_arcane_shroud_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_MOD_THREAT); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_item_arcane_shroud_AuraScript(); + } +}; + +// 64411 - Blessing of Ancient Kings (Val'anyr, Hammer of Ancient Kings) +enum BlessingOfAncientKings +{ + SPELL_PROTECTION_OF_ANCIENT_KINGS = 64413 +}; + +class spell_item_blessing_of_ancient_kings : public SpellScriptLoader +{ + public: + spell_item_blessing_of_ancient_kings() : SpellScriptLoader("spell_item_blessing_of_ancient_kings") { } + + class spell_item_blessing_of_ancient_kings_AuraScript : public AuraScript + { + PrepareAuraScript(spell_item_blessing_of_ancient_kings_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_PROTECTION_OF_ANCIENT_KINGS)) + return false; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + return eventInfo.GetProcTarget(); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + int32 absorb = int32(CalculatePct(eventInfo.GetHealInfo()->GetHeal(), 15.0f)); + if (AuraEffect* protEff = eventInfo.GetProcTarget()->GetAuraEffect(SPELL_PROTECTION_OF_ANCIENT_KINGS, 0, eventInfo.GetActor()->GetGUID())) + { + // The shield can grow to a maximum size of 20,000 damage absorbtion + protEff->SetAmount(std::min<int32>(protEff->GetAmount() + absorb, 20000)); + + // Refresh and return to prevent replacing the aura + aurEff->GetBase()->RefreshDuration(); + } + else + GetTarget()->CastCustomSpell(SPELL_PROTECTION_OF_ANCIENT_KINGS, SPELLVALUE_BASE_POINT0, absorb, eventInfo.GetProcTarget(), true, NULL, aurEff); + } + + void Register() + { + DoCheckProc += AuraCheckProcFn(spell_item_blessing_of_ancient_kings_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_item_blessing_of_ancient_kings_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_item_blessing_of_ancient_kings_AuraScript(); + } +}; + +// 8342 - Defibrillate (Goblin Jumper Cables) have 33% chance on success +// 22999 - Defibrillate (Goblin Jumper Cables XL) have 50% chance on success +// 54732 - Defibrillate (Gnomish Army Knife) have 67% chance on success +enum Defibrillate +{ + SPELL_GOBLIN_JUMPER_CABLES_FAIL = 8338, + SPELL_GOBLIN_JUMPER_CABLES_XL_FAIL = 23055 +}; + +class spell_item_defibrillate : public SpellScriptLoader +{ + public: + spell_item_defibrillate(char const* name, uint8 chance, uint32 failSpell = 0) : SpellScriptLoader(name), _chance(chance), _failSpell(failSpell) { } + + class spell_item_defibrillate_SpellScript : public SpellScript + { + PrepareSpellScript(spell_item_defibrillate_SpellScript); + + public: + spell_item_defibrillate_SpellScript(uint8 chance, uint32 failSpell) : SpellScript(), _chance(chance), _failSpell(failSpell) { } + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (_failSpell && !sSpellMgr->GetSpellInfo(_failSpell)) + return false; + return true; + } + + void HandleScript(SpellEffIndex effIndex) + { + if (roll_chance_i(_chance)) + { + PreventHitDefaultEffect(effIndex); + if (_failSpell) + GetCaster()->CastSpell(GetCaster(), _failSpell, true, GetCastItem()); + } + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_item_defibrillate_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_RESURRECT); + } + + private: + uint8 _chance; + uint32 _failSpell; + }; + + SpellScript* GetSpellScript() const + { + return new spell_item_defibrillate_SpellScript(_chance, _failSpell); + } + + private: + uint8 _chance; + uint32 _failSpell; +}; + // http://www.wowhead.com/item=6522 Deviate Fish // 8063 Deviate Fish enum DeviateFishSpells @@ -357,6 +501,47 @@ class spell_item_mingos_fortune_generator : public SpellScriptLoader } }; +// 71875, 71877 - Item - Black Bruise: Necrotic Touch Proc +enum NecroticTouch +{ + SPELL_ITEM_NECROTIC_TOUCH_PROC = 71879 +}; + +class spell_item_necrotic_touch : public SpellScriptLoader +{ + public: + spell_item_necrotic_touch() : SpellScriptLoader("spell_item_necrotic_touch") { } + + class spell_item_necrotic_touch_AuraScript : public AuraScript + { + PrepareAuraScript(spell_item_necrotic_touch_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_ITEM_NECROTIC_TOUCH_PROC)) + return false; + return true; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + int32 bp = CalculatePct(int32(eventInfo.GetDamageInfo()->GetDamage()), aurEff->GetAmount()); + GetTarget()->CastCustomSpell(SPELL_ITEM_NECROTIC_TOUCH_PROC, SPELLVALUE_BASE_POINT0, bp, GetTarget(), true, NULL, aurEff); + } + + void Register() + { + OnEffectProc += AuraEffectProcFn(spell_item_necrotic_touch_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_item_necrotic_touch_AuraScript(); + } +}; + // http://www.wowhead.com/item=10720 Gnomish Net-o-Matic Projector // 13120 Net-o-Matic enum NetOMaticSpells @@ -464,6 +649,35 @@ class spell_item_noggenfogger_elixir : public SpellScriptLoader } }; +// 17512 - Piccolo of the Flaming Fire +class spell_item_piccolo_of_the_flaming_fire : public SpellScriptLoader +{ + public: + spell_item_piccolo_of_the_flaming_fire() : SpellScriptLoader("spell_item_piccolo_of_the_flaming_fire") { } + + class spell_item_piccolo_of_the_flaming_fire_SpellScript : public SpellScript + { + PrepareSpellScript(spell_item_piccolo_of_the_flaming_fire_SpellScript); + + void HandleScript(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + if (Player* target = GetHitPlayer()) + target->HandleEmoteCommand(EMOTE_STATE_DANCE); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_item_piccolo_of_the_flaming_fire_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_item_piccolo_of_the_flaming_fire_SpellScript(); + } +}; + // http://www.wowhead.com/item=6657 Savory Deviate Delight // 8213 Savory Deviate Delight enum SavoryDeviateDelight @@ -522,6 +736,262 @@ class spell_item_savory_deviate_delight : public SpellScriptLoader } }; +// 48129 - Scroll of Recall +// 60320 - Scroll of Recall II +// 60321 - Scroll of Recall III +enum ScrollOfRecall +{ + SPELL_SCROLL_OF_RECALL_I = 48129, + SPELL_SCROLL_OF_RECALL_II = 60320, + SPELL_SCROLL_OF_RECALL_III = 60321, + SPELL_LOST = 60444, + SPELL_SCROLL_OF_RECALL_FAIL_ALLIANCE_1 = 60323, + SPELL_SCROLL_OF_RECALL_FAIL_HORDE_1 = 60328, +}; + +class spell_item_scroll_of_recall : public SpellScriptLoader +{ + public: + spell_item_scroll_of_recall() : SpellScriptLoader("spell_item_scroll_of_recall") { } + + class spell_item_scroll_of_recall_SpellScript : public SpellScript + { + PrepareSpellScript(spell_item_scroll_of_recall_SpellScript); + + bool Load() + { + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } + + void HandleScript(SpellEffIndex effIndex) + { + Unit* caster = GetCaster(); + uint8 maxSafeLevel = 0; + switch (GetSpellInfo()->Id) + { + case SPELL_SCROLL_OF_RECALL_I: // Scroll of Recall + maxSafeLevel = 40; + break; + case SPELL_SCROLL_OF_RECALL_II: // Scroll of Recall II + maxSafeLevel = 70; + break; + case SPELL_SCROLL_OF_RECALL_III: // Scroll of Recal III + maxSafeLevel = 80; + break; + default: + break; + } + + if (caster->getLevel() > maxSafeLevel) + { + caster->CastSpell(caster, SPELL_LOST, true); + + // ALLIANCE from 60323 to 60330 - HORDE from 60328 to 60335 + uint32 spellId = SPELL_SCROLL_OF_RECALL_FAIL_ALLIANCE_1; + if (GetCaster()->ToPlayer()->GetTeam() == HORDE) + spellId = SPELL_SCROLL_OF_RECALL_FAIL_HORDE_1; + + GetCaster()->CastSpell(GetCaster(), spellId + urand(0, 7), true); + + PreventHitDefaultEffect(effIndex); + } + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_item_scroll_of_recall_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_TELEPORT_UNITS); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_item_scroll_of_recall_SpellScript(); + } +}; + +// 71169 - Shadow's Fate (Shadowmourne questline) +enum ShadowsFate +{ + SPELL_SOUL_FEAST = 71203, + QUEST_A_FEAST_OF_SOULS = 24547 +}; + +class spell_item_shadows_fate : public SpellScriptLoader +{ + public: + spell_item_shadows_fate() : SpellScriptLoader("spell_item_shadows_fate") { } + + class spell_item_shadows_fate_AuraScript : public AuraScript + { + PrepareAuraScript(spell_item_shadows_fate_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_SOUL_FEAST)) + return false; + if (!sObjectMgr->GetQuestTemplate(QUEST_A_FEAST_OF_SOULS)) + return false; + return true; + } + + bool Load() + { + _procTarget = NULL; + return true; + } + + bool CheckProc(ProcEventInfo& /*eventInfo*/) + { + _procTarget = GetCaster(); + return _procTarget && _procTarget->GetTypeId() == TYPEID_PLAYER && _procTarget->ToPlayer()->GetQuestStatus(QUEST_A_FEAST_OF_SOULS) == QUEST_STATUS_INCOMPLETE; + } + + void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + GetTarget()->CastSpell(_procTarget, SPELL_SOUL_FEAST, true); + } + + void Register() + { + DoCheckProc += AuraCheckProcFn(spell_item_shadows_fate_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_item_shadows_fate_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + + private: + Unit* _procTarget; + }; + + AuraScript* GetAuraScript() const + { + return new spell_item_shadows_fate_AuraScript(); + } +}; + +enum Shadowmourne +{ + SPELL_SHADOWMOURNE_CHAOS_BANE_DAMAGE = 71904, + SPELL_SHADOWMOURNE_SOUL_FRAGMENT = 71905, + SPELL_SHADOWMOURNE_VISUAL_LOW = 72521, + SPELL_SHADOWMOURNE_VISUAL_HIGH = 72523, + SPELL_SHADOWMOURNE_CHAOS_BANE_BUFF = 73422, +}; + +// 71903 - Item - Shadowmourne Legendary +class spell_item_shadowmourne : public SpellScriptLoader +{ + public: + spell_item_shadowmourne() : SpellScriptLoader("spell_item_shadowmourne") { } + + class spell_item_shadowmourne_AuraScript : public AuraScript + { + PrepareAuraScript(spell_item_shadowmourne_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_SHADOWMOURNE_CHAOS_BANE_DAMAGE)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_SHADOWMOURNE_SOUL_FRAGMENT)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_SHADOWMOURNE_CHAOS_BANE_BUFF)) + return false; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + if (GetTarget()->HasAura(SPELL_SHADOWMOURNE_CHAOS_BANE_BUFF)) // cant collect shards while under effect of Chaos Bane buff + return false; + return eventInfo.GetProcTarget() && eventInfo.GetProcTarget()->isAlive(); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + GetTarget()->CastSpell(GetTarget(), SPELL_SHADOWMOURNE_SOUL_FRAGMENT, true, NULL, aurEff); + + // this can't be handled in AuraScript of SoulFragments because we need to know victim + if (Aura* soulFragments = GetTarget()->GetAura(SPELL_SHADOWMOURNE_SOUL_FRAGMENT)) + { + if (soulFragments->GetStackAmount() >= 10) + { + GetTarget()->CastSpell(eventInfo.GetProcTarget(), SPELL_SHADOWMOURNE_CHAOS_BANE_DAMAGE, true, NULL, aurEff); + soulFragments->Remove(); + } + } + } + + void Register() + { + DoCheckProc += AuraCheckProcFn(spell_item_shadowmourne_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_item_shadowmourne_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_item_shadowmourne_AuraScript(); + } +}; + +// 71905 - Soul Fragment +class spell_item_shadowmourne_soul_fragment : public SpellScriptLoader +{ + public: + spell_item_shadowmourne_soul_fragment() : SpellScriptLoader("spell_item_shadowmourne_soul_fragment") { } + + class spell_item_shadowmourne_soul_fragment_AuraScript : public AuraScript + { + PrepareAuraScript(spell_item_shadowmourne_soul_fragment_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_SHADOWMOURNE_VISUAL_LOW) || !sSpellMgr->GetSpellInfo(SPELL_SHADOWMOURNE_VISUAL_HIGH) || !sSpellMgr->GetSpellInfo(SPELL_SHADOWMOURNE_CHAOS_BANE_BUFF)) + return false; + return true; + } + + void OnStackChange(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + switch (GetStackAmount()) + { + case 1: + target->CastSpell(target, SPELL_SHADOWMOURNE_VISUAL_LOW, true); + break; + case 6: + target->RemoveAurasDueToSpell(SPELL_SHADOWMOURNE_VISUAL_LOW); + target->CastSpell(target, SPELL_SHADOWMOURNE_VISUAL_HIGH, true); + break; + case 10: + target->RemoveAurasDueToSpell(SPELL_SHADOWMOURNE_VISUAL_HIGH); + target->CastSpell(target, SPELL_SHADOWMOURNE_CHAOS_BANE_BUFF, true); + break; + default: + break; + } + } + + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + target->RemoveAurasDueToSpell(SPELL_SHADOWMOURNE_VISUAL_LOW); + target->RemoveAurasDueToSpell(SPELL_SHADOWMOURNE_VISUAL_HIGH); + } + + void Register() + { + AfterEffectApply += AuraEffectApplyFn(spell_item_shadowmourne_soul_fragment_AuraScript::OnStackChange, EFFECT_0, SPELL_AURA_MOD_STAT, AuraEffectHandleModes(AURA_EFFECT_HANDLE_REAL | AURA_EFFECT_HANDLE_REAPPLY)); + AfterEffectRemove += AuraEffectRemoveFn(spell_item_shadowmourne_soul_fragment_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_MOD_STAT, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_item_shadowmourne_soul_fragment_AuraScript(); + } +}; + // http://www.wowhead.com/item=7734 Six Demon Bag // 14537 Six Demon Bag enum SixDemonBagSpells @@ -593,6 +1063,35 @@ class spell_item_six_demon_bag : public SpellScriptLoader } }; +// 28862 - The Eye of Diminution +class spell_item_the_eye_of_diminution : public SpellScriptLoader +{ + public: + spell_item_the_eye_of_diminution() : SpellScriptLoader("spell_item_the_eye_of_diminution") { } + + class spell_item_the_eye_of_diminution_AuraScript : public AuraScript + { + PrepareAuraScript(spell_item_the_eye_of_diminution_AuraScript); + + void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/) + { + int32 diff = GetUnitOwner()->getLevel() - 60; + if (diff > 0) + amount += diff; + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_item_the_eye_of_diminution_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_MOD_THREAT); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_item_the_eye_of_diminution_AuraScript(); + } +}; + // http://www.wowhead.com/item=44012 Underbelly Elixir // 59640 Underbelly Elixir enum UnderbellyElixirSpells @@ -646,70 +1145,6 @@ class spell_item_underbelly_elixir : public SpellScriptLoader } }; -enum eShadowmourneVisuals -{ - SPELL_SHADOWMOURNE_VISUAL_LOW = 72521, - SPELL_SHADOWMOURNE_VISUAL_HIGH = 72523, - SPELL_SHADOWMOURNE_CHAOS_BANE_BUFF = 73422, -}; - -class spell_item_shadowmourne : public SpellScriptLoader -{ -public: - spell_item_shadowmourne() : SpellScriptLoader("spell_item_shadowmourne") { } - - class spell_item_shadowmourne_AuraScript : public AuraScript - { - PrepareAuraScript(spell_item_shadowmourne_AuraScript); - - bool Validate(SpellInfo const* /*spellEntry*/) - { - if (!sSpellMgr->GetSpellInfo(SPELL_SHADOWMOURNE_VISUAL_LOW) || !sSpellMgr->GetSpellInfo(SPELL_SHADOWMOURNE_VISUAL_HIGH) || !sSpellMgr->GetSpellInfo(SPELL_SHADOWMOURNE_CHAOS_BANE_BUFF)) - return false; - return true; - } - - void OnStackChange(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - Unit* target = GetTarget(); - switch (GetStackAmount()) - { - case 1: - target->CastSpell(target, SPELL_SHADOWMOURNE_VISUAL_LOW, true); - break; - case 6: - target->RemoveAurasDueToSpell(SPELL_SHADOWMOURNE_VISUAL_LOW); - target->CastSpell(target, SPELL_SHADOWMOURNE_VISUAL_HIGH, true); - break; - case 10: - target->RemoveAurasDueToSpell(SPELL_SHADOWMOURNE_VISUAL_HIGH); - target->CastSpell(target, SPELL_SHADOWMOURNE_CHAOS_BANE_BUFF, true); - break; - default: - break; - } - } - - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - Unit* target = GetTarget(); - target->RemoveAurasDueToSpell(SPELL_SHADOWMOURNE_VISUAL_LOW); - target->RemoveAurasDueToSpell(SPELL_SHADOWMOURNE_VISUAL_HIGH); - } - - void Register() - { - AfterEffectApply += AuraEffectApplyFn(spell_item_shadowmourne_AuraScript::OnStackChange, EFFECT_0, SPELL_AURA_MOD_STAT, AuraEffectHandleModes(AURA_EFFECT_HANDLE_REAL | AURA_EFFECT_HANDLE_REAPPLY)); - AfterEffectRemove += AuraEffectRemoveFn(spell_item_shadowmourne_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_MOD_STAT, AURA_EFFECT_HANDLE_REAL); - } - }; - - AuraScript* GetAuraScript() const - { - return new spell_item_shadowmourne_AuraScript(); - } -}; - enum AirRifleSpells { SPELL_AIR_RIFLE_HOLD_VISUAL = 65582, @@ -2030,17 +2465,28 @@ void AddSC_item_spell_scripts() // 23075 Mithril Mechanical Dragonling new spell_item_trigger_spell("spell_item_mithril_mechanical_dragonling", SPELL_MITHRIL_MECHANICAL_DRAGONLING); + new spell_item_arcane_shroud(); + new spell_item_blessing_of_ancient_kings(); + new spell_item_defibrillate("spell_item_goblin_jumper_cables", 67, SPELL_GOBLIN_JUMPER_CABLES_FAIL); + new spell_item_defibrillate("spell_item_goblin_jumper_cables_xl", 50, SPELL_GOBLIN_JUMPER_CABLES_XL_FAIL); + new spell_item_defibrillate("spell_item_gnomish_army_knife", 33); new spell_item_deviate_fish(); new spell_item_flask_of_the_north(); new spell_item_gnomish_death_ray(); new spell_item_make_a_wish(); new spell_item_mingos_fortune_generator(); + new spell_item_necrotic_touch(); new spell_item_net_o_matic(); new spell_item_noggenfogger_elixir(); + new spell_item_piccolo_of_the_flaming_fire(); new spell_item_savory_deviate_delight(); + new spell_item_scroll_of_recall(); + new spell_item_shadows_fate(); + new spell_item_shadowmourne(); + new spell_item_shadowmourne_soul_fragment(); new spell_item_six_demon_bag(); + new spell_item_the_eye_of_diminution(); new spell_item_underbelly_elixir(); - new spell_item_shadowmourne(); new spell_item_red_rider_air_rifle(); new spell_item_create_heart_candy(); diff --git a/src/server/scripts/Spells/spell_mage.cpp b/src/server/scripts/Spells/spell_mage.cpp index 8c33117bb96..e14327b0f36 100644 --- a/src/server/scripts/Spells/spell_mage.cpp +++ b/src/server/scripts/Spells/spell_mage.cpp @@ -28,42 +28,43 @@ enum MageSpells { + SPELL_MAGE_BURNOUT = 29077, + SPELL_MAGE_COLD_SNAP = 11958, + SPELL_MAGE_FOCUS_MAGIC_PROC = 54648, + SPELL_MAGE_FROST_WARDING_R1 = 11189, + SPELL_MAGE_FROST_WARDING_TRIGGERED = 57776, + 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_SQUIRREL_FORM = 32813, + SPELL_MAGE_GIRAFFE_FORM = 32816, + SPELL_MAGE_SERPENT_FORM = 32817, + SPELL_MAGE_DRAGONHAWK_FORM = 32818, + SPELL_MAGE_WORGEN_FORM = 32819, + SPELL_MAGE_SHEEP_FORM = 32820, + SPELL_MAGE_GLYPH_OF_ETERNAL_WATER = 70937, + 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_COLD_SNAP = 11958, - 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_FROST_WARDING_R1 = 28332, - SPELL_MAGE_FROST_WARDING_TRIGGERED = 57776, - 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_INCANTER_S_ABSORPTION_TRIGGERED = 44413, - SPELL_MAGE_INCANTER_S_ABSORPTION_KNOCKBACK = 86261, - - SPELL_MAGE_SQUIRREL_FORM = 32813, - SPELL_MAGE_GIRAFFE_FORM = 32816, - SPELL_MAGE_SERPENT_FORM = 32817, - SPELL_MAGE_DRAGONHAWK_FORM = 32818, - SPELL_MAGE_WORGEN_FORM = 32819, - SPELL_MAGE_SHEEP_FORM = 32820, - SPELL_MAGE_IMPROVED_MANA_GEM_TRIGGERED = 83098, - SPELL_MAGE_GLYPH_OF_ETERNAL_WATER = 70937, - SPELL_MAGE_SUMMON_WATER_ELEMENTAL_PERMANENT = 70908, - SPELL_MAGE_SUMMON_WATER_ELEMENTAL_TEMPORARY = 70907, - SPELL_MAGE_FINGERS_OF_FROST = 44544 }; @@ -76,6 +77,31 @@ enum MageIcons ICON_MAGE_IMPROVED_MANA_GEM = 1036 }; +// Incanter's Absorbtion +class spell_mage_incanters_absorbtion_base_AuraScript : public AuraScript +{ + public: + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_INCANTERS_ABSORBTION_TRIGGERED)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_INCANTERS_ABSORBTION_R1)) + return false; + return true; + } + + void Trigger(AuraEffect* aurEff, DamageInfo& /*dmgInfo*/, uint32& absorbAmount) + { + Unit* target = GetTarget(); + + if (AuraEffect* talentAurEff = target->GetAuraEffectOfRankedSpell(SPELL_MAGE_INCANTERS_ABSORBTION_R1, EFFECT_0)) + { + int32 bp = CalculatePct(absorbAmount, talentAurEff->GetAmount()); + target->CastCustomSpell(target, SPELL_MAGE_INCANTERS_ABSORBTION_TRIGGERED, &bp, NULL, NULL, true, NULL, aurEff); + } + } +}; + // 11113 - Blast Wave class spell_mage_blast_wave : public SpellScriptLoader { @@ -130,6 +156,51 @@ class spell_mage_blast_wave : public SpellScriptLoader } }; +// -44449 - Burnout +class spell_mage_burnout : public SpellScriptLoader +{ + public: + spell_mage_burnout() : SpellScriptLoader("spell_mage_burnout") { } + + class spell_mage_burnout_AuraScript : public AuraScript + { + PrepareAuraScript(spell_mage_burnout_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_BURNOUT)) + return false; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + return eventInfo.GetDamageInfo()->GetSpellInfo(); // eventInfo.GetSpellInfo() + } + + void HandleProc(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); + } + + void Register() + { + DoCheckProc += AuraCheckProcFn(spell_mage_burnout_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_mage_burnout_AuraScript::HandleProc, EFFECT_1, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_mage_burnout_AuraScript(); + } +}; + // 42208 - Blizzard /// Updated 4.3.4 class spell_mage_blizzard : public SpellScriptLoader @@ -327,29 +398,47 @@ class spell_mage_conjure_refreshment : public SpellScriptLoader } }; -// -6143, -543 - Frost Warding -class spell_mage_frost_warding_trigger : public SpellScriptLoader +// -543 - Fire Ward +// -6143 - Frost Ward +class spell_mage_fire_frost_ward : public SpellScriptLoader { public: - spell_mage_frost_warding_trigger() : SpellScriptLoader("spell_mage_frost_warding_trigger") { } + spell_mage_fire_frost_ward() : SpellScriptLoader("spell_mage_fire_frost_ward") { } - class spell_mage_frost_warding_trigger_AuraScript : public AuraScript + class spell_mage_fire_frost_ward_AuraScript : public spell_mage_incanters_absorbtion_base_AuraScript { - PrepareAuraScript(spell_mage_frost_warding_trigger_AuraScript); + PrepareAuraScript(spell_mage_fire_frost_ward_AuraScript); bool Validate(SpellInfo const* /*spellInfo*/) { - if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_FROST_WARDING_TRIGGERED) || !sSpellMgr->GetSpellInfo(SPELL_MAGE_FROST_WARDING_R1)) + if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_FROST_WARDING_TRIGGERED)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_FROST_WARDING_R1)) return false; return true; } - void Absorb(AuraEffect* aurEff, DamageInfo & dmgInfo, uint32 & absorbAmount) + void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& canBeRecalculated) + { + canBeRecalculated = false; + if (Unit* caster = GetCaster()) + { + // +80.68% from sp bonus + float bonus = 0.8068f; + + bonus *= caster->SpellBaseHealingBonusDone(GetSpellInfo()->GetSchoolMask()); + bonus *= caster->CalculateLevelPenalty(GetSpellInfo()); + + amount += int32(bonus); + } + } + + void Absorb(AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount) { Unit* target = GetTarget(); if (AuraEffect* talentAurEff = target->GetAuraEffectOfRankedSpell(SPELL_MAGE_FROST_WARDING_R1, EFFECT_0)) { - int32 chance = talentAurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue(); + int32 chance = talentAurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue(); // SPELL_EFFECT_DUMMY with NO_TARGET if (roll_chance_i(chance)) { @@ -364,13 +453,66 @@ class spell_mage_frost_warding_trigger : public SpellScriptLoader void Register() { - OnEffectAbsorb += AuraEffectAbsorbFn(spell_mage_frost_warding_trigger_AuraScript::Absorb, EFFECT_0); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_mage_fire_frost_ward_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB); + OnEffectAbsorb += AuraEffectAbsorbFn(spell_mage_fire_frost_ward_AuraScript::Absorb, EFFECT_0); + AfterEffectAbsorb += AuraEffectAbsorbFn(spell_mage_fire_frost_ward_AuraScript::Trigger, EFFECT_0); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_mage_fire_frost_ward_AuraScript(); + } +}; + +// 54646 - Focus Magic +class spell_mage_focus_magic : public SpellScriptLoader +{ + public: + spell_mage_focus_magic() : SpellScriptLoader("spell_mage_focus_magic") { } + + class spell_mage_focus_magic_AuraScript : public AuraScript + { + PrepareAuraScript(spell_mage_focus_magic_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_FOCUS_MAGIC_PROC)) + return false; + return true; + } + + bool Load() + { + _procTarget = NULL; + return true; + } + + bool CheckProc(ProcEventInfo& /*eventInfo*/) + { + _procTarget = GetCaster(); + return _procTarget && _procTarget->isAlive(); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + GetTarget()->CastSpell(_procTarget, SPELL_MAGE_FOCUS_MAGIC_PROC, true, NULL, aurEff); + } + + void Register() + { + DoCheckProc += AuraCheckProcFn(spell_mage_focus_magic_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_mage_focus_magic_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_MOD_SPELL_CRIT_CHANCE); } + + private: + Unit* _procTarget; }; AuraScript* GetAuraScript() const { - return new spell_mage_frost_warding_trigger_AuraScript(); + return new spell_mage_focus_magic_AuraScript(); } }; @@ -483,16 +625,63 @@ class spell_mage_ice_barrier : public SpellScriptLoader } }; -// 1463 - Mana Shield -/// Updated 4.3.4 -class spell_mage_mana_shield : public SpellScriptLoader +// -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 AuraScript + class spell_mage_ignite_AuraScript : public AuraScript + { + PrepareAuraScript(spell_mage_ignite_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_IGNITE)) + return false; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + return eventInfo.GetProcTarget(); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + SpellInfo const* igniteDot = sSpellMgr->GetSpellInfo(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() + { + DoCheckProc += AuraCheckProcFn(spell_mage_ignite_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_mage_ignite_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + 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_mana_shield_AuraScript); + PrepareAuraScript(spell_mage_mage_ward_AuraScript); void HandleAbsorb(AuraEffect* /*aurEff*/, DamageInfo & /*dmgInfo*/, uint32 & absorbAmount) { @@ -503,35 +692,28 @@ class spell_mage_mana_shield : public SpellScriptLoader } } - void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_ENEMY_SPELL) - GetTarget()->CastSpell(GetTarget(), SPELL_MAGE_INCANTER_S_ABSORPTION_KNOCKBACK, true); - } - void Register() { - 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); + AfterEffectAbsorb += AuraEffectAbsorbFn(spell_mage_mage_ward_AuraScript::HandleAbsorb, EFFECT_0); } }; AuraScript* GetAuraScript() const { - return new spell_mage_mana_shield_AuraScript(); + return new spell_mage_mage_ward_AuraScript(); } }; -// 543 - Mage Ward +// 1463 - Mana Shield /// Updated 4.3.4 -class spell_mage_mage_ward : public SpellScriptLoader +class spell_mage_mana_shield : public SpellScriptLoader { - public: - spell_mage_mage_ward() : SpellScriptLoader("spell_mage_mage_ward") { } + public: + spell_mage_mana_shield() : SpellScriptLoader("spell_mage_mana_shield") { } - class spell_mage_mage_ward_AuraScript : public AuraScript + class spell_mage_mana_shield_AuraScript : public AuraScript { - PrepareAuraScript(spell_mage_mage_ward_AuraScript); + PrepareAuraScript(spell_mage_mana_shield_AuraScript); void HandleAbsorb(AuraEffect* /*aurEff*/, DamageInfo & /*dmgInfo*/, uint32 & absorbAmount) { @@ -542,18 +724,71 @@ class spell_mage_mage_ward : public SpellScriptLoader } } + void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_ENEMY_SPELL) + GetTarget()->CastSpell(GetTarget(), SPELL_MAGE_INCANTER_S_ABSORPTION_KNOCKBACK, true); + } + void Register() { - AfterEffectAbsorb += AuraEffectAbsorbFn(spell_mage_mage_ward_AuraScript::HandleAbsorb, EFFECT_0); + 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 { - return new spell_mage_mage_ward_AuraScript(); + return new spell_mage_mana_shield_AuraScript(); } }; +// -29074 - Master of Elements +class spell_mage_master_of_elements : public SpellScriptLoader +{ + public: + spell_mage_master_of_elements() : SpellScriptLoader("spell_mage_master_of_elements") { } + + class spell_mage_master_of_elements_AuraScript : public AuraScript + { + PrepareAuraScript(spell_mage_master_of_elements_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_MASTER_OF_ELEMENTS_ENERGIZE)) + return false; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + return eventInfo.GetDamageInfo()->GetSpellInfo(); // eventInfo.GetSpellInfo() + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + int32 mana = int32(eventInfo.GetDamageInfo()->GetSpellInfo()->CalcPowerCost(GetTarget(), eventInfo.GetDamageInfo()->GetSchoolMask())); + mana = CalculatePct(mana, aurEff->GetAmount()); + + if (mana > 0) + GetTarget()->CastCustomSpell(SPELL_MAGE_MASTER_OF_ELEMENTS_ENERGIZE, SPELLVALUE_BASE_POINT0, mana, GetTarget(), true, NULL, aurEff); + } + + void Register() + { + DoCheckProc += AuraCheckProcFn(spell_mage_master_of_elements_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_mage_master_of_elements_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_mage_master_of_elements_AuraScript(); + } +}; + enum SilvermoonPolymorph { NPC_AUROSALIA = 18744 @@ -748,15 +983,19 @@ void AddSC_mage_spell_scripts() { new spell_mage_blast_wave(); new spell_mage_blizzard(); + new spell_mage_burnout(); new spell_mage_cold_snap(); new spell_mage_cone_of_cold(); new spell_mage_conjure_refreshment(); - new spell_mage_frost_warding_trigger(); + new spell_mage_fire_frost_ward(); + new spell_mage_focus_magic(); new spell_mage_frostbolt(); - new spell_mage_living_bomb(); new spell_mage_ice_barrier(); - new spell_mage_mana_shield(); + new spell_mage_ignite(); + new spell_mage_living_bomb(); new spell_mage_mage_ward(); + new spell_mage_mana_shield(); + new spell_mage_master_of_elements(); new spell_mage_polymorph_cast_visual(); new spell_mage_replenish_mana(); new spell_mage_summon_water_elemental(); diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp index 7625ed548ac..a581a6ee351 100644 --- a/src/server/scripts/Spells/spell_paladin.cpp +++ b/src/server/scripts/Spells/spell_paladin.cpp @@ -31,6 +31,7 @@ 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, @@ -45,6 +46,8 @@ enum PaladinSpells SPELL_PALADIN_DIVINE_STORM_DUMMY = 54171, SPELL_PALADIN_DIVINE_STORM_HEAL = 54172, + SPELL_PALADIN_EYE_FOR_AN_EYE_DAMAGE = 25997, + SPELL_PALADIN_FORBEARANCE = 25771, SPELL_PALADIN_AVENGING_WRATH_MARKER = 61987, SPELL_PALADIN_IMMUNE_SHIELD_MARKER = 61988, @@ -52,7 +55,16 @@ enum PaladinSpells SPELL_PALADIN_HAND_OF_SACRIFICE = 6940, SPELL_PALADIN_DIVINE_SACRIFICE = 64205, - SPELL_PALADIN_DIVINE_PURPOSE_PROC = 90174 + SPELL_PALADIN_DIVINE_PURPOSE_PROC = 90174, + + SPELL_PALADIN_GLYPH_OF_SALVATION = 63225, + + SPELL_PALADIN_RIGHTEOUS_DEFENSE_TAUNT = 31790, + + SPELL_PALADIN_SEAL_OF_RIGHTEOUSNESS = 25742, + + SPELL_GENERIC_ARENA_DAMPENING = 74410, + SPELL_GENERIC_BATTLEGROUND_DAMPENING = 74411 }; // 31850 - Ardent Defender @@ -187,8 +199,8 @@ class spell_pal_blessing_of_faith : public SpellScriptLoader } }; -// 20911 Blessing of Sanctuary -// 25899 Greater Blessing of Sanctuary +// 20911 - Blessing of Sanctuary +// 25899 - Greater Blessing of Sanctuary class spell_pal_blessing_of_sanctuary : public SpellScriptLoader { public: @@ -202,6 +214,8 @@ class spell_pal_blessing_of_sanctuary : public SpellScriptLoader { if (!sSpellMgr->GetSpellInfo(SPELL_PALADIN_BLESSING_OF_SANCTUARY_BUFF)) return false; + if (!sSpellMgr->GetSpellInfo(SPELL_PALADIN_BLESSING_OF_SANCTUARY_ENERGIZE)) + return false; return true; } @@ -218,10 +232,23 @@ class spell_pal_blessing_of_sanctuary : public SpellScriptLoader 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() { 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); } }; @@ -412,6 +439,43 @@ class spell_pal_exorcism_and_holy_wrath_damage : public SpellScriptLoader } }; +// -9799 - Eye for an Eye +class spell_pal_eye_for_an_eye : public SpellScriptLoader +{ + public: + spell_pal_eye_for_an_eye() : SpellScriptLoader("spell_pal_eye_for_an_eye") { } + + class spell_pal_eye_for_an_eye_AuraScript : public AuraScript + { + PrepareAuraScript(spell_pal_eye_for_an_eye_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_PALADIN_EYE_FOR_AN_EYE_DAMAGE)) + return false; + return true; + } + + void OnProc(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)); + GetTarget()->CastCustomSpell(SPELL_PALADIN_EYE_FOR_AN_EYE_DAMAGE, SPELLVALUE_BASE_POINT0, damage, eventInfo.GetProcTarget(), true, NULL, aurEff); + } + + void Register() + { + OnEffectProc += AuraEffectProcFn(spell_pal_eye_for_an_eye_AuraScript::OnProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_pal_eye_for_an_eye_AuraScript(); + } +}; + // 63521 - Guarded by The Light class spell_pal_guarded_by_the_light : public SpellScriptLoader { @@ -492,6 +556,39 @@ 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() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_pal_hand_of_salvation_AuraScript::CalculateAmount, EFFECT_1, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_pal_hand_of_salvation_AuraScript(); + } +}; + // -20473 - Holy Shock class spell_pal_holy_shock : public SpellScriptLoader { @@ -658,6 +755,13 @@ class spell_pal_righteous_defense : public SpellScriptLoader { PrepareSpellScript(spell_pal_righteous_defense_SpellScript); + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_PALADIN_RIGHTEOUS_DEFENSE_TAUNT)) + return false; + return true; + } + SpellCastResult CheckCast() { Unit* caster = GetCaster(); @@ -675,9 +779,27 @@ class spell_pal_righteous_defense : public SpellScriptLoader return SPELL_CAST_OK; } + void HandleTriggerSpellLaunch(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + } + + void HandleTriggerSpellHit(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + if (Unit* target = GetHitUnit()) + GetCaster()->CastSpell(target, SPELL_PALADIN_RIGHTEOUS_DEFENSE_TAUNT, true); + } + void Register() { OnCheckCast += SpellCheckCastFn(spell_pal_righteous_defense_SpellScript::CheckCast); + //! WORKAROUND + //! target select will be executed in hitphase of effect 0 + //! so we must handle trigger spell also in hit phase (default execution in launch phase) + //! see issue #3718 + OnEffectLaunchTarget += SpellEffectFn(spell_pal_righteous_defense_SpellScript::HandleTriggerSpellLaunch, EFFECT_1, SPELL_EFFECT_TRIGGER_SPELL); + OnEffectHitTarget += SpellEffectFn(spell_pal_righteous_defense_SpellScript::HandleTriggerSpellHit, EFFECT_1, SPELL_EFFECT_TRIGGER_SPELL); } }; @@ -789,19 +911,71 @@ class spell_pal_templar_s_verdict : public SpellScriptLoader } }; +// 20154, 21084 - Seal of Righteousness - melee proc dummy (addition ${$MWS*(0.022*$AP+0.044*$SPH)} damage) +class spell_pal_seal_of_righteousness : public SpellScriptLoader +{ + public: + spell_pal_seal_of_righteousness() : SpellScriptLoader("spell_pal_seal_of_righteousness") { } + + class spell_pal_seal_of_righteousness_AuraScript : public AuraScript + { + PrepareAuraScript(spell_pal_seal_of_righteousness_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_PALADIN_SEAL_OF_RIGHTEOUSNESS)) + return false; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + return eventInfo.GetProcTarget(); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + float ap = GetTarget()->GetTotalAttackPowerValue(BASE_ATTACK); + int32 holy = GetTarget()->SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_HOLY); + holy += eventInfo.GetProcTarget()->SpellBaseDamageBonusTaken(SPELL_SCHOOL_MASK_HOLY); + int32 bp = int32((ap * 0.022f + 0.044f * holy) * GetTarget()->GetAttackTime(BASE_ATTACK) / 1000); + GetTarget()->CastCustomSpell(SPELL_PALADIN_SEAL_OF_RIGHTEOUSNESS, SPELLVALUE_BASE_POINT0, bp, eventInfo.GetProcTarget(), true, NULL, aurEff); + } + + void Register() + { + DoCheckProc += AuraCheckProcFn(spell_pal_seal_of_righteousness_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_pal_seal_of_righteousness_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_pal_seal_of_righteousness_AuraScript(); + } +}; + + void AddSC_paladin_spell_scripts() { //new spell_pal_ardent_defender(); 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_guarded_by_the_light(); new spell_pal_hand_of_sacrifice(); + new spell_pal_hand_of_salvation(); new spell_pal_holy_shock(); new spell_pal_judgement_of_command(); 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_priest.cpp b/src/server/scripts/Spells/spell_priest.cpp index b47eff816a3..94b12818626 100644 --- a/src/server/scripts/Spells/spell_priest.cpp +++ b/src/server/scripts/Spells/spell_priest.cpp @@ -29,23 +29,27 @@ enum PriestSpells { + SPELL_PRIEST_DIVINE_AEGIS = 47753, SPELL_PRIEST_EMPOWERED_RENEW = 63544, + 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_LEAP_OF_FAITH = 73325, - SPELL_PRIEST_LEAP_OF_FAITH_TRIGGERED = 92572, - SPELL_PRIEST_LEAP_OF_FAITH_EFFECT_TRIGGER = 92833, 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_SHADOW_WORD_DEATH = 32409, + 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_T9_HEALING_2P = 67201, - SPELL_PRIEST_VAMPIRIC_TOUCH_DISPEL = 64085 + SPELL_PRIEST_VAMPIRIC_TOUCH_DISPEL = 64085, }; enum PriestSpellIcons @@ -54,6 +58,94 @@ enum PriestSpellIcons PRIEST_ICON_ID_PAIN_AND_SUFFERING = 2874 }; +// -47509 - Divine Aegis +class spell_pri_divine_aegis : public SpellScriptLoader +{ + public: + spell_pri_divine_aegis() : SpellScriptLoader("spell_pri_divine_aegis") { } + + class spell_pri_divine_aegis_AuraScript : public AuraScript + { + PrepareAuraScript(spell_pri_divine_aegis_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_DIVINE_AEGIS)) + return false; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + return eventInfo.GetProcTarget(); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + int32 absorb = CalculatePct(int32(eventInfo.GetHealInfo()->GetHeal()), aurEff->GetAmount()); + + // Multiple effects stack, so let's try to find this aura. + if (AuraEffect const* aegis = eventInfo.GetProcTarget()->GetAuraEffect(SPELL_PRIEST_DIVINE_AEGIS, EFFECT_0)) + absorb += aegis->GetAmount(); + + absorb = std::min(absorb, eventInfo.GetProcTarget()->getLevel() * 125); + + GetTarget()->CastCustomSpell(SPELL_PRIEST_DIVINE_AEGIS, SPELLVALUE_BASE_POINT0, absorb, eventInfo.GetProcTarget(), true, NULL, aurEff); + } + + void Register() + { + DoCheckProc += AuraCheckProcFn(spell_pri_divine_aegis_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_pri_divine_aegis_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_pri_divine_aegis_AuraScript(); + } +}; + +// 55680 - Glyph of Prayer of Healing +class spell_pri_glyph_of_prayer_of_healing : public SpellScriptLoader +{ + public: + spell_pri_glyph_of_prayer_of_healing() : SpellScriptLoader("spell_pri_glyph_of_prayer_of_healing") { } + + class spell_pri_glyph_of_prayer_of_healing_AuraScript : public AuraScript + { + PrepareAuraScript(spell_pri_glyph_of_prayer_of_healing_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_GLYPH_OF_PRAYER_OF_HEALING_HEAL)) + return false; + return true; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + SpellInfo const* triggeredSpellInfo = sSpellMgr->GetSpellInfo(SPELL_PRIEST_GLYPH_OF_PRAYER_OF_HEALING_HEAL); + int32 heal = int32(CalculatePct(int32(eventInfo.GetHealInfo()->GetHeal()), aurEff->GetAmount()) / triggeredSpellInfo->GetMaxTicks()); + GetTarget()->CastCustomSpell(SPELL_PRIEST_GLYPH_OF_PRAYER_OF_HEALING_HEAL, SPELLVALUE_BASE_POINT0, heal, eventInfo.GetProcTarget(), true, NULL, aurEff); + } + + void Register() + { + OnEffectProc += AuraEffectProcFn(spell_pri_glyph_of_prayer_of_healing_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_pri_glyph_of_prayer_of_healing_AuraScript(); + } +}; + // 47788 - Guardian Spirit class spell_pri_guardian_spirit : public SpellScriptLoader { @@ -151,6 +243,38 @@ class spell_pri_leap_of_faith_effect_trigger : public SpellScriptLoader } }; +// -7001 - Lightwell Renew +class spell_pri_lightwell_renew : public SpellScriptLoader +{ + public: + spell_pri_lightwell_renew() : SpellScriptLoader("spell_pri_lightwell_renew") { } + + class spell_pri_lightwell_renew_AuraScript : public AuraScript + { + PrepareAuraScript(spell_pri_lightwell_renew_AuraScript); + + void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/) + { + if (Unit* caster = GetCaster()) + { + // Bonus from Glyph of Lightwell + if (AuraEffect* modHealing = caster->GetAuraEffect(SPELL_PRIEST_GLYPH_OF_LIGHTWELL, EFFECT_0)) + AddPct(amount, modHealing->GetAmount()); + } + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_pri_lightwell_renew_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_PERIODIC_HEAL); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_pri_lightwell_renew_AuraScript(); + } +}; + // 8129 - Mana Burn class spell_pri_mana_burn : public SpellScriptLoader { @@ -179,6 +303,57 @@ class spell_pri_mana_burn : public SpellScriptLoader } }; +// 28305 - Mana Leech (Passive) (Priest Pet Aura) +class spell_pri_mana_leech : public SpellScriptLoader +{ + public: + spell_pri_mana_leech() : SpellScriptLoader("spell_pri_mana_leech") { } + + class spell_pri_mana_leech_AuraScript : public AuraScript + { + PrepareAuraScript(spell_pri_mana_leech_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_MANA_LEECH_PROC)) + return false; + return true; + } + + bool Load() + { + _procTarget = NULL; + return true; + } + + bool CheckProc(ProcEventInfo& /*eventInfo*/) + { + _procTarget = GetTarget()->GetOwner(); + return _procTarget; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + GetTarget()->CastSpell(_procTarget, SPELL_PRIEST_MANA_LEECH_PROC, true, NULL, aurEff); + } + + void Register() + { + DoCheckProc += AuraCheckProcFn(spell_pri_mana_leech_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_pri_mana_leech_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + + private: + Unit* _procTarget; + }; + + AuraScript* GetAuraScript() const + { + return new spell_pri_mana_leech_AuraScript(); + } +}; + // 49821 - Mind Sear class spell_pri_mind_sear : public SpellScriptLoader { @@ -307,6 +482,82 @@ class spell_pri_penance : public SpellScriptLoader } }; +// -17 - Power Word: Shield +class spell_pri_power_word_shield : public SpellScriptLoader +{ + public: + spell_pri_power_word_shield() : SpellScriptLoader("spell_pri_power_word_shield") { } + + class spell_pri_power_word_shield_AuraScript : public AuraScript + { + PrepareAuraScript(spell_pri_power_word_shield_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_REFLECTIVE_SHIELD_TRIGGERED)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_REFLECTIVE_SHIELD_R1)) + return false; + return true; + } + + void CalculateAmount(AuraEffect const* aurEff, int32& amount, bool& canBeRecalculated) + { + canBeRecalculated = false; + if (Unit* caster = GetCaster()) + { + // +80.68% from sp bonus + float bonus = 0.8068f; + + // Borrowed Time + if (AuraEffect const* borrowedTime = caster->GetDummyAuraEffect(SPELLFAMILY_PRIEST, PRIEST_ICON_ID_BORROWED_TIME, EFFECT_1)) + bonus += CalculatePct(1.0f, borrowedTime->GetAmount()); + + bonus *= caster->SpellBaseHealingBonusDone(GetSpellInfo()->GetSchoolMask()); + + // Improved PW: Shield: its weird having a SPELLMOD_ALL_EFFECTS here but its blizzards doing :) + // Improved PW: Shield 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()); + + amount += int32(bonus); + + // Twin Disciplines + if (AuraEffect const* twinDisciplines = caster->GetAuraEffect(SPELL_AURA_ADD_PCT_MODIFIER, SPELLFAMILY_PRIEST, 0x400000, 0, 0, GetCasterGUID())) + AddPct(amount, twinDisciplines->GetAmount()); + + // Focused Power + amount *= caster->GetTotalAuraMultiplier(SPELL_AURA_MOD_HEALING_DONE_PERCENT); + } + } + + void ReflectDamage(AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount) + { + Unit* target = GetTarget(); + if (dmgInfo.GetAttacker() == target) + return; + + if (Unit* caster = GetCaster()) + if (AuraEffect* talentAurEff = caster->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); + } + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_pri_power_word_shield_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB); + AfterEffectAbsorb += AuraEffectAbsorbFn(spell_pri_power_word_shield_AuraScript::ReflectDamage, EFFECT_0); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_pri_power_word_shield_AuraScript(); + } +}; + // 33110 - Prayer of Mending Heal class spell_pri_prayer_of_mending_heal : public SpellScriptLoader { @@ -545,12 +796,17 @@ class spell_pri_vampiric_touch : public SpellScriptLoader void AddSC_priest_spell_scripts() { + new spell_pri_divine_aegis(); + new spell_pri_glyph_of_prayer_of_healing(); 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_power_word_shield(); new spell_pri_prayer_of_mending_heal(); new spell_pri_reflective_shield_trigger(); new spell_pri_renew(); diff --git a/src/server/scripts/Spells/spell_rogue.cpp b/src/server/scripts/Spells/spell_rogue.cpp index 14d1c1a2f98..b19f5e2cbed 100644 --- a/src/server/scripts/Spells/spell_rogue.cpp +++ b/src/server/scripts/Spells/spell_rogue.cpp @@ -28,10 +28,13 @@ enum RogueSpells { + SPELL_ROGUE_BLADE_FLURRY_EXTRA_ATTACK = 22482, SPELL_ROGUE_CHEAT_DEATH_COOLDOWN = 31231, SPELL_ROGUE_GLYPH_OF_PREPARATION = 56819, SPELL_ROGUE_PREY_ON_THE_WEAK = 58670, - SPELL_ROGUE_SHIV_TRIGGERED = 5940 + SPELL_ROGUE_SHIV_TRIGGERED = 5940, + SPELL_ROGUE_TRICKS_OF_THE_TRADE_DMG_BOOST = 57933, + SPELL_ROGUE_TRICKS_OF_THE_TRADE_PROC = 59628, }; enum RogueSpellIcons @@ -39,6 +42,61 @@ enum RogueSpellIcons ICON_ROGUE_IMPROVED_RECUPERATE = 4819 }; +// 13877, 33735, (check 51211, 65956) - Blade Flurry +class spell_rog_blade_flurry : public SpellScriptLoader +{ + public: + spell_rog_blade_flurry() : SpellScriptLoader("spell_rog_blade_flurry") { } + + class spell_rog_blade_flurry_AuraScript : public AuraScript + { + PrepareAuraScript(spell_rog_blade_flurry_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_ROGUE_BLADE_FLURRY_EXTRA_ATTACK)) + return false; + return true; + } + + bool Load() + { + _procTarget = NULL; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + _procTarget = eventInfo.GetActor()->SelectNearbyTarget(eventInfo.GetProcTarget()); + return _procTarget; + } + + 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); + } + } + + void Register() + { + DoCheckProc += AuraCheckProcFn(spell_rog_blade_flurry_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_rog_blade_flurry_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_MOD_MELEE_HASTE); + } + + private: + Unit* _procTarget; + }; + + AuraScript* GetAuraScript() const + { + return new spell_rog_blade_flurry_AuraScript(); + } +}; + // 31228 - Cheat Death class spell_rog_cheat_death : public SpellScriptLoader { @@ -404,6 +462,58 @@ class spell_rog_recuperate : public SpellScriptLoader } }; +// -1943 - Rupture +class spell_rog_rupture : public SpellScriptLoader +{ + public: + spell_rog_rupture() : SpellScriptLoader("spell_rog_rupture") { } + + class spell_rog_rupture_AuraScript : public AuraScript + { + PrepareAuraScript(spell_rog_rupture_AuraScript); + + bool Load() + { + Unit* caster = GetCaster(); + return caster && caster->GetTypeId() == TYPEID_PLAYER; + } + + void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& canBeRecalculated) + { + if (Unit* caster = GetCaster()) + { + canBeRecalculated = false; + + float const attackpowerPerCombo[6] = + { + 0.0f, + 0.015f, // 1 point: ${($m1 + $b1*1 + 0.015 * $AP) * 4} damage over 8 secs + 0.024f, // 2 points: ${($m1 + $b1*2 + 0.024 * $AP) * 5} damage over 10 secs + 0.03f, // 3 points: ${($m1 + $b1*3 + 0.03 * $AP) * 6} damage over 12 secs + 0.03428571f, // 4 points: ${($m1 + $b1*4 + 0.03428571 * $AP) * 7} damage over 14 secs + 0.0375f // 5 points: ${($m1 + $b1*5 + 0.0375 * $AP) * 8} damage over 16 secs + }; + + uint8 cp = caster->ToPlayer()->GetComboPoints(); + if (cp > 5) + cp = 5; + + amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * attackpowerPerCombo[cp]); + } + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_rog_rupture_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_rog_rupture_AuraScript(); + } +}; + // 5938 - Shiv class spell_rog_shiv : public SpellScriptLoader { @@ -445,13 +555,108 @@ class spell_rog_shiv : public SpellScriptLoader } }; +// 57934 - Tricks of the Trade +class spell_rog_tricks_of_the_trade : public SpellScriptLoader +{ + public: + spell_rog_tricks_of_the_trade() : SpellScriptLoader("spell_rog_tricks_of_the_trade") { } + + class spell_rog_tricks_of_the_trade_AuraScript : public AuraScript + { + PrepareAuraScript(spell_rog_tricks_of_the_trade_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_ROGUE_TRICKS_OF_THE_TRADE_DMG_BOOST)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_ROGUE_TRICKS_OF_THE_TRADE_PROC)) + return false; + return true; + } + + bool Load() + { + _redirectTarget = NULL; + return true; + } + + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_DEFAULT) + GetTarget()->ResetRedirectThreat(); + } + + bool CheckProc(ProcEventInfo& /*eventInfo*/) + { + _redirectTarget = GetTarget()->GetRedirectThreatTarget(); + return _redirectTarget; + } + + void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + + Unit* target = GetTarget(); + target->CastSpell(_redirectTarget, SPELL_ROGUE_TRICKS_OF_THE_TRADE_DMG_BOOST, true); + target->CastSpell(target, SPELL_ROGUE_TRICKS_OF_THE_TRADE_PROC, true); + Remove(AURA_REMOVE_BY_DEFAULT); // maybe handle by proc charges + } + + void Register() + { + AfterEffectRemove += AuraEffectRemoveFn(spell_rog_tricks_of_the_trade_AuraScript::OnRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + DoCheckProc += AuraCheckProcFn(spell_rog_tricks_of_the_trade_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_rog_tricks_of_the_trade_AuraScript::HandleProc, EFFECT_1, SPELL_AURA_DUMMY); + } + + private: + Unit* _redirectTarget; + }; + + AuraScript* GetAuraScript() const + { + return new spell_rog_tricks_of_the_trade_AuraScript(); + } +}; + +// 59628 - Tricks of the Trade (Proc) +class spell_rog_tricks_of_the_trade_proc : public SpellScriptLoader +{ + public: + spell_rog_tricks_of_the_trade_proc() : SpellScriptLoader("spell_rog_tricks_of_the_trade_proc") { } + + class spell_rog_tricks_of_the_trade_proc_AuraScript : public AuraScript + { + PrepareAuraScript(spell_rog_tricks_of_the_trade_proc_AuraScript); + + void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->ResetRedirectThreat(); + } + + void Register() + { + AfterEffectRemove += AuraEffectRemoveFn(spell_rog_tricks_of_the_trade_proc_AuraScript::HandleRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_rog_tricks_of_the_trade_proc_AuraScript(); + } +}; + void AddSC_rogue_spell_scripts() { + new spell_rog_blade_flurry(); new spell_rog_cheat_death(); new spell_rog_deadly_poison(); new spell_rog_nerves_of_steel(); 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_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 e2e3f5a52e7..045227a8f99 100644 --- a/src/server/scripts/Spells/spell_shaman.cpp +++ b/src/server/scripts/Spells/spell_shaman.cpp @@ -34,9 +34,14 @@ enum ShamanSpells SPELL_MAGE_TEMPORAL_DISPLACEMENT = 80354, SPELL_SHAMAN_ANCESTRAL_AWAKENING_PROC = 52752, SPELL_SHAMAN_BIND_SIGHT = 6277, + SPELL_SHAMAN_EARTH_SHIELD_HEAL = 379, SPELL_SHAMAN_EXHAUSTION = 57723, SPELL_SHAMAN_FIRE_NOVA_TRIGGERED_R1 = 8349, SPELL_SHAMAN_FLAME_SHOCK = 8050, + SPELL_SHAMAN_GLYPH_OF_EARTH_SHIELD = 63279, + SPELL_SHAMAN_GLYPH_OF_HEALING_STREAM_TOTEM = 55456, + SPELL_SHAMAN_GLYPH_OF_MANA_TIDE = 55441, + SPELL_SHAMAN_GLYPH_OF_THUNDERSTORM = 62132, SPELL_SHAMAN_LAVA_FLOWS_R1 = 51480, SPELL_SHAMAN_LAVA_FLOWS_TRIGGERED_R1 = 65264, SPELL_SHAMAN_SATED = 57724, @@ -193,6 +198,68 @@ class spell_sha_chain_heal : public SpellScriptLoader } }; +// -974 - Earth Shield +class spell_sha_earth_shield : public SpellScriptLoader +{ + public: + spell_sha_earth_shield() : SpellScriptLoader("spell_sha_earth_shield") { } + + class spell_sha_earth_shield_AuraScript : public AuraScript + { + PrepareAuraScript(spell_sha_earth_shield_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_EARTH_SHIELD_HEAL)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_GLYPH_OF_EARTH_SHIELD)) + return false; + return true; + } + + void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool & /*canBeRecalculated*/) + { + if (Unit* caster = GetCaster()) + { + amount = caster->SpellHealingBonusDone(GetUnitOwner(), GetSpellInfo(), amount, HEAL); + amount = GetUnitOwner()->SpellHealingBonusTaken(caster, GetSpellInfo(), amount, HEAL); + + // Glyph of Earth Shield + //! WORKAROUND + //! this glyph is a proc + if (AuraEffect* glyph = caster->GetAuraEffect(SPELL_SHAMAN_GLYPH_OF_EARTH_SHIELD, EFFECT_0)) + AddPct(amount, glyph->GetAmount()); + } + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + + //! HACK due to currenct proc system implementation + if (Player* player = GetTarget()->ToPlayer()) + if (player->HasSpellCooldown(SPELL_SHAMAN_EARTH_SHIELD_HEAL)) + return; + + GetTarget()->CastCustomSpell(SPELL_SHAMAN_EARTH_SHIELD_HEAL, SPELLVALUE_BASE_POINT0, aurEff->GetAmount(), GetTarget(), true, NULL, aurEff, GetCasterGUID()); + + if (Player* player = GetTarget()->ToPlayer()) + player->AddSpellCooldown(SPELL_SHAMAN_EARTH_SHIELD_HEAL, 0, time(NULL) + 3); + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_sha_earth_shield_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_DUMMY); + OnEffectProc += AuraEffectProcFn(spell_sha_earth_shield_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_sha_earth_shield_AuraScript(); + } +}; + // 6474 - Earthbind Totem - Fix Talent:Earthen Power, Earth's Grasp /// Updated 4.3.4 class spell_sha_earthbind_totem : public SpellScriptLoader @@ -549,11 +616,41 @@ class spell_sha_mana_tide_totem : public SpellScriptLoader } }; +// -51490 - Thunderstorm +class spell_sha_thunderstorm : public SpellScriptLoader +{ + public: + spell_sha_thunderstorm() : SpellScriptLoader("spell_sha_thunderstorm") { } + + class spell_sha_thunderstorm_SpellScript : public SpellScript + { + PrepareSpellScript(spell_sha_thunderstorm_SpellScript); + + void HandleKnockBack(SpellEffIndex effIndex) + { + // Glyph of Thunderstorm + if (GetCaster()->HasAura(SPELL_SHAMAN_GLYPH_OF_THUNDERSTORM)) + PreventHitDefaultEffect(effIndex); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_sha_thunderstorm_SpellScript::HandleKnockBack, EFFECT_2, SPELL_EFFECT_KNOCK_BACK); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_sha_thunderstorm_SpellScript(); + } +}; + void AddSC_shaman_spell_scripts() { new spell_sha_ancestral_awakening_proc(); new spell_sha_bloodlust(); new spell_sha_chain_heal(); + new spell_sha_earth_shield(); new spell_sha_earthbind_totem(); new spell_sha_earthen_power(); new spell_sha_fire_nova(); @@ -562,4 +659,5 @@ void AddSC_shaman_spell_scripts() new spell_sha_heroism(); new spell_sha_lava_lash(); new spell_sha_mana_tide_totem(); + new spell_sha_thunderstorm(); } diff --git a/src/server/scripts/Spells/spell_warlock.cpp b/src/server/scripts/Spells/spell_warlock.cpp index 21dea0b726b..31833524861 100644 --- a/src/server/scripts/Spells/spell_warlock.cpp +++ b/src/server/scripts/Spells/spell_warlock.cpp @@ -37,6 +37,8 @@ enum WarlockSpells SPELL_WARLOCK_DEMONIC_EMPOWERMENT_FELGUARD = 54508, SPELL_WARLOCK_DEMONIC_EMPOWERMENT_FELHUNTER = 54509, SPELL_WARLOCK_DEMONIC_EMPOWERMENT_IMP = 54444, + SPELL_WARLOCK_FEL_SYNERGY_HEAL = 54181, + SPELL_WARLOCK_GLYPH_OF_SIPHON_LIFE = 63106, SPELL_WARLOCK_IMPROVED_HEALTHSTONE_R1 = 18692, SPELL_WARLOCK_IMPROVED_HEALTHSTONE_R2 = 18693, SPELL_WARLOCK_IMPROVED_HEALTH_FUNNEL_R1 = 18703, @@ -48,6 +50,7 @@ enum WarlockSpells SPELL_WARLOCK_LIFE_TAP_ENERGIZE = 31818, SPELL_WARLOCK_LIFE_TAP_ENERGIZE_2 = 32553, SPELL_WARLOCK_SOULSHATTER = 32835, + SPELL_WARLOCK_SIPHON_LIFE_HEAL = 63106, SPELL_WARLOCK_UNSTABLE_AFFLICTION_DISPEL = 31117 }; @@ -426,6 +429,49 @@ class spell_warl_everlasting_affliction : public SpellScriptLoader } }; +// -47230 - Fel Synergy +class spell_warl_fel_synergy : public SpellScriptLoader +{ + public: + spell_warl_fel_synergy() : SpellScriptLoader("spell_warl_fel_synergy") { } + + class spell_warl_fel_synergy_AuraScript : public AuraScript + { + PrepareAuraScript(spell_warl_fel_synergy_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_FEL_SYNERGY_HEAL)) + return false; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + return GetTarget()->GetGuardianPet() && eventInfo.GetDamageInfo()->GetDamage(); + } + + void OnProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + int32 heal = CalculatePct(int32(eventInfo.GetDamageInfo()->GetDamage()), aurEff->GetAmount()); + GetTarget()->CastCustomSpell(SPELL_WARLOCK_FEL_SYNERGY_HEAL, SPELLVALUE_BASE_POINT0, heal, (Unit*)NULL, true, NULL, aurEff); // TARGET_UNIT_PET + } + + void Register() + { + DoCheckProc += AuraCheckProcFn(spell_warl_fel_synergy_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_warl_fel_synergy_AuraScript::OnProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_warl_fel_synergy_AuraScript(); + } +}; + // 48181 - Haunt /// Updated 4.3.4 class spell_warl_haunt : public SpellScriptLoader @@ -630,6 +676,92 @@ class spell_warl_seed_of_corruption : public SpellScriptLoader } }; +// -7235 - Shadow Ward +class spell_warl_shadow_ward : public SpellScriptLoader +{ + public: + spell_warl_shadow_ward() : SpellScriptLoader("spell_warl_shadow_ward") { } + + class spell_warl_shadow_ward_AuraScript : public AuraScript + { + PrepareAuraScript(spell_warl_shadow_ward_AuraScript); + + void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& canBeRecalculated) + { + canBeRecalculated = false; + if (Unit* caster = GetCaster()) + { + // +80.68% from sp bonus + float bonus = 0.8068f; + + bonus *= caster->SpellBaseHealingBonusDone(GetSpellInfo()->GetSchoolMask()); + bonus *= caster->CalculateLevelPenalty(GetSpellInfo()); + + amount += int32(bonus); + } + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_shadow_ward_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_warl_shadow_ward_AuraScript(); + } +}; + +// 63108 - Siphon Life +class spell_warl_siphon_life : public SpellScriptLoader +{ + public: + spell_warl_siphon_life() : SpellScriptLoader("spell_warl_siphon_life") { } + + class spell_warl_siphon_life_AuraScript : public AuraScript + { + PrepareAuraScript(spell_warl_siphon_life_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_SIPHON_LIFE_HEAL)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_GLYPH_OF_SIPHON_LIFE)) + return false; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + return eventInfo.GetDamageInfo()->GetDamage(); + } + + void OnProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + 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()); + + GetTarget()->CastCustomSpell(SPELL_WARLOCK_SIPHON_LIFE_HEAL, SPELLVALUE_BASE_POINT0, amount, GetTarget(), true, NULL, aurEff); + } + + void Register() + { + DoCheckProc += AuraCheckProcFn(spell_warl_siphon_life_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_warl_siphon_life_AuraScript::OnProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_warl_siphon_life_AuraScript(); + } +}; + // 29858 - Soulshatter /// Updated 4.3.4 class spell_warl_soulshatter : public SpellScriptLoader @@ -714,14 +846,19 @@ void AddSC_warlock_spell_scripts() new spell_warl_bane_of_doom(); new spell_warl_banish(); 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_everlasting_affliction(); + new spell_warl_fel_synergy(); new spell_warl_haunt(); new spell_warl_health_funnel(); new spell_warl_life_tap(); + new spell_warl_ritual_of_doom_effect(); new spell_warl_seed_of_corruption(); + new spell_warl_shadow_ward(); + new spell_warl_siphon_life(); 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 909e90beaad..c155c39ffdb 100644 --- a/src/server/scripts/Spells/spell_warrior.cpp +++ b/src/server/scripts/Spells/spell_warrior.cpp @@ -31,14 +31,32 @@ enum WarriorSpells SPELL_WARRIOR_BLOODTHIRST = 23885, SPELL_WARRIOR_BLOODTHIRST_DAMAGE = 23881, SPELL_WARRIOR_CHARGE = 34846, + SPELL_WARRIOR_DAMAGE_SHIELD_DAMAGE = 59653, 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_SLAM = 50782 + SPELL_WARRIOR_SLAM = 50782, + SPELL_WARRIOR_SLAM = 50783, + SPELL_WARRIOR_SWEEPING_STRIKES_EXTRA_ATTACK = 26654, + SPELL_WARRIOR_TAUNT = 355, + SPELL_WARRIOR_UNRELENTING_ASSAULT_RANK_1 = 46859, + SPELL_WARRIOR_UNRELENTING_ASSAULT_RANK_2 = 46860, + 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_PALADIN_BLESSING_OF_SANCTUARY = 20911, + SPELL_PALADIN_GREATER_BLESSING_OF_SANCTUARY = 25899, + SPELL_PRIEST_RENEWED_HOPE = 63944, + SPELL_GEN_DAMAGE_REDUCTION_AURA = 68066, }; enum WarriorSpellIcons @@ -183,6 +201,44 @@ 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*/) + { + 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() + { + OnEffectProc += AuraEffectProcFn(spell_warr_damage_shield_AuraScript::OnProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_warr_damage_shield_AuraScript(); + } +}; + /// Updated 4.3.4 class spell_warr_deep_wounds : public SpellScriptLoader { @@ -286,6 +342,62 @@ class spell_warr_execute : public SpellScriptLoader } }; +// 59725 - Improved Spell Reflection +class spell_warr_improved_spell_reflection : public SpellScriptLoader +{ + public: + spell_warr_improved_spell_reflection() : SpellScriptLoader("spell_warr_improved_spell_reflection") { } + + class spell_warr_improved_spell_reflection_SpellScript : public SpellScript + { + PrepareSpellScript(spell_warr_improved_spell_reflection_SpellScript); + + void FilterTargets(std::list<WorldObject*>& unitList) + { + if (GetCaster()) + unitList.remove(GetCaster()); + } + + void Register() + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_warr_improved_spell_reflection_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_PARTY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_warr_improved_spell_reflection_SpellScript(); + } +}; + +// 5246 - Intimidating Shout +class spell_warr_intimidating_shout : public SpellScriptLoader +{ + public: + spell_warr_intimidating_shout() : SpellScriptLoader("spell_warr_intimidating_shout") { } + + class spell_warr_intimidating_shout_SpellScript : public SpellScript + { + PrepareSpellScript(spell_warr_intimidating_shout_SpellScript); + + void FilterTargets(std::list<WorldObject*>& unitList) + { + unitList.remove(GetExplTargetWorldObject()); + } + + void Register() + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_warr_intimidating_shout_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY); + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_warr_intimidating_shout_SpellScript::FilterTargets, EFFECT_2, TARGET_UNIT_SRC_AREA_ENEMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_warr_intimidating_shout_SpellScript(); + } +}; + /// Updated 4.3.4 class spell_warr_last_stand : public SpellScriptLoader { @@ -325,6 +437,121 @@ class spell_warr_last_stand : public SpellScriptLoader } }; +// 7384, 7887, 11584, 11585 - Overpower +class spell_warr_overpower : public SpellScriptLoader +{ + public: + spell_warr_overpower() : SpellScriptLoader("spell_warr_overpower") { } + + class spell_warr_overpower_SpellScript : public SpellScript + { + PrepareSpellScript(spell_warr_overpower_SpellScript); + + void HandleEffect(SpellEffIndex /*effIndex*/) + { + uint32 spellId = 0; + if (GetCaster()->HasAura(SPELL_WARRIOR_UNRELENTING_ASSAULT_RANK_1)) + spellId = SPELL_WARRIOR_UNRELENTING_ASSAULT_TRIGGER_1; + else if (GetCaster()->HasAura(SPELL_WARRIOR_UNRELENTING_ASSAULT_RANK_2)) + spellId = SPELL_WARRIOR_UNRELENTING_ASSAULT_TRIGGER_2; + + if (!spellId) + return; + + if (Player* target = GetHitPlayer()) + if (target->HasUnitState(UNIT_STATE_CASTING)) + target->CastSpell(target, spellId, true); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_warr_overpower_SpellScript::HandleEffect, EFFECT_0, SPELL_EFFECT_ANY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_warr_overpower_SpellScript(); + } +}; + +// -772 - Rend +class spell_warr_rend : public SpellScriptLoader +{ + public: + spell_warr_rend() : SpellScriptLoader("spell_warr_rend") { } + + class spell_warr_rend_AuraScript : public AuraScript + { + PrepareAuraScript(spell_warr_rend_AuraScript); + + void CalculateAmount(AuraEffect const* aurEff, int32& amount, bool& canBeRecalculated) + { + if (Unit* caster = GetCaster()) + { + canBeRecalculated = false; + + // $0.2 * (($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; + 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)); + } + } + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warr_rend_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_warr_rend_AuraScript(); + } +}; + +// 64380, 65941 - Shattering Throw +class spell_warr_shattering_throw : public SpellScriptLoader +{ + public: + spell_warr_shattering_throw() : SpellScriptLoader("spell_warr_shattering_throw") { } + + class spell_warr_shattering_throw_SpellScript : public SpellScript + { + PrepareSpellScript(spell_warr_shattering_throw_SpellScript); + + void HandleScript(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + + // remove shields, will still display immune to damage part + if (Unit* target = GetHitUnit()) + target->RemoveAurasWithMechanic(1 << MECHANIC_IMMUNE_SHIELD, AURA_REMOVE_BY_ENEMY_SPELL); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_warr_shattering_throw_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_warr_shattering_throw_SpellScript(); + } +}; + /// Updated 4.3.4 class spell_warr_slam : public SpellScriptLoader { @@ -361,14 +588,199 @@ class spell_warr_slam : public SpellScriptLoader } }; +// 12328, 18765, 35429 - Sweeping Strikes +class spell_warr_sweeping_strikes : public SpellScriptLoader +{ + public: + spell_warr_sweeping_strikes() : SpellScriptLoader("spell_warr_sweeping_strikes") { } + + class spell_warr_sweeping_strikes_AuraScript : public AuraScript + { + PrepareAuraScript(spell_warr_sweeping_strikes_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_SWEEPING_STRIKES_EXTRA_ATTACK)) + return false; + return true; + } + + bool Load() + { + _procTarget = NULL; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + _procTarget = eventInfo.GetActor()->SelectNearbyTarget(eventInfo.GetProcTarget()); + return _procTarget; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + GetTarget()->CastSpell(_procTarget, SPELL_WARRIOR_SWEEPING_STRIKES_EXTRA_ATTACK, true, NULL, aurEff); + } + + void Register() + { + DoCheckProc += AuraCheckProcFn(spell_warr_sweeping_strikes_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_warr_sweeping_strikes_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + + private: + Unit* _procTarget; + }; + + AuraScript* GetAuraScript() const + { + return new spell_warr_sweeping_strikes_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*/) + { + 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)) + return false; + return true; + } + + bool Load() + { + _procTarget = NULL; + return true; + } + + void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + target->CastSpell(target, SPELL_GEN_DAMAGE_REDUCTION_AURA, true); + + if (Unit* caster = GetCaster()) + target->CastSpell(caster, SPELL_WARRIOR_VIGILANCE_REDIRECT_THREAT, true); + } + + void HandleAfterApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + //! 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()); + } + } + + void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + 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); + } + + target->ResetRedirectThreat(); + } + + bool CheckProc(ProcEventInfo& /*eventInfo*/) + { + _procTarget = GetCaster(); + return _procTarget; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + GetTarget()->CastSpell(_procTarget, SPELL_WARRIOR_VIGILANCE_PROC, true, NULL, aurEff); + } + + void Register() + { + 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); + } + + private: + Unit* _procTarget; + }; + + AuraScript* GetAuraScript() const + { + return new spell_warr_vigilance_AuraScript(); + } +}; + +// 50725 Vigilance +class spell_warr_vigilance_trigger : public SpellScriptLoader +{ + public: + spell_warr_vigilance_trigger() : SpellScriptLoader("spell_warr_vigilance_trigger") { } + + class spell_warr_vigilance_trigger_SpellScript : public SpellScript + { + PrepareSpellScript(spell_warr_vigilance_trigger_SpellScript); + + void HandleScript(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + + // Remove Taunt cooldown + if (Player* target = GetHitPlayer()) + target->RemoveSpellCooldown(SPELL_WARRIOR_TAUNT, true); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_warr_vigilance_trigger_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_warr_vigilance_trigger_SpellScript(); + } +}; + void AddSC_warrior_spell_scripts() { new spell_warr_bloodthirst(); 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_improved_spell_reflection(); + new spell_warr_intimidating_shout(); new spell_warr_last_stand(); + new spell_warr_overpower(); + new spell_warr_rend(); + new spell_warr_shattering_throw(); new spell_warr_slam(); + new spell_warr_sweeping_strikes(); + new spell_warr_vigilance(); + new spell_warr_vigilance_trigger(); } |
