diff options
Diffstat (limited to 'src/server/scripts')
27 files changed, 1414 insertions, 973 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..438d05c5687 100644 --- a/src/server/scripts/Commands/cs_npc.cpp +++ b/src/server/scripts/Commands/cs_npc.cpp @@ -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..787265cc19b 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,9 +68,9 @@ public:              return false;          } -        CreatureTemplate const* creatrueTemplate = creatureTarget->GetCreatureTemplate(); +        CreatureTemplate const* creatureTemplate = creatureTarget->GetCreatureTemplate();          // Creatures with family 0 crashes the server -        if (!creatrueTemplate->family) +        if (!creatureTemplate->family)          {              handler->PSendSysMessage("This creature cannot be tamed. (family id: 0).");              handler->SetSentErrorMessage(true); @@ -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_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/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/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..11cc645f0cb 100644 --- a/src/server/scripts/Northrend/isle_of_conquest.cpp +++ b/src/server/scripts/Northrend/IsleOfConquest/isle_of_conquest.cpp 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/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..4eafc1cd94e 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,254 @@ 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); + +        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 +1115,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/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/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 | 
