diff options
Diffstat (limited to 'src/server/scripts')
58 files changed, 3038 insertions, 1065 deletions
diff --git a/src/server/scripts/Commands/cs_character.cpp b/src/server/scripts/Commands/cs_character.cpp index 9557d182df1..01602e2f24c 100644 --- a/src/server/scripts/Commands/cs_character.cpp +++ b/src/server/scripts/Commands/cs_character.cpp @@ -436,7 +436,7 @@ public: if (isalpha(levelStr[0])) { nameStr = levelStr; - levelStr = NULL; // current level will used + levelStr = nullptr; // current level will used } Player* target; diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp index 1d8094885d4..ca4dd814e01 100644 --- a/src/server/scripts/Commands/cs_debug.cpp +++ b/src/server/scripts/Commands/cs_debug.cpp @@ -34,6 +34,7 @@ EndScriptData */ #include "Transport.h" #include "Language.h" #include "MapManager.h" +#include "M2Stores.h" #include <fstream> @@ -847,7 +848,7 @@ public: if (Unit* unit = ref->GetSource()->GetOwner()) { ++count; - handler->PSendSysMessage(" %u. %s (guid %u) - threat %f", count, unit->GetName().c_str(), unit->GetGUID().GetCounter(), ref->getThreat()); + handler->PSendSysMessage(" %u. %s (current guid %u, DB guid %u) - threat %f", count, unit->GetName().c_str(), unit->GetGUID().GetCounter(), unit->GetTypeId() == TYPEID_UNIT ? unit->ToCreature()->GetSpawnId() : 0, ref->getThreat()); } ref = ref->next(); } diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index 3e35a721162..a98f9f4bf9c 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -796,7 +796,7 @@ public: target->CleanupAfterTaxiFlight(); } - target->TeleportTo(target->m_recallMap, target->m_recallX, target->m_recallY, target->m_recallZ, target->m_recallO); + target->Recall(); return true; } diff --git a/src/server/scripts/Commands/cs_modify.cpp b/src/server/scripts/Commands/cs_modify.cpp index f1ddb448b35..e25018cf1bd 100644 --- a/src/server/scripts/Commands/cs_modify.cpp +++ b/src/server/scripts/Commands/cs_modify.cpp @@ -80,23 +80,32 @@ public: return commandTable; } - //Edit Player HP - static bool HandleModifyHPCommand(ChatHandler* handler, const char* args) + template<typename... Args> + static void NotifyModification(ChatHandler* handler, Unit* target, TrinityStrings resourceMessage, TrinityStrings resourceReportMessage, Args&&... args) + { + if (Player* player = target->ToPlayer()) + { + handler->PSendSysMessage(resourceMessage, handler->GetNameLink(player).c_str(), args...); + if (handler->needReportToTarget(player)) + ChatHandler(player->GetSession()).PSendSysMessage(resourceReportMessage, handler->GetNameLink().c_str(), std::forward<Args>(args)...); + } + } + + static bool CheckModifyResources(ChatHandler* handler, const char* args, Player* target, int32& res, int32& resmax, int8 const multiplier = 1) { if (!*args) return false; - int32 hp = atoi((char*)args); - int32 hpm = atoi((char*)args); + res = atoi((char*)args) * multiplier; + resmax = atoi((char*)args) * multiplier; - if (hp < 1 || hpm < 1 || hpm < hp) + if (res < 1 || resmax < 1 || resmax < res) { handler->SendSysMessage(LANG_BAD_VALUE); handler->SetSentErrorMessage(true); return false; } - Player* target = handler->getSelectedPlayerOrSelf(); if (!target) { handler->SendSysMessage(LANG_NO_CHAR_SELECTED); @@ -107,164 +116,87 @@ public: if (handler->HasLowerSecurity(target, ObjectGuid::Empty)) return false; - handler->PSendSysMessage(LANG_YOU_CHANGE_HP, handler->GetNameLink(target).c_str(), hp, hpm); - if (handler->needReportToTarget(target)) - ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOURS_HP_CHANGED, handler->GetNameLink().c_str(), hp, hpm); - - target->SetMaxHealth(hpm); - target->SetHealth(hp); - return true; } - //Edit Player Mana - static bool HandleModifyManaCommand(ChatHandler* handler, const char* args) + //Edit Player HP + static bool HandleModifyHPCommand(ChatHandler* handler, const char* args) { - if (!*args) - return false; - - int32 mana = atoi((char*)args); - int32 manam = atoi((char*)args); - - if (mana <= 0 || manam <= 0 || manam < mana) + int32 hp, hpmax; + Player* target = handler->getSelectedPlayerOrSelf(); + if (CheckModifyResources(handler, args, target, hp, hpmax)) { - handler->SendSysMessage(LANG_BAD_VALUE); - handler->SetSentErrorMessage(true); - return false; + NotifyModification(handler, target, LANG_YOU_CHANGE_HP, LANG_YOURS_HP_CHANGED, hp, hpmax); + target->SetMaxHealth(hpmax); + target->SetHealth(hp); + return true; } + return false; + } + //Edit Player Mana + static bool HandleModifyManaCommand(ChatHandler* handler, const char* args) + { + int32 mana, manamax; Player* target = handler->getSelectedPlayerOrSelf(); - if (!target) + + if (CheckModifyResources(handler, args, target, mana, manamax)) { - handler->SendSysMessage(LANG_NO_CHAR_SELECTED); - handler->SetSentErrorMessage(true); - return false; + NotifyModification(handler, target, LANG_YOU_CHANGE_MANA, LANG_YOURS_MANA_CHANGED, mana, manamax); + target->SetMaxPower(POWER_MANA, manamax); + target->SetPower(POWER_MANA, mana); + return true; } - - // check online security - if (handler->HasLowerSecurity(target, ObjectGuid::Empty)) - return false; - - handler->PSendSysMessage(LANG_YOU_CHANGE_MANA, handler->GetNameLink(target).c_str(), mana, manam); - if (handler->needReportToTarget(target)) - ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOURS_MANA_CHANGED, handler->GetNameLink().c_str(), mana, manam); - - target->SetMaxPower(POWER_MANA, manam); - target->SetPower(POWER_MANA, mana); - - return true; + return false; } //Edit Player Energy static bool HandleModifyEnergyCommand(ChatHandler* handler, const char* args) { - if (!*args) - return false; - - int32 energy = atoi((char*)args)*10; - int32 energym = atoi((char*)args)*10; - - if (energy <= 0 || energym <= 0 || energym < energy) - { - handler->SendSysMessage(LANG_BAD_VALUE); - handler->SetSentErrorMessage(true); - return false; - } - + int32 energy, energymax; Player* target = handler->getSelectedPlayerOrSelf(); - if (!target) + int8 const energyMultiplier = 10; + if (CheckModifyResources(handler, args, target, energy, energymax, energyMultiplier)) { - handler->SendSysMessage(LANG_NO_CHAR_SELECTED); - handler->SetSentErrorMessage(true); - return false; + NotifyModification(handler, target, LANG_YOU_CHANGE_ENERGY, LANG_YOURS_ENERGY_CHANGED, energy / energyMultiplier, energymax / energyMultiplier); + target->SetMaxPower(POWER_ENERGY, energymax); + target->SetPower(POWER_ENERGY, energy); + TC_LOG_DEBUG("misc", handler->GetTrinityString(LANG_CURRENT_ENERGY), target->GetMaxPower(POWER_ENERGY)); + return true; } - - // check online security - if (handler->HasLowerSecurity(target, ObjectGuid::Empty)) - return false; - - handler->PSendSysMessage(LANG_YOU_CHANGE_ENERGY, handler->GetNameLink(target).c_str(), energy/10, energym/10); - if (handler->needReportToTarget(target)) - ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOURS_ENERGY_CHANGED, handler->GetNameLink().c_str(), energy/10, energym/10); - - target->SetMaxPower(POWER_ENERGY, energym); - target->SetPower(POWER_ENERGY, energy); - - TC_LOG_DEBUG("misc", handler->GetTrinityString(LANG_CURRENT_ENERGY), target->GetMaxPower(POWER_ENERGY)); - - return true; + return false; } //Edit Player Rage static bool HandleModifyRageCommand(ChatHandler* handler, const char* args) { - if (!*args) - return false; - - int32 rage = atoi((char*)args)*10; - int32 ragem = atoi((char*)args)*10; - - if (rage <= 0 || ragem <= 0 || ragem < rage) - { - handler->SendSysMessage(LANG_BAD_VALUE); - handler->SetSentErrorMessage(true); - return false; - } - + int32 rage, ragemax; Player* target = handler->getSelectedPlayerOrSelf(); - if (!target) + int8 const rageMultiplier = 10; + if (CheckModifyResources(handler, args, target, rage, ragemax, rageMultiplier)) { - handler->SendSysMessage(LANG_NO_CHAR_SELECTED); - handler->SetSentErrorMessage(true); - return false; + NotifyModification(handler, target, LANG_YOU_CHANGE_RAGE, LANG_YOURS_RAGE_CHANGED, rage / rageMultiplier, ragemax / rageMultiplier); + target->SetMaxPower(POWER_RAGE, ragemax); + target->SetPower(POWER_RAGE, rage); + return true; } - - // check online security - if (handler->HasLowerSecurity(target, ObjectGuid::Empty)) - return false; - - handler->PSendSysMessage(LANG_YOU_CHANGE_RAGE, handler->GetNameLink(target).c_str(), rage/10, ragem/10); - if (handler->needReportToTarget(target)) - ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOURS_RAGE_CHANGED, handler->GetNameLink().c_str(), rage/10, ragem/10); - - target->SetMaxPower(POWER_RAGE, ragem); - target->SetPower(POWER_RAGE, rage); - - return true; + return false; } // Edit Player Runic Power static bool HandleModifyRunicPowerCommand(ChatHandler* handler, const char* args) { - if (!*args) - return false; - - int32 rune = atoi((char*)args)*10; - int32 runem = atoi((char*)args)*10; - - if (rune <= 0 || runem <= 0 || runem < rune) - { - handler->SendSysMessage(LANG_BAD_VALUE); - handler->SetSentErrorMessage(true); - return false; - } - + int32 rune, runemax; Player* target = handler->getSelectedPlayerOrSelf(); - if (!target) + int8 const runeMultiplier = 10; + if (CheckModifyResources(handler, args, target, rune, runemax, runeMultiplier)) { - handler->SendSysMessage(LANG_NO_CHAR_SELECTED); - handler->SetSentErrorMessage(true); - return false; + NotifyModification(handler, target, LANG_YOU_CHANGE_RUNIC_POWER, LANG_YOURS_RUNIC_POWER_CHANGED, rune / runeMultiplier, runemax / runeMultiplier); + target->SetMaxPower(POWER_RUNIC_POWER, runemax); + target->SetPower(POWER_RUNIC_POWER, rune); + return true; } - - handler->PSendSysMessage(LANG_YOU_CHANGE_RUNIC_POWER, handler->GetNameLink(target).c_str(), rune/10, runem/10); - if (handler->needReportToTarget(target)) - ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOURS_RUNIC_POWER_CHANGED, handler->GetNameLink().c_str(), rune/10, runem/10); - - target->SetMaxPower(POWER_RUNIC_POWER, runem); - target->SetPower(POWER_RUNIC_POWER, rune); - - return true; + return false; } //Edit Player Faction @@ -437,22 +369,20 @@ public: return false; } - //Edit Player Aspeed - static bool HandleModifyASpeedCommand(ChatHandler* handler, const char* args) + static bool CheckModifySpeed(ChatHandler* handler, const char* args, Unit* target, float& speed, float minimumBound, float maximumBound, bool checkInFlight = true) { if (!*args) return false; - float ASpeed = (float)atof((char*)args); + speed = (float)atof((char*)args); - if (ASpeed > 50.0f || ASpeed < 0.1f) + if (speed > maximumBound || speed < minimumBound) { handler->SendSysMessage(LANG_BAD_VALUE); handler->SetSentErrorMessage(true); return false; } - Player* target = handler->getSelectedPlayerOrSelf(); if (!target) { handler->SendSysMessage(LANG_NO_CHAR_SELECTED); @@ -460,238 +390,107 @@ public: return false; } - // check online security - if (handler->HasLowerSecurity(target, ObjectGuid::Empty)) - return false; - - std::string targetNameLink = handler->GetNameLink(target); - - if (target->IsInFlight()) + if (Player* player = target->ToPlayer()) { - handler->PSendSysMessage(LANG_CHAR_IN_FLIGHT, targetNameLink.c_str()); - handler->SetSentErrorMessage(true); - return false; - } - - handler->PSendSysMessage(LANG_YOU_CHANGE_ASPEED, targetNameLink.c_str(), ASpeed); - if (handler->needReportToTarget(target)) - ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOURS_ASPEED_CHANGED, handler->GetNameLink().c_str(), ASpeed); + // check online security + if (handler->HasLowerSecurity(player, ObjectGuid::Empty)) + return false; - target->SetSpeedRate(MOVE_WALK, ASpeed); - target->SetSpeedRate(MOVE_RUN, ASpeed); - target->SetSpeedRate(MOVE_SWIM, ASpeed); - //target->SetSpeedRate(MOVE_TURN, ASpeed); - target->SetSpeedRate(MOVE_FLIGHT, ASpeed); + if (player->IsInFlight() && checkInFlight) + { + handler->PSendSysMessage(LANG_CHAR_IN_FLIGHT, handler->GetNameLink(player).c_str()); + handler->SetSentErrorMessage(true); + return false; + } + } return true; } - //Edit Player Speed - static bool HandleModifySpeedCommand(ChatHandler* handler, const char* args) + //Edit Player Aspeed + static bool HandleModifyASpeedCommand(ChatHandler* handler, const char* args) { - if (!*args) - return false; - - float Speed = (float)atof((char*)args); - - if (Speed > 50.0f || Speed < 0.1f) - { - handler->SendSysMessage(LANG_BAD_VALUE); - handler->SetSentErrorMessage(true); - return false; - } - + float allSpeed; Player* target = handler->getSelectedPlayerOrSelf(); - if (!target) + if (CheckModifySpeed(handler, args, target, allSpeed, 0.1f, 50.0f)) { - handler->SendSysMessage(LANG_NO_CHAR_SELECTED); - handler->SetSentErrorMessage(true); - return false; + NotifyModification(handler, target, LANG_YOU_CHANGE_ASPEED, LANG_YOURS_ASPEED_CHANGED, allSpeed); + target->SetSpeedRate(MOVE_WALK, allSpeed); + target->SetSpeedRate(MOVE_RUN, allSpeed); + target->SetSpeedRate(MOVE_SWIM, allSpeed); + target->SetSpeedRate(MOVE_FLIGHT, allSpeed); + return true; } + return false; + } - // check online security - if (handler->HasLowerSecurity(target, ObjectGuid::Empty)) - return false; - - std::string targetNameLink = handler->GetNameLink(target); - - if (target->IsInFlight()) + //Edit Player Speed + static bool HandleModifySpeedCommand(ChatHandler* handler, const char* args) + { + float Speed; + Player* target = handler->getSelectedPlayerOrSelf(); + if (CheckModifySpeed(handler, args, target, Speed, 0.1f, 50.0f)) { - handler->PSendSysMessage(LANG_CHAR_IN_FLIGHT, targetNameLink.c_str()); - handler->SetSentErrorMessage(true); - return false; + NotifyModification(handler, target, LANG_YOU_CHANGE_SPEED, LANG_YOURS_SPEED_CHANGED, Speed); + target->SetSpeedRate(MOVE_RUN, Speed); + return true; } - - handler->PSendSysMessage(LANG_YOU_CHANGE_SPEED, targetNameLink.c_str(), Speed); - if (handler->needReportToTarget(target)) - ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOURS_SPEED_CHANGED, handler->GetNameLink().c_str(), Speed); - - target->SetSpeedRate(MOVE_RUN, Speed); - - return true; + return false; } //Edit Player Swim Speed static bool HandleModifySwimCommand(ChatHandler* handler, const char* args) { - if (!*args) - return false; - - float Swim = (float)atof((char*)args); - - if (Swim > 50.0f || Swim < 0.1f) - { - handler->SendSysMessage(LANG_BAD_VALUE); - handler->SetSentErrorMessage(true); - return false; - } - + float swimSpeed; Player* target = handler->getSelectedPlayerOrSelf(); - if (!target) + if (CheckModifySpeed(handler, args, target, swimSpeed, 0.1f, 50.0f)) { - handler->SendSysMessage(LANG_NO_CHAR_SELECTED); - handler->SetSentErrorMessage(true); - return false; - } - - // check online security - if (handler->HasLowerSecurity(target, ObjectGuid::Empty)) - return false; - - std::string targetNameLink = handler->GetNameLink(target); - - if (target->IsInFlight()) - { - handler->PSendSysMessage(LANG_CHAR_IN_FLIGHT, targetNameLink.c_str()); - handler->SetSentErrorMessage(true); - return false; + NotifyModification(handler, target, LANG_YOU_CHANGE_SWIM_SPEED, LANG_YOURS_SWIM_SPEED_CHANGED, swimSpeed); + target->SetSpeedRate(MOVE_SWIM, swimSpeed); + return true; } - - handler->PSendSysMessage(LANG_YOU_CHANGE_SWIM_SPEED, targetNameLink.c_str(), Swim); - if (handler->needReportToTarget(target)) - ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOURS_SWIM_SPEED_CHANGED, handler->GetNameLink().c_str(), Swim); - - target->SetSpeedRate(MOVE_SWIM, Swim); - - return true; + return false; } - //Edit Player Walk Speed + //Edit Player Backwards Walk Speed static bool HandleModifyBWalkCommand(ChatHandler* handler, const char* args) { - if (!*args) - return false; - - float BSpeed = (float)atof((char*)args); - - if (BSpeed > 50.0f || BSpeed < 0.1f) - { - handler->SendSysMessage(LANG_BAD_VALUE); - handler->SetSentErrorMessage(true); - return false; - } - + float backSpeed; Player* target = handler->getSelectedPlayerOrSelf(); - if (!target) + if (CheckModifySpeed(handler, args, target, backSpeed, 0.1f, 50.0f)) { - handler->SendSysMessage(LANG_NO_CHAR_SELECTED); - handler->SetSentErrorMessage(true); - return false; - } - - // check online security - if (handler->HasLowerSecurity(target, ObjectGuid::Empty)) - return false; - - std::string targetNameLink = handler->GetNameLink(target); - - if (target->IsInFlight()) - { - handler->PSendSysMessage(LANG_CHAR_IN_FLIGHT, targetNameLink.c_str()); - handler->SetSentErrorMessage(true); - return false; + NotifyModification(handler, target, LANG_YOU_CHANGE_BACK_SPEED, LANG_YOURS_BACK_SPEED_CHANGED, backSpeed); + target->SetSpeedRate(MOVE_RUN_BACK, backSpeed); + return true; } - - handler->PSendSysMessage(LANG_YOU_CHANGE_BACK_SPEED, targetNameLink.c_str(), BSpeed); - if (handler->needReportToTarget(target)) - ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOURS_BACK_SPEED_CHANGED, handler->GetNameLink().c_str(), BSpeed); - - target->SetSpeedRate(MOVE_RUN_BACK, BSpeed); - - return true; + return false; } //Edit Player Fly static bool HandleModifyFlyCommand(ChatHandler* handler, const char* args) { - if (!*args) - return false; - - float FSpeed = (float)atof((char*)args); - - if (FSpeed > 50.0f || FSpeed < 0.1f) - { - handler->SendSysMessage(LANG_BAD_VALUE); - handler->SetSentErrorMessage(true); - return false; - } - + float flySpeed; Player* target = handler->getSelectedPlayerOrSelf(); - if (!target) + if (CheckModifySpeed(handler, args, target, flySpeed, 0.1f, 50.0f, false)) { - handler->SendSysMessage(LANG_NO_CHAR_SELECTED); - handler->SetSentErrorMessage(true); - return false; + NotifyModification(handler, target, LANG_YOU_CHANGE_FLY_SPEED, LANG_YOURS_FLY_SPEED_CHANGED, flySpeed); + target->SetSpeedRate(MOVE_FLIGHT, flySpeed); + return true; } - - // check online security - if (handler->HasLowerSecurity(target, ObjectGuid::Empty)) - return false; - - handler->PSendSysMessage(LANG_YOU_CHANGE_FLY_SPEED, handler->GetNameLink(target).c_str(), FSpeed); - if (handler->needReportToTarget(target)) - ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOURS_FLY_SPEED_CHANGED, handler->GetNameLink().c_str(), FSpeed); - - target->SetSpeedRate(MOVE_FLIGHT, FSpeed); - - return true; + return false; } //Edit Player or Creature Scale static bool HandleModifyScaleCommand(ChatHandler* handler, const char* args) { - if (!*args) - return false; - - float Scale = (float)atof((char*)args); - if (Scale > 10.0f || Scale < 0.1f) - { - handler->SendSysMessage(LANG_BAD_VALUE); - handler->SetSentErrorMessage(true); - return false; - } - + float Scale; Unit* target = handler->getSelectedUnit(); - if (!target) + if (CheckModifySpeed(handler, args, target, Scale, 0.1f, 10.0f, false)) { - handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); - handler->SetSentErrorMessage(true); - return false; - } - - if (Player* player = target->ToPlayer()) - { - // check online security - if (handler->HasLowerSecurity(player, ObjectGuid::Empty)) - return false; - - handler->PSendSysMessage(LANG_YOU_CHANGE_SIZE, handler->GetNameLink(player).c_str(), Scale); - if (handler->needReportToTarget(player)) - ChatHandler(player->GetSession()).PSendSysMessage(LANG_YOURS_SIZE_CHANGED, handler->GetNameLink().c_str(), Scale); + NotifyModification(handler, target, LANG_YOU_CHANGE_SIZE, LANG_YOURS_SIZE_CHANGED, Scale); + target->SetObjectScale(Scale); + return true; } - - target->SetObjectScale(Scale); - - return true; + return false; } //Enable Player mount @@ -932,9 +731,7 @@ public: if (handler->HasLowerSecurity(target, ObjectGuid::Empty)) return false; - handler->PSendSysMessage(LANG_YOU_GIVE_MOUNT, handler->GetNameLink(target).c_str()); - if (handler->needReportToTarget(target)) - ChatHandler(target->GetSession()).PSendSysMessage(LANG_MOUNT_GIVED, handler->GetNameLink().c_str()); + NotifyModification(handler, target, LANG_YOU_GIVE_MOUNT, LANG_MOUNT_GIVED); target->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP); target->Mount(mId); @@ -988,10 +785,7 @@ public: TC_LOG_DEBUG("misc", handler->GetTrinityString(LANG_CURRENT_MONEY), targetMoney, moneyToAdd, newmoney); if (newmoney <= 0) { - handler->PSendSysMessage(LANG_YOU_TAKE_ALL_MONEY, handler->GetNameLink(target).c_str()); - if (handler->needReportToTarget(target)) - ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOURS_ALL_MONEY_GONE, handler->GetNameLink().c_str()); - + NotifyModification(handler, target, LANG_YOU_TAKE_ALL_MONEY, LANG_YOURS_ALL_MONEY_GONE); target->SetMoney(0); } else diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp index fbd199b99db..38aa96a6a66 100644 --- a/src/server/scripts/Commands/cs_npc.cpp +++ b/src/server/scripts/Commands/cs_npc.cpp @@ -113,7 +113,7 @@ EnumName<UnitFlags> const unitFlags[MAX_UNIT_FLAGS] = { CREATE_NAMED_ENUM(UNIT_FLAG_SERVER_CONTROLLED), CREATE_NAMED_ENUM(UNIT_FLAG_NON_ATTACKABLE), - CREATE_NAMED_ENUM(UNIT_FLAG_DISABLE_MOVE), + CREATE_NAMED_ENUM(UNIT_FLAG_REMOVE_CLIENT_CONTROL), CREATE_NAMED_ENUM(UNIT_FLAG_PVP_ATTACKABLE), CREATE_NAMED_ENUM(UNIT_FLAG_RENAME), CREATE_NAMED_ENUM(UNIT_FLAG_PREPARATION), @@ -125,7 +125,7 @@ EnumName<UnitFlags> const unitFlags[MAX_UNIT_FLAGS] = CREATE_NAMED_ENUM(UNIT_FLAG_PET_IN_COMBAT), CREATE_NAMED_ENUM(UNIT_FLAG_PVP), CREATE_NAMED_ENUM(UNIT_FLAG_SILENCED), - CREATE_NAMED_ENUM(UNIT_FLAG_UNK_14), + CREATE_NAMED_ENUM(UNIT_FLAG_CANNOT_SWIM), CREATE_NAMED_ENUM(UNIT_FLAG_UNK_15), CREATE_NAMED_ENUM(UNIT_FLAG_UNK_16), CREATE_NAMED_ENUM(UNIT_FLAG_PACIFIED), @@ -220,14 +220,15 @@ public: { "whisper", rbac::RBAC_PERM_COMMAND_NPC_WHISPER, false, &HandleNpcWhisperCommand, "" }, { "yell", rbac::RBAC_PERM_COMMAND_NPC_YELL, false, &HandleNpcYellCommand, "" }, { "tame", rbac::RBAC_PERM_COMMAND_NPC_TAME, false, &HandleNpcTameCommand, "" }, - { "add", rbac::RBAC_PERM_COMMAND_NPC_ADD, false, NULL, "", npcAddCommandTable }, - { "delete", rbac::RBAC_PERM_COMMAND_NPC_DELETE, false, NULL, "", npcDeleteCommandTable }, - { "follow", rbac::RBAC_PERM_COMMAND_NPC_FOLLOW, false, NULL, "", npcFollowCommandTable }, - { "set", rbac::RBAC_PERM_COMMAND_NPC_SET, false, NULL, "", npcSetCommandTable }, + { "add", rbac::RBAC_PERM_COMMAND_NPC_ADD, false, nullptr, "", npcAddCommandTable }, + { "delete", rbac::RBAC_PERM_COMMAND_NPC_DELETE, false, nullptr, "", npcDeleteCommandTable }, + { "follow", rbac::RBAC_PERM_COMMAND_NPC_FOLLOW, false, nullptr, "", npcFollowCommandTable }, + { "set", rbac::RBAC_PERM_COMMAND_NPC_SET, false, nullptr, "", npcSetCommandTable }, + { "evade", rbac::RBAC_PERM_COMMAND_NPC_EVADE, false, &HandleNpcEvadeCommand, "" }, }; static std::vector<ChatCommand> commandTable = { - { "npc", rbac::RBAC_PERM_COMMAND_NPC, false, NULL, "", npcCommandTable }, + { "npc", rbac::RBAC_PERM_COMMAND_NPC, false, nullptr, "", npcCommandTable }, }; return commandTable; } @@ -318,17 +319,17 @@ public: uint32 itemId = item_int; - char* fmaxcount = strtok(NULL, " "); //add maxcount, default: 0 + char* fmaxcount = strtok(nullptr, " "); //add maxcount, default: 0 uint32 maxcount = 0; if (fmaxcount) maxcount = atoul(fmaxcount); - char* fincrtime = strtok(NULL, " "); //add incrtime, default: 0 + char* fincrtime = strtok(nullptr, " "); //add incrtime, default: 0 uint32 incrtime = 0; if (fincrtime) incrtime = atoul(fincrtime); - char* fextendedcost = strtok(NULL, " "); //add ExtendedCost, default: 0 + char* fextendedcost = strtok(nullptr, " "); //add ExtendedCost, default: 0 uint32 extendedcost = fextendedcost ? atoul(fextendedcost) : 0; Creature* vendor = handler->getSelectedCreature(); if (!vendor) @@ -361,7 +362,7 @@ public: return false; char* guidStr = strtok((char*)args, " "); - char* waitStr = strtok((char*)NULL, " "); + char* waitStr = strtok((char*)nullptr, " "); ObjectGuid::LowType lowGuid = atoi((char*)guidStr); @@ -446,36 +447,24 @@ public: } Creature* creature = handler->getSelectedCreature(); - if (!creature) + if (!creature || creature->IsPet()) { handler->SendSysMessage(LANG_SELECT_CREATURE); handler->SetSentErrorMessage(true); return false; } - if (creature->IsPet()) - { - if (((Pet*)creature)->getPetType() == HUNTER_PET) - { - creature->SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, sObjectMgr->GetXPForLevel(lvl)/4); - creature->SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, 0); - } - ((Pet*)creature)->GivePetLevel(lvl); - } - else - { - creature->SetMaxHealth(100 + 30*lvl); - creature->SetHealth(100 + 30*lvl); - creature->SetLevel(lvl); - creature->SaveToDB(); - } + creature->SetMaxHealth(100 + 30*lvl); + creature->SetHealth(100 + 30*lvl); + creature->SetLevel(lvl); + creature->SaveToDB(); return true; } static bool HandleNpcDeleteCommand(ChatHandler* handler, char const* args) { - Creature* unit = NULL; + Creature* unit = nullptr; if (*args) { @@ -628,7 +617,7 @@ public: return false; char* arg1 = strtok((char*)args, " "); - char* arg2 = strtok((char*)NULL, ""); + char* arg2 = strtok((char*)nullptr, ""); if (!arg1 || !arg2) return false; @@ -926,8 +915,8 @@ public: // later switched on/off according to special events (like escort // quests, etc) char* guid_str = strtok((char*)args, " "); - char* type_str = strtok((char*)NULL, " "); - char* dontdel_str = strtok((char*)NULL, " "); + char* type_str = strtok((char*)nullptr, " "); + char* dontdel_str = strtok((char*)nullptr, " "); bool doNotDelete = false; @@ -935,7 +924,7 @@ public: return false; ObjectGuid::LowType lowguid = 0; - Creature* creature = NULL; + Creature* creature = nullptr; if (dontdel_str) { @@ -961,7 +950,7 @@ public: { //TC_LOG_ERROR("misc", "DEBUG: type_str, NODEL "); doNotDelete = true; - type_str = NULL; + type_str = nullptr; } } } @@ -1001,7 +990,7 @@ public: } // now lowguid is low guid really existed creature - // and creature point (maybe) to this creature or NULL + // and creature point (maybe) to this creature or nullptr MovementGeneratorType move_type; @@ -1260,7 +1249,7 @@ public: } char* receiver_str = strtok((char*)args, " "); - char* text = strtok(NULL, ""); + char* text = strtok(nullptr, ""); if (!receiver_str || !text) { @@ -1319,7 +1308,16 @@ public: if (!*args) return false; - char* charID = handler->extractKeyFromLink((char*)args, "Hcreature_entry"); + bool loot = false; + char const* spawntype_str = strtok((char*)args, " "); + char const* entry_str = strtok(nullptr, ""); + if (stricmp(spawntype_str, "LOOT") == 0) + loot = true; + else if (stricmp(spawntype_str, "NOLOOT") == 0) + loot = false; + else + entry_str = args; + char* charID = handler->extractKeyFromLink((char*)entry_str, "Hcreature_entry"); if (!charID) return false; @@ -1332,7 +1330,7 @@ public: if (!sObjectMgr->GetCreatureTemplate(id)) return false; - chr->SummonCreature(id, *chr, TEMPSUMMON_CORPSE_DESPAWN, 120); + chr->SummonCreature(id, *chr, loot ? TEMPSUMMON_CORPSE_TIMED_DESPAWN : TEMPSUMMON_CORPSE_DESPAWN, 30 * IN_MILLISECONDS); return true; } @@ -1404,6 +1402,51 @@ public: return true; } + static bool HandleNpcEvadeCommand(ChatHandler* handler, char const* args) + { + Creature* creatureTarget = handler->getSelectedCreature(); + if (!creatureTarget || creatureTarget->IsPet()) + { + handler->PSendSysMessage(LANG_SELECT_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + if (!creatureTarget->IsAIEnabled) + { + handler->PSendSysMessage(LANG_CREATURE_NOT_AI_ENABLED); + handler->SetSentErrorMessage(true); + return false; + } + + char* type_str = args ? strtok((char*)args, " ") : nullptr; + char* force_str = args ? strtok(nullptr, " ") : nullptr; + + CreatureAI::EvadeReason why = CreatureAI::EVADE_REASON_OTHER; + bool force = false; + if (type_str) + { + if (stricmp(type_str, "NO_HOSTILES") == 0 || stricmp(type_str, "EVADE_REASON_NO_HOSTILES") == 0) + why = CreatureAI::EVADE_REASON_NO_HOSTILES; + else if (stricmp(type_str, "BOUNDARY") == 0 || stricmp(type_str, "EVADE_REASON_BOUNDARY") == 0) + why = CreatureAI::EVADE_REASON_BOUNDARY; + else if (stricmp(type_str, "SEQUENCE_BREAK") == 0 || stricmp(type_str, "EVADE_REASON_SEQUENCE_BREAK") == 0) + why = CreatureAI::EVADE_REASON_SEQUENCE_BREAK; + else if (stricmp(type_str, "FORCE") == 0) + force = true; + + if (!force && force_str) + if (stricmp(force_str, "FORCE") == 0) + force = true; + } + + if (force) + creatureTarget->ClearUnitState(UNIT_STATE_EVADE); + creatureTarget->AI()->EnterEvadeMode(why); + + return true; + } + static bool HandleNpcAddFormationCommand(ChatHandler* handler, char const* args) { if (!*args) @@ -1515,7 +1558,7 @@ public: if (!pSlotID) return false; - char* pItemID = strtok(NULL, " "); + char* pItemID = strtok(nullptr, " "); if (!pItemID) return false; diff --git a/src/server/scripts/Commands/cs_pet.cpp b/src/server/scripts/Commands/cs_pet.cpp index 4f0a179142d..a86de766117 100644 --- a/src/server/scripts/Commands/cs_pet.cpp +++ b/src/server/scripts/Commands/cs_pet.cpp @@ -22,6 +22,19 @@ #include "ObjectMgr.h" #include "ScriptMgr.h" +static inline Pet* GetSelectedPlayerPetOrOwn(ChatHandler* handler) +{ + if (Unit* target = handler->getSelectedUnit()) + { + if (target->GetTypeId() == TYPEID_PLAYER) + return target->ToPlayer()->GetPet(); + if (target->IsPet()) + return target->ToPet(); + return nullptr; + } + Player* player = handler->GetSession()->GetPlayer(); + return player ? player->GetPet() : nullptr; +} class pet_commandscript : public CommandScript { public: @@ -34,6 +47,7 @@ public: { "create", rbac::RBAC_PERM_COMMAND_PET_CREATE, false, &HandlePetCreateCommand, "" }, { "learn", rbac::RBAC_PERM_COMMAND_PET_LEARN, false, &HandlePetLearnCommand, "" }, { "unlearn", rbac::RBAC_PERM_COMMAND_PET_UNLEARN, false, &HandlePetUnlearnCommand, "" }, + { "level", rbac::RBAC_PERM_COMMAND_PET_LEVEL, false, &HandlePetLevelCommand, "" }, }; static std::vector<ChatCommand> commandTable = @@ -54,11 +68,11 @@ public: return false; } - CreatureTemplate const* creatrueTemplate = creatureTarget->GetCreatureTemplate(); - // Creatures with family 0 crashes the server - if (!creatrueTemplate->family) + CreatureTemplate const* creatureTemplate = creatureTarget->GetCreatureTemplate(); + // Creatures with family CREATURE_FAMILY_NONE crashes the server + if (creatureTemplate->family == CREATURE_FAMILY_NONE) { - handler->PSendSysMessage("This creature cannot be tamed. (family id: 0)."); + handler->PSendSysMessage("This creature cannot be tamed. Family id: 0 (CREATURE_FAMILY_NONE)."); handler->SetSentErrorMessage(true); return false; } @@ -119,12 +133,11 @@ public: if (!*args) return false; - Player* player = handler->GetSession()->GetPlayer(); - Pet* pet = player->GetPet(); + Pet* pet = GetSelectedPlayerPetOrOwn(handler); if (!pet) { - handler->PSendSysMessage("You have no pet"); + handler->SendSysMessage(LANG_SELECT_PLAYER_OR_PET); handler->SetSentErrorMessage(true); return false; } @@ -162,11 +175,10 @@ public: if (!*args) return false; - Player* player = handler->GetSession()->GetPlayer(); - Pet* pet = player->GetPet(); + Pet* pet = GetSelectedPlayerPetOrOwn(handler); if (!pet) { - handler->PSendSysMessage("You have no pet"); + handler->SendSysMessage(LANG_SELECT_PLAYER_OR_PET); handler->SetSentErrorMessage(true); return false; } @@ -180,6 +192,37 @@ public: return true; } + + static bool HandlePetLevelCommand(ChatHandler* handler, char const* args) + { + Pet* pet = GetSelectedPlayerPetOrOwn(handler); + Player* owner = pet ? pet->GetOwner() : nullptr; + if (!pet || !owner) + { + handler->SendSysMessage(LANG_SELECT_PLAYER_OR_PET); + handler->SetSentErrorMessage(true); + return false; + } + + int32 level = args ? atoi(args) : 0; + if (level == 0) + level = owner->getLevel() - pet->getLevel(); + if (level == 0 || level < -STRONG_MAX_LEVEL || level > STRONG_MAX_LEVEL) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + + int32 newLevel = pet->getLevel() + level; + if (newLevel < 1) + newLevel = 1; + else if (newLevel > owner->getLevel()) + newLevel = owner->getLevel(); + + pet->GivePetLevel(newLevel); + return true; + } }; void AddSC_pet_commandscript() diff --git a/src/server/scripts/Commands/cs_reload.cpp b/src/server/scripts/Commands/cs_reload.cpp index eb28a8adae4..4470fa7de42 100644 --- a/src/server/scripts/Commands/cs_reload.cpp +++ b/src/server/scripts/Commands/cs_reload.cpp @@ -91,7 +91,7 @@ public: { "disenchant_loot_template", rbac::RBAC_PERM_COMMAND_RELOAD_DISENCHANT_LOOT_TEMPLATE, true, &HandleReloadLootTemplatesDisenchantCommand, "" }, { "event_scripts", rbac::RBAC_PERM_COMMAND_RELOAD_EVENT_SCRIPTS, true, &HandleReloadEventScriptsCommand, "" }, { "fishing_loot_template", rbac::RBAC_PERM_COMMAND_RELOAD_FISHING_LOOT_TEMPLATE, true, &HandleReloadLootTemplatesFishingCommand, "" }, - { "game_graveyard_zone", rbac::RBAC_PERM_COMMAND_RELOAD_GAME_GRAVEYARD_ZONE, true, &HandleReloadGameGraveyardZoneCommand, "" }, + { "graveyard_zone", rbac::RBAC_PERM_COMMAND_RELOAD_GRAVEYARD_ZONE, true, &HandleReloadGameGraveyardZoneCommand, "" }, { "game_tele", rbac::RBAC_PERM_COMMAND_RELOAD_GAME_TELE, true, &HandleReloadGameTeleCommand, "" }, { "gameobject_questender", rbac::RBAC_PERM_COMMAND_RELOAD_GAMEOBJECT_QUESTENDER, true, &HandleReloadGOQuestEnderCommand, "" }, { "gameobject_loot_template", rbac::RBAC_PERM_COMMAND_RELOAD_GAMEOBJECT_QUEST_LOOT_TEMPLATE, true, &HandleReloadLootTemplatesGameobjectCommand, "" }, diff --git a/src/server/scripts/Commands/cs_server.cpp b/src/server/scripts/Commands/cs_server.cpp index 83bc2e47674..e0e52d4e1f5 100644 --- a/src/server/scripts/Commands/cs_server.cpp +++ b/src/server/scripts/Commands/cs_server.cpp @@ -29,6 +29,7 @@ EndScriptData */ #include "Player.h" #include "ScriptMgr.h" #include "GitRevision.h" +#include "Util.h" class server_commandscript : public CommandScript { @@ -52,12 +53,14 @@ public: static std::vector<ChatCommand> serverRestartCommandTable = { { "cancel", rbac::RBAC_PERM_COMMAND_SERVER_RESTART_CANCEL, true, &HandleServerShutDownCancelCommand, "" }, + { "force", rbac::RBAC_PERM_COMMAND_SERVER_RESTART_FORCE, true, &HandleServerForceRestartCommand, "" }, { "" , rbac::RBAC_PERM_COMMAND_SERVER_RESTART, true, &HandleServerRestartCommand, "" }, }; static std::vector<ChatCommand> serverShutdownCommandTable = { { "cancel", rbac::RBAC_PERM_COMMAND_SERVER_SHUTDOWN_CANCEL, true, &HandleServerShutDownCancelCommand, "" }, + { "force", rbac::RBAC_PERM_COMMAND_SERVER_SHUTDOWN_FORCE, true, &HandleServerForceShutDownCommand, "" }, { "" , rbac::RBAC_PERM_COMMAND_SERVER_SHUTDOWN, true, &HandleServerShutDownCommand, "" }, }; @@ -73,19 +76,19 @@ public: { { "corpses", rbac::RBAC_PERM_COMMAND_SERVER_CORPSES, true, &HandleServerCorpsesCommand, "" }, { "exit", rbac::RBAC_PERM_COMMAND_SERVER_EXIT, true, &HandleServerExitCommand, "" }, - { "idlerestart", rbac::RBAC_PERM_COMMAND_SERVER_IDLERESTART, true, NULL, "", serverIdleRestartCommandTable }, - { "idleshutdown", rbac::RBAC_PERM_COMMAND_SERVER_IDLESHUTDOWN, true, NULL, "", serverIdleShutdownCommandTable }, + { "idlerestart", rbac::RBAC_PERM_COMMAND_SERVER_IDLERESTART, true, nullptr, "", serverIdleRestartCommandTable }, + { "idleshutdown", rbac::RBAC_PERM_COMMAND_SERVER_IDLESHUTDOWN, true, nullptr, "", serverIdleShutdownCommandTable }, { "info", rbac::RBAC_PERM_COMMAND_SERVER_INFO, true, &HandleServerInfoCommand, "" }, { "motd", rbac::RBAC_PERM_COMMAND_SERVER_MOTD, true, &HandleServerMotdCommand, "" }, { "plimit", rbac::RBAC_PERM_COMMAND_SERVER_PLIMIT, true, &HandleServerPLimitCommand, "" }, - { "restart", rbac::RBAC_PERM_COMMAND_SERVER_RESTART, true, NULL, "", serverRestartCommandTable }, - { "shutdown", rbac::RBAC_PERM_COMMAND_SERVER_SHUTDOWN, true, NULL, "", serverShutdownCommandTable }, - { "set", rbac::RBAC_PERM_COMMAND_SERVER_SET, true, NULL, "", serverSetCommandTable }, + { "restart", rbac::RBAC_PERM_COMMAND_SERVER_RESTART, true, nullptr, "", serverRestartCommandTable }, + { "shutdown", rbac::RBAC_PERM_COMMAND_SERVER_SHUTDOWN, true, nullptr, "", serverShutdownCommandTable }, + { "set", rbac::RBAC_PERM_COMMAND_SERVER_SET, true, nullptr, "", serverSetCommandTable }, }; static std::vector<ChatCommand> commandTable = { - { "server", rbac::RBAC_PERM_COMMAND_SERVER, true, NULL, "", serverCommandTable }, + { "server", rbac::RBAC_PERM_COMMAND_SERVER, true, nullptr, "", serverCommandTable }, }; return commandTable; } @@ -192,19 +195,34 @@ public: return true; } - static bool HandleServerShutDownCommand(ChatHandler* /*handler*/, char const* args) + static inline bool IsOnlyUser(WorldSession* mySession) { - return ShutdownServer(args, 0, SHUTDOWN_EXIT_CODE); + // check if there is any session connected from a different address + std::string myAddr = mySession ? mySession->GetRemoteAddress() : ""; + SessionMap const& sessions = sWorld->GetAllSessions(); + for (SessionMap::value_type const& session : sessions) + if (session.second && myAddr != session.second->GetRemoteAddress()) + return false; + return true; + } + static bool HandleServerShutDownCommand(ChatHandler* handler, char const* args) + { + return ShutdownServer(args, IsOnlyUser(handler->GetSession()) ? SHUTDOWN_MASK_FORCE : 0, SHUTDOWN_EXIT_CODE); } - static bool HandleServerRestartCommand(ChatHandler* /*handler*/, char const* args) + static bool HandleServerRestartCommand(ChatHandler* handler, char const* args) { - return ShutdownServer(args, SHUTDOWN_MASK_RESTART, RESTART_EXIT_CODE); + return ShutdownServer(args, IsOnlyUser(handler->GetSession()) ? (SHUTDOWN_MASK_FORCE | SHUTDOWN_MASK_RESTART) : SHUTDOWN_MASK_RESTART, RESTART_EXIT_CODE); } - static bool HandleServerIdleRestartCommand(ChatHandler* /*handler*/, char const* args) + static bool HandleServerForceShutDownCommand(ChatHandler* /*handler*/, char const* args) { - return ShutdownServer(args, SHUTDOWN_MASK_RESTART | SHUTDOWN_MASK_IDLE, RESTART_EXIT_CODE); + return ShutdownServer(args, SHUTDOWN_MASK_FORCE, SHUTDOWN_EXIT_CODE); + } + + static bool HandleServerForceRestartCommand(ChatHandler* /*handler*/, char const* args) + { + return ShutdownServer(args, SHUTDOWN_MASK_FORCE | SHUTDOWN_MASK_RESTART, RESTART_EXIT_CODE); } static bool HandleServerIdleShutDownCommand(ChatHandler* /*handler*/, char const* args) @@ -212,6 +230,11 @@ public: return ShutdownServer(args, SHUTDOWN_MASK_IDLE, SHUTDOWN_EXIT_CODE); } + static bool HandleServerIdleRestartCommand(ChatHandler* /*handler*/, char const* args) + { + return ShutdownServer(args, SHUTDOWN_MASK_RESTART | SHUTDOWN_MASK_IDLE, RESTART_EXIT_CODE); + } + // Exit the realm static bool HandleServerExitCommand(ChatHandler* handler, char const* /*args*/) { @@ -256,8 +279,8 @@ public: return false; char* type = strtok((char*)args, " "); - char* name = strtok(NULL, " "); - char* level = strtok(NULL, " "); + char* name = strtok(nullptr, " "); + char* level = strtok(nullptr, " "); if (!type || !name || !level || *name == '\0' || *level == '\0' || (*type != 'a' && *type != 'l')) return false; @@ -313,10 +336,26 @@ private: return false; // #delay [#exit_code] [reason] + int32 delay = 0; char* delayStr = strtok((char*)args, " "); - if (!delayStr || !isNumeric(delayStr)) + if (!delayStr) return false; + if (isNumeric(delayStr)) + { + delay = atoi(delayStr); + // Prevent interpret wrong arg value as 0 secs shutdown time + if ((delay == 0 && (delayStr[0] != '0' || delayStr[1] != '\0')) || delay < 0) + return false; + } + else + { + delay = TimeStringToSecs(std::string(delayStr)); + + if (delay == 0) + return false; + } + char* exitCodeStr = nullptr; char reason[256] = { 0 }; @@ -337,17 +376,14 @@ private: } } - int32 delay = atoi(delayStr); - - // Prevent interpret wrong arg value as 0 secs shutdown time - if ((delay == 0 && (delayStr[0] != '0' || delayStr[1] != '\0')) || delay < 0) - return false; - int32 exitCode = defaultExitCode; if (exitCodeStr) if (!ParseExitCode(exitCodeStr, exitCode)) return false; + if (delay < (int32)sWorld->getIntConfig(CONFIG_FORCE_SHUTDOWN_THRESHOLD) && !(shutdownMask & SHUTDOWN_MASK_FORCE)) + return false; + sWorld->ShutdownServ(delay, shutdownMask, static_cast<uint8>(exitCode), std::string(reason)); return true; diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp index f7a1c18c234..734b70933aa 100644 --- a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp @@ -894,12 +894,12 @@ public: if (instance->GetBossState(DATA_HORSEMAN_EVENT) == IN_PROGRESS) return false; - player->AreaExploredOrEventHappens(11405); - if (Creature* horseman = go->SummonCreature(HH_MOUNTED, FlightPoint[20].x, FlightPoint[20].y, FlightPoint[20].z, 0, TEMPSUMMON_MANUAL_DESPAWN, 0)) - { - ENSURE_AI(boss_headless_horseman::boss_headless_horsemanAI, horseman->AI())->PlayerGUID = player->GetGUID(); - ENSURE_AI(boss_headless_horseman::boss_headless_horsemanAI, horseman->AI())->FlyMode(); - } + player->AreaExploredOrEventHappens(11405); + if (Creature* horseman = go->SummonCreature(HH_MOUNTED, FlightPoint[20].x, FlightPoint[20].y, FlightPoint[20].z, 0, TEMPSUMMON_MANUAL_DESPAWN, 0)) + { + ENSURE_AI(boss_headless_horseman::boss_headless_horsemanAI, horseman->AI())->PlayerGUID = player->GetGUID(); + ENSURE_AI(boss_headless_horseman::boss_headless_horsemanAI, horseman->AI())->FlyMode(); + } return true; } }; diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp index d86b3707606..7563a880f0a 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp @@ -143,11 +143,7 @@ enum Spells SPELL_RING_OF_BLUE_FLAMES = 45825 //Cast this spell when the go is activated }; -/*** Error messages ***/ -#define ERROR_KJ_NOT_SUMMONED "TSCR ERROR: Unable to summon Kil'Jaeden for some reason" - /*** Others ***/ -#define FLOOR_Z 28.050388f #define SHIELD_ORB_Z 45.000f enum Phase diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp index 04d23cd7d4e..6c84677708e 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp @@ -15,88 +15,119 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Boss_Muru -SD%Complete: 80 -SDComment: all sounds, black hole effect triggers to often (46228) -*/ - #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "sunwell_plateau.h" -#include "Player.h" -#include "SpellInfo.h" +#include "SpellScript.h" +#include "SpellAuraEffects.h" -// Muru & Entropius's spells enum Spells { - SPELL_ENRAGE = 26662, - // Muru's spells - SPELL_NEGATIVE_ENERGY = 46009, //(this trigger 46008) - SPELL_DARKNESS = 45999, - SPELL_OPEN_ALL_PORTALS = 46177, - SPELL_OPEN_PORTAL = 45977, - SPELL_OPEN_PORTAL_2 = 45976, - SPELL_SUMMON_BERSERKER = 46037, - SPELL_SUMNON_FURY_MAGE = 46038, - SPELL_SUMMON_VOID_SENTINEL = 45988, - SPELL_SUMMON_ENTROPIUS = 46217, + SPELL_OPEN_PORTAL_PERIODIC = 45994, + SPELL_DARKNESS_PERIODIC = 45998, + SPELL_NEGATIVE_ENERGY_PERIODIC = 46009, + SPELL_SUMMON_VOID_SPAWN = 46071, + SPELL_SUMMON_BLOOD_ELVES_SCRIPT = 46050, + SPELL_SUMMON_BLOOD_ELVES_PERIODIC = 46041, + SPELL_OPEN_ALL_PORTALS = 46177, + SPELL_SUMMON_ENTROPIUS = 46217, + SPELL_ENRAGE = 26662, + SPELL_SUMMON_DARK_FIEND_0 = 46000, + SPELL_SUMMON_DARK_FIEND_1 = 46001, + SPELL_SUMMON_DARK_FIEND_2 = 46002, + SPELL_SUMMON_DARK_FIEND_3 = 46003, + SPELL_SUMMON_DARK_FIEND_4 = 46004, + SPELL_SUMMON_DARK_FIEND_5 = 46005, + SPELL_SUMMON_DARK_FIEND_6 = 46006, + SPELL_SUMMON_DARK_FIEND_7 = 46007, + SPELL_SUMMON_BERSERKER = 46037, + SPELL_SUMMON_BERSERKER_2 = 46040, + SPELL_SUMMON_FURY_MAGE = 46038, + SPELL_SUMMON_FURY_MAGE_2 = 46039, // Entropius's spells - SPELL_DARKNESS_E = 46269, - SPELL_BLACKHOLE = 46282, - SPELL_NEGATIVE_ENERGY_E = 46284, - SPELL_ENTROPIUS_SPAWN = 46223, - - // Shadowsword Berserker's spells - SPELL_FLURRY = 46160, - SPELL_DUAL_WIELD = 29651, + SPELL_ENTROPIUS_COSMETIC_SPAWN = 46223, + SPELL_DARKNESS_E = 46269, + SPELL_NEGATIVE_ENERGY_PERIODIC_E = 46284, + SPELL_BLACKHOLE = 46282, + SPELL_SUMMON_DARKFIEND_E = 46263, + + // Myruu's Portal Target + SPELL_SUMMON_VOID_SENTINEL_SUMMONER = 45978, + SPELL_SUMMON_VOID_SENTINEL_SUMMONER_VISUAL = 45989, + SPELL_SUMMON_VOID_SENTINEL = 45988, + SPELL_TRANSFORM_VISUAL_MISSILE = 46205, + TRANSFORM_VISUAL_MISSILE_1 = 46208, + TRANSFORM_VISUAL_MISSILE_2 = 46178, + SPELL_OPEN_PORTAL = 45977, + SPELL_OPEN_PORTAL_2 = 45976, - // Shadowsword Fury Mage's spells - SPELL_FEL_FIREBALL = 46101, - SPELL_SPELL_FURY = 46102, + //Dark Fiend Spells + SPELL_DARKFIEND_DAMAGE = 45944, + SPELL_DARKFIEND_VISUAL = 45936, + SPELL_DARKFIEND_SKIN = 45934, // Void Sentinel's spells - SPELL_SHADOW_PULSE = 46087, - SPELL_VOID_BLAST = 46161, + SPELL_SHADOW_PULSE_PERIODIC = 46086, + SPELL_VOID_BLAST = 46161, - // Void Spawn's spells - SPELL_SHADOW_BOLT_VOLLEY = 46082, + //Black Hole Spells + SPELL_BLACKHOLE_SUMMON_VISUAL = 46242, + SPELL_BLACKHOLE_SUMMON_VISUAL_2 = 46247, + SPELL_BLACKHOLE_PASSIVE = 46228, + SPELL_BLACK_HOLE_VISUAL_2 = 46235 +}; - //Dark Fiend Spells - SPELL_DARKFIEND_AOE = 45944, - SPELL_DARKFIEND_VISUAL = 45936, - SPELL_DARKFIEND_SKIN = 45934, +enum Phases +{ + PHASE_ONE = 1, + PHASE_TWO = 2 +}; - //Black Hole Spells - SPELL_BLACKHOLE_SPAWN = 46242, - SPELL_BLACKHOLE_GROW = 46228 +enum Misc +{ + MAX_VOID_SPAWNS = 6, + MAX_SUMMON_BLOOD_ELVES = 4, + MAX_SUMMON_DARK_FIEND = 8 }; -enum Events +uint32 const SummonDarkFiendSpells[MAX_SUMMON_DARK_FIEND] = { - // M'uru - EVENT_DARKNESS = 1, - EVENT_SUMMON_HUMANOIDS, - EVENT_SUMMON_SENTINEL, - EVENT_PHASE_TRANSITION, // Delayed phase transition. - EVENT_ENRAGE, - - // Entropius - EVENT_SUMMON_BLACK_HOLE + SPELL_SUMMON_DARK_FIEND_0, + SPELL_SUMMON_DARK_FIEND_1, + SPELL_SUMMON_DARK_FIEND_2, + SPELL_SUMMON_DARK_FIEND_3, + SPELL_SUMMON_DARK_FIEND_4, + SPELL_SUMMON_DARK_FIEND_5, + SPELL_SUMMON_DARK_FIEND_6, + SPELL_SUMMON_DARK_FIEND_7 }; -enum Phases +uint32 const SummonBloodElvesSpells[MAX_SUMMON_BLOOD_ELVES] = { - PHASE_ONE = 1, - PHASE_TWO, + SPELL_SUMMON_BERSERKER, + SPELL_SUMMON_BERSERKER_2, + SPELL_SUMMON_FURY_MAGE, + SPELL_SUMMON_FURY_MAGE_2 }; -enum CreatureGroups +class VoidSpawnSummon : public BasicEvent { - CREATURE_GROUP_HUMANOIDS, - CREATURE_GROUP_DARKFIENDS + public: + explicit VoidSpawnSummon(Creature* owner) + : _owner(owner) + { + } + + bool Execute(uint64 /*time*/, uint32 /*diff*/) + { + _owner->CastSpell((Unit*)nullptr, SPELL_SUMMON_VOID_SENTINEL, true); + return true; + } + + private: + Creature* _owner; }; class boss_entropius : public CreatureScript @@ -110,53 +141,78 @@ public: void Reset() override { - DoCastAOE(SPELL_NEGATIVE_ENERGY_E); + _Reset(); + DoCast(me, SPELL_ENTROPIUS_COSMETIC_SPAWN, true); } - void EnterCombat(Unit* /*who*/) override + void ScheduleTasks() override { - _EnterCombat(); - DoCastAOE(SPELL_NEGATIVE_ENERGY_E, true); - DoCast(me, SPELL_ENTROPIUS_SPAWN); - events.ScheduleEvent(EVENT_SUMMON_BLACK_HOLE, 15000); + scheduler.Schedule(Milliseconds(2000), [this](TaskContext /*context*/) + { + DoResetPortals(); + DoCastAOE(SPELL_NEGATIVE_ENERGY_PERIODIC_E, true); + }); + + scheduler.Schedule(Seconds(15), [this](TaskContext context) + { + DoCastAOE(SPELL_DARKNESS_E, true); + DoCastAOE(SPELL_BLACKHOLE, true); + + context.Repeat(); + }); } - void JustSummoned(Creature* summoned) override + void JustSummoned(Creature* summon) override { - switch (summoned->GetEntry()) + switch (summon->GetEntry()) { case NPC_DARK_FIENDS: - summoned->CastSpell(summoned, SPELL_DARKFIEND_VISUAL); + summon->CastSpell(summon, SPELL_DARKFIEND_VISUAL); break; case NPC_DARKNESS: - summoned->AddUnitState(UNIT_STATE_STUNNED); - float x, y, z, o; - summoned->GetHomePosition(x, y, z, o); - me->SummonCreature(NPC_DARK_FIENDS, x, y, z, o, TEMPSUMMON_CORPSE_DESPAWN, 0); + summon->SetReactState(REACT_PASSIVE); + summon->CastSpell(summon, SPELL_BLACKHOLE); + summon->CastSpell(summon, SPELL_SUMMON_DARKFIEND_E, true); break; } - summoned->AI()->AttackStart(SelectTarget(SELECT_TARGET_RANDOM, 0, 50, true)); - summons.Summon(summoned); + summons.Summon(summon); } - void ExecuteEvent(uint32 eventId) override + void EnterEvadeMode(EvadeReason /*why*/) override { - if (eventId == EVENT_SUMMON_BLACK_HOLE) - { - if (Unit* random = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) - DoCast(random, SPELL_DARKNESS_E); - if (Unit* random = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) - random->CastSpell(random, SPELL_BLACKHOLE); - events.ScheduleEvent(EVENT_SUMMON_BLACK_HOLE, 15000); - } + if (Creature* muru = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_MURU))) + muru->AI()->EnterEvadeMode(); + + DoResetPortals(); + summons.DespawnAll(); + me->DespawnOrUnsummon(); } - void EnterEvadeMode(EvadeReason /*why*/) override + void JustDied(Unit* /*killer*/) override { + _JustDied(); + if (Creature* muru = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_MURU))) - muru->AI()->Reset(); // Reset encounter. - me->DisappearAndDie(); - summons.DespawnAll(); + muru->DisappearAndDie(); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + scheduler.Update(diff, [this] + { + DoMeleeAttackIfReady(); + }); + } + + void DoResetPortals() + { + std::list<Creature*> portals; + me->GetCreatureListWithEntryInGrid(portals, NPC_MURU_PORTAL_TARGET, 100.0f); + for (Creature* portal : portals) + portal->RemoveAllAuras(); } }; @@ -181,101 +237,96 @@ public: void Initialize() { - DarkFiend = false; - HasEnraged = false; - EntropiusGUID.Clear(); + _hasEnraged = false; + _phase = PHASE_ONE; + _entropiusGUID.Clear(); } void Reset() override { - Initialize(); _Reset(); + Initialize(); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->SetVisible(true); } + void EnterEvadeMode(EvadeReason /*why*/) override + { + BossAI::EnterEvadeMode(); + if (Creature* entropius = ObjectAccessor::GetCreature(*me, _entropiusGUID)) + entropius->AI()->EnterEvadeMode(); + } + + void ScheduleTasks() override + { + scheduler.Schedule(Minutes(10), [this](TaskContext /*context*/) + { + if (Creature* entropius = ObjectAccessor::GetCreature(*me, _entropiusGUID)) + entropius->CastSpell(entropius, SPELL_ENRAGE); + DoCast(me, SPELL_ENRAGE); + _hasEnraged = true; + }); + + scheduler.Schedule(Seconds(10), [this](TaskContext /*context*/) + { + DoCast(me, SPELL_SUMMON_BLOOD_ELVES_SCRIPT, true); + DoCast(me, SPELL_SUMMON_BLOOD_ELVES_PERIODIC, true); + }); + } + void EnterCombat(Unit* /*who*/) override { _EnterCombat(); - events.SetPhase(PHASE_ONE); - events.ScheduleEvent(EVENT_ENRAGE, 600000); - events.ScheduleEvent(EVENT_DARKNESS, 45000, 0, PHASE_ONE); - events.ScheduleEvent(EVENT_SUMMON_HUMANOIDS, 10000, 0, PHASE_ONE); - events.ScheduleEvent(EVENT_SUMMON_SENTINEL, 31500, 0, PHASE_ONE); - DoCastAOE(SPELL_NEGATIVE_ENERGY); + DoCast(me, SPELL_OPEN_PORTAL_PERIODIC, true); + DoCast(me, SPELL_DARKNESS_PERIODIC, true); + DoCast(me, SPELL_NEGATIVE_ENERGY_PERIODIC, true); } void DamageTaken(Unit* /*done_by*/, uint32 &damage) override { - if (damage >= me->GetHealth() && events.IsInPhase(PHASE_ONE)) + if (damage >= me->GetHealth()) { - damage = 0; + damage = me->GetHealth() - 1; + if (_phase != PHASE_ONE) + return; + + _phase = PHASE_TWO; me->RemoveAllAuras(); - DoCast(me, SPELL_OPEN_ALL_PORTALS); + DoCast(me, SPELL_OPEN_ALL_PORTALS, true); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - events.SetPhase(PHASE_TWO); - events.ScheduleEvent(EVENT_PHASE_TRANSITION, 2000); + + scheduler.Schedule(Seconds(6), [this](TaskContext /*context*/) + { + DoCast(me, SPELL_SUMMON_ENTROPIUS, true); + }); } } - void JustSummoned(Creature* summoned) override + void JustSummoned(Creature* summon) override { - switch (summoned->GetEntry()) + if (summon->GetEntry() == NPC_ENTROPIUS) { - case NPC_ENTROPIUS: - me->SetVisible(false); - EntropiusGUID = summoned->GetGUID(); - if (HasEnraged) // If we hit phase transition while enraged, enrage Entropius as well. - summoned->CastSpell(summoned, SPELL_ENRAGE); - break; - case NPC_DARK_FIENDS: - summoned->CastSpell(summoned, SPELL_DARKFIEND_VISUAL); - break; + me->SetVisible(false); + _entropiusGUID = summon->GetGUID(); + if (_hasEnraged) + summon->CastSpell(summon, SPELL_ENRAGE, true); + return; } - summoned->AI()->AttackStart(SelectTarget(SELECT_TARGET_RANDOM, 0, 50, true)); - summons.Summon(summoned); + BossAI::JustSummoned(summon); } - void ExecuteEvent(uint32 eventId) override + void UpdateAI(uint32 diff) override { - switch (eventId) - { - case EVENT_DARKNESS: - if (!DarkFiend) - { - DarkFiend = true; - DoCastAOE(SPELL_DARKNESS); - } - else - me->SummonCreatureGroup(CREATURE_GROUP_DARKFIENDS); - events.ScheduleEvent(EVENT_DARKNESS, DarkFiend ? 3000 : 42000, 0, PHASE_ONE); - break; - case EVENT_SUMMON_HUMANOIDS: - me->SummonCreatureGroup(CREATURE_GROUP_HUMANOIDS); - events.ScheduleEvent(EVENT_SUMMON_HUMANOIDS, 60000, 0, PHASE_ONE); - break; - case EVENT_SUMMON_SENTINEL: - DoCastAOE(SPELL_OPEN_PORTAL_2); - events.ScheduleEvent(EVENT_SUMMON_SENTINEL, 30000, 0, PHASE_ONE); - break; - case EVENT_PHASE_TRANSITION: - DoCast(me, SPELL_SUMMON_ENTROPIUS); - break; - case EVENT_ENRAGE: - if (Creature* entropius = ObjectAccessor::GetCreature(*me, EntropiusGUID)) - entropius->CastSpell(entropius, SPELL_ENRAGE); - DoCast(me, SPELL_ENRAGE); - HasEnraged = true; - break; - default: - break; - } + if (!UpdateVictim()) + return; + + scheduler.Update(diff); } private: - bool DarkFiend; - bool HasEnraged; - ObjectGuid EntropiusGUID; + ObjectGuid _entropiusGUID; + bool _hasEnraged; + uint8 _phase; }; CreatureAI* GetAI(Creature* creature) const override @@ -289,89 +340,50 @@ class npc_muru_portal : public CreatureScript public: npc_muru_portal() : CreatureScript("npc_muru_portal") { } - CreatureAI* GetAI(Creature* creature) const override - { - return GetInstanceAI<npc_muru_portalAI>(creature); - } - struct npc_muru_portalAI : public ScriptedAI { - npc_muru_portalAI(Creature* creature) : ScriptedAI(creature), Summons(creature) - { - Initialize(); - SetCombatMovement(false); - instance = creature->GetInstanceScript(); - } - - void Initialize() - { - SummonTimer = 5000; - - InAction = false; - SummonSentinel = false; - } - - InstanceScript* instance; - - SummonList Summons; - - bool SummonSentinel; - bool InAction; - - uint32 SummonTimer; - - void Reset() override - { - Initialize(); + npc_muru_portalAI(Creature* creature) : ScriptedAI(creature) { } - me->AddUnitState(UNIT_STATE_STUNNED); - - Summons.DespawnAll(); - } - - void JustSummoned(Creature* summoned) override + void JustSummoned(Creature* summon) override { - if (Player* target = ObjectAccessor::GetPlayer(*me, instance->GetGuidData(DATA_PLAYER_GUID))) - summoned->AI()->AttackStart(target); + DoCast(summon, SPELL_SUMMON_VOID_SENTINEL_SUMMONER_VISUAL, true); - Summons.Summon(summoned); + summon->m_Events.AddEvent(new VoidSpawnSummon(summon), summon->m_Events.CalculateTime(1500)); } - void SpellHit(Unit* /*caster*/, const SpellInfo* Spell) override + void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override { - float x, y, z, o; - me->GetHomePosition(x, y, z, o); - me->NearTeleportTo(x, y, z, o); - InAction = true; - switch (Spell->Id) + switch (spell->Id) { case SPELL_OPEN_ALL_PORTALS: - DoCastAOE(SPELL_OPEN_PORTAL); + DoCastAOE(SPELL_OPEN_PORTAL, true); + DoCastAOE(SPELL_TRANSFORM_VISUAL_MISSILE, true); break; case SPELL_OPEN_PORTAL_2: - DoCastAOE(SPELL_OPEN_PORTAL); - SummonSentinel = true; + DoCastAOE(SPELL_OPEN_PORTAL, true); + _scheduler.Schedule(Seconds(6), [this](TaskContext /*context*/) + { + DoCastAOE(SPELL_SUMMON_VOID_SENTINEL_SUMMONER, true); + }); + break; + default: break; } } void UpdateAI(uint32 diff) override { - if (!SummonSentinel) - { - if (InAction && instance->GetBossState(DATA_MURU) == NOT_STARTED) - Reset(); - return; - } - - if (SummonTimer <= diff) - { - DoCastAOE(SPELL_SUMMON_VOID_SENTINEL, false); - SummonTimer = 5000; - SummonSentinel = false; - } else SummonTimer -= diff; + _scheduler.Update(diff); } + + private: + TaskScheduler _scheduler; }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetSunwellPlateauAI<npc_muru_portalAI>(creature); + } }; class npc_dark_fiend : public CreatureScript @@ -379,11 +391,6 @@ class npc_dark_fiend : public CreatureScript public: npc_dark_fiend() : CreatureScript("npc_dark_fiend") { } - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_dark_fiendAI(creature); - } - struct npc_dark_fiendAI : public ScriptedAI { npc_dark_fiendAI(Creature* creature) : ScriptedAI(creature) @@ -393,54 +400,56 @@ public: void Initialize() { - WaitTimer = 2000; - InAction = false; - } + me->SetDisplayId(me->GetCreatureTemplate()->Modelid2); + me->SetReactState(REACT_PASSIVE); + DoCast(me, SPELL_DARKFIEND_SKIN, true); - uint32 WaitTimer; - bool InAction; + _scheduler.Schedule(Seconds(2), [this](TaskContext /*context*/) + { + me->SetReactState(REACT_AGGRESSIVE); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - void Reset() override - { - Initialize(); + if (Creature* _summoner = ObjectAccessor::GetCreature(*me, _summonerGUID)) + if (Unit* target = _summoner->AI()->SelectTarget(SELECT_TARGET_RANDOM, 0)) + AttackStart(target); + }); - me->AddUnitState(UNIT_STATE_STUNNED); + _scheduler.Schedule(Seconds(3), [this](TaskContext context) + { + if (me->IsWithinDist(me->GetVictim(), 5.0f) && me->HasAura(SPELL_DARKFIEND_SKIN)) + { + DoCastAOE(SPELL_DARKFIEND_DAMAGE, false); + me->DisappearAndDie(); + } + + context.Repeat(Milliseconds(500)); + }); } - void SpellHit(Unit* /*caster*/, const SpellInfo* Spell) override + void IsSummonedBy(Unit* summoner) override { - for (uint8 i = 0; i < 3; ++i) - if (Spell->Effects[i].Effect == 38) - me->DisappearAndDie(); + _summonerGUID = summoner->GetGUID(); } - void UpdateAI(uint32 diff) override + bool CanAIAttack(Unit const* /*target*/) const override { - if (!UpdateVictim()) - return; + return me->HasAura(SPELL_DARKFIEND_SKIN); + } - if (WaitTimer <= diff) - { - if (!InAction) - { - me->ClearUnitState(UNIT_STATE_STUNNED); - DoCastAOE(SPELL_DARKFIEND_SKIN, false); - AttackStart(SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)); - InAction = true; - WaitTimer = 500; - } - else - { - if (me->IsWithinDist(me->GetVictim(), 5)) - { - DoCastAOE(SPELL_DARKFIEND_AOE, false); - me->DisappearAndDie(); - } - WaitTimer = 500; - } - } else WaitTimer -= diff; + void UpdateAI(uint32 diff) override + { + _scheduler.Update(diff); } + + private: + TaskScheduler _scheduler; + ObjectGuid _summonerGUID; }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetSunwellPlateauAI<npc_dark_fiendAI>(creature); + } }; class npc_void_sentinel : public CreatureScript @@ -448,63 +457,54 @@ class npc_void_sentinel : public CreatureScript public: npc_void_sentinel() : CreatureScript("npc_void_sentinel") { } - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_void_sentinelAI(creature); - } - struct npc_void_sentinelAI : public ScriptedAI { npc_void_sentinelAI(Creature* creature) : ScriptedAI(creature) { - Initialize(); + _instance = me->GetInstanceScript(); } - void Initialize() + void IsSummonedBy(Unit* /*summoner*/) override { - PulseTimer = 3000; - VoidBlastTimer = 45000; //is this a correct timer? + if (Creature* muru = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_MURU))) + muru->AI()->JustSummoned(me); } - uint32 PulseTimer; - uint32 VoidBlastTimer; - - void Reset() override + void EnterCombat(Unit* /*who*/) override { - Initialize(); + DoCast(me, SPELL_SHADOW_PULSE_PERIODIC, true); - float x, y, z, o; - me->GetHomePosition(x, y, z, o); - me->NearTeleportTo(x, y, 71, o); + _scheduler.Schedule(Seconds(45), [this](TaskContext context) + { + DoCastVictim(SPELL_VOID_BLAST, false); + + context.Repeat(); + }); } - void JustDied(Unit* killer) override + void JustDied(Unit* /*killer*/) override { - for (uint8 i = 0; i < 8; ++i) - if (Creature* temp = me->SummonCreature(NPC_VOID_SPAWN, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), float(rand32() % 6), TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 180000)) - temp->AI()->AttackStart(killer); + for (uint8 i = 0; i < MAX_VOID_SPAWNS; ++i) + DoCastAOE(SPELL_SUMMON_VOID_SPAWN, true); } void UpdateAI(uint32 diff) override { - if (!UpdateVictim()) - return; - - if (PulseTimer <= diff) - { - DoCastAOE(SPELL_SHADOW_PULSE, true); - PulseTimer = 3000; - } else PulseTimer -= diff; - - if (VoidBlastTimer <= diff) + _scheduler.Update(diff, [this] { - DoCastVictim(SPELL_VOID_BLAST, false); - VoidBlastTimer = 45000; - } else VoidBlastTimer -= diff; - - DoMeleeAttackIfReady(); + DoMeleeAttackIfReady(); + }); } + + private: + TaskScheduler _scheduler; + InstanceScript* _instance; }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetSunwellPlateauAI<npc_void_sentinelAI>(creature); + } }; class npc_blackhole : public CreatureScript @@ -512,84 +512,220 @@ class npc_blackhole : public CreatureScript public: npc_blackhole() : CreatureScript("npc_blackhole") { } - CreatureAI* GetAI(Creature* creature) const override - { - return GetInstanceAI<npc_blackholeAI>(creature); - } - struct npc_blackholeAI : public ScriptedAI { npc_blackholeAI(Creature* creature) : ScriptedAI(creature) { - Initialize(); - instance = creature->GetInstanceScript(); + _instance = creature->GetInstanceScript(); } - void Initialize() - { - DespawnTimer = 15000; - SpellTimer = 5000; - Phase = 0; - NeedForAHack = 0; - } - - InstanceScript* instance; - - uint32 DespawnTimer; - uint32 SpellTimer; - uint8 Phase; - uint8 NeedForAHack; - void Reset() override { - Initialize(); + me->SetReactState(REACT_PASSIVE); + DoCast(SPELL_BLACKHOLE_SUMMON_VISUAL); - me->AddUnitState(UNIT_STATE_STUNNED); - DoCastAOE(SPELL_BLACKHOLE_SPAWN, true); - } + _scheduler.Schedule(Seconds(15), [this](TaskContext /*context*/) + { + me->DisappearAndDie(); + }); - void UpdateAI(uint32 diff) override - { - if (SpellTimer <= diff) + _scheduler.Schedule(Seconds(1), [this](TaskContext context) { - Unit* Victim = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_PLAYER_GUID)); - switch (NeedForAHack) + switch (context.GetRepeatCounter()) { case 0: - me->ClearUnitState(UNIT_STATE_STUNNED); - DoCastAOE(SPELL_BLACKHOLE_GROW, false); - if (Victim) - AttackStart(Victim); - SpellTimer = 700; - NeedForAHack = 2; + me->SetReactState(REACT_AGGRESSIVE); + DoCast(SPELL_BLACKHOLE_SUMMON_VISUAL_2); + if (Unit* victim = ObjectAccessor::GetUnit(*me, _instance->GetGuidData(DATA_PLAYER_GUID))) + AttackStart(victim); + context.Repeat(Milliseconds(1200)); break; case 1: - me->AddAura(SPELL_BLACKHOLE_GROW, me); - NeedForAHack = 2; - SpellTimer = 600; + DoCast(SPELL_BLACKHOLE_SUMMON_VISUAL); + context.Repeat(Seconds(2)); break; case 2: - SpellTimer = 400; - NeedForAHack = 3; - me->RemoveAura(SPELL_BLACKHOLE_GROW); + DoCast(SPELL_BLACKHOLE_PASSIVE); + DoCast(SPELL_BLACK_HOLE_VISUAL_2); + break; + default: break; - case 3: - SpellTimer = urand(400, 900); - NeedForAHack = 1; - if (Unit* Temp = me->GetVictim()) - { - if (Temp->GetPositionZ() > 73 && Victim) - AttackStart(Victim); - } else - return; } - } else SpellTimer -= diff; + }); + } - if (DespawnTimer <= diff) - me->DisappearAndDie(); - else DespawnTimer -= diff; + void UpdateAI(uint32 diff) override + { + _scheduler.Update(diff); } + + private: + TaskScheduler _scheduler; + InstanceScript* _instance; }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetSunwellPlateauAI<npc_blackholeAI>(creature); + } +}; + +class spell_summon_blood_elves_script : SpellScriptLoader +{ + public: + spell_summon_blood_elves_script() : SpellScriptLoader("spell_summon_blood_elves_script") { } + + class spell_summon_blood_elves_script_SpellScript : public SpellScript + { + PrepareSpellScript(spell_summon_blood_elves_script_SpellScript); + + bool Validate(SpellInfo const* /*spell*/) override + { + for (uint8 i = 0; i < MAX_SUMMON_BLOOD_ELVES; ++i) + if (!sSpellMgr->GetSpellInfo(SummonBloodElvesSpells[i])) + return false; + return true; + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + for (uint8 i = 0; i < MAX_SUMMON_BLOOD_ELVES; ++i) + GetCaster()->CastSpell((Unit*)nullptr, SummonBloodElvesSpells[urand(0,3)], true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_summon_blood_elves_script_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_summon_blood_elves_script_SpellScript(); + } +}; + +class spell_muru_darkness : SpellScriptLoader +{ + public: + spell_muru_darkness() : SpellScriptLoader("spell_muru_darkness") { } + + class spell_muru_darkness_SpellScript : public SpellScript + { + PrepareSpellScript(spell_muru_darkness_SpellScript); + + bool Validate(SpellInfo const* /*spell*/) override + { + for (uint8 i = 0; i < MAX_SUMMON_DARK_FIEND; ++i) + if (!sSpellMgr->GetSpellInfo(SummonDarkFiendSpells[i])) + return false; + return true; + } + + void HandleAfterCast() + { + for (uint8 i = 0; i < MAX_SUMMON_DARK_FIEND; ++i) + GetCaster()->CastSpell((Unit*)nullptr, SummonDarkFiendSpells[i], true); + } + + void Register() override + { + AfterCast += SpellCastFn(spell_muru_darkness_SpellScript::HandleAfterCast); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_muru_darkness_SpellScript(); + } +}; + +class spell_dark_fiend_skin : public SpellScriptLoader +{ + public: + spell_dark_fiend_skin() : SpellScriptLoader("spell_dark_fiend_skin") { } + + class spell_dark_fiend_skin_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dark_fiend_skin_AuraScript); + + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_ENEMY_SPELL) + return; + + if (Creature* target = GetTarget()->ToCreature()) + { + target->SetReactState(REACT_PASSIVE); + target->AttackStop(); + target->StopMoving(); + target->CastSpell(target, SPELL_DARKFIEND_VISUAL, true); + target->DespawnOrUnsummon(3000); + } + } + + void Register() override + { + AfterEffectRemove += AuraEffectRemoveFn(spell_dark_fiend_skin_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_dark_fiend_skin_AuraScript(); + } +}; + +class spell_transform_visual_missile_periodic : public SpellScriptLoader +{ + public: + spell_transform_visual_missile_periodic() : SpellScriptLoader("spell_transform_visual_missile_periodic") { } + + class spell_transform_visual_missile_periodic_AuraScript : public AuraScript + { + PrepareAuraScript(spell_transform_visual_missile_periodic_AuraScript); + + void OnPeriodic(AuraEffect const* /*aurEff*/) + { + GetTarget()->CastSpell((Unit*)nullptr, RAND(TRANSFORM_VISUAL_MISSILE_1, TRANSFORM_VISUAL_MISSILE_2), true); + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_transform_visual_missile_periodic_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_transform_visual_missile_periodic_AuraScript(); + } +}; + +class spell_summon_blood_elves_periodic : public SpellScriptLoader +{ + public: + spell_summon_blood_elves_periodic() : SpellScriptLoader("spell_summon_blood_elves_periodic") { } + + class spell_summon_blood_elves_periodic_AuraScript : public AuraScript + { + PrepareAuraScript(spell_summon_blood_elves_periodic_AuraScript); + + void OnPeriodic(AuraEffect const* /*aurEff*/) + { + GetTarget()->CastSpell((Unit*)nullptr, SPELL_SUMMON_BLOOD_ELVES_SCRIPT, true); + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_summon_blood_elves_periodic_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_summon_blood_elves_periodic_AuraScript(); + } }; void AddSC_boss_muru() @@ -600,4 +736,9 @@ void AddSC_boss_muru() new npc_dark_fiend(); new npc_void_sentinel(); new npc_blackhole(); + new spell_summon_blood_elves_script(); + new spell_muru_darkness(); + new spell_dark_fiend_skin(); + new spell_transform_visual_missile_periodic(); + new spell_summon_blood_elves_periodic(); } diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/sunwell_plateau.h b/src/server/scripts/EasternKingdoms/SunwellPlateau/sunwell_plateau.h index c6b4ae753a5..7ea0fc4bc7d 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/sunwell_plateau.h +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/sunwell_plateau.h @@ -97,7 +97,8 @@ enum CreatureIds NPC_FURY_MAGE = 25799, NPC_VOID_SENTINEL = 25772, NPC_VOID_SPAWN = 25824, - NPC_BLACK_HOLE = 25855 + NPC_BLACK_HOLE = 25855, + NPC_MURU_PORTAL_TARGET = 25770 }; enum GameObjectIds diff --git a/src/server/scripts/EasternKingdoms/Uldaman/boss_archaedas.cpp b/src/server/scripts/EasternKingdoms/Uldaman/boss_archaedas.cpp index a5fed30a6c6..68391c65655 100644 --- a/src/server/scripts/EasternKingdoms/Uldaman/boss_archaedas.cpp +++ b/src/server/scripts/EasternKingdoms/Uldaman/boss_archaedas.cpp @@ -98,7 +98,7 @@ class boss_archaedas : public CreatureScript instance->SetData(0, 5); // respawn any dead minions me->setFaction(35); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_REMOVE_CLIENT_CONTROL); me->AddAura(SPELL_FREEZE_ANIM, me); } @@ -111,7 +111,7 @@ class boss_archaedas : public CreatureScript DoCast(minion, SPELL_AWAKEN_VAULT_WALKER, flag); minion->CastSpell(minion, SPELL_ARCHAEDAS_AWAKEN, true); minion->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - minion->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); + minion->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_REMOVE_CLIENT_CONTROL); minion->setFaction(14); minion->RemoveAura(SPELL_MINION_FREEZE_ANIM); } @@ -121,7 +121,7 @@ class boss_archaedas : public CreatureScript { me->setFaction(14); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_REMOVE_CLIENT_CONTROL); } void SpellHit(Unit* /*caster*/, const SpellInfo* spell) override @@ -261,7 +261,7 @@ class npc_archaedas_minions : public CreatureScript me->setFaction(35); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_REMOVE_CLIENT_CONTROL); me->RemoveAllAuras(); me->AddAura(SPELL_MINION_FREEZE_ANIM, me); } @@ -271,7 +271,7 @@ class npc_archaedas_minions : public CreatureScript me->setFaction (14); me->RemoveAllAuras(); me->RemoveFlag (UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->RemoveFlag (UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); + me->RemoveFlag (UNIT_FIELD_FLAGS, UNIT_FLAG_REMOVE_CLIENT_CONTROL); bAmIAwake = true; } @@ -350,7 +350,7 @@ class npc_stonekeepers : public CreatureScript { me->setFaction(35); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_REMOVE_CLIENT_CONTROL); me->RemoveAllAuras(); me->AddAura(SPELL_MINION_FREEZE_ANIM, me); } @@ -359,7 +359,7 @@ class npc_stonekeepers : public CreatureScript { me->setFaction(14); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_REMOVE_CLIENT_CONTROL); } void UpdateAI(uint32 /*diff*/) override diff --git a/src/server/scripts/EasternKingdoms/Uldaman/instance_uldaman.cpp b/src/server/scripts/EasternKingdoms/Uldaman/instance_uldaman.cpp index 8c78fb7ff1b..28a3a4eb4e0 100644 --- a/src/server/scripts/EasternKingdoms/Uldaman/instance_uldaman.cpp +++ b/src/server/scripts/EasternKingdoms/Uldaman/instance_uldaman.cpp @@ -147,7 +147,7 @@ class instance_uldaman : public InstanceMapScript creature->setFaction(35); creature->RemoveAllAuras(); creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); + creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_REMOVE_CLIENT_CONTROL); creature->AddAura(SPELL_MINION_FREEZE_ANIM, creature); } @@ -178,7 +178,7 @@ class instance_uldaman : public InstanceMapScript Creature* target = instance->GetCreature(*i); if (!target || !target->IsAlive()) continue; - target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); + target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_REMOVE_CLIENT_CONTROL); target->setFaction(14); target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); target->RemoveAura(SPELL_MINION_FREEZE_ANIM); @@ -202,7 +202,7 @@ class instance_uldaman : public InstanceMapScript Creature* target = instance->GetCreature(*i); if (!target || !target->IsAlive() || target->getFaction() == 14) continue; - target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); + target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_REMOVE_CLIENT_CONTROL); target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); target->setFaction(14); target->RemoveAura(SPELL_MINION_FREEZE_ANIM); @@ -268,7 +268,7 @@ class instance_uldaman : public InstanceMapScript return; ironaya->setFaction(415); - ironaya->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); + ironaya->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_REMOVE_CLIENT_CONTROL); ironaya->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); ironaya->GetMotionMaster()->Clear(); diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp index 8c179af2adf..3697b0876c8 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp @@ -148,6 +148,11 @@ class boss_mandokir : public CreatureScript instance->SaveToDB(); } + void JustReachedHome() override + { + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC); + } + void EnterCombat(Unit* /*who*/) override { _EnterCombat(); @@ -194,9 +199,9 @@ class boss_mandokir : public CreatureScript me->SetWalk(false); if (id == POINT_MANDOKIR_END) { - me->SetHomePosition(PosMandokir[0]); + me->SetHomePosition(PosMandokir[1]); + me->GetMotionMaster()->MoveTargetedHome(); instance->SetBossState(DATA_MANDOKIR, NOT_STARTED); - me->DespawnOrUnsummon(6000); // No idea how to respawn on wipe. } } } diff --git a/src/server/scripts/Kalimdor/BlackfathomDeeps/instance_blackfathom_deeps.cpp b/src/server/scripts/Kalimdor/BlackfathomDeeps/instance_blackfathom_deeps.cpp index b0d6e782052..03c957fa221 100644 --- a/src/server/scripts/Kalimdor/BlackfathomDeeps/instance_blackfathom_deeps.cpp +++ b/src/server/scripts/Kalimdor/BlackfathomDeeps/instance_blackfathom_deeps.cpp @@ -174,7 +174,7 @@ public: if (state == DONE) if (GameObject* go = instance->GetGameObject(shrineOfGelihastGUID)) go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - break; + break; case DATA_AKU_MAI: if (state == DONE) if (GameObject* go = instance->GetGameObject(altarOfTheDeepsGUID)) diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp index 0526dcfa630..8e53ab06ca5 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp @@ -535,12 +535,12 @@ public: if (!UpdateVictim()) return; - /// @todo add his abilities'n-crap here - if (!LowHp && HealthBelowPct(20)) - { - Talk(SAY_TH_RANDOM_LOW_HP); - LowHp = true; - } + /// @todo add his abilities'n-crap here + if (!LowHp && HealthBelowPct(20)) + { + Talk(SAY_TH_RANDOM_LOW_HP); + LowHp = true; + } } }; diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/boss_aeonus.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/boss_aeonus.cpp index 8715f3ca0f6..4d0f80d502d 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/boss_aeonus.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/boss_aeonus.cpp @@ -106,33 +106,33 @@ public: if (!UpdateVictim()) return; - events.Update(diff); + events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - while (uint32 eventId = events.ExecuteEvent()) + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) { - switch (eventId) - { - case EVENT_SANDBREATH: - DoCastVictim(SPELL_SAND_BREATH); - events.ScheduleEvent(EVENT_SANDBREATH, urand(15000, 25000)); - break; - case EVENT_TIMESTOP: - DoCastVictim(SPELL_TIME_STOP); - events.ScheduleEvent(EVENT_TIMESTOP, urand(20000, 35000)); - break; - case EVENT_FRENZY: - Talk(EMOTE_FRENZY); - DoCast(me, SPELL_ENRAGE); - events.ScheduleEvent(EVENT_FRENZY, urand(20000, 35000)); - break; - default: - break; - } + case EVENT_SANDBREATH: + DoCastVictim(SPELL_SAND_BREATH); + events.ScheduleEvent(EVENT_SANDBREATH, urand(15000, 25000)); + break; + case EVENT_TIMESTOP: + DoCastVictim(SPELL_TIME_STOP); + events.ScheduleEvent(EVENT_TIMESTOP, urand(20000, 35000)); + break; + case EVENT_FRENZY: + Talk(EMOTE_FRENZY); + DoCast(me, SPELL_ENRAGE); + events.ScheduleEvent(EVENT_FRENZY, urand(20000, 35000)); + break; + default: + break; } - DoMeleeAttackIfReady(); + } + DoMeleeAttackIfReady(); } }; diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/boss_temporus.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/boss_temporus.cpp index 2befdabe550..844ce239bdf 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/boss_temporus.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/boss_temporus.cpp @@ -107,36 +107,36 @@ public: if (!UpdateVictim()) return; - events.Update(diff); + events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - while (uint32 eventId = events.ExecuteEvent()) + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) { - switch (eventId) - { - case EVENT_HASTE: - DoCast(me, SPELL_HASTE); - events.ScheduleEvent(EVENT_HASTE, urand(20000, 25000)); - break; - case EVENT_MORTAL_WOUND: - DoCast(me, SPELL_MORTAL_WOUND); - events.ScheduleEvent(EVENT_MORTAL_WOUND, urand(10000, 20000)); - break; - case EVENT_WING_BUFFET: - DoCast(me, SPELL_WING_BUFFET); - events.ScheduleEvent(EVENT_WING_BUFFET, urand(20000, 30000)); - break; - case EVENT_SPELL_REFLECTION: // Only in Heroic - DoCast(me, SPELL_REFLECT); - events.ScheduleEvent(EVENT_SPELL_REFLECTION, urand(25000, 35000)); - break; - default: - break; - } + case EVENT_HASTE: + DoCast(me, SPELL_HASTE); + events.ScheduleEvent(EVENT_HASTE, urand(20000, 25000)); + break; + case EVENT_MORTAL_WOUND: + DoCast(me, SPELL_MORTAL_WOUND); + events.ScheduleEvent(EVENT_MORTAL_WOUND, urand(10000, 20000)); + break; + case EVENT_WING_BUFFET: + DoCast(me, SPELL_WING_BUFFET); + events.ScheduleEvent(EVENT_WING_BUFFET, urand(20000, 30000)); + break; + case EVENT_SPELL_REFLECTION: // Only in Heroic + DoCast(me, SPELL_REFLECT); + events.ScheduleEvent(EVENT_SPELL_REFLECTION, urand(25000, 35000)); + break; + default: + break; } - DoMeleeAttackIfReady(); + } + DoMeleeAttackIfReady(); } }; diff --git a/src/server/scripts/Kalimdor/zone_the_barrens.cpp b/src/server/scripts/Kalimdor/zone_the_barrens.cpp index b113615ca50..7a963d066b6 100644 --- a/src/server/scripts/Kalimdor/zone_the_barrens.cpp +++ b/src/server/scripts/Kalimdor/zone_the_barrens.cpp @@ -43,38 +43,37 @@ EndContentData */ ## npc_beaten_corpse ######*/ -#define GOSSIP_CORPSE "Examine corpse in detail..." - enum BeatenCorpse { - QUEST_LOST_IN_BATTLE = 4921 + GOSSIP_OPTION_ID_BEATEN_CORPSE = 0, + GOSSIP_MENU_OPTION_INSPECT_BODY = 2871 }; class npc_beaten_corpse : public CreatureScript { -public: - npc_beaten_corpse() : CreatureScript("npc_beaten_corpse") { } + public: + npc_beaten_corpse() : CreatureScript("npc_beaten_corpse") { } - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF +1) + struct npc_beaten_corpseAI : public ScriptedAI { - player->SEND_GOSSIP_MENU(3558, creature->GetGUID()); - player->TalkedToCreature(creature->GetEntry(), creature->GetGUID()); - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) override - { - if (player->GetQuestStatus(QUEST_LOST_IN_BATTLE) == QUEST_STATUS_INCOMPLETE || player->GetQuestStatus(QUEST_LOST_IN_BATTLE) == QUEST_STATUS_COMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_CORPSE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + npc_beaten_corpseAI(Creature* creature) : ScriptedAI(creature) + { + } - player->SEND_GOSSIP_MENU(3557, creature->GetGUID()); - return true; - } + void sGossipSelect(Player* player, uint32 menuId, uint32 gossipListId) override + { + if (menuId == GOSSIP_MENU_OPTION_INSPECT_BODY && gossipListId == GOSSIP_OPTION_ID_BEATEN_CORPSE) + { + player->CLOSE_GOSSIP_MENU(); + player->TalkedToCreature(me->GetEntry(), me->GetGUID()); + } + } + }; + CreatureAI* GetAI(Creature* creature) const override + { + return new npc_beaten_corpseAI(creature); + } }; /*###### diff --git a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_anubarak.cpp b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_anubarak.cpp index 16cfb30e2dc..2df0fceab9c 100644 --- a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_anubarak.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_anubarak.cpp @@ -156,7 +156,7 @@ public: ImpaleTarget = impaleTarget->GetGUID(); impaleTarget->SetReactState(REACT_PASSIVE); impaleTarget->SetDisplayId(DISPLAY_INVISIBLE); - impaleTarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE|UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE); + impaleTarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_REMOVE_CLIENT_CONTROL|UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE); return impaleTarget; } diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp index abca9a42d45..7f4a2158d25 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp @@ -646,7 +646,7 @@ struct boss_jormungarAI : public BossAI // if the worm was mobile before submerging, make him stationary now if (WasMobile) { - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_REMOVE_CLIENT_CONTROL); SetCombatMovement(false); me->SetDisplayId(ModelStationary); me->CastSpell(me, SPELL_GROUND_VISUAL_1, true); @@ -658,7 +658,7 @@ struct boss_jormungarAI : public BossAI } else { - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_REMOVE_CLIENT_CONTROL); SetCombatMovement(true); me->GetMotionMaster()->MoveChase(me->GetVictim()); me->SetDisplayId(ModelMobile); @@ -1023,7 +1023,7 @@ class boss_icehowl : public CreatureScript me->SetTarget(_trampleTargetGUID); _trampleCast = false; SetCombatMovement(false); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_REMOVE_CLIENT_CONTROL); me->GetMotionMaster()->Clear(); me->GetMotionMaster()->MoveIdle(); events.ScheduleEvent(EVENT_TRAMPLE, 4*IN_MILLISECONDS); @@ -1107,7 +1107,7 @@ class boss_icehowl : public CreatureScript Talk(EMOTE_TRAMPLE_FAIL); } _movementStarted = false; - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_REMOVE_CLIENT_CONTROL); SetCombatMovement(true); me->GetMotionMaster()->MovementExpired(); me->GetMotionMaster()->Clear(); diff --git a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_devourer_of_souls.cpp b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_devourer_of_souls.cpp index 055d0a07f41..94d1d93225c 100644 --- a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_devourer_of_souls.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_devourer_of_souls.cpp @@ -144,7 +144,7 @@ class boss_devourer_of_souls : public CreatureScript void Reset() override { _Reset(); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_REMOVE_CLIENT_CONTROL); me->SetDisplayId(DISPLAY_ANGER); me->SetReactState(REACT_AGGRESSIVE); @@ -297,7 +297,7 @@ class boss_devourer_of_souls : public CreatureScript me->SetTarget(ObjectGuid::Empty); me->GetMotionMaster()->Clear(); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_REMOVE_CLIENT_CONTROL); wailingSoulTick = 15; events.DelayEvents(18000); // no other events during wailing souls @@ -317,7 +317,7 @@ class boss_devourer_of_souls : public CreatureScript { me->SetReactState(REACT_AGGRESSIVE); me->SetDisplayId(DISPLAY_ANGER); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_REMOVE_CLIENT_CONTROL); me->GetMotionMaster()->MoveChase(me->GetVictim()); events.ScheduleEvent(EVENT_WAILING_SOULS, urand(60000, 70000)); } diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp index d77842fff0a..73a7de36580 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp @@ -2461,6 +2461,33 @@ class spell_igb_teleport_players_on_victory : public SpellScriptLoader } }; +// 71201 - Battle Experience - proc should never happen, handled in script +class spell_igb_battle_experience_check : public SpellScriptLoader +{ +public: + spell_igb_battle_experience_check() : SpellScriptLoader("spell_igb_battle_experience_check") { } + + class spell_igb_battle_experience_check_AuraScript : public AuraScript + { + PrepareAuraScript(spell_igb_battle_experience_check_AuraScript); + + bool CheckProc(ProcEventInfo& /*eventInfo*/) + { + return false; + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_igb_battle_experience_check_AuraScript::CheckProc); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_igb_battle_experience_check_AuraScript(); + } +}; + class achievement_im_on_a_boat : public AchievementCriteriaScript { public: @@ -2500,5 +2527,6 @@ void AddSC_boss_icecrown_gunship_battle() new spell_igb_gunship_fall_teleport(); new spell_igb_check_for_players(); new spell_igb_teleport_players_on_victory(); + new spell_igb_battle_experience_check(); new achievement_im_on_a_boat(); } diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp index caa37465165..1a37d5238d2 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp @@ -604,6 +604,7 @@ class npc_ice_tomb : public CreatureScript _trappedPlayerGUID.Clear(); player->RemoveAurasDueToSpell(SPELL_ICE_TOMB_DAMAGE); player->RemoveAurasDueToSpell(SPELL_ASPHYXIATION); + player->RemoveAurasDueToSpell(SPELL_ICE_TOMB_UNTARGETABLE); } } @@ -1284,9 +1285,9 @@ class spell_sindragosa_ice_tomb : public SpellScriptLoader public: spell_sindragosa_ice_tomb() : SpellScriptLoader("spell_sindragosa_ice_tomb_trap") { } - class spell_sindragosa_ice_tomb_SpellScript : public SpellScript + class spell_sindragosa_ice_tomb_AuraScript : public AuraScript { - PrepareSpellScript(spell_sindragosa_ice_tomb_SpellScript); + PrepareAuraScript(spell_sindragosa_ice_tomb_AuraScript); bool Validate(SpellInfo const* /*spell*/) override { @@ -1297,46 +1298,42 @@ class spell_sindragosa_ice_tomb : public SpellScriptLoader return true; } - void SummonTomb() + void PeriodicTick(AuraEffect const* aurEff) { - Position pos = GetHitUnit()->GetPosition(); - if (TempSummon* summon = GetCaster()->SummonCreature(NPC_ICE_TOMB, pos)) + PreventDefaultAction(); + + if (aurEff->GetTickNumber() == 1) { - summon->AI()->SetGUID(GetHitUnit()->GetGUID(), DATA_TRAPPED_PLAYER); - if (GameObject* go = summon->SummonGameObject(GO_ICE_BLOCK, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 0)) + if (Unit* caster = GetCaster()) { - go->SetSpellId(SPELL_ICE_TOMB_DAMAGE); - summon->AddGameObject(go); + Position pos = GetTarget()->GetPosition(); + + if (TempSummon* summon = caster->SummonCreature(NPC_ICE_TOMB, pos)) + { + summon->AI()->SetGUID(GetTarget()->GetGUID(), DATA_TRAPPED_PLAYER); + GetTarget()->CastSpell(GetTarget(), SPELL_ICE_TOMB_UNTARGETABLE); + if (GameObject* go = summon->SummonGameObject(GO_ICE_BLOCK, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 0)) + { + go->SetSpellId(SPELL_ICE_TOMB_DAMAGE); + summon->AddGameObject(go); + } + } } } } - void Register() override - { - AfterHit += SpellHitFn(spell_sindragosa_ice_tomb_SpellScript::SummonTomb); - } - }; - - class spell_sindragosa_ice_tomb_AuraScript : public AuraScript - { - PrepareAuraScript(spell_sindragosa_ice_tomb_AuraScript); - - void PeriodicTick(AuraEffect const* /*aurEff*/) + void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { - PreventDefaultAction(); + GetTarget()->RemoveAurasDueToSpell(SPELL_ICE_TOMB_UNTARGETABLE); } void Register() override { OnEffectPeriodic += AuraEffectPeriodicFn(spell_sindragosa_ice_tomb_AuraScript::PeriodicTick, EFFECT_2, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + AfterEffectRemove += AuraEffectRemoveFn(spell_sindragosa_ice_tomb_AuraScript::HandleRemove, EFFECT_2, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL); } }; - SpellScript* GetSpellScript() const override - { - return new spell_sindragosa_ice_tomb_SpellScript(); - } - AuraScript* GetAuraScript() const override { return new spell_sindragosa_ice_tomb_AuraScript(); diff --git a/src/server/scripts/Northrend/IsleOfConquest/boss_ioc_horde_alliance.cpp b/src/server/scripts/Northrend/IsleOfConquest/boss_ioc_horde_alliance.cpp new file mode 100644 index 00000000000..71d90da21a1 --- /dev/null +++ b/src/server/scripts/Northrend/IsleOfConquest/boss_ioc_horde_alliance.cpp @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "BattlegroundIC.h" + +enum BossSpells +{ + SPELL_BRUTAL_STRIKE = 58460, + SPELL_DAGGER_THROW = 67280, + SPELL_CRUSHING_LEAP = 68506, + SPELL_RAGE = 66776 +}; + +enum BossEvents +{ + EVENT_BRUTAL_STRIKE = 1, + EVENT_DAGGER_THROW = 2, + EVENT_CRUSHING_LEAP = 3, + EVENT_CHECK_RANGE = 4 +}; + +class boss_ioc_horde_alliance : public CreatureScript +{ +public: + boss_ioc_horde_alliance() : CreatureScript("boss_ioc_horde_alliance") { } + + struct boss_ioc_horde_allianceAI : public ScriptedAI + { + boss_ioc_horde_allianceAI(Creature* creature) : ScriptedAI(creature) { } + + void Reset() override + { + _events.Reset(); + + uint32 _npcGuard; + if (me->GetEntry() == NPC_HIGH_COMMANDER_HALFORD_WYRMBANE) + _npcGuard = NPC_SEVEN_TH_LEGION_INFANTRY; + else + _npcGuard = NPC_KOR_KRON_GUARD; + + std::list<Creature*> guardsList; + me->GetCreatureListWithEntryInGrid(guardsList, _npcGuard, 100.0f); + for (std::list<Creature*>::const_iterator itr = guardsList.begin(); itr != guardsList.end(); ++itr) + (*itr)->Respawn(); + }; + + void EnterCombat(Unit* /*who*/) override + { + _events.ScheduleEvent(EVENT_BRUTAL_STRIKE, 5 * IN_MILLISECONDS); + _events.ScheduleEvent(EVENT_DAGGER_THROW, 7 * IN_MILLISECONDS); + _events.ScheduleEvent(EVENT_CHECK_RANGE, 1 * IN_MILLISECONDS); + _events.ScheduleEvent(EVENT_CRUSHING_LEAP, 15 * IN_MILLISECONDS); + } + + void SpellHit(Unit* caster, SpellInfo const* /*spell*/) override + { + if (caster->IsVehicle()) + me->Kill(caster); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_BRUTAL_STRIKE: + DoCastVictim(SPELL_BRUTAL_STRIKE); + _events.ScheduleEvent(EVENT_BRUTAL_STRIKE, 5 * IN_MILLISECONDS); + break; + case EVENT_DAGGER_THROW: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1)) + DoCast(target, SPELL_DAGGER_THROW); + _events.ScheduleEvent(EVENT_DAGGER_THROW, 7 * IN_MILLISECONDS); + break; + case EVENT_CRUSHING_LEAP: + DoCastVictim(SPELL_CRUSHING_LEAP); + _events.ScheduleEvent(EVENT_CRUSHING_LEAP, 25 * IN_MILLISECONDS); + break; + case EVENT_CHECK_RANGE: + if (me->GetDistance(me->GetHomePosition()) > 25.0f) + DoCast(me, SPELL_RAGE); + else + me->RemoveAurasDueToSpell(SPELL_RAGE); + _events.ScheduleEvent(EVENT_CHECK_RANGE, 1 * IN_MILLISECONDS); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } + + private: + EventMap _events; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new boss_ioc_horde_allianceAI(creature); + } +}; + +void AddSC_boss_ioc_horde_alliance() +{ + new boss_ioc_horde_alliance(); +} diff --git a/src/server/scripts/Northrend/isle_of_conquest.cpp b/src/server/scripts/Northrend/IsleOfConquest/isle_of_conquest.cpp index 11cc645f0cb..f7e83ff1f42 100644 --- a/src/server/scripts/Northrend/isle_of_conquest.cpp +++ b/src/server/scripts/Northrend/IsleOfConquest/isle_of_conquest.cpp @@ -259,6 +259,58 @@ class spell_ioc_launch : public SpellScriptLoader } }; +enum SeaforiumBombSpells +{ + SPELL_SEAFORIUM_BLAST = 66676, + SPELL_HUGE_SEAFORIUM_BLAST = 66672, + SPELL_A_BOMB_INABLE_CREDIT = 68366, + SPELL_A_BOMB_INATION_CREDIT = 68367 +}; + +class spell_ioc_seaforium_blast_credit : public SpellScriptLoader +{ + public: + spell_ioc_seaforium_blast_credit() : SpellScriptLoader("spell_ioc_seaforium_blast_credit") { } + + class spell_ioc_seaforium_blast_credit_SpellScript : public SpellScript + { + PrepareSpellScript(spell_ioc_seaforium_blast_credit_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_A_BOMB_INABLE_CREDIT) || !sSpellMgr->GetSpellInfo(SPELL_A_BOMB_INATION_CREDIT)) + return false; + return true; + } + + void HandleAchievementCredit(SpellEffIndex /*effIndex*/) + { + uint32 _creditSpell = 0; + Unit* caster = GetOriginalCaster(); + if (!caster) + return; + + if (GetSpellInfo()->Id == SPELL_SEAFORIUM_BLAST) + _creditSpell = SPELL_A_BOMB_INABLE_CREDIT; + else if (GetSpellInfo()->Id == SPELL_HUGE_SEAFORIUM_BLAST) + _creditSpell = SPELL_A_BOMB_INATION_CREDIT; + + if (GetHitGObj() && GetHitGObj()->IsDestructibleBuilding()) + caster->CastSpell(caster, _creditSpell, true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_ioc_seaforium_blast_credit_SpellScript::HandleAchievementCredit, EFFECT_1, SPELL_EFFECT_GAMEOBJECT_DAMAGE); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_ioc_seaforium_blast_credit_SpellScript(); + } +}; + void AddSC_isle_of_conquest() { new npc_four_car_garage(); @@ -266,4 +318,5 @@ void AddSC_isle_of_conquest() new spell_ioc_gunship_portal(); new spell_ioc_parachute_ic(); new spell_ioc_launch(); + new spell_ioc_seaforium_blast_credit(); } diff --git a/src/server/scripts/Northrend/Naxxramas/boss_gluth.cpp b/src/server/scripts/Northrend/Naxxramas/boss_gluth.cpp index 1e2eb06a2d5..ef6ccf5bf4b 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_gluth.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_gluth.cpp @@ -332,7 +332,7 @@ public: OnEffectHit += SpellEffectFn(spell_gluth_decimate_SpellScript::HandleEvent, EFFECT_2, SPELL_EFFECT_SEND_EVENT); } - bool Load() + bool Load() override { return GetCaster() && GetCaster()->GetEntry() == NPC_GLUTH; } @@ -366,7 +366,7 @@ public: AfterHit += SpellHitFn(spell_gluth_zombiechow_search_SpellScript::HealForEachTargetHit); } - bool Load() + bool Load() override { return GetCaster() && GetCaster()->GetEntry() == NPC_GLUTH; } @@ -393,6 +393,7 @@ public: GluthGUID = creature->GetInstanceScript()->GetGuidData(DATA_GLUTH); DoCast(me, SPELL_INFECTED_WOUND); + timer = 0; state = STATE_ZOMBIE_NORMAL; } diff --git a/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp b/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp index 47807ec28cb..42efdfbfe67 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp @@ -309,7 +309,7 @@ public: _Reset(); me->setFaction(35); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_NOT_SELECTABLE); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_REMOVE_CLIENT_CONTROL | UNIT_FLAG_NOT_SELECTABLE); ResetPlayerScale(); spawns.DespawnAll(); @@ -356,7 +356,7 @@ public: } DoCast(me, SPELL_KELTHUZAD_CHANNEL, false); Talk(SAY_SUMMON_MINIONS); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_NOT_SELECTABLE); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_REMOVE_CLIENT_CONTROL | UNIT_FLAG_NOT_SELECTABLE); me->SetFloatValue(UNIT_FIELD_COMBATREACH, 4); me->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 4); events.SetPhase(PHASE_ONE); @@ -426,7 +426,7 @@ public: Talk(SAY_AGGRO); Talk(EMOTE_PHASE_TWO); spawns.DespawnAll(); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_NOT_SELECTABLE); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_REMOVE_CLIENT_CONTROL | UNIT_FLAG_NOT_SELECTABLE); me->CastStop(); DoStartMovement(me->GetVictim()); diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp index f000d7a3ef7..3d5a6ee8dfb 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp @@ -1224,13 +1224,15 @@ public: void DoAction(int32 /*action*/) override { if (Vehicle* vehicleTemp = me->GetVehicleKit()) + { if (vehicleTemp->GetPassenger(0) && vehicleTemp->GetPassenger(0)->GetTypeId() == TYPEID_PLAYER) { vehicleTemp->RemoveAllPassengers(); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); } + } - me->DespawnOrUnsummon(3*IN_MILLISECONDS); + me->DespawnOrUnsummon(3*IN_MILLISECONDS); } void MovementInform(uint32 type, uint32 id) override diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_ionar.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_ionar.cpp index 8f7687d0fca..55295a534e1 100644 --- a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_ionar.cpp +++ b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_ionar.cpp @@ -113,7 +113,7 @@ public: Initialize(); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_DISABLE_MOVE); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_REMOVE_CLIENT_CONTROL); if (!me->IsVisible()) me->SetVisible(true); @@ -152,7 +152,7 @@ public: me->AttackStop(); me->SetVisible(false); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_DISABLE_MOVE); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_REMOVE_CLIENT_CONTROL); me->GetMotionMaster()->Clear(); me->GetMotionMaster()->MoveIdle(); @@ -236,7 +236,7 @@ public: else if (lSparkList.empty()) { me->SetVisible(true); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_DISABLE_MOVE); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_REMOVE_CLIENT_CONTROL); DoCast(me, SPELL_SPARK_DESPAWN, false); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp index 05beacca638..fa59c021cad 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp @@ -171,8 +171,7 @@ enum FreyaNpcs enum FreyaActions { - ACTION_ELDER_DEATH = 1, - ACTION_ELDER_FREYA_KILLED = 2 + ACTION_ELDER_FREYA_KILLED = 1 }; enum FreyaEvents @@ -619,7 +618,7 @@ class boss_freya : public CreatureScript Elder->AttackStop(); Elder->CombatStop(true); Elder->DeleteThreatList(); - Elder->GetAI()->DoAction(ACTION_ELDER_FREYA_KILLED); + Elder->AI()->DoAction(ACTION_ELDER_FREYA_KILLED); } } } @@ -705,19 +704,10 @@ class boss_elder_brightleaf : public CreatureScript Talk(SAY_ELDER_SLAY); } - void JustDied(Unit* killer) override + void JustDied(Unit* /*killer*/) override { _JustDied(); Talk(SAY_ELDER_DEATH); - - if (killer->GetTypeId() == TYPEID_PLAYER) - { - if (Creature* Ironbranch = ObjectAccessor::GetCreature(*me, instance->GetGuidData(BOSS_IRONBRANCH))) - Ironbranch->AI()->DoAction(ACTION_ELDER_DEATH); - - if (Creature* Stonebark = ObjectAccessor::GetCreature(*me, instance->GetGuidData(BOSS_STONEBARK))) - Stonebark->AI()->DoAction(ACTION_ELDER_DEATH); - } } void EnterCombat(Unit* /*who*/) override @@ -812,19 +802,10 @@ class boss_elder_stonebark : public CreatureScript Talk(SAY_ELDER_SLAY); } - void JustDied(Unit* killer) override + void JustDied(Unit* /*killer*/) override { _JustDied(); Talk(SAY_ELDER_DEATH); - - if (killer->GetTypeId() == TYPEID_PLAYER) - { - if (Creature* Ironbranch = ObjectAccessor::GetCreature(*me, instance->GetGuidData(BOSS_IRONBRANCH))) - Ironbranch->AI()->DoAction(ACTION_ELDER_DEATH); - - if (Creature* Brightleaf = ObjectAccessor::GetCreature(*me, instance->GetGuidData(BOSS_BRIGHTLEAF))) - Brightleaf->AI()->DoAction(ACTION_ELDER_DEATH); - } } void EnterCombat(Unit* /*who*/) override @@ -925,19 +906,10 @@ class boss_elder_ironbranch : public CreatureScript Talk(SAY_ELDER_SLAY); } - void JustDied(Unit* killer) override + void JustDied(Unit* /*killer*/) override { _JustDied(); Talk(SAY_ELDER_DEATH); - - if (killer->GetTypeId() == TYPEID_PLAYER) - { - if (Creature* Brightleaf = ObjectAccessor::GetCreature(*me, instance->GetGuidData(BOSS_BRIGHTLEAF))) - Brightleaf->AI()->DoAction(ACTION_ELDER_DEATH); - - if (Creature* Stonebark = ObjectAccessor::GetCreature(*me, instance->GetGuidData(BOSS_STONEBARK))) - Stonebark->AI()->DoAction(ACTION_ELDER_DEATH); - } } void EnterCombat(Unit* /*who*/) override diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_general_vezax.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_general_vezax.cpp index 09d95b34521..cbd24141bdf 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_general_vezax.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_general_vezax.cpp @@ -415,7 +415,7 @@ class npc_saronite_vapors : public CreatureScript if (damage >= me->GetHealth()) { damage = 0; - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_DISABLE_MOVE); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_REMOVE_CLIENT_CONTROL); me->SetStandState(UNIT_STAND_STATE_DEAD); me->SetHealth(me->GetMaxHealth()); me->RemoveAllAuras(); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp index c35a5936822..86068a1ecba 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp @@ -184,7 +184,7 @@ class npc_flash_freeze : public CreatureScript Initialize(); instance = me->GetInstanceScript(); me->SetDisplayId(me->GetCreatureTemplate()->Modelid2); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_STUNNED | UNIT_FLAG_PACIFIED); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_REMOVE_CLIENT_CONTROL | UNIT_FLAG_STUNNED | UNIT_FLAG_PACIFIED); } void Initialize() @@ -259,7 +259,7 @@ class npc_ice_block : public CreatureScript { instance = me->GetInstanceScript(); me->SetDisplayId(me->GetCreatureTemplate()->Modelid2); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_STUNNED | UNIT_FLAG_PACIFIED); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_REMOVE_CLIENT_CONTROL | UNIT_FLAG_STUNNED | UNIT_FLAG_PACIFIED); } InstanceScript* instance; @@ -269,7 +269,7 @@ class npc_ice_block : public CreatureScript void IsSummonedBy(Unit* summoner) override { targetGUID = summoner->GetGUID(); - summoner->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_STUNNED | UNIT_FLAG_PACIFIED); + summoner->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_REMOVE_CLIENT_CONTROL | UNIT_FLAG_STUNNED | UNIT_FLAG_PACIFIED); me->SetInCombatWith(summoner); me->AddThreat(summoner, 250.0f); summoner->AddThreat(me, 250.0f); @@ -285,7 +285,7 @@ class npc_ice_block : public CreatureScript { if (Creature* Helper = ObjectAccessor::GetCreature(*me, targetGUID)) { - Helper->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_STUNNED | UNIT_FLAG_PACIFIED); + Helper->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_REMOVE_CLIENT_CONTROL | UNIT_FLAG_STUNNED | UNIT_FLAG_PACIFIED); if (Creature* Hodir = ObjectAccessor::GetCreature(*me, instance->GetGuidData(BOSS_HODIR))) { @@ -388,7 +388,7 @@ class boss_hodir : public CreatureScript me->RemoveAllAttackers(); me->AttackStop(); me->SetReactState(REACT_PASSIVE); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_REMOVE_CLIENT_CONTROL); me->InterruptNonMeleeSpells(true); me->StopMoving(); me->GetMotionMaster()->Clear(); @@ -539,7 +539,7 @@ class npc_icicle : public CreatureScript { Initialize(); me->SetDisplayId(me->GetCreatureTemplate()->Modelid1); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_PACIFIED | UNIT_FLAG_NOT_SELECTABLE); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_REMOVE_CLIENT_CONTROL | UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_PACIFIED | UNIT_FLAG_NOT_SELECTABLE); me->SetReactState(REACT_PASSIVE); } @@ -593,7 +593,7 @@ class npc_snowpacked_icicle : public CreatureScript { Initialize(); me->SetDisplayId(me->GetCreatureTemplate()->Modelid2); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_PACIFIED); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_REMOVE_CLIENT_CONTROL | UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_PACIFIED); me->SetReactState(REACT_PASSIVE); } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.cpp index cd214a0114f..7106e9e4ebe 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.cpp @@ -178,7 +178,7 @@ class boss_ignis : public CreatureScript { summon->setFaction(16); summon->SetReactState(REACT_AGGRESSIVE); - summon->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_PACIFIED | UNIT_FLAG_STUNNED | UNIT_FLAG_DISABLE_MOVE); + summon->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_PACIFIED | UNIT_FLAG_STUNNED | UNIT_FLAG_REMOVE_CLIENT_CONTROL); } summon->AI()->AttackStart(me->GetVictim()); @@ -375,7 +375,7 @@ class npc_scorch_ground : public CreatureScript npc_scorch_groundAI(Creature* creature) : ScriptedAI(creature) { Initialize(); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE |UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_PACIFIED); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_REMOVE_CLIENT_CONTROL |UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_PACIFIED); creature->SetDisplayId(16925); //model 2 in db cannot overwrite wdb fields } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp index 470ad388fff..45d4fa58a03 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp @@ -104,7 +104,7 @@ class boss_kologarn : public CreatureScript left(false), right(false) { me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_REMOVE_CLIENT_CONTROL); DoCast(SPELL_KOLOGARN_REDUCE_PARRY); SetCombatMovement(false); diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_palehoof.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_palehoof.cpp index ee71c696d7c..3dec0c60991 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_palehoof.cpp +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_palehoof.cpp @@ -102,7 +102,7 @@ public: Sequence[i] = Phase(i); /// This ensures a random order and only executes each phase once. - std::random_shuffle(Sequence, Sequence + PHASE_GORTOK_PALEHOOF); + Trinity::Containers::RandomShuffle(Sequence); uiArcingSmashTimer = 15000; uiImpaleTimer = 12000; @@ -118,7 +118,7 @@ public: uint32 uiWhiteringRoarTimer; Phase currentPhase; uint8 AddCount; - Phase Sequence[4]; + std::array<Phase, 4> Sequence; void Reset() override { diff --git a/src/server/scripts/Northrend/VaultOfArchavon/boss_toravon.cpp b/src/server/scripts/Northrend/VaultOfArchavon/boss_toravon.cpp index 06ebcbdc2fb..e7305e53808 100644 --- a/src/server/scripts/Northrend/VaultOfArchavon/boss_toravon.cpp +++ b/src/server/scripts/Northrend/VaultOfArchavon/boss_toravon.cpp @@ -247,7 +247,7 @@ class npc_frozen_orb_stalker : public CreatureScript npc_frozen_orb_stalkerAI(Creature* creature) : ScriptedAI(creature) { creature->SetVisible(false); - creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE); + creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_REMOVE_CLIENT_CONTROL); creature->SetReactState(REACT_PASSIVE); instance = creature->GetInstanceScript(); diff --git a/src/server/scripts/Northrend/northrend_script_loader.cpp b/src/server/scripts/Northrend/northrend_script_loader.cpp index 7d104b85f6d..d84bb1c4072 100644 --- a/src/server/scripts/Northrend/northrend_script_loader.cpp +++ b/src/server/scripts/Northrend/northrend_script_loader.cpp @@ -178,6 +178,8 @@ void AddSC_boss_baltharus_the_warborn(); void AddSC_boss_saviana_ragefire(); void AddSC_boss_general_zarithrian(); void AddSC_boss_halion(); +void AddSC_isle_of_conquest(); // Isle of Conquest +void AddSC_boss_ioc_horde_alliance(); void AddSC_dalaran(); void AddSC_borean_tundra(); @@ -190,7 +192,6 @@ void AddSC_storm_peaks(); void AddSC_wintergrasp(); void AddSC_zuldrak(); void AddSC_crystalsong_forest(); -void AddSC_isle_of_conquest(); // The name of this function should match: // void Add${NameOfDirectory}Scripts() @@ -358,6 +359,8 @@ void AddNorthrendScripts() AddSC_boss_saviana_ragefire(); AddSC_boss_general_zarithrian(); AddSC_boss_halion(); + AddSC_isle_of_conquest(); // Isle of Conquest + AddSC_boss_ioc_horde_alliance(); AddSC_dalaran(); AddSC_borean_tundra(); @@ -370,5 +373,4 @@ void AddNorthrendScripts() AddSC_wintergrasp(); AddSC_zuldrak(); AddSC_crystalsong_forest(); - AddSC_isle_of_conquest(); } diff --git a/src/server/scripts/Northrend/zone_grizzly_hills.cpp b/src/server/scripts/Northrend/zone_grizzly_hills.cpp index 59802165a94..adade245c2b 100644 --- a/src/server/scripts/Northrend/zone_grizzly_hills.cpp +++ b/src/server/scripts/Northrend/zone_grizzly_hills.cpp @@ -22,6 +22,7 @@ #include "Player.h" #include "SpellScript.h" #include "CreatureTextMgr.h" +#include "CombatAI.h" /*###### ## Quest 12027: Mr. Floppy's Perilous Adventure @@ -854,6 +855,260 @@ class spell_infected_worgen_bite : public SpellScriptLoader } }; +/*###### +## Quest: Riding the Red Rocket +######*/ + +enum RedRocket +{ + SPELL_VEHICLE_WARHEAD_FUSE = 49107, + SPELL_ALLIANCE_KILL_CREDIT_TORPEDO = 49510, + SPELL_HORDE_KILL_CREDIT_TORPEDO = 49340, + NPC_HORDE_LUMBERBOAT = 27702, + NPC_ALLIANCE_LUMBERBOAT = 27688, + SPELL_DETONATE = 49250 +}; + +class npc_rocket_propelled_warhead : public CreatureScript +{ +public: + npc_rocket_propelled_warhead() : CreatureScript("npc_rocket_propelled_warhead") { } + + struct npc_rocket_propelled_warheadAI : public VehicleAI + { + npc_rocket_propelled_warheadAI(Creature* creature) : VehicleAI(creature) + { + _finished = false; + _faction = ALLIANCE; + } + + void PassengerBoarded(Unit* who, int8 /*seatId*/, bool apply) override + { + if (apply && who->ToPlayer()) + { + DoCast(me, SPELL_VEHICLE_WARHEAD_FUSE); + _faction = who->ToPlayer()->GetTeam(); + } + } + + void JustReachedHome() override + { + _finished = false; + me->SetVisible(true); + me->GetMotionMaster()->Clear(true); + } + + void DoAction(int32 /*action*/) override + { + FinishQuest(false, _faction); + } + + void SpellHit(Unit* caster, SpellInfo const* /*spellInfo*/) override + { + if (caster->GetEntry() == NPC_HORDE_LUMBERBOAT || caster->GetEntry() == NPC_ALLIANCE_LUMBERBOAT) + FinishQuest(true, _faction); + } + + void FinishQuest(bool success, uint32 faction) + { + if (_finished) + return; + + _finished = true; + + if (success) + DoCast(me, faction == ALLIANCE ? SPELL_ALLIANCE_KILL_CREDIT_TORPEDO : SPELL_HORDE_KILL_CREDIT_TORPEDO); + + DoCast(me, SPELL_DETONATE); + me->RemoveAllAuras(); + me->SetVisible(false); + me->GetMotionMaster()->MoveTargetedHome(); + } + + private: + uint32 _faction; + bool _finished; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return new npc_rocket_propelled_warheadAI(creature); + } +}; + +enum WarheadSpells +{ + SPELL_WARHEAD_Z_CHECK = 61678, + SPELL_WARHEAD_SEEKING_LUMBERSHIP = 49331, + SPELL_WARHEAD_FUSE = 49181 +}; +// 49107 - Vehicle: Warhead Fuse +class spell_vehicle_warhead_fuse : public SpellScriptLoader +{ +public: + spell_vehicle_warhead_fuse() : SpellScriptLoader("spell_vehicle_warhead_fuse") { } + + class spell_vehicle_warhead_fuse_SpellScript : public SpellScript + { + PrepareSpellScript(spell_vehicle_warhead_fuse_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_WARHEAD_Z_CHECK) || !sSpellMgr->GetSpellInfo(SPELL_WARHEAD_SEEKING_LUMBERSHIP) || !sSpellMgr->GetSpellInfo(SPELL_WARHEAD_FUSE)) + return false; + return true; + } + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + + caster->CastSpell(caster, SPELL_WARHEAD_Z_CHECK, true); + caster->CastSpell(caster, SPELL_WARHEAD_SEEKING_LUMBERSHIP, true); + caster->CastSpell(caster, SPELL_WARHEAD_FUSE, true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_vehicle_warhead_fuse_SpellScript::HandleDummy, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_vehicle_warhead_fuse_SpellScript(); + } +}; + +enum WarheadDenonate +{ + SPELL_PARACHUTE = 66154, + SPELL_TORPEDO_EXPLOSION = 49290, + NPC_ALLIANCE_LUMBERBOAT_EXPLOSIONS = 27689 +}; +// 49250 - Detonate +class spell_warhead_detonate : public SpellScriptLoader +{ +public: + spell_warhead_detonate() : SpellScriptLoader("spell_warhead_detonate") { } + + class spell_warhead_detonate_SpellScript : public SpellScript + { + PrepareSpellScript(spell_warhead_detonate_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_PARACHUTE) || !sSpellMgr->GetSpellInfo(SPELL_TORPEDO_EXPLOSION)) + return false; + return true; + } + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + Player* player = GetHitPlayer(); + if (!player) + return; + + player->ExitVehicle(); + float horizontalSpeed = 3.0f; + float verticalSpeed = 40.0f; + player->KnockbackFrom(caster->GetPositionX(), caster->GetPositionY(), horizontalSpeed, verticalSpeed); + caster->CastSpell(player, SPELL_PARACHUTE, true); + + std::list<Creature*> explosionBunnys; + caster->GetCreatureListWithEntryInGrid(explosionBunnys, NPC_ALLIANCE_LUMBERBOAT_EXPLOSIONS, 90.0f); + for (std::list<Creature*>::const_iterator itr = explosionBunnys.begin(); itr != explosionBunnys.end(); ++itr) + (*itr)->CastSpell((*itr), SPELL_TORPEDO_EXPLOSION, true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_warhead_detonate_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_warhead_detonate_SpellScript(); + } +}; + +// 61678 - Z Check +class spell_z_check : public SpellScriptLoader +{ +public: + spell_z_check() : SpellScriptLoader("spell_z_check") { } + + class spell_z_check_AuraScript : public AuraScript + { + PrepareAuraScript(spell_z_check_AuraScript); + + public: + spell_z_check_AuraScript() + { + _posZ = 0.0f; + } + + void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + _posZ = GetTarget()->GetPositionZ(); + } + + void HandleEffectPeriodic(AuraEffect const* /*aurEff*/) + { + PreventDefaultAction(); + + if (_posZ != GetTarget()->GetPositionZ()) + if (Creature* target = GetTarget()->ToCreature()) + target->AI()->DoAction(0); + } + + private: + float _posZ; + + void Register() override + { + OnEffectApply += AuraEffectApplyFn(spell_z_check_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL); + OnEffectPeriodic += AuraEffectPeriodicFn(spell_z_check_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_z_check_AuraScript(); + } +}; + +// 49181 - Warhead Fuse +class spell_warhead_fuse : public SpellScriptLoader +{ +public: + spell_warhead_fuse() : SpellScriptLoader("spell_warhead_fuse") { } + + class spell_warhead_fuse_AuraScript : public AuraScript + { + PrepareAuraScript(spell_warhead_fuse_AuraScript); + + void HandleOnEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Unit* rocketUnit = GetTarget()->GetVehicleBase()) + if (Creature* rocketCrea = rocketUnit->ToCreature()) + rocketCrea->AI()->DoAction(0); + } + + void Register() override + { + OnEffectRemove += AuraEffectRemoveFn(spell_warhead_fuse_AuraScript::HandleOnEffectRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_warhead_fuse_AuraScript(); + } +}; + void AddSC_grizzly_hills() { new npc_emily(); @@ -866,4 +1121,9 @@ void AddSC_grizzly_hills() new npc_lake_frog(); new spell_shredder_delivery(); new spell_infected_worgen_bite(); + new npc_rocket_propelled_warhead(); + new spell_z_check(); + new spell_warhead_detonate(); + new spell_vehicle_warhead_fuse(); + new spell_warhead_fuse(); } diff --git a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp index 3c651e10a1e..14aeda04a7e 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp @@ -1301,15 +1301,17 @@ public: EventMaiev Event = EVENT_MAIEV_NULL; for (uint8 i = 1; i <= MaxTimer; ++i) + { if (Timer[i]) { if (Timer[i] <= diff) Event = (EventMaiev)i; else Timer[i] -= diff; } + } - switch (Event) - { + switch (Event) + { case EVENT_MAIEV_STEALTH: { me->SetFullHealth(); @@ -1345,21 +1347,21 @@ public: break; default: break; - } + } - if (HealthBelowPct(50)) - { - me->SetVisible(false); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - if (Creature* illidan = ObjectAccessor::GetCreature(*me, IllidanGUID)) - ENSURE_AI(boss_illidan_stormrage::boss_illidan_stormrageAI, illidan->AI())->DeleteFromThreatList(me->GetGUID()); - me->AttackStop(); - Timer[EVENT_MAIEV_STEALTH] = 60000; // reappear after 1 minute - MaxTimer = 1; - } + if (HealthBelowPct(50)) + { + me->SetVisible(false); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + if (Creature* illidan = ObjectAccessor::GetCreature(*me, IllidanGUID)) + ENSURE_AI(boss_illidan_stormrage::boss_illidan_stormrageAI, illidan->AI())->DeleteFromThreatList(me->GetGUID()); + me->AttackStop(); + Timer[EVENT_MAIEV_STEALTH] = 60000; // reappear after 1 minute + MaxTimer = 1; + } - if (Phase == PHASE_NORMAL_MAIEV) - DoMeleeAttackIfReady(); + if (Phase == PHASE_NORMAL_MAIEV) + DoMeleeAttackIfReady(); } private: diff --git a/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/boss_ahune.cpp b/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/boss_ahune.cpp index 9b53b62cdee..5a7a7786c6a 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/boss_ahune.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/boss_ahune.cpp @@ -174,7 +174,7 @@ public: void Initialize() { - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_REMOVE_CLIENT_CONTROL); } void EnterCombat(Unit* /*who*/) override @@ -308,7 +308,7 @@ public: void Initialize() { me->SetReactState(REACT_PASSIVE); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_REMOVE_CLIENT_CONTROL); DoCast(me, SPELL_FROZEN_CORE_GETS_HIT); DoCast(me, SPELL_ICE_SPEAR_AURA); } @@ -341,7 +341,7 @@ public: { _events.Reset(); DoCast(me, SPELL_ICE_SPEAR_AURA); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_DISABLE_MOVE); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_REMOVE_CLIENT_CONTROL); } } @@ -542,6 +542,7 @@ public: npc_earthen_ring_flamecallerAI(Creature* creature) : ScriptedAI(creature) { _instance = me->GetInstanceScript(); + _mySpot = 0; } void Reset() override @@ -888,7 +889,7 @@ public: GetCaster()->CastSpell(GetHitUnit(), SPELL_SUMMON_ICE_SPEAR_BUNNY, true); } - void Register() + void Register() override { OnEffectHitTarget += SpellEffectFn(spell_ice_spear_target_picker_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } diff --git a/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/instance_the_slave_pens.cpp b/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/instance_the_slave_pens.cpp index 0d85a8f0d86..0fac7b5a39d 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/instance_the_slave_pens.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/instance_the_slave_pens.cpp @@ -81,7 +81,7 @@ public: } } - void SetGuidData(uint32 data, ObjectGuid guid) + void SetGuidData(uint32 data, ObjectGuid guid) override { switch (data) { diff --git a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_nethekurse.cpp b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_nethekurse.cpp index 499550945c6..2592ed3b262 100644 --- a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_nethekurse.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_nethekurse.cpp @@ -180,24 +180,23 @@ class boss_grand_warlock_nethekurse : public CreatureScript } void MoveInLineOfSight(Unit* who) override - { if (!IntroOnce && me->IsWithinDistInMap(who, 30.0f)) - { + { if (who->GetTypeId() != TYPEID_PLAYER) return; - Talk(SAY_INTRO); - IntroOnce = true; - IsIntroEvent = true; + Talk(SAY_INTRO); + IntroOnce = true; + IsIntroEvent = true; - instance->SetBossState(DATA_NETHEKURSE, IN_PROGRESS); - } + instance->SetBossState(DATA_NETHEKURSE, IN_PROGRESS); + } - if (IsIntroEvent || !IsMainEvent) - return; + if (IsIntroEvent || !IsMainEvent) + return; - ScriptedAI::MoveInLineOfSight(who); + ScriptedAI::MoveInLineOfSight(who); } void EnterCombat(Unit* /*who*/) override diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp index 9fd1c5c7388..30b3fd67687 100644 --- a/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp +++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp @@ -325,86 +325,85 @@ class boss_high_astromancer_solarian : public CreatureScript else Phase1_Timer-=diff; } - else - if (Phase == 2) + else if (Phase == 2) + { + //10 seconds after Solarian disappears, 12 mobs spawn out of the three portals. + me->AttackStop(); + me->StopMoving(); + if (Phase2_Timer <= diff) { - //10 seconds after Solarian disappears, 12 mobs spawn out of the three portals. - me->AttackStop(); - me->StopMoving(); - if (Phase2_Timer <= diff) - { - Phase = 3; - for (int i=0; i <= 2; ++i) - for (int j=1; j <= 4; j++) - SummonMinion(NPC_SOLARIUM_AGENT, Portals[i][0], Portals[i][1], Portals[i][2]); + Phase = 3; + for (int i=0; i <= 2; ++i) + for (int j=1; j <= 4; j++) + SummonMinion(NPC_SOLARIUM_AGENT, Portals[i][0], Portals[i][1], Portals[i][2]); - Talk(SAY_SUMMON1); - Phase2_Timer = 10000; - } - else - Phase2_Timer -= diff; + Talk(SAY_SUMMON1); + Phase2_Timer = 10000; } else - if (Phase == 3) - { - me->AttackStop(); - me->StopMoving(); - //Check Phase3_Timer - if (Phase3_Timer <= diff) - { - Phase = 1; - //15 seconds later Solarian reappears out of one of the 3 portals. Simultaneously, 2 healers appear in the two other portals. - int i = rand32() % 3; - me->GetMotionMaster()->Clear(); - me->SetPosition(Portals[i][0], Portals[i][1], Portals[i][2], CENTER_O); - - for (int j=0; j <= 2; j++) - if (j != i) - SummonMinion(NPC_SOLARIUM_PRIEST, Portals[j][0], Portals[j][1], Portals[j][2]); - - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->SetVisible(true); - - Talk(SAY_SUMMON2); - AppearDelay = true; - Phase3_Timer = 15000; - } - else - Phase3_Timer -= diff; - } - else - if (Phase == 4) - { - //Fear_Timer - if (Fear_Timer <= diff) - { - DoCast(me, SPELL_FEAR); - Fear_Timer = 20000; - } - else - Fear_Timer -= diff; - //VoidBolt_Timer - if (VoidBolt_Timer <= diff) - { - DoCastVictim(SPELL_VOID_BOLT); - VoidBolt_Timer = 10000; - } - else - VoidBolt_Timer -= diff; - } - //When Solarian reaches 20% she will transform into a huge void walker. - if (Phase != 4 && me->HealthBelowPct(20)) - { - Phase = 4; - //To make sure she wont be invisible or not selecatble - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->SetVisible(true); - Talk(SAY_VOIDA); - Talk(SAY_VOIDB); - me->SetArmor(WV_ARMOR); - me->SetDisplayId(MODEL_VOIDWALKER); - me->SetObjectScale(defaultsize*2.5f); - } + Phase2_Timer -= diff; + } + else if (Phase == 3) + { + me->AttackStop(); + me->StopMoving(); + //Check Phase3_Timer + if (Phase3_Timer <= diff) + { + Phase = 1; + //15 seconds later Solarian reappears out of one of the 3 portals. Simultaneously, 2 healers appear in the two other portals. + int i = rand32() % 3; + me->GetMotionMaster()->Clear(); + me->SetPosition(Portals[i][0], Portals[i][1], Portals[i][2], CENTER_O); + + for (int j=0; j <= 2; j++) + if (j != i) + SummonMinion(NPC_SOLARIUM_PRIEST, Portals[j][0], Portals[j][1], Portals[j][2]); + + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + me->SetVisible(true); + + Talk(SAY_SUMMON2); + AppearDelay = true; + Phase3_Timer = 15000; + } + else + Phase3_Timer -= diff; + } + else if (Phase == 4) + { + //Fear_Timer + if (Fear_Timer <= diff) + { + DoCast(me, SPELL_FEAR); + Fear_Timer = 20000; + } + else + Fear_Timer -= diff; + //VoidBolt_Timer + if (VoidBolt_Timer <= diff) + { + DoCastVictim(SPELL_VOID_BOLT); + VoidBolt_Timer = 10000; + } + else + VoidBolt_Timer -= diff; + } + + //When Solarian reaches 20% she will transform into a huge void walker. + if (Phase != 4 && me->HealthBelowPct(20)) + { + Phase = 4; + //To make sure she wont be invisible or not selecatble + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + me->SetVisible(true); + Talk(SAY_VOIDA); + Talk(SAY_VOIDB); + me->SetArmor(WV_ARMOR); + me->SetDisplayId(MODEL_VOIDWALKER); + me->SetObjectScale(defaultsize*2.5f); + } + DoMeleeAttackIfReady(); } }; diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp index 724019a1b19..980c0db19cc 100644 --- a/src/server/scripts/Spells/spell_dk.cpp +++ b/src/server/scripts/Spells/spell_dk.cpp @@ -30,6 +30,13 @@ enum DeathKnightSpells { + SPELL_DK_ACCLIMATION_HOLY = 50490, + SPELL_DK_ACCLIMATION_FIRE = 50362, + SPELL_DK_ACCLIMATION_FROST = 50485, + SPELL_DK_ACCLIMATION_ARCANE = 50486, + SPELL_DK_ACCLIMATION_SHADOW = 50489, + SPELL_DK_ACCLIMATION_NATURE = 50488, + SPELL_DK_ADVANTAGE_T10_4P_MELEE = 70657, SPELL_DK_ANTI_MAGIC_SHELL_TALENT = 51052, SPELL_DK_BLACK_ICE_R1 = 49140, SPELL_DK_BLOOD_BOIL_TRIGGERED = 65658, @@ -51,6 +58,7 @@ enum DeathKnightSpells SPELL_DK_IMPROVED_BLOOD_PRESENCE_R1 = 50365, SPELL_DK_IMPROVED_FROST_PRESENCE_R1 = 50384, SPELL_DK_IMPROVED_UNHOLY_PRESENCE_R1 = 50391, + SPELL_DK_IMPROVED_BLOOD_PRESENCE_HEAL = 50475, SPELL_DK_IMPROVED_BLOOD_PRESENCE_TRIGGERED = 63611, SPELL_DK_IMPROVED_UNHOLY_PRESENCE_TRIGGERED = 63622, SPELL_DK_ITEM_SIGIL_VENGEFUL_HEART = 64962, @@ -78,6 +86,141 @@ enum Misc NPC_DK_GHOUL = 26125 }; +// -49200 - Acclimation +class spell_dk_acclimation : public SpellScriptLoader +{ +public: + spell_dk_acclimation() : SpellScriptLoader("spell_dk_acclimation") { } + + class spell_dk_acclimation_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dk_acclimation_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_DK_ACCLIMATION_HOLY) || + !sSpellMgr->GetSpellInfo(SPELL_DK_ACCLIMATION_FIRE) || + !sSpellMgr->GetSpellInfo(SPELL_DK_ACCLIMATION_FROST) || + !sSpellMgr->GetSpellInfo(SPELL_DK_ACCLIMATION_NATURE) || + !sSpellMgr->GetSpellInfo(SPELL_DK_ACCLIMATION_SHADOW) || + !sSpellMgr->GetSpellInfo(SPELL_DK_ACCLIMATION_ARCANE)) + return false; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + if (eventInfo.GetDamageInfo()) + { + switch (GetFirstSchoolInMask(eventInfo.GetDamageInfo()->GetSchoolMask())) + { + case SPELL_SCHOOL_HOLY: + case SPELL_SCHOOL_FIRE: + case SPELL_SCHOOL_NATURE: + case SPELL_SCHOOL_FROST: + case SPELL_SCHOOL_SHADOW: + case SPELL_SCHOOL_ARCANE: + return true; + default: + break; + } + } + + return false; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + uint32 triggerspell = 0; + + switch (GetFirstSchoolInMask(eventInfo.GetDamageInfo()->GetSchoolMask())) + { + case SPELL_SCHOOL_HOLY: + triggerspell = SPELL_DK_ACCLIMATION_HOLY; + break; + case SPELL_SCHOOL_FIRE: + triggerspell = SPELL_DK_ACCLIMATION_FIRE; + break; + case SPELL_SCHOOL_NATURE: + triggerspell = SPELL_DK_ACCLIMATION_NATURE; + break; + case SPELL_SCHOOL_FROST: + triggerspell = SPELL_DK_ACCLIMATION_FROST; + break; + case SPELL_SCHOOL_SHADOW: + triggerspell = SPELL_DK_ACCLIMATION_SHADOW; + break; + case SPELL_SCHOOL_ARCANE: + triggerspell = SPELL_DK_ACCLIMATION_ARCANE; + break; + default: + return; + } + + if (Unit* target = eventInfo.GetActionTarget()) + target->CastSpell(target, triggerspell, true, nullptr, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_dk_acclimation_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_dk_acclimation_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_dk_acclimation_AuraScript(); + } +}; + +// 70656 - Advantage (T10 4P Melee Bonus) +class spell_dk_advantage_t10_4p : public SpellScriptLoader +{ +public: + spell_dk_advantage_t10_4p() : SpellScriptLoader("spell_dk_advantage_t10_4p") { } + + class spell_dk_advantage_t10_4p_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dk_advantage_t10_4p_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_DK_ADVANTAGE_T10_4P_MELEE)) + return false; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + if (Unit* caster = eventInfo.GetActor()) + { + if (caster->GetTypeId() != TYPEID_PLAYER || caster->getClass() != CLASS_DEATH_KNIGHT) + return false; + + for (uint8 i = 0; i < MAX_RUNES; ++i) + if (caster->ToPlayer()->GetRuneCooldown(i) == 0) + return false; + + return true; + } + + return false; + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_dk_advantage_t10_4p_AuraScript::CheckProc); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_dk_advantage_t10_4p_AuraScript(); + } +}; + // 50462 - Anti-Magic Shell (on raid member) class spell_dk_anti_magic_shell_raid : public SpellScriptLoader { @@ -919,6 +1062,52 @@ class spell_dk_improved_blood_presence : public SpellScriptLoader } }; +// 63611 - Improved Blood Presence Triggered +class spell_dk_improved_blood_presence_triggered : public SpellScriptLoader +{ +public: + spell_dk_improved_blood_presence_triggered() : SpellScriptLoader("spell_dk_improved_blood_presence_triggered") { } + + class spell_dk_improved_blood_presence_triggered_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dk_improved_blood_presence_triggered_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_DK_IMPROVED_BLOOD_PRESENCE_HEAL)) + return false; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + if (eventInfo.GetActor()->GetTypeId() == TYPEID_PLAYER) + return true; + + return false; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + if (DamageInfo* dmgInfo = eventInfo.GetDamageInfo()) + eventInfo.GetActor()->CastCustomSpell(SPELL_DK_IMPROVED_BLOOD_PRESENCE_HEAL, SPELLVALUE_BASE_POINT0, CalculatePct(int32(dmgInfo->GetDamage()), aurEff->GetAmount()), + eventInfo.GetActor(), true, nullptr, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_dk_improved_blood_presence_triggered_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_dk_improved_blood_presence_triggered_AuraScript::HandleProc, EFFECT_1, SPELL_AURA_PROC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_dk_improved_blood_presence_triggered_AuraScript(); + } +}; + // -50384 - Improved Frost Presence class spell_dk_improved_frost_presence : public SpellScriptLoader { @@ -2006,6 +2195,8 @@ public: void AddSC_deathknight_spell_scripts() { + new spell_dk_acclimation(); + new spell_dk_advantage_t10_4p(); new spell_dk_anti_magic_shell_raid(); new spell_dk_anti_magic_shell_self(); new spell_dk_anti_magic_zone(); @@ -2022,6 +2213,7 @@ void AddSC_deathknight_spell_scripts() new spell_dk_ghoul_explode(); new spell_dk_icebound_fortitude(); new spell_dk_improved_blood_presence(); + new spell_dk_improved_blood_presence_triggered(); new spell_dk_improved_frost_presence(); new spell_dk_improved_unholy_presence(); new spell_dk_pestilence(); diff --git a/src/server/scripts/Spells/spell_druid.cpp b/src/server/scripts/Spells/spell_druid.cpp index c088ae07e66..0bf5ab01f45 100644 --- a/src/server/scripts/Spells/spell_druid.cpp +++ b/src/server/scripts/Spells/spell_druid.cpp @@ -31,6 +31,13 @@ enum DruidSpells { SPELL_DRUID_BEAR_FORM_PASSIVE = 1178, SPELL_DRUID_DIRE_BEAR_FORM_PASSIVE = 9635, + SPELL_DRUID_ECLIPSE_LUNAR_PROC = 48518, + SPELL_DRUID_ECLIPSE_SOLAR_PROC = 48517, + SPELL_DRUID_FORMS_TRINKET_BEAR = 37340, + SPELL_DRUID_FORMS_TRINKET_CAT = 37341, + SPELL_DRUID_FORMS_TRINKET_MOONKIN = 37343, + SPELL_DRUID_FORMS_TRINKET_NONE = 37344, + SPELL_DRUID_FORMS_TRINKET_TREE = 37342, SPELL_DRUID_ENRAGE = 5229, SPELL_DRUID_ENRAGE_MOD_DAMAGE = 51185, SPELL_DRUID_ENRAGED_DEFENSE = 70725, @@ -48,6 +55,8 @@ enum DruidSpells SPELL_DRUID_NATURES_SPLENDOR = 57865, SPELL_DRUID_SURVIVAL_INSTINCTS = 50322, SPELL_DRUID_SAVAGE_ROAR = 62071, + SPELL_DRUID_T9_FERAL_RELIC_BEAR = 67354, + SPELL_DRUID_T9_FERAL_RELIC_CAT = 67355, SPELL_DRUID_TIGER_S_FURY_ENERGIZE = 51178 }; @@ -131,6 +140,69 @@ class spell_dru_dash : public SpellScriptLoader } }; +class spell_dru_eclipse : public SpellScriptLoader +{ +public: + spell_dru_eclipse() : SpellScriptLoader("spell_dru_eclipse") { } + + class spell_dru_eclipse_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dru_eclipse_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_DRUID_ECLIPSE_LUNAR_PROC)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_DRUID_ECLIPSE_SOLAR_PROC)) + return false; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + if (!eventInfo.GetSpellInfo()) + return false; + + if (eventInfo.GetActor()->HasAura(SPELL_DRUID_ECLIPSE_LUNAR_PROC) || eventInfo.GetActor()->HasAura(SPELL_DRUID_ECLIPSE_SOLAR_PROC)) + return false; + + // Triggered by Wrath? + if (eventInfo.GetSpellInfo()->SpellFamilyFlags[0] & 1) + return roll_chance_f(GetSpellInfo()->ProcChance * 0.6f) && _lunarProcCooldownEnd <= std::chrono::steady_clock::now(); + + return _solarProcCooldownEnd <= std::chrono::steady_clock::now(); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + if (eventInfo.GetSpellInfo()->SpellFamilyFlags[0] & 1) + { + _lunarProcCooldownEnd = std::chrono::steady_clock::now() + Seconds(aurEff->GetAmount()); + eventInfo.GetActor()->CastSpell(eventInfo.GetActor(), SPELL_DRUID_ECLIPSE_LUNAR_PROC, TRIGGERED_FULL_MASK, nullptr, aurEff); + } + else + { + _solarProcCooldownEnd = std::chrono::steady_clock::now() + Seconds(aurEff->GetAmount()); + eventInfo.GetActor()->CastSpell(eventInfo.GetActor(), SPELL_DRUID_ECLIPSE_SOLAR_PROC, TRIGGERED_FULL_MASK, nullptr, aurEff); + } + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_dru_eclipse_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_dru_eclipse_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + + std::chrono::steady_clock::time_point _lunarProcCooldownEnd = std::chrono::steady_clock::time_point::min(); + std::chrono::steady_clock::time_point _solarProcCooldownEnd = std::chrono::steady_clock::time_point::min(); + }; + + AuraScript* GetAuraScript() const override + { + return new spell_dru_eclipse_AuraScript(); + } +}; + // 5229 - Enrage class spell_dru_enrage : public SpellScriptLoader { @@ -197,6 +269,91 @@ class spell_dru_enrage : public SpellScriptLoader } }; +// 37336 - Druid Forms Trinket +class spell_dru_forms_trinket : public SpellScriptLoader +{ +public: + spell_dru_forms_trinket() : SpellScriptLoader("spell_dru_forms_trinket") { } + + class spell_dru_forms_trinket_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dru_forms_trinket_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_DRUID_FORMS_TRINKET_BEAR) || + !sSpellMgr->GetSpellInfo(SPELL_DRUID_FORMS_TRINKET_CAT) || + !sSpellMgr->GetSpellInfo(SPELL_DRUID_FORMS_TRINKET_MOONKIN) || + !sSpellMgr->GetSpellInfo(SPELL_DRUID_FORMS_TRINKET_NONE) || + !sSpellMgr->GetSpellInfo(SPELL_DRUID_FORMS_TRINKET_TREE)) + return false; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + Unit* target = eventInfo.GetActor(); + + switch (target->GetShapeshiftForm()) + { + case FORM_BEAR: + case FORM_DIREBEAR: + case FORM_CAT: + case FORM_MOONKIN: + case FORM_NONE: + case FORM_TREE: + return true; + default: + break; + } + + return false; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + Unit* target = eventInfo.GetActor(); + uint32 triggerspell = 0; + + switch (target->GetShapeshiftForm()) + { + case FORM_BEAR: + case FORM_DIREBEAR: + triggerspell = SPELL_DRUID_FORMS_TRINKET_BEAR; + break; + case FORM_CAT: + triggerspell = SPELL_DRUID_FORMS_TRINKET_CAT; + break; + case FORM_MOONKIN: + triggerspell = SPELL_DRUID_FORMS_TRINKET_MOONKIN; + break; + case FORM_NONE: + triggerspell = SPELL_DRUID_FORMS_TRINKET_NONE; + break; + case FORM_TREE: + triggerspell = SPELL_DRUID_FORMS_TRINKET_TREE; + break; + default: + return; + } + + target->CastSpell(target, triggerspell, true, nullptr, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_dru_forms_trinket_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_dru_forms_trinket_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_dru_forms_trinket_AuraScript(); + } +}; + // 54846 - Glyph of Starfire class spell_dru_glyph_of_starfire : public SpellScriptLoader { @@ -1079,6 +1236,77 @@ class spell_dru_typhoon : public SpellScriptLoader } }; +// 67353 - T9 Feral Relic (Idol of Mutilation) +class spell_dru_t9_feral_relic : public SpellScriptLoader +{ +public: + spell_dru_t9_feral_relic() : SpellScriptLoader("spell_dru_t9_feral_relic") { } + + class spell_dru_t9_feral_relic_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dru_t9_feral_relic_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_DRUID_T9_FERAL_RELIC_BEAR) || + !sSpellMgr->GetSpellInfo(SPELL_DRUID_T9_FERAL_RELIC_CAT)) + return false; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + Unit* target = eventInfo.GetActor(); + + switch (target->GetShapeshiftForm()) + { + case FORM_BEAR: + case FORM_DIREBEAR: + case FORM_CAT: + return true; + default: + break; + } + + return false; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + uint32 triggerspell = 0; + + Unit* target = eventInfo.GetActor(); + + switch (target->GetShapeshiftForm()) + { + case FORM_BEAR: + case FORM_DIREBEAR: + triggerspell = SPELL_DRUID_T9_FERAL_RELIC_BEAR; + break; + case FORM_CAT: + triggerspell = SPELL_DRUID_T9_FERAL_RELIC_CAT; + break; + default: + return; + } + + target->CastSpell(target, triggerspell, true, nullptr, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_dru_t9_feral_relic_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_dru_t9_feral_relic_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_dru_t9_feral_relic_AuraScript(); + } +}; + // 70691 - Item T10 Restoration 4P Bonus class spell_dru_t10_restoration_4p_bonus : public SpellScriptLoader { @@ -1208,7 +1436,9 @@ void AddSC_druid_spell_scripts() { new spell_dru_bear_form_passive(); new spell_dru_dash(); + new spell_dru_eclipse(); new spell_dru_enrage(); + new spell_dru_forms_trinket(); new spell_dru_glyph_of_starfire(); new spell_dru_idol_lifebloom(); new spell_dru_innervate(); @@ -1230,6 +1460,7 @@ void AddSC_druid_spell_scripts() new spell_dru_flight_form(); new spell_dru_tiger_s_fury(); new spell_dru_typhoon(); + new spell_dru_t9_feral_relic(); new spell_dru_t10_restoration_4p_bonus(); new spell_dru_wild_growth(); } diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index 8b8c5300a9e..e8ad73ceadb 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -430,6 +430,61 @@ class spell_gen_bandage : public SpellScriptLoader } }; +// Blood Reserve - 64568 +enum BloodReserve +{ + SPELL_GEN_BLOOD_RESERVE_AURA = 64568, + SPELL_GEN_BLOOD_RESERVE_HEAL = 64569 +}; + +class spell_gen_blood_reserve : public SpellScriptLoader +{ + public: + spell_gen_blood_reserve() : SpellScriptLoader("spell_gen_blood_reserve") { } + + class spell_gen_blood_reserve_AuraScript : public AuraScript + { + PrepareAuraScript(spell_gen_blood_reserve_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_GEN_BLOOD_RESERVE_HEAL)) + return false; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + if (DamageInfo* dmgInfo = eventInfo.GetDamageInfo()) + if (Unit* caster = eventInfo.GetActionTarget()) + if (caster->HealthBelowPctDamaged(35, dmgInfo->GetDamage())) + return true; + + return false; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + Unit* caster = eventInfo.GetActionTarget(); + caster->CastCustomSpell(SPELL_GEN_BLOOD_RESERVE_HEAL, SPELLVALUE_BASE_POINT0, aurEff->GetAmount(), caster, TRIGGERED_FULL_MASK, nullptr, aurEff); + caster->RemoveAura(SPELL_GEN_BLOOD_RESERVE_AURA); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_gen_blood_reserve_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_gen_blood_reserve_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_gen_blood_reserve_AuraScript(); + } +}; + enum Bonked { SPELL_BONKED = 62991, @@ -2085,7 +2140,7 @@ class spell_gen_mounted_charge: public SpellScriptLoader } // If target isn't a training dummy there's a chance of failing the charge - if (!target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE) && roll_chance_f(12.5f)) + if (!target->IsCharmedOwnedByPlayerOrPlayer() && roll_chance_f(12.5f)) spellId = SPELL_CHARGE_MISS_EFFECT; if (Unit* vehicle = GetCaster()->GetVehicleBase()) @@ -4199,6 +4254,7 @@ void AddSC_generic_spell_scripts() new spell_gen_aura_service_uniform(); new spell_gen_av_drekthar_presence(); new spell_gen_bandage(); + new spell_gen_blood_reserve(); new spell_gen_bonked(); new spell_gen_break_shield("spell_gen_break_shield"); new spell_gen_break_shield("spell_gen_tournament_counterattack"); diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp index 82d9d134445..0e952818a2f 100644 --- a/src/server/scripts/Spells/spell_hunter.cpp +++ b/src/server/scripts/Spells/spell_hunter.cpp @@ -51,9 +51,11 @@ enum HunterSpells SPELL_HUNTER_PET_HEART_OF_THE_PHOENIX_TRIGGERED = 54114, SPELL_HUNTER_PET_HEART_OF_THE_PHOENIX_DEBUFF = 55711, SPELL_HUNTER_PET_CARRION_FEEDER_TRIGGERED = 54045, + SPELL_HUNTER_PIERCING_SHOTS = 63468, SPELL_HUNTER_READINESS = 23989, SPELL_HUNTER_SNIPER_TRAINING_R1 = 53302, SPELL_HUNTER_SNIPER_TRAINING_BUFF_R1 = 64418, + SPELL_HUNTER_T9_4P_GREATNESS = 68130, SPELL_HUNTER_VICIOUS_VIPER = 61609, SPELL_HUNTER_VIPER_ATTACK_SPEED = 60144, SPELL_DRAENEI_GIFT_OF_THE_NAARU = 59543 @@ -704,6 +706,63 @@ class spell_hun_pet_heart_of_the_phoenix : public SpellScriptLoader } }; +// -53234 - Piercing Shots +class spell_hun_piercing_shots : public SpellScriptLoader +{ +public: + spell_hun_piercing_shots() : SpellScriptLoader("spell_hun_piercing_shots") { } + + class spell_hun_piercing_shots_AuraScript : public AuraScript + { + PrepareAuraScript(spell_hun_piercing_shots_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_PIERCING_SHOTS)) + return false; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + if (eventInfo.GetActionTarget()) + return true; + return false; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + Unit* caster = eventInfo.GetActor(); + Unit* target = eventInfo.GetActionTarget(); + + if (DamageInfo* dmgInfo = eventInfo.GetDamageInfo()) + { + SpellInfo const* piercingShots = sSpellMgr->AssertSpellInfo(SPELL_HUNTER_PIERCING_SHOTS); + int32 duration = piercingShots->GetMaxDuration(); + uint32 amplitude = piercingShots->Effects[EFFECT_0].Amplitude; + uint32 dmg = dmgInfo->GetDamage(); + + uint32 bp = CalculatePct(int32(dmg), aurEff->GetAmount()) / (duration / int32(amplitude)); + bp += target->GetRemainingPeriodicAmount(target->GetGUID(), SPELL_HUNTER_PIERCING_SHOTS, SPELL_AURA_PERIODIC_DAMAGE); + + caster->CastCustomSpell(SPELL_HUNTER_PIERCING_SHOTS, SPELLVALUE_BASE_POINT0, bp, target, true, nullptr, aurEff); + } + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_hun_piercing_shots_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_hun_piercing_shots_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_hun_piercing_shots_AuraScript(); + } +}; + // 56654, 58882 - Rapid Recuperation class spell_hun_rapid_recuperation : public SpellScriptLoader { @@ -967,6 +1026,51 @@ class spell_hun_target_only_pet_and_owner : public SpellScriptLoader } }; +// 67151 - T9 4P Bonus +class spell_hun_t9_4p_bonus : public SpellScriptLoader +{ +public: + spell_hun_t9_4p_bonus() : SpellScriptLoader("spell_hun_t9_4p_bonus") { } + + class spell_hun_t9_4p_bonus_AuraScript : public AuraScript + { + PrepareAuraScript(spell_hun_t9_4p_bonus_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_T9_4P_GREATNESS)) + return false; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + if (eventInfo.GetActor()->GetTypeId() == TYPEID_PLAYER && eventInfo.GetActor()->ToPlayer()->GetPet()) + return true; + return false; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + Unit* caster = eventInfo.GetActor(); + + caster->CastSpell(caster->ToPlayer()->GetPet(), SPELL_HUNTER_T9_4P_GREATNESS, true, nullptr, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_hun_t9_4p_bonus_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_hun_t9_4p_bonus_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_hun_t9_4p_bonus_AuraScript(); + } +}; + // 60144 - Viper Attack Speed class spell_hun_viper_attack_speed : public SpellScriptLoader { @@ -1025,11 +1129,13 @@ void AddSC_hunter_spell_scripts() new spell_hun_misdirection_proc(); new spell_hun_pet_carrion_feeder(); new spell_hun_pet_heart_of_the_phoenix(); + new spell_hun_piercing_shots(); new spell_hun_rapid_recuperation(); new spell_hun_readiness(); new spell_hun_scatter_shot(); new spell_hun_sniper_training(); new spell_hun_tame_beast(); new spell_hun_target_only_pet_and_owner(); + new spell_hun_t9_4p_bonus(); new spell_hun_viper_attack_speed(); } diff --git a/src/server/scripts/Spells/spell_item.cpp b/src/server/scripts/Spells/spell_item.cpp index 0abff255e4b..f7c2cefa202 100644 --- a/src/server/scripts/Spells/spell_item.cpp +++ b/src/server/scripts/Spells/spell_item.cpp @@ -201,6 +201,55 @@ class spell_item_blessing_of_ancient_kings : public SpellScriptLoader } }; +// 47770 - Roll Dice +class spell_item_decahedral_dwarven_dice : public SpellScriptLoader +{ + public: + spell_item_decahedral_dwarven_dice() : SpellScriptLoader("spell_item_decahedral_dwarven_dice") { } + + class spell_item_decahedral_dwarven_dice_SpellScript : public SpellScript + { + PrepareSpellScript(spell_item_decahedral_dwarven_dice_SpellScript); + + enum + { + TEXT_DECAHEDRAL_DWARVEN_DICE = 26147 + }; + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sObjectMgr->GetBroadcastText(TEXT_DECAHEDRAL_DWARVEN_DICE)) + return false; + return true; + } + + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + GetCaster()->TextEmote(TEXT_DECAHEDRAL_DWARVEN_DICE, GetHitUnit()); + + static uint32 const minimum = 1; + static uint32 const maximum = 100; + + GetCaster()->ToPlayer()->DoRandomRoll(minimum, maximum); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_item_decahedral_dwarven_dice_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_item_decahedral_dwarven_dice_SpellScript(); + } +}; + // 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 @@ -1319,6 +1368,57 @@ class spell_item_underbelly_elixir : public SpellScriptLoader } }; +// 47776 - Roll 'dem Bones +class spell_item_worn_troll_dice : public SpellScriptLoader +{ + public: + spell_item_worn_troll_dice() : SpellScriptLoader("spell_item_worn_troll_dice") { } + + class spell_item_worn_troll_dice_SpellScript : public SpellScript + { + PrepareSpellScript(spell_item_worn_troll_dice_SpellScript); + + enum + { + TEXT_WORN_TROLL_DICE = 26152 + }; + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sObjectMgr->GetBroadcastText(TEXT_WORN_TROLL_DICE)) + return false; + return true; + } + + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + GetCaster()->TextEmote(TEXT_WORN_TROLL_DICE, GetHitUnit()); + + static uint32 const minimum = 1; + static uint32 const maximum = 6; + + // roll twice + GetCaster()->ToPlayer()->DoRandomRoll(minimum, maximum); + GetCaster()->ToPlayer()->DoRandomRoll(minimum, maximum); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_item_worn_troll_dice_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_item_worn_troll_dice_SpellScript(); + } +}; + enum AirRifleSpells { SPELL_AIR_RIFLE_HOLD_VISUAL = 65582, @@ -2631,6 +2731,70 @@ public: } }; +enum SoulPreserver +{ + SPELL_SOUL_PRESERVER_DRUID = 60512, + SPELL_SOUL_PRESERVER_PALADIN = 60513, + SPELL_SOUL_PRESERVER_PRIEST = 60514, + SPELL_SOUL_PRESERVER_SHAMAN = 60515, +}; + +class spell_item_soul_preserver : public SpellScriptLoader +{ +public: + spell_item_soul_preserver() : SpellScriptLoader("spell_item_soul_preserver") { } + + class spell_item_soul_preserver_AuraScript : public AuraScript + { + PrepareAuraScript(spell_item_soul_preserver_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_SOUL_PRESERVER_DRUID) || + !sSpellMgr->GetSpellInfo(SPELL_SOUL_PRESERVER_PALADIN) || + !sSpellMgr->GetSpellInfo(SPELL_SOUL_PRESERVER_PRIEST) || + !sSpellMgr->GetSpellInfo(SPELL_SOUL_PRESERVER_SHAMAN)) + return false; + return true; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + Unit* caster = eventInfo.GetActor(); + + switch (caster->getClass()) + { + case CLASS_DRUID: + caster->CastSpell(caster, SPELL_SOUL_PRESERVER_DRUID, true, nullptr, aurEff); + break; + case CLASS_PALADIN: + caster->CastSpell(caster, SPELL_SOUL_PRESERVER_PALADIN, true, nullptr, aurEff); + break; + case CLASS_PRIEST: + caster->CastSpell(caster, SPELL_SOUL_PRESERVER_PRIEST, true, nullptr, aurEff); + break; + case CLASS_SHAMAN: + caster->CastSpell(caster, SPELL_SOUL_PRESERVER_SHAMAN, true, nullptr, aurEff); + break; + default: + break; + } + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_soul_preserver_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_item_soul_preserver_AuraScript(); + } +}; + class spell_item_toy_train_set_pulse : public SpellScriptLoader { public: @@ -2668,6 +2832,336 @@ public: } }; +enum DeathChoiceSpells +{ + SPELL_DEATH_CHOICE_NORMAL_AURA = 67702, + SPELL_DEATH_CHOICE_NORMAL_AGILITY = 67703, + SPELL_DEATH_CHOICE_NORMAL_STRENGTH = 67708, + SPELL_DEATH_CHOICE_HEROIC_AURA = 67771, + SPELL_DEATH_CHOICE_HEROIC_AGILITY = 67772, + SPELL_DEATH_CHOICE_HEROIC_STRENGTH = 67773 +}; + +class spell_item_death_choice : public SpellScriptLoader +{ +public: + spell_item_death_choice() : SpellScriptLoader("spell_item_death_choice") { } + + class spell_item_death_choice_AuraScript : public AuraScript + { + PrepareAuraScript(spell_item_death_choice_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_DEATH_CHOICE_NORMAL_STRENGTH) || + !sSpellMgr->GetSpellInfo(SPELL_DEATH_CHOICE_NORMAL_AGILITY) || + !sSpellMgr->GetSpellInfo(SPELL_DEATH_CHOICE_HEROIC_STRENGTH) || + !sSpellMgr->GetSpellInfo(SPELL_DEATH_CHOICE_HEROIC_AGILITY)) + return false; + return true; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + Unit* caster = eventInfo.GetActor(); + float str = caster->GetStat(STAT_STRENGTH); + float agi = caster->GetStat(STAT_AGILITY); + + switch (aurEff->GetId()) + { + case SPELL_DEATH_CHOICE_NORMAL_AURA: + { + if (str > agi) + caster->CastSpell(caster, SPELL_DEATH_CHOICE_NORMAL_STRENGTH, true, nullptr, aurEff); + else + caster->CastSpell(caster, SPELL_DEATH_CHOICE_NORMAL_AGILITY, true, nullptr, aurEff); + break; + } + case SPELL_DEATH_CHOICE_HEROIC_AURA: + { + if (str > agi) + caster->CastSpell(caster, SPELL_DEATH_CHOICE_HEROIC_STRENGTH, true, nullptr, aurEff); + else + caster->CastSpell(caster, SPELL_DEATH_CHOICE_HEROIC_AGILITY, true, nullptr, aurEff); + break; + } + default: + break; + } + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_death_choice_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_item_death_choice_AuraScript(); + } +}; + +enum TrinketStackSpells +{ + SPELL_LIGHTNING_CAPACITOR_AURA = 37657, // Lightning Capacitor + SPELL_LIGHTNING_CAPACITOR_STACK = 37658, + SPELL_LIGHTNING_CAPACITOR_TRIGGER = 37661, + SPELL_THUNDER_CAPACITOR_AURA = 54841, // Thunder Capacitor + SPELL_THUNDER_CAPACITOR_STACK = 54842, + SPELL_THUNDER_CAPACITOR_TRIGGER = 54843, + SPELL_TOC25_CASTER_TRINKET_NORMAL_AURA = 67712, // Item - Coliseum 25 Normal Caster Trinket + SPELL_TOC25_CASTER_TRINKET_NORMAL_STACK = 67713, + SPELL_TOC25_CASTER_TRINKET_NORMAL_TRIGGER = 67714, + SPELL_TOC25_CASTER_TRINKET_HEROIC_AURA = 67758, // Item - Coliseum 25 Heroic Caster Trinket + SPELL_TOC25_CASTER_TRINKET_HEROIC_STACK = 67759, + SPELL_TOC25_CASTER_TRINKET_HEROIC_TRIGGER = 67760, +}; + +class spell_item_trinket_stack : public SpellScriptLoader +{ +public: + spell_item_trinket_stack(char const* scriptName, uint32 stackSpell, uint32 triggerSpell) : SpellScriptLoader(scriptName), + _stackSpell(stackSpell), _triggerSpell(triggerSpell) + { + } + + class spell_item_trinket_stack_AuraScript : public AuraScript + { + PrepareAuraScript(spell_item_trinket_stack_AuraScript); + + public: + spell_item_trinket_stack_AuraScript(uint32 stackSpell, uint32 triggerSpell) : _stackSpell(stackSpell), _triggerSpell(triggerSpell) + { + } + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(_stackSpell) || !sSpellMgr->GetSpellInfo(_triggerSpell)) + return false; + return true; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + Unit* caster = eventInfo.GetActor(); + + caster->CastSpell(caster, _stackSpell, true, nullptr, aurEff); // cast the stack + + Aura* dummy = caster->GetAura(_stackSpell); // retrieve aura + + //dont do anything if it's not the right amount of stacks; + if (!dummy || dummy->GetStackAmount() < aurEff->GetAmount()) + return; + + // if right amount, remove the aura and cast real trigger + caster->RemoveAurasDueToSpell(_stackSpell); + if (Unit* target = eventInfo.GetActionTarget()) + caster->CastSpell(target, _triggerSpell, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_trinket_stack_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } + + private: + uint32 _stackSpell; + uint32 _triggerSpell; + }; + + AuraScript* GetAuraScript() const override + { + return new spell_item_trinket_stack_AuraScript(_stackSpell, _triggerSpell); + } + +private: + uint32 _stackSpell; + uint32 _triggerSpell; +}; + +// 57345 - Darkmoon Card: Greatness +enum DarkmoonCardSpells +{ + SPELL_DARKMOON_CARD_STRENGHT = 60229, + SPELL_DARKMOON_CARD_AGILITY = 60233, + SPELL_DARKMOON_CARD_INTELLECT = 60234, + SPELL_DARKMOON_CARD_SPIRIT = 60235, +}; + +class spell_item_darkmoon_card_greatness : public SpellScriptLoader +{ +public: + spell_item_darkmoon_card_greatness() : SpellScriptLoader("spell_item_darkmoon_card_greatness") { } + + class spell_item_darkmoon_card_greatness_AuraScript : public AuraScript + { + PrepareAuraScript(spell_item_darkmoon_card_greatness_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_DARKMOON_CARD_STRENGHT) || + !sSpellMgr->GetSpellInfo(SPELL_DARKMOON_CARD_AGILITY) || + !sSpellMgr->GetSpellInfo(SPELL_DARKMOON_CARD_INTELLECT) || + !sSpellMgr->GetSpellInfo(SPELL_DARKMOON_CARD_SPIRIT)) + return false; + return true; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + Unit* caster = eventInfo.GetActor(); + float str = caster->GetStat(STAT_STRENGTH); + float agi = caster->GetStat(STAT_AGILITY); + float intl = caster->GetStat(STAT_INTELLECT); + float spi = caster->GetStat(STAT_SPIRIT); + float stat = 0.0f; + + uint32 spellTrigger = SPELL_DARKMOON_CARD_STRENGHT; + + if (str > stat) + { + spellTrigger = SPELL_DARKMOON_CARD_STRENGHT; + stat = str; + } + + if (agi > stat) + { + spellTrigger = SPELL_DARKMOON_CARD_AGILITY; + stat = agi; + } + + if (intl > stat) + { + spellTrigger = SPELL_DARKMOON_CARD_INTELLECT; + stat = intl; + } + + if (spi > stat) + { + spellTrigger = SPELL_DARKMOON_CARD_SPIRIT; + stat = spi; + } + + caster->CastSpell(caster, spellTrigger, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_darkmoon_card_greatness_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_item_darkmoon_card_greatness_AuraScript(); + } +}; + +// 43820 - Amani Charm of the Witch Doctor +enum CharmWitchDoctor +{ + SPELL_CHARM_WITCH_DOCTOR_PROC = 43821 +}; + +class spell_item_charm_witch_doctor : public SpellScriptLoader +{ +public: + spell_item_charm_witch_doctor() : SpellScriptLoader("spell_item_charm_witch_doctor") { } + + class spell_item_charm_witch_doctor_AuraScript : public AuraScript + { + PrepareAuraScript(spell_item_charm_witch_doctor_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_CHARM_WITCH_DOCTOR_PROC)) + return false; + return true; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + Unit* caster = eventInfo.GetActor(); + Unit* target = eventInfo.GetActionTarget(); + + if (target) + { + int32 bp = CalculatePct(target->GetCreateHealth(),aurEff->GetSpellInfo()->Effects[1].CalcValue()); + caster->CastCustomSpell(target, SPELL_CHARM_WITCH_DOCTOR_PROC, &bp, nullptr, nullptr, true, nullptr, aurEff); + } + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_charm_witch_doctor_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_item_charm_witch_doctor_AuraScript(); + } +}; + +// 27522,40336 - Mana Drain +enum ManaDrainSpells +{ + SPELL_MANA_DRAIN_ENERGIZE = 29471, + SPELL_MANA_DRAIN_LEECH = 27526 +}; + +class spell_item_mana_drain : public SpellScriptLoader +{ +public: + spell_item_mana_drain() : SpellScriptLoader("spell_item_mana_drain") { } + + class spell_item_mana_drain_AuraScript : public AuraScript + { + PrepareAuraScript(spell_item_mana_drain_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_MANA_DRAIN_ENERGIZE) + || !sSpellMgr->GetSpellInfo(SPELL_MANA_DRAIN_LEECH)) + return false; + return true; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + Unit* caster = eventInfo.GetActor(); + Unit* target = eventInfo.GetActionTarget(); + + if (caster->IsAlive()) + caster->CastSpell(caster, SPELL_MANA_DRAIN_ENERGIZE, true, nullptr, aurEff); + + if (target && target->IsAlive()) + caster->CastSpell(target, SPELL_MANA_DRAIN_LEECH, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_mana_drain_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_item_mana_drain_AuraScript(); + } +}; + void AddSC_item_spell_scripts() { // 23074 Arcanite Dragonling @@ -2682,6 +3176,7 @@ void AddSC_item_spell_scripts() new spell_item_aegis_of_preservation(); new spell_item_arcane_shroud(); new spell_item_blessing_of_ancient_kings(); + new spell_item_decahedral_dwarven_dice(); new spell_item_defibrillate("spell_item_goblin_jumper_cables", 67, SPELL_GOBLIN_JUMPER_CABLES_FAIL); new spell_item_defibrillate("spell_item_goblin_jumper_cables_xl", 50, SPELL_GOBLIN_JUMPER_CABLES_XL_FAIL); new spell_item_defibrillate("spell_item_gnomish_army_knife", 33); @@ -2706,6 +3201,7 @@ void AddSC_item_spell_scripts() new spell_item_six_demon_bag(); new spell_item_the_eye_of_diminution(); new spell_item_underbelly_elixir(); + new spell_item_worn_troll_dice(); new spell_item_red_rider_air_rifle(); new spell_item_create_heart_candy(); @@ -2736,5 +3232,14 @@ void AddSC_item_spell_scripts() new spell_item_chicken_cover(); new spell_item_muisek_vessel(); new spell_item_greatmothers_soulcatcher(); + new spell_item_soul_preserver(); new spell_item_toy_train_set_pulse(); + new spell_item_death_choice(); + new spell_item_trinket_stack("spell_item_lightning_capacitor", SPELL_LIGHTNING_CAPACITOR_STACK, SPELL_LIGHTNING_CAPACITOR_TRIGGER); + new spell_item_trinket_stack("spell_item_thunder_capacitor", SPELL_THUNDER_CAPACITOR_STACK, SPELL_THUNDER_CAPACITOR_TRIGGER); + new spell_item_trinket_stack("spell_item_toc25_normal_caster_trinket", SPELL_TOC25_CASTER_TRINKET_NORMAL_STACK, SPELL_TOC25_CASTER_TRINKET_NORMAL_TRIGGER); + new spell_item_trinket_stack("spell_item_toc25_heroic_caster_trinket", SPELL_TOC25_CASTER_TRINKET_HEROIC_STACK, SPELL_TOC25_CASTER_TRINKET_HEROIC_TRIGGER); + new spell_item_darkmoon_card_greatness(); + new spell_item_charm_witch_doctor(); + new spell_item_mana_drain(); } diff --git a/src/server/scripts/Spells/spell_mage.cpp b/src/server/scripts/Spells/spell_mage.cpp index 2f4e4fa6f44..bacbe31630c 100644 --- a/src/server/scripts/Spells/spell_mage.cpp +++ b/src/server/scripts/Spells/spell_mage.cpp @@ -29,6 +29,7 @@ enum MageSpells { + SPELL_MAGE_BLAZING_SPEED = 31643, SPELL_MAGE_BURNOUT = 29077, SPELL_MAGE_COLD_SNAP = 11958, SPELL_MAGE_FOCUS_MAGIC_PROC = 54648, @@ -116,6 +117,42 @@ class spell_mage_blast_wave : public SpellScriptLoader } }; +// -31641 - Blazing Speed +class spell_mage_blazing_speed : public SpellScriptLoader +{ +public: + spell_mage_blazing_speed() : SpellScriptLoader("spell_mage_blazing_speed") { } + + class spell_mage_blazing_speed_AuraScript : public AuraScript + { + PrepareAuraScript(spell_mage_blazing_speed_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_BLAZING_SPEED)) + return false; + return true; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + if (Unit* target = eventInfo.GetActionTarget()) + target->CastSpell(target, SPELL_MAGE_BLAZING_SPEED, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_mage_blazing_speed_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_mage_blazing_speed_AuraScript(); + } +}; + // -44449 - Burnout class spell_mage_burnout : public SpellScriptLoader { @@ -647,6 +684,7 @@ class spell_mage_summon_water_elemental : public SpellScriptLoader void AddSC_mage_spell_scripts() { new spell_mage_blast_wave(); + new spell_mage_blazing_speed(); new spell_mage_burnout(); new spell_mage_cold_snap(); new spell_mage_fire_frost_ward(); diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp index d9fd36f5fd4..eed84d4ff6b 100644 --- a/src/server/scripts/Spells/spell_paladin.cpp +++ b/src/server/scripts/Spells/spell_paladin.cpp @@ -37,6 +37,7 @@ enum PaladinSpells SPELL_PALADIN_HOLY_SHOCK_R1 = 20473, SPELL_PALADIN_HOLY_SHOCK_R1_DAMAGE = 25912, SPELL_PALADIN_HOLY_SHOCK_R1_HEALING = 25914, + SPELL_PALADIN_ILLUMINATION_ENERGIZE = 20272, SPELL_PALADIN_BLESSING_OF_LOWER_CITY_DRUID = 37878, SPELL_PALADIN_BLESSING_OF_LOWER_CITY_PALADIN = 37879, @@ -871,6 +872,61 @@ class spell_pal_holy_shock : public SpellScriptLoader } }; +// -20210 - Illumination +class spell_pal_illumination : public SpellScriptLoader +{ +public: + spell_pal_illumination() : SpellScriptLoader("spell_pal_illumination") { } + + class spell_pal_illumination_AuraScript : public AuraScript + { + PrepareAuraScript(spell_pal_illumination_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_PALADIN_HOLY_SHOCK_R1_HEALING) || + !sSpellMgr->GetSpellInfo(SPELL_PALADIN_ILLUMINATION_ENERGIZE) || + !sSpellMgr->GetSpellInfo(SPELL_PALADIN_HOLY_SHOCK_R1)) + return false; + return true; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + // this script is valid only for the Holy Shock procs of illumination + if (eventInfo.GetHealInfo() && eventInfo.GetHealInfo()->GetSpellInfo()) + { + if (eventInfo.GetHealInfo()->GetSpellInfo()->SpellFamilyFlags[1] & 0x00010000) + { + PreventDefaultAction(); + Unit* target = eventInfo.GetActor(); // Paladin is the target of the energize + + // proc comes from the Holy Shock heal, need to get mana cost of original spell + uint32 originalspellid = sSpellMgr->GetSpellWithRank(SPELL_PALADIN_HOLY_SHOCK_R1, eventInfo.GetHealInfo()->GetSpellInfo()->GetRank()); + SpellInfo const* originalSpell = sSpellMgr->GetSpellInfo(originalspellid); + if (originalSpell && aurEff->GetSpellInfo()) + { + uint32 bp = CalculatePct(originalSpell->CalcPowerCost(target, originalSpell->GetSchoolMask()), aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue()); + target->CastCustomSpell(SPELL_PALADIN_ILLUMINATION_ENERGIZE, SPELLVALUE_BASE_POINT0, bp, target, true, nullptr, aurEff); + } + } + } + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_pal_illumination_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_pal_illumination_AuraScript(); + } +}; + // Maybe this is incorrect // These spells should always be cast on login, regardless of whether the player has the talent or not @@ -1393,6 +1449,7 @@ void AddSC_paladin_spell_scripts() new spell_pal_hand_of_sacrifice(); new spell_pal_hand_of_salvation(); new spell_pal_holy_shock(); + new spell_pal_illumination(); new spell_pal_improved_aura("spell_pal_improved_concentraction_aura", SPELL_PALADIN_IMPROVED_CONCENTRACTION_AURA); new spell_pal_improved_aura("spell_pal_improved_devotion_aura", SPELL_PALADIN_IMPROVED_DEVOTION_AURA); new spell_pal_improved_aura("spell_pal_sanctified_retribution", SPELL_PALADIN_SANCTIFIED_RETRIBUTION_AURA); diff --git a/src/server/scripts/Spells/spell_priest.cpp b/src/server/scripts/Spells/spell_priest.cpp index 51f03346df1..9e2d265aa9c 100644 --- a/src/server/scripts/Spells/spell_priest.cpp +++ b/src/server/scripts/Spells/spell_priest.cpp @@ -29,6 +29,7 @@ enum PriestSpells { + SPELL_PRIEST_BLESSED_RECOVERY_R1 = 27813, SPELL_PRIEST_DIVINE_AEGIS = 47753, SPELL_PRIEST_EMPOWERED_RENEW = 63544, SPELL_PRIEST_GLYPH_OF_CIRCLE_OF_HEALING = 55675, @@ -88,6 +89,50 @@ class RaidCheck Unit const* _caster; }; +// -27811 - Blessed Recovery +class spell_pri_blessed_recovery : public SpellScriptLoader +{ +public: + spell_pri_blessed_recovery() : SpellScriptLoader("spell_pri_blessed_recovery") { } + + class spell_pri_blessed_recovery_AuraScript : public AuraScript + { + PrepareAuraScript(spell_pri_blessed_recovery_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_BLESSED_RECOVERY_R1)) + return false; + return true; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + if (DamageInfo* dmgInfo = eventInfo.GetDamageInfo()) + { + if (Unit* target = eventInfo.GetActionTarget()) + { + uint32 triggerSpell = sSpellMgr->GetSpellWithRank(SPELL_PRIEST_BLESSED_RECOVERY_R1, aurEff->GetSpellInfo()->GetRank()); + uint32 bp = CalculatePct(int32(dmgInfo->GetDamage()), aurEff->GetAmount()) / 3; + bp += target->GetRemainingPeriodicAmount(target->GetGUID(), triggerSpell, SPELL_AURA_PERIODIC_HEAL); + target->CastCustomSpell(triggerSpell, SPELLVALUE_BASE_POINT0, bp, target, true, nullptr, aurEff); + } + } + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_pri_blessed_recovery_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_pri_blessed_recovery_AuraScript(); + } +}; + // -34861 - Circle of Healing class spell_pri_circle_of_healing : public SpellScriptLoader { @@ -869,6 +914,7 @@ class spell_pri_vampiric_touch : public SpellScriptLoader void AddSC_priest_spell_scripts() { + new spell_pri_blessed_recovery(); new spell_pri_circle_of_healing(); new spell_pri_divine_aegis(); new spell_pri_divine_hymn(); diff --git a/src/server/scripts/Spells/spell_rogue.cpp b/src/server/scripts/Spells/spell_rogue.cpp index affc4d1c26c..1abb6741e0d 100644 --- a/src/server/scripts/Spells/spell_rogue.cpp +++ b/src/server/scripts/Spells/spell_rogue.cpp @@ -43,7 +43,8 @@ enum RogueSpells SPELL_ROGUE_TRICKS_OF_THE_TRADE_PROC = 59628, SPELL_ROGUE_HONOR_AMONG_THIEVES = 51698, SPELL_ROGUE_HONOR_AMONG_THIEVES_PROC = 52916, - SPELL_ROGUE_HONOR_AMONG_THIEVES_2 = 51699 + SPELL_ROGUE_HONOR_AMONG_THIEVES_2 = 51699, + SPELL_ROGUE_T10_2P_BONUS = 70804, }; // 13877, 33735, (check 51211, 65956) - Blade Flurry @@ -843,6 +844,40 @@ public: } }; +// 70805 - Rogue T10 2P Bonus -- THIS SHOULD BE REMOVED WITH NEW PROC SYSTEM. +class spell_rog_t10_2p_bonus : public SpellScriptLoader +{ +public: + spell_rog_t10_2p_bonus() : SpellScriptLoader("spell_rog_t10_2p_bonus") { } + + class spell_rog_t10_2p_bonus_AuraScript : public AuraScript + { + PrepareAuraScript(spell_rog_t10_2p_bonus_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_ROGUE_T10_2P_BONUS)) + return false; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + return eventInfo.GetActor() == eventInfo.GetActionTarget(); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_rog_t10_2p_bonus_AuraScript::CheckProc); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_rog_t10_2p_bonus_AuraScript(); + } +}; + void AddSC_rogue_spell_scripts() { new spell_rog_blade_flurry(); @@ -858,4 +893,5 @@ void AddSC_rogue_spell_scripts() new spell_rog_tricks_of_the_trade_proc(); new spell_rog_honor_among_thieves(); new spell_rog_honor_among_thieves_proc(); + new spell_rog_t10_2p_bonus(); } diff --git a/src/server/scripts/Spells/spell_shaman.cpp b/src/server/scripts/Spells/spell_shaman.cpp index 41e72b1388b..ad65c7c6ec7 100644 --- a/src/server/scripts/Spells/spell_shaman.cpp +++ b/src/server/scripts/Spells/spell_shaman.cpp @@ -48,8 +48,10 @@ enum ShamanSpells SPELL_SHAMAN_ITEM_MANA_SURGE = 23571, SPELL_SHAMAN_LAVA_FLOWS_R1 = 51480, SPELL_SHAMAN_LAVA_FLOWS_TRIGGERED_R1 = 64694, + SPELL_SHAMAN_LIGHTNING_SHIELD_R1 = 26364, SPELL_SHAMAN_MANA_SPRING_TOTEM_ENERGIZE = 52032, SPELL_SHAMAN_MANA_TIDE_TOTEM = 39609, + SPELL_SHAMAN_NATURE_GUARDIAN = 31616, SPELL_SHAMAN_SATED = 57724, SPELL_SHAMAN_STORM_EARTH_AND_FIRE = 51483, SPELL_SHAMAN_TOTEM_EARTHBIND_EARTHGRAB = 64695, @@ -671,7 +673,7 @@ class spell_sha_heroism : public SpellScriptLoader } }; -// 23551 - Lightning Shield +// 23551 - Lightning Shield T2 Bonus class spell_sha_item_lightning_shield : public SpellScriptLoader { public: @@ -706,7 +708,7 @@ class spell_sha_item_lightning_shield : public SpellScriptLoader } }; -// 23552 - Lightning Shield +// 23552 - Lightning Shield T2 Bonus class spell_sha_item_lightning_shield_trigger : public SpellScriptLoader { public: @@ -718,7 +720,7 @@ class spell_sha_item_lightning_shield_trigger : public SpellScriptLoader bool Validate(SpellInfo const* /*spellInfo*/) override { - if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_ITEM_MANA_SURGE)) + if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_ITEM_LIGHTNING_SHIELD_DAMAGE)) return false; return true; } @@ -753,7 +755,7 @@ class spell_sha_item_mana_surge : public SpellScriptLoader bool Validate(SpellInfo const* /*spellInfo*/) override { - if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_ITEM_LIGHTNING_SHIELD_DAMAGE)) + if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_ITEM_MANA_SURGE)) return false; return true; } @@ -865,6 +867,51 @@ class spell_sha_lava_lash : public SpellScriptLoader } }; +// -324 - Lightning Shield +class spell_sha_lightning_shield : public SpellScriptLoader +{ +public: + spell_sha_lightning_shield() : SpellScriptLoader("spell_sha_lightning_shield") { } + + class spell_sha_lightning_shield_AuraScript : public AuraScript + { + PrepareAuraScript(spell_sha_lightning_shield_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_LIGHTNING_SHIELD_R1)) + return false; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + if (eventInfo.GetActionTarget()) + return true; + return false; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + uint32 triggerSpell = sSpellMgr->GetSpellWithRank(SPELL_SHAMAN_LIGHTNING_SHIELD_R1, aurEff->GetSpellInfo()->GetRank()); + + eventInfo.GetActionTarget()->CastSpell(eventInfo.GetActor(), triggerSpell, true, nullptr, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_sha_lightning_shield_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_sha_lightning_shield_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_sha_lightning_shield_AuraScript(); + } +}; + // 52031, 52033, 52034, 52035, 52036, 58778, 58779, 58780 - Mana Spring Totem class spell_sha_mana_spring_totem : public SpellScriptLoader { @@ -924,6 +971,7 @@ class spell_sha_mana_tide_totem : public SpellScriptLoader void HandleDummy(SpellEffIndex /*effIndex*/) { if (Unit* caster = GetCaster()) + { if (Unit* unitTarget = GetHitUnit()) { if (unitTarget->getPowerType() == POWER_MANA) @@ -938,6 +986,7 @@ class spell_sha_mana_tide_totem : public SpellScriptLoader caster->CastCustomSpell(unitTarget, SPELL_SHAMAN_MANA_TIDE_TOTEM, &effBasePoints0, NULL, NULL, true, NULL, NULL, GetOriginalCaster()->GetGUID()); } } + } } void Register() override @@ -952,6 +1001,56 @@ class spell_sha_mana_tide_totem : public SpellScriptLoader } }; +// -30881 - Nature's Guardian +class spell_sha_nature_guardian : public SpellScriptLoader +{ +public: + spell_sha_nature_guardian() : SpellScriptLoader("spell_sha_nature_guardian") { } + + class spell_sha_nature_guardian_AuraScript : public AuraScript + { + PrepareAuraScript(spell_sha_nature_guardian_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_NATURE_GUARDIAN)) + return false; + return true; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + int32 healthpct = aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue(); // %s2 - the 30% threshold for health + + if (Unit* target = eventInfo.GetActionTarget()) + { + if (target->HealthBelowPctDamaged(healthpct, eventInfo.GetDamageInfo()->GetDamage())) + { + + uint32 bp = CalculatePct(target->GetMaxHealth(), aurEff->GetAmount()); + target->CastCustomSpell(SPELL_SHAMAN_NATURE_GUARDIAN, SPELLVALUE_BASE_POINT0, bp, target, true, nullptr, aurEff); + + // Threat reduction is around 10% confirmed in retail and from wiki + Unit* attacker = eventInfo.GetActor(); + if (attacker->IsAlive()) + attacker->getThreatManager().modifyThreatPercent(target, -10); + } + } + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_sha_nature_guardian_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_sha_nature_guardian_AuraScript(); + } +}; + // 6495 - Sentry Totem class spell_sha_sentry_totem : public SpellScriptLoader { @@ -1085,8 +1184,10 @@ void AddSC_shaman_spell_scripts() new spell_sha_item_mana_surge(); new spell_sha_item_t10_elemental_2p_bonus(); new spell_sha_lava_lash(); + new spell_sha_lightning_shield(); new spell_sha_mana_spring_totem(); new spell_sha_mana_tide_totem(); + new spell_sha_nature_guardian(); new spell_sha_sentry_totem(); new spell_sha_thunderstorm(); new spell_sha_totemic_mastery(); diff --git a/src/server/scripts/Spells/spell_warlock.cpp b/src/server/scripts/Spells/spell_warlock.cpp index a0a6189cbe2..5e0074bf9f7 100644 --- a/src/server/scripts/Spells/spell_warlock.cpp +++ b/src/server/scripts/Spells/spell_warlock.cpp @@ -50,6 +50,12 @@ enum WarlockSpells SPELL_WARLOCK_IMPROVED_HEALTH_FUNNEL_BUFF_R2 = 60956, SPELL_WARLOCK_LIFE_TAP_ENERGIZE = 31818, SPELL_WARLOCK_LIFE_TAP_ENERGIZE_2 = 32553, + SPELL_WARLOCK_NETHER_PROTECTION_HOLY = 54370, + SPELL_WARLOCK_NETHER_PROTECTION_FIRE = 54371, + SPELL_WARLOCK_NETHER_PROTECTION_FROST = 54372, + SPELL_WARLOCK_NETHER_PROTECTION_ARCANE = 54373, + SPELL_WARLOCK_NETHER_PROTECTION_SHADOW = 54374, + SPELL_WARLOCK_NETHER_PROTECTION_NATURE = 54375, SPELL_WARLOCK_SOULSHATTER = 32835, SPELL_WARLOCK_SIPHON_LIFE_HEAL = 63106, SPELL_WARLOCK_UNSTABLE_AFFLICTION_DISPEL = 31117 @@ -377,6 +383,8 @@ class spell_warl_demonic_empowerment : public SpellScriptLoader case CREATURE_FAMILY_IMP: targetCreature->CastSpell(targetCreature, SPELL_WARLOCK_DEMONIC_EMPOWERMENT_IMP, true); break; + default: + break; } } } @@ -682,6 +690,95 @@ class spell_warl_life_tap : public SpellScriptLoader } }; +// -30299 - Nether Protection +class spell_warl_nether_protection : public SpellScriptLoader +{ +public: + spell_warl_nether_protection() : SpellScriptLoader("spell_warl_nether_protection") { } + + class spell_warl_nether_protection_AuraScript : public AuraScript + { + PrepareAuraScript(spell_warl_nether_protection_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_NETHER_PROTECTION_HOLY) || + !sSpellMgr->GetSpellInfo(SPELL_WARLOCK_NETHER_PROTECTION_FIRE) || + !sSpellMgr->GetSpellInfo(SPELL_WARLOCK_NETHER_PROTECTION_FROST) || + !sSpellMgr->GetSpellInfo(SPELL_WARLOCK_NETHER_PROTECTION_ARCANE) || + !sSpellMgr->GetSpellInfo(SPELL_WARLOCK_NETHER_PROTECTION_SHADOW) || + !sSpellMgr->GetSpellInfo(SPELL_WARLOCK_NETHER_PROTECTION_NATURE)) + return false; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + if (eventInfo.GetDamageInfo()) + { + switch (GetFirstSchoolInMask(eventInfo.GetDamageInfo()->GetSchoolMask())) + { + case SPELL_SCHOOL_HOLY: + case SPELL_SCHOOL_FIRE: + case SPELL_SCHOOL_NATURE: + case SPELL_SCHOOL_FROST: + case SPELL_SCHOOL_SHADOW: + case SPELL_SCHOOL_ARCANE: + return true; + default: + break; + } + } + + return false; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + uint32 triggerspell = 0; + + switch (GetFirstSchoolInMask(eventInfo.GetDamageInfo()->GetSchoolMask())) + { + case SPELL_SCHOOL_HOLY: + triggerspell = SPELL_WARLOCK_NETHER_PROTECTION_HOLY; + break; + case SPELL_SCHOOL_FIRE: + triggerspell = SPELL_WARLOCK_NETHER_PROTECTION_FIRE; + break; + case SPELL_SCHOOL_NATURE: + triggerspell = SPELL_WARLOCK_NETHER_PROTECTION_NATURE; + break; + case SPELL_SCHOOL_FROST: + triggerspell = SPELL_WARLOCK_NETHER_PROTECTION_FROST; + break; + case SPELL_SCHOOL_SHADOW: + triggerspell = SPELL_WARLOCK_NETHER_PROTECTION_SHADOW; + break; + case SPELL_SCHOOL_ARCANE: + triggerspell = SPELL_WARLOCK_NETHER_PROTECTION_ARCANE; + break; + default: + return; + } + + if (Unit* target = eventInfo.GetActionTarget()) + target->CastSpell(target, triggerspell, true, nullptr, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_warl_nether_protection_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_warl_nether_protection_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_warl_nether_protection_AuraScript(); + } +}; + // 18541 - Ritual of Doom Effect class spell_warl_ritual_of_doom_effect : public SpellScriptLoader { @@ -917,6 +1014,7 @@ void AddSC_warlock_spell_scripts() new spell_warl_haunt(); new spell_warl_health_funnel(); new spell_warl_life_tap(); + new spell_warl_nether_protection(); new spell_warl_ritual_of_doom_effect(); new spell_warl_seed_of_corruption(); new spell_warl_shadow_ward(); diff --git a/src/server/scripts/World/go_scripts.cpp b/src/server/scripts/World/go_scripts.cpp index 3094ecd660a..8f2ea5887d2 100644 --- a/src/server/scripts/World/go_scripts.cpp +++ b/src/server/scripts/World/go_scripts.cpp @@ -1171,7 +1171,7 @@ public: player->CastSpell(player, SPELL_CLEANSING_SOUL); player->SetStandState(UNIT_STAND_STATE_SIT); } - return true; + return true; } }; diff --git a/src/server/scripts/World/item_scripts.cpp b/src/server/scripts/World/item_scripts.cpp index f4241ba0819..52174e1b012 100644 --- a/src/server/scripts/World/item_scripts.cpp +++ b/src/server/scripts/World/item_scripts.cpp @@ -57,18 +57,18 @@ public: //for special scripts switch (itemId) { - case 24538: + case 24538: if (player->GetAreaId() != 3628) disabled = true; - break; - case 34489: + break; + case 34489: if (player->GetZoneId() != 4080) disabled = true; - break; - case 34475: - if (const SpellInfo* spellInfo = sSpellMgr->GetSpellInfo(SPELL_ARCANE_CHARGES)) + break; + case 34475: + if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(SPELL_ARCANE_CHARGES)) Spell::SendCastResult(player, spellInfo, 1, SPELL_FAILED_NOT_ON_GROUND); - break; + break; } // allow use in flight only |
