diff options
Diffstat (limited to 'src/server')
222 files changed, 9968 insertions, 6396 deletions
diff --git a/src/server/collision/BoundingIntervalHierarchy.h b/src/server/collision/BoundingIntervalHierarchy.h index ea70fc3e322..a4bbe21006a 100755 --- a/src/server/collision/BoundingIntervalHierarchy.h +++ b/src/server/collision/BoundingIntervalHierarchy.h @@ -128,7 +128,7 @@ class BIH              delete[] dat.primBound;              delete[] dat.indices;          } -        uint32 primCount() { return objects.size(); } +        uint32 primCount() const { return objects.size(); }          template<typename RayCallback>          void intersectRay(const Ray &r, RayCallback& intersectCallback, float &maxDist, bool stopAtFirst=false) const @@ -400,7 +400,8 @@ class BIH          void buildHierarchy(std::vector<uint32> &tempTree, buildData &dat, BuildStats &stats); -        void createNode(std::vector<uint32> &tempTree, int nodeIndex, uint32 left, uint32 right) { +        void createNode(std::vector<uint32> &tempTree, int nodeIndex, uint32 left, uint32 right) const +        {              // write leaf node              tempTree[nodeIndex + 0] = (3 << 30) | left;              tempTree[nodeIndex + 1] = right - left + 1; diff --git a/src/server/collision/Maps/TileAssembler.cpp b/src/server/collision/Maps/TileAssembler.cpp index e7693a70de4..3bfed7d322d 100644 --- a/src/server/collision/Maps/TileAssembler.cpp +++ b/src/server/collision/Maps/TileAssembler.cpp @@ -312,7 +312,7 @@ namespace VMAP          // write WorldModel          WorldModel model;          model.setRootWmoID(raw_model.RootWMOID); -        if (raw_model.groupsArray.size()) +        if (!raw_model.groupsArray.empty())          {              std::vector<GroupModel> groupsArray; diff --git a/src/server/collision/Models/GameObjectModel.cpp b/src/server/collision/Models/GameObjectModel.cpp index 84c736c22e8..8b63620e783 100644 --- a/src/server/collision/Models/GameObjectModel.cpp +++ b/src/server/collision/Models/GameObjectModel.cpp @@ -176,7 +176,7 @@ bool GameObjectModel::intersectRay(const G3D::Ray& ray, float& MaxDist, bool Sto      Ray modRay(p, iInvRot * ray.direction());      float distance = MaxDist * iInvScale;      bool hit = iModel->IntersectRay(modRay, distance, StopAtFirstHit); -    if(hit) +    if (hit)      {          distance *= iScale;          MaxDist = distance; diff --git a/src/server/collision/Models/WorldModel.cpp b/src/server/collision/Models/WorldModel.cpp index b818232fb32..b4f3f73fc98 100644 --- a/src/server/collision/Models/WorldModel.cpp +++ b/src/server/collision/Models/WorldModel.cpp @@ -42,7 +42,7 @@ namespace VMAP          const Vector3 p(ray.direction().cross(e2));          const float a = e1.dot(p); -        if (abs(a) < EPS) { +        if (fabs(a) < EPS) {              // Determinant is ill-conditioned; abort early              return false;          } diff --git a/src/server/collision/RegularGrid.h b/src/server/collision/RegularGrid.h index 2867b29cfc1..00d7b0cd209 100644 --- a/src/server/collision/RegularGrid.h +++ b/src/server/collision/RegularGrid.h @@ -176,7 +176,7 @@ public:              }              if (cell == last_cell)                  break; -            if(tMaxX < tMaxY) +            if (tMaxX < tMaxY)              {                  tMaxX += tDeltaX;                  cell.x += stepX; diff --git a/src/server/game/AI/CoreAI/GameObjectAI.h b/src/server/game/AI/CoreAI/GameObjectAI.h index f4555649210..fbc8675cc47 100644 --- a/src/server/game/AI/CoreAI/GameObjectAI.h +++ b/src/server/game/AI/CoreAI/GameObjectAI.h @@ -53,7 +53,8 @@ class GameObjectAI          virtual uint64 GetData64(uint32 /*id*/) { return 0; }          virtual void SetData(uint32 /*id*/, uint32 /*value*/) {}          virtual void OnGameEvent(bool /*start*/, uint16 /*eventId*/) {} -        virtual void OnStateChanged(uint32 /*state*/, Unit* /*unit*/) { } +        virtual void OnStateChanged(uint32 /*state*/, Unit* /*unit*/) {} +        virtual void EventInform(uint32 /*eventId*/) {}  };  class NullGameObjectAI : public GameObjectAI diff --git a/src/server/game/AI/CoreAI/PetAI.cpp b/src/server/game/AI/CoreAI/PetAI.cpp index 160b406a6ea..97ae0581a18 100755 --- a/src/server/game/AI/CoreAI/PetAI.cpp +++ b/src/server/game/AI/CoreAI/PetAI.cpp @@ -532,3 +532,19 @@ bool PetAI::CanAttack(Unit* target)      // default, though we shouldn't ever get here      return false;  } + +void PetAI::ReceiveEmote(Player* player, uint32 emote) +{ +    if (me->GetOwnerGUID() && me->GetOwnerGUID() == player->GetGUID()) +        switch (emote) +        { +            case TEXT_EMOTE_COWER: +                if (me->isPet() && me->ToPet()->IsPetGhoul()) +                    me->HandleEmoteCommand(EMOTE_ONESHOT_ROAR); +                break; +            case TEXT_EMOTE_ANGRY: +                if (me->isPet() && me->ToPet()->IsPetGhoul()) +                    me->HandleEmoteCommand(EMOTE_ONESHOT_COWER); +                break; +        } +} diff --git a/src/server/game/AI/CoreAI/PetAI.h b/src/server/game/AI/CoreAI/PetAI.h index ed3e2305556..8e5311fa000 100755 --- a/src/server/game/AI/CoreAI/PetAI.h +++ b/src/server/game/AI/CoreAI/PetAI.h @@ -42,6 +42,7 @@ class PetAI : public CreatureAI          void MovementInform(uint32 moveType, uint32 data);          void OwnerDamagedBy(Unit* attacker);          void OwnerAttacked(Unit* target); +        void ReceiveEmote(Player* player, uint32 textEmote);      private:          bool _isVisible(Unit*) const; diff --git a/src/server/game/AI/CreatureAI.h b/src/server/game/AI/CreatureAI.h index 94ac452b9f3..68752b82e7f 100755 --- a/src/server/game/AI/CreatureAI.h +++ b/src/server/game/AI/CreatureAI.h @@ -128,8 +128,6 @@ class CreatureAI : public UnitAI          void OnCharmed(bool apply); -        //virtual void SpellClick(Player* player) {} -          // Called at reaching home after evade          virtual void JustReachedHome() {} @@ -171,6 +169,8 @@ class CreatureAI : public UnitAI          virtual void PassengerBoarded(Unit* /*passenger*/, int8 /*seatId*/, bool /*apply*/) {} +        virtual void OnSpellClick(Unit* /*clicker*/) { } +          virtual bool CanSeeAlways(WorldObject const* /*obj*/) { return false; }      protected:          virtual void MoveInLineOfSight(Unit* /*who*/); diff --git a/src/server/game/AI/EventAI/CreatureEventAIMgr.cpp b/src/server/game/AI/EventAI/CreatureEventAIMgr.cpp index 517e55af457..a863f2f89cf 100755 --- a/src/server/game/AI/EventAI/CreatureEventAIMgr.cpp +++ b/src/server/game/AI/EventAI/CreatureEventAIMgr.cpp @@ -204,12 +204,17 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()          temp.raw.param3 = fields[8].GetInt32();          temp.raw.param4 = fields[9].GetInt32(); +        CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(creature_id);          //Creature does not exist in database -        if (!sObjectMgr->GetCreatureTemplate(temp.creature_id)) +        if (!cInfo)          { -            sLog->outErrorDb("CreatureEventAI:  Event %u has script for non-existing creature entry (%u), skipping.", i, temp.creature_id); +            sLog->outErrorDb("CreatureEventAI:  Event %u has script for non-existing creature entry (%u), skipping.", i, creature_id);              continue;          } +         +        // Only on the first script +        if (cInfo->AIName != "EventAI" && m_CreatureEventAI_Event_Map[creature_id].empty()) +            sLog->outErrorDb("Creature entry %u has EventAI scripts, but its AIName is not 'EventAI' - possible AI-mismatch?", temp.creature_id);          //No chance of this event occuring          if (temp.event_chance == 0) @@ -735,18 +740,6 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()      }      while (result->NextRow()); -    for (CreatureEventAI_Event_Map::const_iterator itr = m_CreatureEventAI_Event_Map.begin(); itr != m_CreatureEventAI_Event_Map.end(); ++itr) -    { -        if (CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(itr->first)) -        { -            if (cInfo->AIName != "EventAI") -            { -                sLog->outErrorDb("Creature entry %u has EventAI scripts, but its AIName is not 'EventAI', changing to EventAI", itr->first); -                const_cast<CreatureTemplate*>(cInfo)->AIName = "EventAI"; -            } -        } -    } -      sLog->outString(">> Loaded %u CreatureEventAI scripts in %u ms", count, GetMSTimeDiffToNow(oldMSTime));      sLog->outString();  } diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.h b/src/server/game/AI/ScriptedAI/ScriptedCreature.h index 4fac8b3cba5..ba0a94d2590 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedCreature.h +++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.h @@ -191,7 +191,7 @@ struct ScriptedAI : public CreatureAI      //Generally used to control if MoveChase() is to be used or not in AttackStart(). Some creatures does not chase victims      void SetCombatMovement(bool allowMovement); -    bool IsCombatMovementAllowed() { return _isCombatMovementAllowed; } +    bool IsCombatMovementAllowed() const { return _isCombatMovementAllowed; }      bool EnterEvadeIfOutOfCombatArea(uint32 const diff); @@ -200,16 +200,16 @@ struct ScriptedAI : public CreatureAI      //   - for raid in mode 10-Heroic      //   - for raid in mode 25-heroic      // DO NOT USE to check raid in mode 25-normal. -    bool IsHeroic() { return _isHeroic; } +    bool IsHeroic() const { return _isHeroic; }      // return the dungeon or raid difficulty -    Difficulty GetDifficulty() { return _difficulty; } +    Difficulty GetDifficulty() const { return _difficulty; }      // return true for 25 man or 25 man heroic mode -    bool Is25ManRaid() { return _difficulty & RAID_DIFFICULTY_MASK_25MAN; } +    bool Is25ManRaid() const { return _difficulty & RAID_DIFFICULTY_MASK_25MAN; }      template<class T> inline -    const T& DUNGEON_MODE(const T& normal5, const T& heroic10) +    const T& DUNGEON_MODE(const T& normal5, const T& heroic10) const      {          switch (_difficulty)          { @@ -225,7 +225,7 @@ struct ScriptedAI : public CreatureAI      }      template<class T> inline -    const T& RAID_MODE(const T& normal10, const T& normal25) +    const T& RAID_MODE(const T& normal10, const T& normal25) const      {          switch (_difficulty)          { @@ -241,7 +241,7 @@ struct ScriptedAI : public CreatureAI      }      template<class T> inline -    const T& RAID_MODE(const T& normal10, const T& normal25, const T& heroic10, const T& heroic25) +    const T& RAID_MODE(const T& normal10, const T& normal25, const T& heroic10, const T& heroic25) const      {          switch (_difficulty)          { diff --git a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp index 13bbbe2c338..987af82e496 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp +++ b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp @@ -327,7 +327,6 @@ Player* FollowerAI::GetLeaderForFollower()                          sLog->outDebug(LOG_FILTER_TSCR, "TSCR: FollowerAI GetLeader changed and returned new leader.");                          m_uiLeaderGUID = member->GetGUID();                          return member; -                        break;                      }                  }              } diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp index 08f1b18ffad..96fc43e0572 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.cpp +++ b/src/server/game/AI/SmartScripts/SmartAI.cpp @@ -696,8 +696,9 @@ void SmartAI::OnCharmed(bool apply)      GetScript()->ProcessEventsFor(SMART_EVENT_CHARMED, NULL, 0, 0, apply);  } -void SmartAI::DoAction(const int32 /*param*/) +void SmartAI::DoAction(const int32 param)  { +    GetScript()->ProcessEventsFor(SMART_EVENT_ACTION_DONE, NULL, param);  }  uint32 SmartAI::GetData(uint32 /*id*/) @@ -825,27 +826,10 @@ void SmartAI::sOnGameEvent(bool start, uint16 eventId)      GetScript()->ProcessEventsFor(start ? SMART_EVENT_GAME_EVENT_START : SMART_EVENT_GAME_EVENT_END, NULL, eventId);  } -/* -SMART_EVENT_UPDATE_OOC -SMART_EVENT_SPELLHIT -SMART_EVENT_RANGE -SMART_EVENT_RESPAWN -SMART_EVENT_SUMMONED_UNIT -SMART_EVENT_ACCEPTED_QUEST -SMART_EVENT_REWARD_QUEST -SMART_EVENT_TARGET_BUFFED -SMART_EVENT_SUMMON_DESPAWNED -SMART_EVENT_AI_INIT -SMART_EVENT_DATA_SET -SMART_EVENT_TEXT_OVER -SMART_EVENT_TIMED_EVENT_TRIGGERED -SMART_EVENT_UPDATE -SMART_EVENT_LINK -SMART_EVENT_GOSSIP_SELECT -SMART_EVENT_JUST_CREATED -SMART_EVENT_GOSSIP_HELLO -SMART_EVENT_DEATH -*/ +void SmartAI::OnSpellClick(Unit* clicker) +{ +    GetScript()->ProcessEventsFor(SMART_EVENT_ON_SPELLCLICK, clicker); +}  int SmartGameObjectAI::Permissible(const GameObject* g)  { @@ -937,6 +921,11 @@ void SmartGameObjectAI::OnStateChanged(uint32 state, Unit* unit)      GetScript()->ProcessEventsFor(SMART_EVENT_GO_STATE_CHANGED, unit, state);  } +void SmartGameObjectAI::EventInform(uint32 eventId) +{ +    GetScript()->ProcessEventsFor(SMART_EVENT_GO_EVENT_INFORM, NULL, eventId); +} +  class SmartTrigger : public AreaTriggerScript  {      public: diff --git a/src/server/game/AI/SmartScripts/SmartAI.h b/src/server/game/AI/SmartScripts/SmartAI.h index 435aa176d4d..79cef0c3b37 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.h +++ b/src/server/game/AI/SmartScripts/SmartAI.h @@ -198,6 +198,8 @@ class SmartAI : public CreatureAI          void RemoveAuras(); +        void OnSpellClick(Unit* clicker); +      private:          uint32 mFollowCreditType;          uint32 mFollowArrivedTimer; @@ -235,30 +237,31 @@ class SmartAI : public CreatureAI  class SmartGameObjectAI : public GameObjectAI  { -public: -    SmartGameObjectAI(GameObject* g) : GameObjectAI(g), go(g) {} -    ~SmartGameObjectAI() {} - -    void UpdateAI(uint32 diff); -    void InitializeAI(); -    void Reset(); -    SmartScript* GetScript() { return &mScript; } -    static int Permissible(const GameObject* g); - -    bool GossipHello(Player* player); -    bool GossipSelect(Player* player, uint32 sender, uint32 action); -    bool GossipSelectCode(Player* /*player*/, uint32 /*sender*/, uint32 /*action*/, const char* /*code*/); -    bool QuestAccept(Player* player, Quest const* quest); -    bool QuestReward(Player* player, Quest const* quest, uint32 opt); -    uint32 GetDialogStatus(Player* /*player*/); -    void Destroyed(Player* player, uint32 eventId); -    void SetData(uint32 id, uint32 value); -    void SetScript9(SmartScriptHolder& e, uint32 entry, Unit* invoker); -    void OnGameEvent(bool start, uint16 eventId); -    void OnStateChanged(uint32 state, Unit* unit); - -protected: -    GameObject* const go; -    SmartScript mScript; +    public: +        SmartGameObjectAI(GameObject* g) : GameObjectAI(g), go(g) {} +        ~SmartGameObjectAI() {} + +        void UpdateAI(uint32 diff); +        void InitializeAI(); +        void Reset(); +        SmartScript* GetScript() { return &mScript; } +        static int Permissible(const GameObject* g); + +        bool GossipHello(Player* player); +        bool GossipSelect(Player* player, uint32 sender, uint32 action); +        bool GossipSelectCode(Player* /*player*/, uint32 /*sender*/, uint32 /*action*/, const char* /*code*/); +        bool QuestAccept(Player* player, Quest const* quest); +        bool QuestReward(Player* player, Quest const* quest, uint32 opt); +        uint32 GetDialogStatus(Player* /*player*/); +        void Destroyed(Player* player, uint32 eventId); +        void SetData(uint32 id, uint32 value); +        void SetScript9(SmartScriptHolder& e, uint32 entry, Unit* invoker); +        void OnGameEvent(bool start, uint16 eventId); +        void OnStateChanged(uint32 state, Unit* unit); +        void EventInform(uint32 eventId); + +    protected: +        GameObject* const go; +        SmartScript mScript;  };  #endif diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index 01a9b777358..103cde80f43 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -160,9 +160,6 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u      {          case SMART_ACTION_TALK:          { -            if (!me) -                break; -              ObjectList* targets = GetTargets(e, unit);              Creature* talker = me;              Player* targetPlayer = NULL; @@ -185,6 +182,9 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u                  delete targets;              } +            if (!talker) +                break; +              mTalkerEntry = talker->GetEntry();              mLastTextID = e.action.talk.textGroupID;              mTextTimer = e.action.talk.duration; @@ -789,7 +789,11 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u                  if (!IsUnit((*itr)))                      continue; -                (*itr)->ToUnit()->RemoveAurasDueToSpell(e.action.removeAura.spell); +                if (e.action.removeAura.spell == 0) +                    (*itr)->ToUnit()->RemoveAllAuras(); +                else +                    (*itr)->ToUnit()->RemoveAurasDueToSpell(e.action.removeAura.spell); +                  sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction: SMART_ACTION_REMOVEAURASFROMSPELL: Unit %u, spell %u",                      (*itr)->GetGUIDLow(), e.action.removeAura.spell);              } @@ -1539,8 +1543,8 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u              if (!IsSmart())                  break; -            float attackDistance = (float)e.action.setRangedMovement.distance; -            float attackAngle = e.action.setRangedMovement.angle / 180.0f * M_PI; +            float attackDistance = float(e.action.setRangedMovement.distance); +            float attackAngle = float(e.action.setRangedMovement.angle) / 180.0f * M_PI;              ObjectList* targets = GetTargets(e, unit);              if (targets) @@ -2016,16 +2020,16 @@ void SmartScript::InstallTemplate(SmartScriptHolder const& e)                  if (!go)                      return;                  //store hostage as id1 -                AddEvent(SMART_EVENT_GOSSIP_HELLO, 0, 0, 0, 0, 0, SMART_ACTION_STORE_TARGET_LIST, 1, 0, 0, 0, 0, 0, SMART_TARGET_CLOSEST_CREATURE, e.action.installTtemplate.param1, 10, 0, 0); +                AddEvent(SMART_EVENT_GO_STATE_CHANGED, 0, 2, 0, 0, 0, SMART_ACTION_STORE_TARGET_LIST, 1, 0, 0, 0, 0, 0, SMART_TARGET_CLOSEST_CREATURE, e.action.installTtemplate.param1, 10, 0, 0);                  //store invoker as id2 -                AddEvent(SMART_EVENT_GOSSIP_HELLO, 0, 0, 0, 0, 0, SMART_ACTION_STORE_TARGET_LIST, 2, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 0); +                AddEvent(SMART_EVENT_GO_STATE_CHANGED, 0, 2, 0, 0, 0, SMART_ACTION_STORE_TARGET_LIST, 2, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 0);                  //signal hostage -                AddEvent(SMART_EVENT_GOSSIP_HELLO, 0, 0, 0, 0, 0, SMART_ACTION_SET_DATA, 0, 0, 0, 0, 0, 0, SMART_TARGET_STORED, 1, 0, 0, 0); +                AddEvent(SMART_EVENT_GO_STATE_CHANGED, 0, 2, 0, 0, 0, SMART_ACTION_SET_DATA, 0, 0, 0, 0, 0, 0, SMART_TARGET_STORED, 1, 0, 0, 0);                  //when hostage raeched end point, give credit to invoker                  if (e.action.installTtemplate.param2)                      AddEvent(SMART_EVENT_DATA_SET, 0, 0, 0, 0, 0, SMART_ACTION_CALL_KILLEDMONSTER, e.action.installTtemplate.param1, 0, 0, 0, 0, 0, SMART_TARGET_STORED, 2, 0, 0, 0);                  else -                    AddEvent(SMART_EVENT_GOSSIP_HELLO, 0, 0, 0, 0, 0, SMART_ACTION_CALL_KILLEDMONSTER, e.action.installTtemplate.param1, 0, 0, 0, 0, 0, SMART_TARGET_STORED, 2, 0, 0, 0); +                    AddEvent(SMART_EVENT_GO_STATE_CHANGED, 0, 2, 0, 0, 0, SMART_ACTION_CALL_KILLEDMONSTER, e.action.installTtemplate.param1, 0, 0, 0, 0, 0, SMART_TARGET_STORED, 2, 0, 0, 0);                  break;              }          case SMARTAI_TEMPLATE_BASIC: @@ -2119,12 +2123,20 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*          case SMART_TARGET_INVOKER_PARTY:              if (trigger)              { -                l->push_back(trigger);                  if (Player* player = trigger->ToPlayer()) +                {                      if (Group* group = player->GetGroup()) +                    {                          for (GroupReference* groupRef = group->GetFirstMember(); groupRef != NULL; groupRef = groupRef->next())                              if (Player* member = groupRef->getSource())                                  l->push_back(member); +                    } +                    // We still add the player to the list if there is no group. If we do +                    // this even if there is a group (thus the else-check), it will add the +                    // same player to the list twice. We don't want that to happen. +                    else +                        l->push_back(trigger); +                }              }              break;          case SMART_TARGET_CREATURE_RANGE: @@ -2522,6 +2534,7 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui          case SMART_EVENT_JUST_CREATED:          case SMART_EVENT_GOSSIP_HELLO:          case SMART_EVENT_FOLLOW_COMPLETED: +        case SMART_EVENT_ON_SPELLCLICK:              ProcessAction(e, unit, var0, var1, bvar, spell, gob);              break;          case SMART_EVENT_IS_BEHIND_TARGET: @@ -2759,6 +2772,20 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui              ProcessAction(e, unit, var0, var1);              break;          } +        case SMART_EVENT_GO_EVENT_INFORM: +        { +            if (e.event.eventInform.eventId != var0) +                return; +            ProcessAction(e, NULL, var0); +            break; +        } +        case SMART_EVENT_ACTION_DONE: +        { +            if (e.event.doAction.eventId != var0) +                return; +            ProcessAction(e, unit, var0); +            break; +        }          default:              sLog->outErrorDb("SmartScript::ProcessEvent: Unhandled Event type %u", e.GetEventType());              break; @@ -2875,23 +2902,6 @@ void SmartScript::InstallEvents()      }  } -bool SmartScript::ConditionValid(Unit* u, int32 c, int32 v1, int32 v2, int32 v3) -{ -    if (c == 0) -        return true; - -    if (!u || !u->ToPlayer()) -        return false; - -    Condition cond; -    cond.ConditionType = ConditionTypes(uint32(c)); -    cond.ConditionValue1 = uint32(v1); -    cond.ConditionValue1 = uint32(v2); -    cond.ConditionValue1 = uint32(v3); -    ConditionSourceInfo srcInfo = ConditionSourceInfo(u->ToPlayer()); -    return cond.Meets(srcInfo); -} -  void SmartScript::OnUpdate(uint32 const diff)  {      if ((mScriptType == SMART_SCRIPT_TYPE_CREATURE || mScriptType == SMART_SCRIPT_TYPE_GAMEOBJECT) && !GetBaseObject()) diff --git a/src/server/game/AI/SmartScripts/SmartScript.h b/src/server/game/AI/SmartScripts/SmartScript.h index 5fb691c87f2..03d533e69e5 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.h +++ b/src/server/game/AI/SmartScripts/SmartScript.h @@ -83,8 +83,6 @@ class SmartScript              return obj && obj->GetTypeId() == TYPEID_GAMEOBJECT;          } -        bool ConditionValid(Unit* u, int32 c, int32 v1, int32 v2, int32 v3); -          void OnUpdate(const uint32 diff);          void OnMoveInLineOfSight(Unit* who); diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index a7149f37480..de766d2a7e1 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -475,64 +475,78 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)                  break;              }              case SMART_EVENT_TRANSPORT_ADDCREATURE: -                { -                    if (e.event.transportAddCreature.creature && !IsCreatureValid(e, e.event.transportAddCreature.creature)) -                        return false; -                    break; -                } +            { +                if (e.event.transportAddCreature.creature && !IsCreatureValid(e, e.event.transportAddCreature.creature)) +                    return false; +                break; +            }              case SMART_EVENT_MOVEMENTINFORM: +            { +                if (e.event.movementInform.type > NULL_MOTION_TYPE)                  { -                    if (e.event.movementInform.type > NULL_MOTION_TYPE) -                    { -                        sLog->outErrorDb("SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses invalid Motion type %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.event.movementInform.type); -                        return false; -                    } -                    break; +                    sLog->outErrorDb("SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses invalid Motion type %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.event.movementInform.type); +                    return false;                  } +                break; +            }              case SMART_EVENT_DATA_SET: -                { -                    if (!IsMinMaxValid(e, e.event.dataSet.cooldownMin, e.event.dataSet.cooldownMax)) -                        return false; -                    break; -                } +            { +                if (!IsMinMaxValid(e, e.event.dataSet.cooldownMin, e.event.dataSet.cooldownMax)) +                    return false; +                break; +            }              case SMART_EVENT_AREATRIGGER_ONTRIGGER: -                { -                    if (e.event.areatrigger.id && !IsAreaTriggerValid(e, e.event.areatrigger.id)) -                        return false; -                    break; -                } +            { +                if (e.event.areatrigger.id && !IsAreaTriggerValid(e, e.event.areatrigger.id)) +                    return false; +                break; +            }              case SMART_EVENT_TEXT_OVER:                  //if (e.event.textOver.textGroupID && !IsTextValid(e, e.event.textOver.textGroupID)) return false;// 0 is a valid text group!                  break;              case SMART_EVENT_LINK: +            { +                if (e.link && e.link == e.event_id)                  { -                    if (e.link && e.link == e.event_id) -                    { -                        sLog->outErrorDb("SmartAIMgr: Entry %d SourceType %u, Event %u, Link Event is linking self (infinite loop), skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id); -                        return false; -                    } -                    break; +                    sLog->outErrorDb("SmartAIMgr: Entry %d SourceType %u, Event %u, Link Event is linking self (infinite loop), skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id); +                    return false;                  } +                break; +            }              case SMART_EVENT_DUMMY_EFFECT: +            {                  if (!IsSpellValid(e, e.event.dummy.spell))                      return false;                  if (e.event.dummy.effIndex > EFFECT_2)                      return false;                  break; +            }              case SMART_EVENT_IS_BEHIND_TARGET: +            {                  if (!IsMinMaxValid(e, e.event.behindTarget.cooldownMin, e.event.behindTarget.cooldownMax))                      return false;                  break; +            }              case SMART_EVENT_GAME_EVENT_START:              case SMART_EVENT_GAME_EVENT_END: +            { +                GameEventMgr::GameEventDataMap const& events = sGameEventMgr->GetEventMap(); +                if (e.event.gameEvent.gameEventId >= events.size() || !events[e.event.gameEvent.gameEventId].isValid()) +                    return false; +                break; +            } +            case SMART_EVENT_ACTION_DONE: +            { +                if (e.event.doAction.eventId > EVENT_CHARGE)                  { -                    GameEventMgr::GameEventDataMap const& events = sGameEventMgr->GetEventMap(); -                    if (e.event.gameEvent.gameEventId >= events.size() || !events[e.event.gameEvent.gameEventId].isValid()) -                        return false; -                    break; +                    sLog->outErrorDb("SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses invalid event id %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.event.doAction.eventId); +                    return false;                  } +                break; +            }              case SMART_EVENT_GO_STATE_CHANGED: +            case SMART_EVENT_GO_EVENT_INFORM:              case SMART_EVENT_TIMED_EVENT_TRIGGERED:              case SMART_EVENT_INSTANCE_PLAYER_ENTER:              case SMART_EVENT_TRANSPORT_RELOCATE: @@ -563,6 +577,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)              case SMART_EVENT_GOSSIP_HELLO:              case SMART_EVENT_JUST_CREATED:              case SMART_EVENT_FOLLOW_COMPLETED: +            case SMART_EVENT_ON_SPELLCLICK:                  break;              default:                  sLog->outErrorDb("SmartAIMgr: Not handled event_type(%u), Entry %d SourceType %u Event %u Action %u, skipped.", e.GetEventType(), e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType()); @@ -709,7 +724,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)                  return false;              break;          case SMART_ACTION_REMOVEAURASFROMSPELL: -            if (!IsSpellValid(e, e.action.removeAura.spell)) +            if (e.action.removeAura.spell != 0 && !IsSpellValid(e, e.action.removeAura.spell))                  return false;              break;          case SMART_ACTION_RANDOM_PHASE: diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index e6c5eb727d7..155f27d0fe7 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -22,7 +22,6 @@  #include "Creature.h"  #include "CreatureAI.h"  #include "Unit.h" -#include "ConditionMgr.h"  #include "Spell.h"  #include "DB2Stores.h" @@ -83,80 +82,82 @@ const uint32 SmartPhaseMask[SMART_EVENT_PHASE_COUNT][2] =  enum SMART_EVENT  { -    SMART_EVENT_UPDATE_IC                = 0,       //1             // InitialMin, InitialMax, RepeatMin, RepeatMax -    SMART_EVENT_UPDATE_OOC               = 1,       //1             // InitialMin, InitialMax, RepeatMin, RepeatMax -    SMART_EVENT_HEALT_PCT                = 2,       //1             // HPMin%, HPMax%,  RepeatMin, RepeatMax -    SMART_EVENT_MANA_PCT                 = 3,       //1             // ManaMin%, ManaMax%, RepeatMin, RepeatMax -    SMART_EVENT_AGGRO                    = 4,       //1             // NONE -    SMART_EVENT_KILL                     = 5,       //1             // CooldownMin0, CooldownMax1, playerOnly2, else creature entry3 -    SMART_EVENT_DEATH                    = 6,       //1             // NONE -    SMART_EVENT_EVADE                    = 7,       //1             // NONE -    SMART_EVENT_SPELLHIT                 = 8,       //1             // SpellID, School, CooldownMin, CooldownMax -    SMART_EVENT_RANGE                    = 9,       //1             // MinDist, MaxDist, RepeatMin, RepeatMax -    SMART_EVENT_OOC_LOS                  = 10,      //1             // NoHostile, MaxRnage, CooldownMin, CooldownMax -    SMART_EVENT_RESPAWN                  = 11,      //1             // type, MapId, ZoneId -    SMART_EVENT_TARGET_HEALTH_PCT        = 12,      //1             // HPMin%, HPMax%, RepeatMin, RepeatMax -    SMART_EVENT_TARGET_CASTING           = 13,      //1             // RepeatMin, RepeatMax -    SMART_EVENT_FRIENDLY_HEALTH          = 14,      //1             // HPDeficit, Radius, RepeatMin, RepeatMax -    SMART_EVENT_FRIENDLY_IS_CC           = 15,      //1             // Radius, RepeatMin, RepeatMax -    SMART_EVENT_FRIENDLY_MISSING_BUFF    = 16,      //1             // SpellId, Radius, RepeatMin, RepeatMax -    SMART_EVENT_SUMMONED_UNIT            = 17,      //1             // CreatureId(0 all), CooldownMin, CooldownMax -    SMART_EVENT_TARGET_MANA_PCT          = 18,      //1             // ManaMin%, ManaMax%, RepeatMin, RepeatMax -    SMART_EVENT_ACCEPTED_QUEST           = 19,      //1             // QuestID(0any) -    SMART_EVENT_REWARD_QUEST             = 20,      //1             // QuestID(0any) -    SMART_EVENT_REACHED_HOME             = 21,      //1             // NONE -    SMART_EVENT_RECEIVE_EMOTE            = 22,      //1             // EmoteId, CooldownMin, CooldownMax, condition, val1, val2, val3 -    SMART_EVENT_HAS_AURA                 = 23,      //1             // Param1 = SpellID, Param2 = Number of Time STacked, Param3/4 RepeatMin, RepeatMax -    SMART_EVENT_TARGET_BUFFED            = 24,      //1             // Param1 = SpellID, Param2 = Number of Time STacked, Param3/4 RepeatMin, RepeatMax -    SMART_EVENT_RESET                    = 25,      //1             // Called after combat, when the creature respawn and spawn. - -    SMART_EVENT_IC_LOS                   = 26,      //1             // NoHostile, MaxRnage, CooldownMin, CooldownMax -    SMART_EVENT_PASSENGER_BOARDED        = 27,      //1             // CooldownMin, CooldownMax -    SMART_EVENT_PASSENGER_REMOVED        = 28,      //1             // CooldownMin, CooldownMax -    SMART_EVENT_CHARMED                  = 29,      //1             // NONE -    SMART_EVENT_CHARMED_TARGET           = 30,      //1             // NONE -    SMART_EVENT_SPELLHIT_TARGET          = 31,      //1             // SpellID, School, CooldownMin, CooldownMax -    SMART_EVENT_DAMAGED                  = 32,      //1             // MinDmg, MaxDmg, CooldownMin, CooldownMax -    SMART_EVENT_DAMAGED_TARGET           = 33,      //1             // MinDmg, MaxDmg, CooldownMin, CooldownMax -    SMART_EVENT_MOVEMENTINFORM           = 34,      //1             // MovementType(any), PointID -    SMART_EVENT_SUMMON_DESPAWNED         = 35,      //1             // Entry, CooldownMin, CooldownMax -    SMART_EVENT_CORPSE_REMOVED           = 36,      //1             // NONE -    SMART_EVENT_AI_INIT                  = 37,      //1             // NONE -    SMART_EVENT_DATA_SET                 = 38,      //1             // Id, Value, CooldownMin, CooldownMax -    SMART_EVENT_WAYPOINT_START           = 39,      //1             // PointId(0any), pathID(0any) -    SMART_EVENT_WAYPOINT_REACHED         = 40,      //1             // PointId(0any), pathID(0any) -    SMART_EVENT_TRANSPORT_ADDPLAYER      = 41,      //1             // NONE -    SMART_EVENT_TRANSPORT_ADDCREATURE    = 42,      //1             // Entry (0 any) -    SMART_EVENT_TRANSPORT_REMOVE_PLAYER  = 43,      //1             // NONE -    SMART_EVENT_TRANSPORT_RELOCATE       = 44,      //1             // PointId -    SMART_EVENT_INSTANCE_PLAYER_ENTER    = 45,      //1             // Team (0 any), CooldownMin, CooldownMax -    SMART_EVENT_AREATRIGGER_ONTRIGGER    = 46,      //1             // TriggerId(0 any) -    SMART_EVENT_QUEST_ACCEPTED           = 47,      //1             // none -    SMART_EVENT_QUEST_OBJ_COPLETETION    = 48,      //1             // none -    SMART_EVENT_QUEST_COMPLETION         = 49,      //1             // none -    SMART_EVENT_QUEST_REWARDED           = 50,      //1             // none -    SMART_EVENT_QUEST_FAIL               = 51,      //1             // none -    SMART_EVENT_TEXT_OVER                = 52,      //1             // GroupId from creature_text,  creature entry who talks (0 any) -    SMART_EVENT_RECEIVE_HEAL             = 53,      //1             // MinHeal, MaxHeal, CooldownMin, CooldownMax -    SMART_EVENT_JUST_SUMMONED            = 54,      //1             // none -    SMART_EVENT_WAYPOINT_PAUSED          = 55,      //1             // PointId(0any), pathID(0any) -    SMART_EVENT_WAYPOINT_RESUMED         = 56,      //1             // PointId(0any), pathID(0any) -    SMART_EVENT_WAYPOINT_STOPPED         = 57,      //1             // PointId(0any), pathID(0any) -    SMART_EVENT_WAYPOINT_ENDED           = 58,      //1             // PointId(0any), pathID(0any) -    SMART_EVENT_TIMED_EVENT_TRIGGERED    = 59,      //1             // id -    SMART_EVENT_UPDATE                   = 60,      //1             // InitialMin, InitialMax, RepeatMin, RepeatMax -    SMART_EVENT_LINK                     = 61,      //1             // INTERNAL USAGE, no params, used to link together multiple events, does not use any extra resources to iterate event lists needlessly -    SMART_EVENT_GOSSIP_SELECT            = 62,      //1             // menuID, actionID -    SMART_EVENT_JUST_CREATED             = 63,      //1             // none -    SMART_EVENT_GOSSIP_HELLO             = 64,      //1             // none -    SMART_EVENT_FOLLOW_COMPLETED         = 65,      //1             // none -    SMART_EVENT_DUMMY_EFFECT             = 66,      //1             // spellId, effectIndex -    SMART_EVENT_IS_BEHIND_TARGET         = 67,      //1             // cooldownMin, CooldownMax -    SMART_EVENT_GAME_EVENT_START         = 68,      //1             // game_event.Entry -    SMART_EVENT_GAME_EVENT_END           = 69,      //1             // game_event.Entry -    SMART_EVENT_GO_STATE_CHANGED         = 70,      //                 go state - -    SMART_EVENT_END                      = 71, +    SMART_EVENT_UPDATE_IC                = 0,       // InitialMin, InitialMax, RepeatMin, RepeatMax +    SMART_EVENT_UPDATE_OOC               = 1,       // InitialMin, InitialMax, RepeatMin, RepeatMax +    SMART_EVENT_HEALT_PCT                = 2,       // HPMin%, HPMax%,  RepeatMin, RepeatMax +    SMART_EVENT_MANA_PCT                 = 3,       // ManaMin%, ManaMax%, RepeatMin, RepeatMax +    SMART_EVENT_AGGRO                    = 4,       // NONE +    SMART_EVENT_KILL                     = 5,       // CooldownMin0, CooldownMax1, playerOnly2, else creature entry3 +    SMART_EVENT_DEATH                    = 6,       // NONE +    SMART_EVENT_EVADE                    = 7,       // NONE +    SMART_EVENT_SPELLHIT                 = 8,       // SpellID, School, CooldownMin, CooldownMax +    SMART_EVENT_RANGE                    = 9,       // MinDist, MaxDist, RepeatMin, RepeatMax +    SMART_EVENT_OOC_LOS                  = 10,      // NoHostile, MaxRnage, CooldownMin, CooldownMax +    SMART_EVENT_RESPAWN                  = 11,      // type, MapId, ZoneId +    SMART_EVENT_TARGET_HEALTH_PCT        = 12,      // HPMin%, HPMax%, RepeatMin, RepeatMax +    SMART_EVENT_TARGET_CASTING           = 13,      // RepeatMin, RepeatMax +    SMART_EVENT_FRIENDLY_HEALTH          = 14,      // HPDeficit, Radius, RepeatMin, RepeatMax +    SMART_EVENT_FRIENDLY_IS_CC           = 15,      // Radius, RepeatMin, RepeatMax +    SMART_EVENT_FRIENDLY_MISSING_BUFF    = 16,      // SpellId, Radius, RepeatMin, RepeatMax +    SMART_EVENT_SUMMONED_UNIT            = 17,      // CreatureId(0 all), CooldownMin, CooldownMax +    SMART_EVENT_TARGET_MANA_PCT          = 18,      // ManaMin%, ManaMax%, RepeatMin, RepeatMax +    SMART_EVENT_ACCEPTED_QUEST           = 19,      // QuestID(0any) +    SMART_EVENT_REWARD_QUEST             = 20,      // QuestID(0any) +    SMART_EVENT_REACHED_HOME             = 21,      // NONE +    SMART_EVENT_RECEIVE_EMOTE            = 22,      // EmoteId, CooldownMin, CooldownMax, condition, val1, val2, val3 +    SMART_EVENT_HAS_AURA                 = 23,      // Param1 = SpellID, Param2 = Number of Time STacked, Param3/4 RepeatMin, RepeatMax +    SMART_EVENT_TARGET_BUFFED            = 24,      // Param1 = SpellID, Param2 = Number of Time STacked, Param3/4 RepeatMin, RepeatMax +    SMART_EVENT_RESET                    = 25,      // Called after combat, when the creature respawn and spawn. +    SMART_EVENT_IC_LOS                   = 26,      // NoHostile, MaxRnage, CooldownMin, CooldownMax +    SMART_EVENT_PASSENGER_BOARDED        = 27,      // CooldownMin, CooldownMax +    SMART_EVENT_PASSENGER_REMOVED        = 28,      // CooldownMin, CooldownMax +    SMART_EVENT_CHARMED                  = 29,      // NONE +    SMART_EVENT_CHARMED_TARGET           = 30,      // NONE +    SMART_EVENT_SPELLHIT_TARGET          = 31,      // SpellID, School, CooldownMin, CooldownMax +    SMART_EVENT_DAMAGED                  = 32,      // MinDmg, MaxDmg, CooldownMin, CooldownMax +    SMART_EVENT_DAMAGED_TARGET           = 33,      // MinDmg, MaxDmg, CooldownMin, CooldownMax +    SMART_EVENT_MOVEMENTINFORM           = 34,      // MovementType(any), PointID +    SMART_EVENT_SUMMON_DESPAWNED         = 35,      // Entry, CooldownMin, CooldownMax +    SMART_EVENT_CORPSE_REMOVED           = 36,      // NONE +    SMART_EVENT_AI_INIT                  = 37,      // NONE +    SMART_EVENT_DATA_SET                 = 38,      // Id, Value, CooldownMin, CooldownMax +    SMART_EVENT_WAYPOINT_START           = 39,      // PointId(0any), pathID(0any) +    SMART_EVENT_WAYPOINT_REACHED         = 40,      // PointId(0any), pathID(0any) +    SMART_EVENT_TRANSPORT_ADDPLAYER      = 41,      // NONE +    SMART_EVENT_TRANSPORT_ADDCREATURE    = 42,      // Entry (0 any) +    SMART_EVENT_TRANSPORT_REMOVE_PLAYER  = 43,      // NONE +    SMART_EVENT_TRANSPORT_RELOCATE       = 44,      // PointId +    SMART_EVENT_INSTANCE_PLAYER_ENTER    = 45,      // Team (0 any), CooldownMin, CooldownMax +    SMART_EVENT_AREATRIGGER_ONTRIGGER    = 46,      // TriggerId(0 any) +    SMART_EVENT_QUEST_ACCEPTED           = 47,      // none +    SMART_EVENT_QUEST_OBJ_COPLETETION    = 48,      // none +    SMART_EVENT_QUEST_COMPLETION         = 49,      // none +    SMART_EVENT_QUEST_REWARDED           = 50,      // none +    SMART_EVENT_QUEST_FAIL               = 51,      // none +    SMART_EVENT_TEXT_OVER                = 52,      // GroupId from creature_text,  creature entry who talks (0 any) +    SMART_EVENT_RECEIVE_HEAL             = 53,      // MinHeal, MaxHeal, CooldownMin, CooldownMax +    SMART_EVENT_JUST_SUMMONED            = 54,      // none +    SMART_EVENT_WAYPOINT_PAUSED          = 55,      // PointId(0any), pathID(0any) +    SMART_EVENT_WAYPOINT_RESUMED         = 56,      // PointId(0any), pathID(0any) +    SMART_EVENT_WAYPOINT_STOPPED         = 57,      // PointId(0any), pathID(0any) +    SMART_EVENT_WAYPOINT_ENDED           = 58,      // PointId(0any), pathID(0any) +    SMART_EVENT_TIMED_EVENT_TRIGGERED    = 59,      // id +    SMART_EVENT_UPDATE                   = 60,      // InitialMin, InitialMax, RepeatMin, RepeatMax +    SMART_EVENT_LINK                     = 61,      // INTERNAL USAGE, no params, used to link together multiple events, does not use any extra resources to iterate event lists needlessly +    SMART_EVENT_GOSSIP_SELECT            = 62,      // menuID, actionID +    SMART_EVENT_JUST_CREATED             = 63,      // none +    SMART_EVENT_GOSSIP_HELLO             = 64,      // none +    SMART_EVENT_FOLLOW_COMPLETED         = 65,      // none +    SMART_EVENT_DUMMY_EFFECT             = 66,      // spellId, effectIndex +    SMART_EVENT_IS_BEHIND_TARGET         = 67,      // cooldownMin, CooldownMax +    SMART_EVENT_GAME_EVENT_START         = 68,      // game_event.Entry +    SMART_EVENT_GAME_EVENT_END           = 69,      // game_event.Entry +    SMART_EVENT_GO_STATE_CHANGED         = 70,      // go state +    SMART_EVENT_GO_EVENT_INFORM          = 71,      // eventId +    SMART_EVENT_ACTION_DONE              = 72,      // eventId (SharedDefines.EventId) +    SMART_EVENT_ON_SPELLCLICK            = 73,      // clicker (unit) + +    SMART_EVENT_END                      = 74,  };  struct SmartEvent @@ -353,6 +354,16 @@ struct SmartEvent          struct          { +            uint32 eventId; +        } eventInform; + +        struct +        { +            uint32 eventId; +        } doAction; + +        struct +        {              uint32 param1;              uint32 param2;              uint32 param3; @@ -399,7 +410,7 @@ enum SMART_ACTION      SMART_ACTION_FLEE_FOR_ASSIST                    = 25,     // With Emote      SMART_ACTION_CALL_GROUPEVENTHAPPENS             = 26,     // QuestID      SMART_ACTION_CALL_CASTEDCREATUREORGO            = 27,     // CreatureId, SpellId -    SMART_ACTION_REMOVEAURASFROMSPELL               = 28,     // Spellid +    SMART_ACTION_REMOVEAURASFROMSPELL               = 28,     // Spellid, 0 removes all auras      SMART_ACTION_FOLLOW                             = 29,     // Distance (0 = default), Angle (0 = default), EndCreatureEntry, credit, creditType (0monsterkill, 1event)      SMART_ACTION_RANDOM_PHASE                       = 30,     // PhaseId1, PhaseId2, PhaseId3...      SMART_ACTION_RANDOM_PHASE_RANGE                 = 31,     // PhaseMin, PhaseMax @@ -847,9 +858,9 @@ struct SmartAction          struct          { -            bool withDelayed; +            uint32 withDelayed;              uint32 spell_id; -            bool withInstant; +            uint32 withInstant;          } interruptSpellCasting;          struct @@ -875,7 +886,7 @@ struct SmartAction          struct          { -            uint8 pointId; +            uint32 pointId;          } MoveToPos;          struct @@ -896,10 +907,13 @@ struct SmartAction          struct          { -            float distance; -            float angle; +            uint32 distance; +            uint32 angle;          } setRangedMovement; +        //! Note for any new future actions +        //! All parameters must have type uint32 +          struct          {              uint32 param1; @@ -1167,7 +1181,9 @@ const uint32 SmartAIEventMask[SMART_EVENT_END][2] =      {SMART_EVENT_GAME_EVENT_START,          SMART_SCRIPT_TYPE_MASK_CREATURE + SMART_SCRIPT_TYPE_MASK_GAMEOBJECT },      {SMART_EVENT_GAME_EVENT_END,            SMART_SCRIPT_TYPE_MASK_CREATURE + SMART_SCRIPT_TYPE_MASK_GAMEOBJECT },      {SMART_EVENT_GO_STATE_CHANGED,          SMART_SCRIPT_TYPE_MASK_GAMEOBJECT }, - +    {SMART_EVENT_GO_EVENT_INFORM,           SMART_SCRIPT_TYPE_MASK_GAMEOBJECT }, +    {SMART_EVENT_ACTION_DONE,               SMART_SCRIPT_TYPE_MASK_CREATURE }, +    {SMART_EVENT_ON_SPELLCLICK,             SMART_SCRIPT_TYPE_MASK_CREATURE },  };  enum SmartEventFlags @@ -1380,26 +1396,6 @@ class SmartAIMgr              }              return true;          } -        /*inline bool IsConditionValid(SmartScriptHolder e, int32 t, int32 v1, int32 v2, int32 v3) -        { -            bool error = false; -            if (t > 0 && v1 >= 0 && v2 >= 0 && v3 >= 0) -            { -                Condition cond; -                cond.mConditionType = ConditionType(t); -                cond.mConditionValue1 = uint32(v1); -                cond.mConditionValue2 = uint32(v2); -                cond.mConditionValue3 = uint32(v3); -                if (!sConditionMgr->isConditionTypeValid(&cond)) -                    error = true; -            } -            if (error) -            { -                sLog->outErrorDb("SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses invalid Condition, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType()); -                return false; -            } -            return true; -        }*/          bool IsTextEmoteValid(SmartScriptHolder const& e, uint32 entry)          { diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp index 21a2a75b470..252e120f0c9 100755 --- a/src/server/game/Achievements/AchievementMgr.cpp +++ b/src/server/game/Achievements/AchievementMgr.cpp @@ -2207,7 +2207,6 @@ void AchievementGlobalMgr::LoadAchievementCriteriaList()      for (uint32 entryId = 0; entryId < sAchievementCriteriaStore.GetNumRows(); ++entryId)      { -          AchievementCriteriaEntry const* criteria = sAchievementCriteriaStore.LookupEntry(entryId);          if (!criteria)              continue; @@ -2238,7 +2237,6 @@ void AchievementGlobalMgr::LoadAchievementReferenceList()      for (uint32 entryId = 0; entryId < sAchievementStore.GetNumRows(); ++entryId)      { -          AchievementEntry const* achievement = sAchievementStore.LookupEntry(entryId);          if (!achievement || !achievement->refAchievement)              continue; @@ -2247,6 +2245,10 @@ void AchievementGlobalMgr::LoadAchievementReferenceList()          ++count;      } +    // Once Bitten, Twice Shy (10 player) - Icecrown Citadel +    if (AchievementEntry const* achievement = sAchievementStore.LookupEntry(4539)) +        const_cast<AchievementEntry*>(achievement)->mapID = 631;    // Correct map requirement (currently has Ulduar) +      sLog->outString(">> Loaded %u achievement references in %u ms", count, GetMSTimeDiffToNow(oldMSTime));      sLog->outString();  } diff --git a/src/server/game/Battlegrounds/ArenaTeamMgr.cpp b/src/server/game/Battlegrounds/ArenaTeamMgr.cpp index c964f47f495..1b666859749 100644 --- a/src/server/game/Battlegrounds/ArenaTeamMgr.cpp +++ b/src/server/game/Battlegrounds/ArenaTeamMgr.cpp @@ -151,11 +151,11 @@ void ArenaTeamMgr::DistributeArenaPoints()          if (ArenaTeam* at = teamItr->second)              at->UpdateArenaPointsHelper(PlayerPoints); +    /*      SQLTransaction trans = CharacterDatabase.BeginTransaction();      // Cycle that gives points to all players -	/* -	PreparedStatement* stmt; +    PreparedStatement* stmt;      for (std::map<uint32, uint32>::iterator playerItr = PlayerPoints.begin(); playerItr != PlayerPoints.end(); ++playerItr)      { @@ -170,9 +170,9 @@ void ArenaTeamMgr::DistributeArenaPoints()              trans->Append(stmt);          }      } -	*/      CharacterDatabase.CommitTransaction(trans); +    */      PlayerPoints.clear(); diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index 54c84f2e6d4..ebcf5495a55 100755 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -850,12 +850,8 @@ void Battleground::EndBattleground(uint32 winner)              if (team == winner)              {                  // update achievement BEFORE personal rating update -                if (ArenaTeamMember* member = winner_arena_team->GetMember(player->GetGUID())) -                { -                    uint32 rating = player->GetArenaPersonalRating(winner_arena_team->GetSlot()); -                    player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, -                        rating ? rating : 1); -                } +                uint32 rating = player->GetArenaPersonalRating(winner_arena_team->GetSlot()); +                player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, rating ? rating : 1);                  winner_arena_team->MemberWon(player, loser_matchmaker_rating, winner_matchmaker_change);              } @@ -1776,15 +1772,19 @@ void Battleground::HandleTriggerBuff(uint64 go_guid)      SpawnBGObject(index, BUFF_RESPAWN_TIME);  } -void Battleground::HandleKillPlayer(Player* player, Player* killer) +void Battleground::HandleKillPlayer(Player* victim, Player* killer)  {      // Keep in mind that for arena this will have to be changed a bit      // Add +1 deaths -    UpdatePlayerScore(player, SCORE_DEATHS, 1); +    UpdatePlayerScore(victim, SCORE_DEATHS, 1);      // Add +1 kills to group and +1 killing_blows to killer      if (killer)      { +        // Don't reward credit for killing ourselves, like fall damage of hellfire (warlock) +        if (killer == victim) +            return; +          UpdatePlayerScore(killer, SCORE_HONORABLE_KILLS, 1);          UpdatePlayerScore(killer, SCORE_KILLING_BLOWS, 1); @@ -1794,7 +1794,7 @@ void Battleground::HandleKillPlayer(Player* player, Player* killer)              if (!creditedPlayer || creditedPlayer == killer)                  continue; -            if (creditedPlayer->GetTeam() == killer->GetTeam() && creditedPlayer->IsAtGroupRewardDistance(player)) +            if (creditedPlayer->GetTeam() == killer->GetTeam() && creditedPlayer->IsAtGroupRewardDistance(victim))                  UpdatePlayerScore(creditedPlayer, SCORE_HONORABLE_KILLS, 1);          }      } @@ -1802,8 +1802,8 @@ void Battleground::HandleKillPlayer(Player* player, Player* killer)      if (!isArena())      {          // To be able to remove insignia -- ONLY IN Battlegrounds -        player->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); -        RewardXPAtKill(killer, player); +        victim->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); +        RewardXPAtKill(killer, victim);      }  } diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.cpp b/src/server/game/Battlegrounds/BattlegroundMgr.cpp index b7079fb00e0..0d4fc458faa 100755 --- a/src/server/game/Battlegrounds/BattlegroundMgr.cpp +++ b/src/server/game/Battlegrounds/BattlegroundMgr.cpp @@ -55,7 +55,7 @@ BattlegroundMgr::BattlegroundMgr() : m_AutoDistributionTimeChecker(0), m_ArenaTe  {      for (uint32 i = BATTLEGROUND_TYPE_NONE; i < MAX_BATTLEGROUND_TYPE_ID; i++)          m_Battlegrounds[i].clear(); -    m_NextRatingDiscardUpdate = sWorld->getIntConfig(CONFIG_ARENA_RATING_DISCARD_TIMER); +    m_NextRatedArenaUpdate = sWorld->getIntConfig(CONFIG_ARENA_RATED_UPDATE_TIMER);      m_Testing=false;  } @@ -143,10 +143,10 @@ void BattlegroundMgr::Update(uint32 diff)      }      // if rating difference counts, maybe force-update queues -    if (sWorld->getIntConfig(CONFIG_ARENA_MAX_RATING_DIFFERENCE) && sWorld->getIntConfig(CONFIG_ARENA_RATING_DISCARD_TIMER)) +    if (sWorld->getIntConfig(CONFIG_ARENA_MAX_RATING_DIFFERENCE) && sWorld->getIntConfig(CONFIG_ARENA_RATED_UPDATE_TIMER))      {          // it's time to force update -        if (m_NextRatingDiscardUpdate < diff) +        if (m_NextRatedArenaUpdate < diff)          {              // forced update for rated arenas (scan all, but skipped non rated)              sLog->outDebug(LOG_FILTER_BATTLEGROUND, "BattlegroundMgr: UPDATING ARENA QUEUES"); @@ -156,10 +156,10 @@ void BattlegroundMgr::Update(uint32 diff)                          BATTLEGROUND_AA, BattlegroundBracketId(bracket),                          BattlegroundMgr::BGArenaType(BattlegroundQueueTypeId(qtype)), true, 0); -            m_NextRatingDiscardUpdate = sWorld->getIntConfig(CONFIG_ARENA_RATING_DISCARD_TIMER); +            m_NextRatedArenaUpdate = sWorld->getIntConfig(CONFIG_ARENA_RATED_UPDATE_TIMER);          }          else -            m_NextRatingDiscardUpdate -= diff; +            m_NextRatedArenaUpdate -= diff;      }      if (sWorld->getBoolConfig(CONFIG_ARENA_AUTO_DISTRIBUTE_POINTS))      { @@ -771,8 +771,9 @@ void BattlegroundMgr::CreateInitialBattlegrounds()              continue;          } -        selectionWeight = fields[10].GetUInt8();          data.StartMaxDist = fields[9].GetFloat(); +         +        selectionWeight = fields[10].GetUInt8();          data.scriptId = sObjectMgr->GetScriptId(fields[11].GetCString());          //data.BattlegroundName = bl->name[sWorld->GetDefaultDbcLocale()]; diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.h b/src/server/game/Battlegrounds/BattlegroundMgr.h index dd502409178..4edad4da742 100755 --- a/src/server/game/Battlegrounds/BattlegroundMgr.h +++ b/src/server/game/Battlegrounds/BattlegroundMgr.h @@ -141,7 +141,7 @@ class BattlegroundMgr          BattlegroundSelectionWeightMap m_BGSelectionWeights;          std::vector<uint64> m_QueueUpdateScheduler;          std::set<uint32> m_ClientBattlegroundIds[MAX_BATTLEGROUND_TYPE_ID][MAX_BATTLEGROUND_BRACKETS]; //the instanceids just visible for the client -        uint32 m_NextRatingDiscardUpdate; +        uint32 m_NextRatedArenaUpdate;          time_t m_NextAutoDistributionTime;          uint32 m_AutoDistributionTimeChecker;          bool   m_ArenaTesting; diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp index 39c6e00946a..bda1bdfa8d3 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp @@ -56,6 +56,8 @@ void BattlegroundSA::Reset()          GateStatus[i] = BG_SA_GATE_OK;      ShipsStarted = false;      gateDestroyed = false; +    _notEvenAScratch[BG_TEAM_ALLIANCE] = true; +    _notEvenAScratch[BG_TEAM_HORDE] = true;      Status = BG_SA_WARMUP;  } @@ -553,13 +555,13 @@ void BattlegroundSA::EventPlayerDamagedGO(Player* /*player*/, GameObject* go, ui          SendWarningToAll(LANG_BG_SA_IS_UNDER_ATTACK, go->GetGOInfo()->name.c_str());  } -void BattlegroundSA::HandleKillUnit(Creature* unit, Player* killer) +void BattlegroundSA::HandleKillUnit(Creature* creature, Player* killer)  { -    if (!unit) -        return; - -    if (unit->GetEntry() == NPC_DEMOLISHER_SA) +    if (creature->GetEntry() == NPC_DEMOLISHER_SA) +    {          UpdatePlayerScore(killer, SCORE_DESTROYED_DEMOLISHER, 1); +        _notEvenAScratch[Attackers] = false; +    }  }  /* diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundSA.h b/src/server/game/Battlegrounds/Zones/BattlegroundSA.h index c18806490f2..fd11cb2c5ea 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundSA.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundSA.h @@ -456,7 +456,7 @@ class BattlegroundSA : public Battleground          /// Called when a player deal damage to building (door)          virtual void EventPlayerDamagedGO(Player* player, GameObject* go, uint32 eventType);          /// Called when a player kill a unit in bg -        virtual void HandleKillUnit(Creature* unit, Player* killer); +        virtual void HandleKillUnit(Creature* creature, Player* killer);          /// Return the nearest graveyard where player can respawn          virtual WorldSafeLocsEntry const* GetClosestGraveYard(Player* player);          /// Called when a player click on flag (graveyard flag) @@ -531,9 +531,12 @@ class BattlegroundSA : public Battleground          /// Update score board          void UpdatePlayerScore(Player* Source, uint32 type, uint32 value, bool doAddHonor = true); -        // Achievement Defense of the Ancients +        // Achievement: Defense of the Ancients          bool gateDestroyed; +        // Achievement: Not Even a Scratch +        bool notEvenAScratch(uint32 team) const { return _notEvenAScratch[GetTeamIndexByTeamId(team)]; } +          /// Id of attacker team          TeamId Attackers; @@ -615,5 +618,7 @@ class BattlegroundSA : public Battleground          bool InitSecondRound;          std::map<uint32/*id*/, uint32/*timer*/> DemoliserRespawnList; +        // Achievement: Not Even a Scratch +        bool _notEvenAScratch[BG_TEAMS_COUNT];  };  #endif diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp index cc64a8e22dd..7a146e89505 100755 --- a/src/server/game/Chat/Chat.cpp +++ b/src/server/game/Chat/Chat.cpp @@ -92,40 +92,6 @@ ChatCommand* ChatHandler::getCommandTable()          { NULL,             0,                  false, NULL,                                           "", NULL }      }; -    static ChatCommand castCommandTable[] = -    { -        { "back",           SEC_ADMINISTRATOR,  false, OldHandler<&ChatHandler::HandleCastBackCommand>,            "", NULL }, -        { "dist",           SEC_ADMINISTRATOR,  false, OldHandler<&ChatHandler::HandleCastDistCommand>,            "", NULL }, -        { "self",           SEC_ADMINISTRATOR,  false, OldHandler<&ChatHandler::HandleCastSelfCommand>,            "", NULL }, -        { "target",         SEC_ADMINISTRATOR,  false, OldHandler<&ChatHandler::HandleCastTargetCommand>,          "", NULL }, -        { "dest",           SEC_ADMINISTRATOR,  false, OldHandler<&ChatHandler::HandleCastDestCommand>,          "", NULL }, -        { "",               SEC_ADMINISTRATOR,  false, OldHandler<&ChatHandler::HandleCastCommand>,                "", NULL }, -        { NULL,             0,                  false, NULL,                                           "", NULL } -    }; - -    static ChatCommand characterDeletedCommandTable[] = -    { -        { "delete",         SEC_CONSOLE,        true,  OldHandler<&ChatHandler::HandleCharacterDeletedDeleteCommand>,   "", NULL }, -        { "list",           SEC_ADMINISTRATOR,  true,  OldHandler<&ChatHandler::HandleCharacterDeletedListCommand>,     "", NULL }, -        { "restore",        SEC_ADMINISTRATOR,  true,  OldHandler<&ChatHandler::HandleCharacterDeletedRestoreCommand>,  "", NULL }, -        { "old",            SEC_CONSOLE,        true,  OldHandler<&ChatHandler::HandleCharacterDeletedOldCommand>,      "", NULL }, -        { NULL,             0,                  false, NULL,                                                "", NULL } -    }; - -    static ChatCommand characterCommandTable[] = -    { -        { "customize",      SEC_GAMEMASTER,     true,  OldHandler<&ChatHandler::HandleCharacterCustomizeCommand>,     "", NULL }, -        { "changefaction",  SEC_GAMEMASTER,     true,  OldHandler<&ChatHandler::HandleCharacterChangeFactionCommand>, "", NULL }, -        { "changerace",     SEC_GAMEMASTER,     true,  OldHandler<&ChatHandler::HandleCharacterChangeRaceCommand>,    "", NULL }, -        { "deleted",        SEC_GAMEMASTER,     true,  NULL,                                              "", characterDeletedCommandTable}, -        { "erase",          SEC_CONSOLE,        true,  OldHandler<&ChatHandler::HandleCharacterEraseCommand>,         "", NULL }, -        { "level",          SEC_ADMINISTRATOR,  true,  OldHandler<&ChatHandler::HandleCharacterLevelCommand>,         "", NULL }, -        { "rename",         SEC_GAMEMASTER,     true,  OldHandler<&ChatHandler::HandleCharacterRenameCommand>,        "", NULL }, -        { "reputation",     SEC_GAMEMASTER,     true,  OldHandler<&ChatHandler::HandleCharacterReputationCommand>,    "", NULL }, -        { "titles",         SEC_GAMEMASTER,     true,  OldHandler<&ChatHandler::HandleCharacterTitlesCommand>,        "", NULL }, -        { NULL,             0,                  false, NULL,                                              "", NULL } -    }; -      static ChatCommand channelSetCommandTable[] =      {          { "ownership",      SEC_ADMINISTRATOR,  false,  OldHandler<&ChatHandler::HandleChannelSetOwnership>, "", NULL }, @@ -156,24 +122,6 @@ ChatCommand* ChatHandler::getCommandTable()          { NULL,             0,                  false, NULL,                                           "", NULL }      }; -    static ChatCommand instanceCommandTable[] = -    { -        { "listbinds",      SEC_ADMINISTRATOR,  false, OldHandler<&ChatHandler::HandleInstanceListBindsCommand>,   "", NULL }, -        { "unbind",         SEC_ADMINISTRATOR,  false, OldHandler<&ChatHandler::HandleInstanceUnbindCommand>,      "", NULL }, -        { "stats",          SEC_ADMINISTRATOR,  true,  OldHandler<&ChatHandler::HandleInstanceStatsCommand>,       "", NULL }, -        { "savedata",       SEC_ADMINISTRATOR,  false, OldHandler<&ChatHandler::HandleInstanceSaveDataCommand>,    "", NULL }, -        { NULL,             0,                  false, NULL,                                           "", NULL } -    }; - -    static ChatCommand listCommandTable[] = -    { -        { "creature",       SEC_ADMINISTRATOR,  true,  OldHandler<&ChatHandler::HandleListCreatureCommand>,        "", NULL }, -        { "item",           SEC_ADMINISTRATOR,  true,  OldHandler<&ChatHandler::HandleListItemCommand>,            "", NULL }, -        { "object",         SEC_ADMINISTRATOR,  true,  OldHandler<&ChatHandler::HandleListObjectCommand>,          "", NULL }, -        { "auras",          SEC_ADMINISTRATOR,  false, OldHandler<&ChatHandler::HandleListAurasCommand>,           "", NULL }, -        { NULL,             0,                  false, NULL,                                           "", NULL } -    }; -      static ChatCommand lookupPlayerCommandTable[] =      {          { "ip",             SEC_GAMEMASTER,     true,  OldHandler<&ChatHandler::HandleLookupPlayerIpCommand>,       "", NULL }, @@ -217,18 +165,6 @@ ChatCommand* ChatHandler::getCommandTable()          { NULL,             0,                  false, NULL,                                           "", NULL }      }; -    static ChatCommand resetCommandTable[] = -    { -        { "achievements",   SEC_ADMINISTRATOR,  true,  OldHandler<&ChatHandler::HandleResetAchievementsCommand>,   "", NULL }, -        { "honor",          SEC_ADMINISTRATOR,  true,  OldHandler<&ChatHandler::HandleResetHonorCommand>,          "", NULL }, -        { "level",          SEC_ADMINISTRATOR,  true,  OldHandler<&ChatHandler::HandleResetLevelCommand>,          "", NULL }, -        { "spells",         SEC_ADMINISTRATOR,  true,  OldHandler<&ChatHandler::HandleResetSpellsCommand>,         "", NULL }, -        { "stats",          SEC_ADMINISTRATOR,  true,  OldHandler<&ChatHandler::HandleResetStatsCommand>,          "", NULL }, -        { "talents",        SEC_ADMINISTRATOR,  true,  OldHandler<&ChatHandler::HandleResetTalentsCommand>,        "", NULL }, -        { "all",            SEC_ADMINISTRATOR,  true,  OldHandler<&ChatHandler::HandleResetAllCommand>,            "", NULL }, -        { NULL,             0,                  false, NULL,                                           "", NULL } -    }; -      static ChatCommand sendCommandTable[] =      {          { "items",          SEC_ADMINISTRATOR,  true,  OldHandler<&ChatHandler::HandleSendItemsCommand>,           "", NULL }, @@ -238,60 +174,6 @@ ChatCommand* ChatHandler::getCommandTable()          { NULL,             0,                  false, NULL,                                           "", NULL }      }; -    static ChatCommand serverIdleRestartCommandTable[] = -    { -        { "cancel",         SEC_ADMINISTRATOR,  true,  OldHandler<&ChatHandler::HandleServerShutDownCancelCommand>, "", NULL }, -        { ""   ,            SEC_ADMINISTRATOR,  true,  OldHandler<&ChatHandler::HandleServerIdleRestartCommand>,   "", NULL }, -        { NULL,             0,                  false, NULL,                                           "", NULL } -    }; - -    static ChatCommand serverIdleShutdownCommandTable[] = -    { -        { "cancel",         SEC_ADMINISTRATOR,  true,  OldHandler<&ChatHandler::HandleServerShutDownCancelCommand>, "", NULL }, -        { ""   ,            SEC_ADMINISTRATOR,  true,  OldHandler<&ChatHandler::HandleServerIdleShutDownCommand>,  "", NULL }, -        { NULL,             0,                  false, NULL,                                           "", NULL } -    }; - -    static ChatCommand serverRestartCommandTable[] = -    { -        { "cancel",         SEC_ADMINISTRATOR,  true,  OldHandler<&ChatHandler::HandleServerShutDownCancelCommand>, "", NULL }, -        { ""   ,            SEC_ADMINISTRATOR,  true,  OldHandler<&ChatHandler::HandleServerRestartCommand>,       "", NULL }, -        { NULL,             0,                  false, NULL,                                           "", NULL } -    }; - -    static ChatCommand serverShutdownCommandTable[] = -    { -        { "cancel",         SEC_ADMINISTRATOR,  true,  OldHandler<&ChatHandler::HandleServerShutDownCancelCommand>, "", NULL }, -        { ""   ,            SEC_ADMINISTRATOR,  true,  OldHandler<&ChatHandler::HandleServerShutDownCommand>,      "", NULL }, -        { NULL,             0,                  false, NULL,                                           "", NULL } -    }; - -    static ChatCommand serverSetCommandTable[] = -    { -        { "difftime",       SEC_CONSOLE,        true,  OldHandler<&ChatHandler::HandleServerSetDiffTimeCommand>,   "", NULL }, -        { "loglevel",       SEC_CONSOLE,        true,  OldHandler<&ChatHandler::HandleServerSetLogLevelCommand>,   "", NULL }, -        { "logfilelevel",   SEC_CONSOLE,        true,  OldHandler<&ChatHandler::HandleServerSetLogFileLevelCommand>,   "", NULL }, -        { "motd",           SEC_ADMINISTRATOR,  true,  OldHandler<&ChatHandler::HandleServerSetMotdCommand>,       "", NULL }, -        { "closed",         SEC_ADMINISTRATOR,  true,  OldHandler<&ChatHandler::HandleServerSetClosedCommand>,     "", NULL }, -        { NULL,             0,                  false, NULL,                                           "", NULL } -    }; - -    static ChatCommand serverCommandTable[] = -    { -        { "corpses",        SEC_GAMEMASTER,     true,  OldHandler<&ChatHandler::HandleServerCorpsesCommand>,     "", NULL }, -        { "exit",           SEC_CONSOLE,        true,  OldHandler<&ChatHandler::HandleServerExitCommand>,        "", NULL }, -        { "idlerestart",    SEC_ADMINISTRATOR,  true,  NULL,                                                     "", serverIdleRestartCommandTable }, -        { "idleshutdown",   SEC_ADMINISTRATOR,  true,  NULL,                                                     "", serverIdleShutdownCommandTable }, -        { "info",           SEC_PLAYER,         true,  OldHandler<&ChatHandler::HandleServerInfoCommand>,        "", NULL }, -        { "motd",           SEC_PLAYER,         true,  OldHandler<&ChatHandler::HandleServerMotdCommand>,        "", NULL }, -        { "plimit",         SEC_ADMINISTRATOR,  true,  OldHandler<&ChatHandler::HandleServerPLimitCommand>,      "", NULL }, -        { "restart",        SEC_ADMINISTRATOR,  true,  NULL,                                                     "", serverRestartCommandTable }, -        { "shutdown",       SEC_ADMINISTRATOR,  true,  NULL,                                                     "", serverShutdownCommandTable }, -        { "set",            SEC_ADMINISTRATOR,  true,  NULL,                                                     "", serverSetCommandTable }, -        { "togglequerylog", SEC_CONSOLE,        true,  OldHandler<&ChatHandler::HandleServerToggleQueryLogging>, "", NULL }, -        { NULL,             0,                  false, NULL,                                                     "", NULL } -    }; -      static ChatCommand unbanCommandTable[] =      {          { "account",        SEC_ADMINISTRATOR,  true,  OldHandler<&ChatHandler::HandleUnBanAccountCommand>,       "", NULL }, @@ -331,16 +213,10 @@ ChatCommand* ChatHandler::getCommandTable()      static ChatCommand commandTable[] =      { -        { "character",      SEC_GAMEMASTER,     true,  NULL,                                           "", characterCommandTable}, -        { "list",           SEC_ADMINISTRATOR,  true,  NULL,                                           "", listCommandTable     },          { "lookup",         SEC_ADMINISTRATOR,  true,  NULL,                                           "", lookupCommandTable   },          { "pdump",          SEC_ADMINISTRATOR,  true,  NULL,                                           "", pdumpCommandTable    },          { "guild",          SEC_ADMINISTRATOR,  true,  NULL,                                           "", guildCommandTable    },          { "group",          SEC_ADMINISTRATOR,  false, NULL,                                           "", groupCommandTable    }, -        { "cast",           SEC_ADMINISTRATOR,  false, NULL,                                           "", castCommandTable     }, -        { "reset",          SEC_ADMINISTRATOR,  true,  NULL,                                           "", resetCommandTable    }, -        { "instance",       SEC_ADMINISTRATOR,  true,  NULL,                                           "", instanceCommandTable }, -        { "server",         SEC_ADMINISTRATOR,  true,  NULL,                                           "", serverCommandTable   },          { "channel",        SEC_ADMINISTRATOR, true, NULL,                                             "", channelCommandTable  }, diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h index e88914a2daf..bbe138b923d 100755 --- a/src/server/game/Chat/Chat.h +++ b/src/server/game/Chat/Chat.h @@ -119,10 +119,13 @@ class ChatHandler          GameObject* GetNearbyGameObject();          GameObject* GetObjectGlobalyWithGuidOrNearWithDbGuid(uint32 lowguid, uint32 entry); -        bool HasSentErrorMessage() const { return sentErrorMessage;} -        void SetSentErrorMessage(bool val){ sentErrorMessage = val;}; -        static bool LoadCommandTable() { return load_command_table;} -        static void SetLoadCommandTable(bool val){ load_command_table = val;}; +        bool HasSentErrorMessage() const { return sentErrorMessage; } +        void SetSentErrorMessage(bool val){ sentErrorMessage = val; } +        static bool LoadCommandTable() { return load_command_table; } +        static void SetLoadCommandTable(bool val) { load_command_table = val; } +         +        // cs_character +        void HandleCharacterLevel(Player* player, uint64 playerGuid, uint32 oldLevel, uint32 newLevel);      protected:          explicit ChatHandler() : m_session(NULL) {}      // for CLI subclass @@ -147,26 +150,6 @@ class ChatHandler          bool HandleBanListCharacterCommand(const char* args);          bool HandleBanListIPCommand(const char* args); -        bool HandleCastCommand(const char *args); -        bool HandleCastBackCommand(const char *args); -        bool HandleCastDistCommand(const char *args); -        bool HandleCastSelfCommand(const char *args); -        bool HandleCastTargetCommand(const char *args); -        bool HandleCastDestCommand(const char *args); - -        bool HandleCharacterCustomizeCommand(const char* args); -        bool HandleCharacterChangeFactionCommand(const char* args); -        bool HandleCharacterChangeRaceCommand(const char * args); -        bool HandleCharacterDeletedDeleteCommand(const char* args); -        bool HandleCharacterDeletedListCommand(const char* args); -        bool HandleCharacterDeletedRestoreCommand(const char* args); -        bool HandleCharacterDeletedOldCommand(const char* args); -        bool HandleCharacterEraseCommand(const char* args); -        bool HandleCharacterLevelCommand(const char* args); -        bool HandleCharacterRenameCommand(const char* args); -        bool HandleCharacterReputationCommand(const char* args); -        bool HandleCharacterTitlesCommand(const char* args); -          bool HandleChannelSetOwnership(const char *args);          bool HandlePossessCommand(const char* args); @@ -180,16 +163,6 @@ class ChatHandler          bool HandleGuildRankCommand(const char* args);          bool HandleGuildDeleteCommand(const char* args); -        bool HandleInstanceListBindsCommand(const char* args); -        bool HandleInstanceUnbindCommand(const char* args); -        bool HandleInstanceStatsCommand(const char* args); -        bool HandleInstanceSaveDataCommand(const char * args); - -        bool HandleListAurasCommand(const char * args); -        bool HandleListCreatureCommand(const char* args); -        bool HandleListItemCommand(const char* args); -        bool HandleListObjectCommand(const char* args); -          bool HandleLookupAreaCommand(const char* args);          bool HandleLookupCreatureCommand(const char* args);          bool HandleLookupEventCommand(const char* args); @@ -211,37 +184,11 @@ class ChatHandler          bool HandlePDumpLoadCommand(const char *args);          bool HandlePDumpWriteCommand(const char *args); -        bool HandleResetAchievementsCommand(const char * args); -        bool HandleResetAllCommand(const char * args); -        bool HandleResetHonorCommand(const char * args); -        bool HandleResetLevelCommand(const char * args); -        bool HandleResetSpellsCommand(const char* args); -        bool HandleResetStatsCommand(const char * args); -        bool HandleResetTalentsCommand(const char* args); -          bool HandleSendItemsCommand(const char* args);          bool HandleSendMailCommand(const char* args);          bool HandleSendMessageCommand(const char * args);          bool HandleSendMoneyCommand(const char* args); -        bool HandleServerCorpsesCommand(const char* args); -        bool HandleServerExitCommand(const char* args); -        bool HandleServerIdleRestartCommand(const char* args); -        bool HandleServerIdleShutDownCommand(const char* args); -        bool HandleServerInfoCommand(const char* args); -        bool HandleServerMotdCommand(const char* args); -        bool HandleServerPLimitCommand(const char* args); -        bool HandleServerRestartCommand(const char* args); -        bool HandleServerSetLogLevelCommand(const char* args); -        bool HandleServerSetMotdCommand(const char* args); -        bool HandleServerShutDownCommand(const char* args); -        bool HandleServerShutDownCancelCommand(const char* args); -        bool HandleServerSetClosedCommand(const char* args); -        bool HandleServerToggleQueryLogging(const char* args); - -        bool HandleServerSetLogFileLevelCommand(const char* args); -        bool HandleServerSetDiffTimeCommand(const char* args); -          bool HandleUnBanAccountCommand(const char* args);          bool HandleUnBanAccountByCharCommand(const char* args);          bool HandleUnBanCharacterCommand(const char* args); @@ -354,25 +301,8 @@ class ChatHandler          bool HandleBanHelper(BanMode mode, char const* args);          bool HandleBanInfoHelper(uint32 accountid, char const* accountname);          bool HandleUnBanHelper(BanMode mode, char const* args); -        void HandleCharacterLevel(Player* player, uint64 playerGuid, uint32 oldLevel, uint32 newLevel);          void HandleLearnSkillRecipesHelper(Player* player, uint32 skill_id); -        // Stores informations about a deleted character -        struct DeletedInfo -        { -            uint32      lowguid;                            ///< the low GUID from the character -            std::string name;                               ///< the character name -            uint32      accountId;                          ///< the account id -            std::string accountName;                        ///< the account name -            time_t      deleteDate;                         ///< the date at which the character has been deleted -        }; - -        typedef std::list<DeletedInfo> DeletedInfoList; -        bool GetDeletedCharacterInfoList(DeletedInfoList& foundList, std::string searchString = ""); -        std::string GenerateDeletedCharacterGUIDsWhereStr(DeletedInfoList::const_iterator& itr, DeletedInfoList::const_iterator const& itr_end); -        void HandleCharacterDeletedListHelper(DeletedInfoList const& foundList); -        void HandleCharacterDeletedRestoreHelper(DeletedInfo const& delInfo); -      private:          bool _HandleGMTicketResponseAppendCommand(const char* args, bool newLine); diff --git a/src/server/game/Chat/Commands/Level0.cpp b/src/server/game/Chat/Commands/Level0.cpp index b2ac090c313..b05ba9b4194 100755 --- a/src/server/game/Chat/Commands/Level0.cpp +++ b/src/server/game/Chat/Commands/Level0.cpp @@ -80,29 +80,6 @@ bool ChatHandler::HandleStartCommand(const char* /*args*/)      return true;  } -bool ChatHandler::HandleServerInfoCommand(const char* /*args*/) -{ -    uint32 playersNum = sWorld->GetPlayerCount(); -    uint32 maxPlayersNum = sWorld->GetMaxPlayerCount(); -    uint32 activeClientsNum = sWorld->GetActiveSessionCount(); -    uint32 queuedClientsNum = sWorld->GetQueuedSessionCount(); -    uint32 maxActiveClientsNum = sWorld->GetMaxActiveSessionCount(); -    uint32 maxQueuedClientsNum = sWorld->GetMaxQueuedSessionCount(); -    std::string uptime = secsToTimeString(sWorld->GetUptime()); -    uint32 updateTime = sWorld->GetUpdateTime(); - -    SendSysMessage(_FULLVERSION); -    PSendSysMessage(LANG_CONNECTED_PLAYERS, playersNum, maxPlayersNum); -    PSendSysMessage(LANG_CONNECTED_USERS, activeClientsNum, maxActiveClientsNum, queuedClientsNum, maxQueuedClientsNum); -    PSendSysMessage(LANG_UPTIME, uptime.c_str()); -    PSendSysMessage(LANG_UPDATE_DIFF, updateTime); -    //! Can't use sWorld->ShutdownMsg here in case of console command -    if (sWorld->IsShuttingDown()) -        PSendSysMessage(LANG_SHUTDOWN_TIMELEFT, secsToTimeString(sWorld->GetShutDownTimeLeft()).c_str()); - -    return true; -} -  bool ChatHandler::HandleDismountCommand(const char* /*args*/)  {      Player* player = m_session->GetPlayer(); @@ -150,10 +127,3 @@ bool ChatHandler::HandleSaveCommand(const char* /*args*/)      return true;  } -/// Display the 'Message of the day' for the realm -bool ChatHandler::HandleServerMotdCommand(const char* /*args*/) -{ -    PSendSysMessage(LANG_MOTD_CURRENT, sWorld->GetMotd()); -    return true; -} - diff --git a/src/server/game/Chat/Commands/Level2.cpp b/src/server/game/Chat/Commands/Level2.cpp index 4359c5ff20c..b1e13b7d92d 100755 --- a/src/server/game/Chat/Commands/Level2.cpp +++ b/src/server/game/Chat/Commands/Level2.cpp @@ -458,190 +458,6 @@ bool ChatHandler::HandlePInfoCommand(const char* args)      return true;  } -//rename characters -bool ChatHandler::HandleCharacterRenameCommand(const char* args) -{ -    Player* target; -    uint64 targetGuid; -    std::string targetName; -    if (!extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) -        return false; - -    if (target) -    { -        // check online security -        if (HasLowerSecurity(target, 0)) -            return false; - -        PSendSysMessage(LANG_RENAME_PLAYER, GetNameLink(target).c_str()); -        target->SetAtLoginFlag(AT_LOGIN_RENAME); -    } -    else -    { -        // check offline security -        if (HasLowerSecurity(NULL, targetGuid)) -            return false; - -        std::string oldNameLink = playerLink(targetName); - -        PSendSysMessage(LANG_RENAME_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGuid)); - -        PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG); - -        stmt->setUInt16(0, uint16(AT_LOGIN_RENAME)); -        stmt->setUInt32(1, GUID_LOPART(targetGuid)); - -        CharacterDatabase.Execute(stmt); -    } - -    return true; -} - -// customize characters -bool ChatHandler::HandleCharacterCustomizeCommand(const char* args) -{ -    Player* target; -    uint64 targetGuid; -    std::string targetName; -    if (!extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) -        return false; - -    PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG); - -    stmt->setUInt16(0, uint16(AT_LOGIN_CUSTOMIZE)); - -    if (target) -    { -        PSendSysMessage(LANG_CUSTOMIZE_PLAYER, GetNameLink(target).c_str()); -        target->SetAtLoginFlag(AT_LOGIN_CUSTOMIZE); - -        stmt->setUInt32(1, target->GetGUIDLow()); -    } -    else -    { -        std::string oldNameLink = playerLink(targetName); - -        stmt->setUInt32(1, GUID_LOPART(targetGuid)); - -        PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGuid)); -    } - -    CharacterDatabase.Execute(stmt); - -    return true; -} - -bool ChatHandler::HandleCharacterChangeFactionCommand(const char* args) -{ -    Player* target; -    uint64 targetGuid; -    std::string targetName; - -    if (!extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) -        return false; - -    PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG); - -    stmt->setUInt16(0, uint16(AT_LOGIN_CHANGE_FACTION)); - -    if (target) -    { -        PSendSysMessage(LANG_CUSTOMIZE_PLAYER, GetNameLink(target).c_str()); -        target->SetAtLoginFlag(AT_LOGIN_CHANGE_FACTION); - -        stmt->setUInt32(1, target->GetGUIDLow()); -    } -    else -    { -        std::string oldNameLink = playerLink(targetName); - -        PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGuid)); - -        stmt->setUInt32(1, GUID_LOPART(targetGuid)); -    } - -    CharacterDatabase.Execute(stmt); - -    return true; -} - -bool ChatHandler::HandleCharacterChangeRaceCommand(const char * args) -{ -    Player* target; -    uint64 targetGuid; -    std::string targetName; -    if (!extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) -        return false; - -    PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG); - -    stmt->setUInt16(0, uint16(AT_LOGIN_CHANGE_RACE)); - -    if (target) -    { -        // TODO : add text into database -        PSendSysMessage(LANG_CUSTOMIZE_PLAYER, GetNameLink(target).c_str()); -        target->SetAtLoginFlag(AT_LOGIN_CHANGE_RACE); - -        stmt->setUInt32(1, target->GetGUIDLow()); -    } -    else -    { -        std::string oldNameLink = playerLink(targetName); - -        // TODO : add text into database -        PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGuid)); - -        stmt->setUInt32(1, GUID_LOPART(targetGuid)); -    } - -    CharacterDatabase.Execute(stmt); - -    return true; -} - -bool ChatHandler::HandleCharacterReputationCommand(const char* args) -{ -    Player* target; -    if (!extractPlayerTarget((char*)args, &target)) -        return false; - -    LocaleConstant loc = GetSessionDbcLocale(); - -    FactionStateList const& targetFSL = target->GetReputationMgr().GetStateList(); -    for (FactionStateList::const_iterator itr = targetFSL.begin(); itr != targetFSL.end(); ++itr) -    { -        const FactionState& faction = itr->second; -        FactionEntry const* factionEntry = sFactionStore.LookupEntry(faction.ID); -        char const* factionName = factionEntry ? factionEntry->name : "#Not found#"; -        ReputationRank rank = target->GetReputationMgr().GetRank(factionEntry); -        std::string rankName = GetTrinityString(ReputationRankStrIndex[rank]); -        std::ostringstream ss; -        if (m_session) -            ss << faction.ID << " - |cffffffff|Hfaction:" << faction.ID << "|h[" << factionName << ' ' << localeNames[loc] << "]|h|r"; -        else -            ss << faction.ID << " - " << factionName << ' ' << localeNames[loc]; - -        ss << ' ' << rankName << " (" << target->GetReputationMgr().GetReputation(factionEntry) << ')'; - -        if (faction.Flags & FACTION_FLAG_VISIBLE) -            ss << GetTrinityString(LANG_FACTION_VISIBLE); -        if (faction.Flags & FACTION_FLAG_AT_WAR) -            ss << GetTrinityString(LANG_FACTION_ATWAR); -        if (faction.Flags & FACTION_FLAG_PEACE_FORCED) -            ss << GetTrinityString(LANG_FACTION_PEACE_FORCED); -        if (faction.Flags & FACTION_FLAG_HIDDEN) -            ss << GetTrinityString(LANG_FACTION_HIDDEN); -        if (faction.Flags & FACTION_FLAG_INVISIBLE_FORCED) -            ss << GetTrinityString(LANG_FACTION_INVISIBLE_FORCED); -        if (faction.Flags & FACTION_FLAG_INACTIVE) -            ss << GetTrinityString(LANG_FACTION_INACTIVE); - -        SendSysMessage(ss.str().c_str()); -    } -    return true; -} -  bool ChatHandler::HandleLookupEventCommand(const char* args)  {      if (!*args) @@ -848,13 +664,6 @@ bool ChatHandler::LookupPlayerSearchCommand(PreparedQueryResult result, int32 li      return true;  } -/// Triggering corpses expire check in world -bool ChatHandler::HandleServerCorpsesCommand(const char* /*args*/) -{ -    sObjectAccessor->RemoveOldCorpses(); -    return true; -} -  bool ChatHandler::HandleRepairitemsCommand(const char* args)  {      Player* target; @@ -1130,43 +939,3 @@ bool ChatHandler::HandleLookupTitleCommand(const char* args)          SendSysMessage(LANG_COMMAND_NOTITLEFOUND);      return true;  } - -bool ChatHandler::HandleCharacterTitlesCommand(const char* args) -{ -    if (!*args) -        return false; - -    Player* target; -    if (!extractPlayerTarget((char*)args, &target)) -        return false; - -    LocaleConstant loc = GetSessionDbcLocale(); -    char const* targetName = target->GetName(); -    char const* knownStr = GetTrinityString(LANG_KNOWN); - -    // Search in CharTitles.dbc -    for (uint32 id = 0; id < sCharTitlesStore.GetNumRows(); id++) -    { -        CharTitlesEntry const* titleInfo = sCharTitlesStore.LookupEntry(id); -        if (titleInfo && target->HasTitle(titleInfo)) -        { -            std::string name = titleInfo->name; -            if (name.empty()) -                continue; - -            char const* activeStr = target && target->GetUInt32Value(PLAYER_CHOSEN_TITLE) == titleInfo->bit_index -                ? GetTrinityString(LANG_ACTIVE) -                : ""; - -            char titleNameStr[80]; -            snprintf(titleNameStr, 80, name.c_str(), targetName); - -            // send title in "id (idx:idx) - [namedlink locale]" format -            if (m_session) -                PSendSysMessage(LANG_TITLE_LIST_CHAT, id, titleInfo->bit_index, id, titleNameStr, localeNames[loc], knownStr, activeStr); -            else -                PSendSysMessage(LANG_TITLE_LIST_CONSOLE, id, titleInfo->bit_index, name.c_str(), localeNames[loc], knownStr, activeStr); -        } -    } -    return true; -} diff --git a/src/server/game/Chat/Commands/Level3.cpp b/src/server/game/Chat/Commands/Level3.cpp index 2ae7e73b828..0386b8786b6 100755 --- a/src/server/game/Chat/Commands/Level3.cpp +++ b/src/server/game/Chat/Commands/Level3.cpp @@ -385,365 +385,6 @@ bool ChatHandler::HandleAddItemSetCommand(const char *args)      return true;  } -bool ChatHandler::HandleListItemCommand(const char *args) -{ -    if (!*args) -        return false; - -    char* cId = extractKeyFromLink((char*)args, "Hitem"); -    if (!cId) -        return false; - -    uint32 item_id = atol(cId); -    if (!item_id) -    { -        PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id); -        SetSentErrorMessage(true); -        return false; -    } - -    ItemTemplate const* itemProto = sObjectMgr->GetItemTemplate(item_id); -    if (!itemProto) -    { -        PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id); -        SetSentErrorMessage(true); -        return false; -    } - -    char* c_count = strtok(NULL, " "); -    int _count = c_count ? atol(c_count) : 10; - -    if (_count < 0) -        return false; -    uint32 count = uint32(_count); - -    PreparedQueryResult result; - -    // inventory case -    uint32 inv_count = 0; - -    PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_INVENTORY_COUNT_ITEM); -    stmt->setUInt32(0, item_id); -    result = CharacterDatabase.Query(stmt); - -    if (result) -        inv_count = (*result)[0].GetUInt64(); - -    stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_INVENTORY_ITEM_BY_ENTRY); -    stmt->setUInt32(0, item_id); -    stmt->setUInt32(1, count); -    result = CharacterDatabase.Query(stmt); - -    if (result) -    { -        do -        { -            Field* fields = result->Fetch(); -            uint32 item_guid = fields[0].GetUInt32(); -            uint32 item_bag = fields[1].GetUInt32(); -            uint8 item_slot = fields[2].GetUInt8(); -            uint32 owner_guid = fields[3].GetUInt32(); -            uint32 owner_acc = fields[4].GetUInt32(); -            std::string owner_name = fields[5].GetString(); - -            char const* item_pos = 0; -            if (Player::IsEquipmentPos(item_bag, item_slot)) -                item_pos = "[equipped]"; -            else if (Player::IsInventoryPos(item_bag, item_slot)) -                item_pos = "[in inventory]"; -            else if (Player::IsBankPos(item_bag, item_slot)) -                item_pos = "[in bank]"; -            else -                item_pos = ""; - -            PSendSysMessage(LANG_ITEMLIST_SLOT, item_guid, owner_name.c_str(), owner_guid, owner_acc, item_pos); -        } -        while (result->NextRow()); - -        uint32 res_count = uint32(result->GetRowCount()); - -        if (count > res_count) -            count -= res_count; -        else if (count) -            count = 0; -    } - -    // mail case -    uint32 mail_count = 0; - -    stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAIL_COUNT_ITEM); -    stmt->setUInt32(0, item_id); -    result = CharacterDatabase.Query(stmt); - -    if (result) -        mail_count = (*result)[0].GetUInt64(); - -    if (count > 0) -    { -        stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAIL_ITEMS_BY_ENTRY); -        stmt->setUInt32(0, item_id); -        stmt->setUInt32(1, count); -        result = CharacterDatabase.Query(stmt); -    } -    else -        result = PreparedQueryResult(NULL); - -    if (result) -    { -        do -        { -            Field* fields = result->Fetch(); -            uint32 item_guid        = fields[0].GetUInt32(); -            uint32 item_s           = fields[1].GetUInt32(); -            uint32 item_r           = fields[2].GetUInt32(); -            uint32 item_s_acc       = fields[3].GetUInt32(); -            std::string item_s_name = fields[4].GetString(); -            uint32 item_r_acc       = fields[5].GetUInt32(); -            std::string item_r_name = fields[6].GetString(); - -            char const* item_pos = "[in mail]"; - -            PSendSysMessage(LANG_ITEMLIST_MAIL, item_guid, item_s_name.c_str(), item_s, item_s_acc, item_r_name.c_str(), item_r, item_r_acc, item_pos); -        } -        while (result->NextRow()); - -        uint32 res_count = uint32(result->GetRowCount()); - -        if (count > res_count) -            count -= res_count; -        else if (count) -            count = 0; -    } - -    // auction case -    uint32 auc_count = 0; - -    stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_AUCTIONHOUSE_COUNT_ITEM); -    stmt->setUInt32(0, item_id); -    result = CharacterDatabase.Query(stmt); - -    if (result) -        auc_count = (*result)[0].GetUInt64(); - -    if (count > 0) -    { -        stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_AUCTIONHOUSE_ITEM_BY_ENTRY); -        stmt->setUInt32(0, item_id); -        stmt->setUInt32(1, count); -        result = CharacterDatabase.Query(stmt); -    } -    else -        result = PreparedQueryResult(NULL); - -    if (result) -    { -        do -        { -            Field* fields = result->Fetch(); -            uint32 item_guid       = fields[0].GetUInt32(); -            uint32 owner           = fields[1].GetUInt32(); -            uint32 owner_acc       = fields[2].GetUInt32(); -            std::string owner_name = fields[3].GetString(); - -            char const* item_pos = "[in auction]"; - -            PSendSysMessage(LANG_ITEMLIST_AUCTION, item_guid, owner_name.c_str(), owner, owner_acc, item_pos); -        } -        while (result->NextRow()); -    } - -    // guild bank case -    uint32 guild_count = 0; - -    stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_BANK_COUNT_ITEM); -    stmt->setUInt32(0, item_id); -    result = CharacterDatabase.Query(stmt); - -    if (result) -        guild_count = (*result)[0].GetUInt64(); - -    stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_BANK_ITEM_BY_ENTRY); -    stmt->setUInt32(0, item_id); -    stmt->setUInt32(1, count); -    result = CharacterDatabase.Query(stmt); - -    if (result) -    { -        do -        { -            Field* fields = result->Fetch(); -            uint32 item_guid = fields[0].GetUInt32(); -            uint32 guild_guid = fields[1].GetUInt32(); -            std::string guild_name = fields[2].GetString(); - -            char const* item_pos = "[in guild bank]"; - -            PSendSysMessage(LANG_ITEMLIST_GUILD, item_guid, guild_name.c_str(), guild_guid, item_pos); -        } -        while (result->NextRow()); - -        uint32 res_count = uint32(result->GetRowCount()); - -        if (count > res_count) -            count -= res_count; -        else if (count) -            count = 0; -    } - -    if (inv_count + mail_count + auc_count + guild_count == 0) -    { -        SendSysMessage(LANG_COMMAND_NOITEMFOUND); -        SetSentErrorMessage(true); -        return false; -    } - -    PSendSysMessage(LANG_COMMAND_LISTITEMMESSAGE, item_id, inv_count + mail_count + auc_count + guild_count, inv_count, mail_count, auc_count, guild_count); -    return true; -} - -bool ChatHandler::HandleListObjectCommand(const char *args) -{ -    if (!*args) -        return false; - -    // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r -    char* cId = extractKeyFromLink((char*)args, "Hgameobject_entry"); -    if (!cId) -        return false; - -    uint32 go_id = atol(cId); -    if (!go_id) -    { -        PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, go_id); -        SetSentErrorMessage(true); -        return false; -    } - -    GameObjectTemplate const* gInfo = sObjectMgr->GetGameObjectTemplate(go_id); -    if (!gInfo) -    { -        PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, go_id); -        SetSentErrorMessage(true); -        return false; -    } - -    char* c_count = strtok(NULL, " "); -    int count = c_count ? atol(c_count) : 10; - -    if (count < 0) -        return false; - -    QueryResult result; - -    uint32 obj_count = 0; -    result = WorldDatabase.PQuery("SELECT COUNT(guid) FROM gameobject WHERE id='%u'", go_id); -    if (result) -        obj_count = (*result)[0].GetUInt64(); - -    if (m_session) -    { -        Player* player = m_session->GetPlayer(); -        result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map, id, (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ FROM gameobject WHERE id = '%u' ORDER BY order_ ASC LIMIT %u", -            player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), go_id, uint32(count)); -    } -    else -        result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map, id FROM gameobject WHERE id = '%u' LIMIT %u", -            go_id, uint32(count)); - -    if (result) -    { -        do -        { -            Field* fields = result->Fetch(); -            uint32 guid = fields[0].GetUInt32(); -            float x = fields[1].GetFloat(); -            float y = fields[2].GetFloat(); -            float z = fields[3].GetFloat(); -            int mapid = fields[4].GetUInt16(); -            uint32 entry = fields[5].GetUInt32(); - -            if (m_session) -                PSendSysMessage(LANG_GO_LIST_CHAT, guid, entry, guid, gInfo->name.c_str(), x, y, z, mapid); -            else -                PSendSysMessage(LANG_GO_LIST_CONSOLE, guid, gInfo->name.c_str(), x, y, z, mapid); -        } while (result->NextRow()); -    } - -    PSendSysMessage(LANG_COMMAND_LISTOBJMESSAGE, go_id, obj_count); -    return true; -} - -bool ChatHandler::HandleListCreatureCommand(const char *args) -{ -    if (!*args) -        return false; - -    // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r -    char* cId = extractKeyFromLink((char*)args, "Hcreature_entry"); -    if (!cId) -        return false; - -    uint32 cr_id = atol(cId); -    if (!cr_id) -    { -        PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, cr_id); -        SetSentErrorMessage(true); -        return false; -    } - -    CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(cr_id); -    if (!cInfo) -    { -        PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, cr_id); -        SetSentErrorMessage(true); -        return false; -    } - -    char* c_count = strtok(NULL, " "); -    int count = c_count ? atol(c_count) : 10; - -    if (count < 0) -        return false; - -    QueryResult result; - -    uint32 cr_count = 0; -    result = WorldDatabase.PQuery("SELECT COUNT(guid) FROM creature WHERE id='%u'", cr_id); -    if (result) -        cr_count = (*result)[0].GetUInt64(); - -    if (m_session) -    { -        Player* player = m_session->GetPlayer(); -        result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map, (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ FROM creature WHERE id = '%u' ORDER BY order_ ASC LIMIT %u", -            player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), cr_id, uint32(count)); -    } -    else -        result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map FROM creature WHERE id = '%u' LIMIT %u", -            cr_id, uint32(count)); - -    if (result) -    { -        do -        { -            Field* fields = result->Fetch(); -            uint32 guid = fields[0].GetUInt32(); -            float x = fields[1].GetFloat(); -            float y = fields[2].GetFloat(); -            float z = fields[3].GetFloat(); -            int mapid = fields[4].GetUInt16(); - -            if (m_session) -                PSendSysMessage(LANG_CREATURE_LIST_CHAT, guid, guid, cInfo->Name.c_str(), x, y, z, mapid); -            else -                PSendSysMessage(LANG_CREATURE_LIST_CONSOLE, guid, cInfo->Name.c_str(), x, y, z, mapid); -        } while (result->NextRow()); -    } - -    PSendSysMessage(LANG_COMMAND_LISTCREATUREMESSAGE, cr_id, cr_count); -    return true; -} -  bool ChatHandler::HandleLookupItemCommand(const char *args)  {      if (!*args) @@ -1144,15 +785,20 @@ bool ChatHandler::HandleLookupQuestCommand(const char *args)                          {                              QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId()); -                            if (status == QUEST_STATUS_COMPLETE) +                            switch (status)                               { -                                if (target->GetQuestRewardStatus(qinfo->GetQuestId())) -                                    statusStr = GetTrinityString(LANG_COMMAND_QUEST_REWARDED); -                                else +                                case QUEST_STATUS_COMPLETE:                                      statusStr = GetTrinityString(LANG_COMMAND_QUEST_COMPLETE); +                                    break; +                                case QUEST_STATUS_INCOMPLETE: +                                    statusStr = GetTrinityString(LANG_COMMAND_QUEST_ACTIVE); +                                    break; +                                case QUEST_STATUS_REWARDED: +                                    statusStr = GetTrinityString(LANG_COMMAND_QUEST_REWARDED); +                                    break; +                                default: +                                    break;                              } -                            else if (status == QUEST_STATUS_INCOMPLETE) -                                statusStr = GetTrinityString(LANG_COMMAND_QUEST_ACTIVE);                          }                          if (m_session) @@ -1187,15 +833,20 @@ bool ChatHandler::HandleLookupQuestCommand(const char *args)              {                  QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId()); -                if (status == QUEST_STATUS_COMPLETE) +                switch (status)                   { -                    if (target->GetQuestRewardStatus(qinfo->GetQuestId())) -                        statusStr = GetTrinityString(LANG_COMMAND_QUEST_REWARDED); -                    else +                    case QUEST_STATUS_COMPLETE:                          statusStr = GetTrinityString(LANG_COMMAND_QUEST_COMPLETE); +                        break; +                    case QUEST_STATUS_INCOMPLETE: +                        statusStr = GetTrinityString(LANG_COMMAND_QUEST_ACTIVE); +                        break; +                    case QUEST_STATUS_REWARDED: +                        statusStr = GetTrinityString(LANG_COMMAND_QUEST_REWARDED); +                        break; +                    default: +                        break;                  } -                else if (status == QUEST_STATUS_INCOMPLETE) -                    statusStr = GetTrinityString(LANG_COMMAND_QUEST_ACTIVE);              }              if (m_session) @@ -1730,7 +1381,7 @@ bool ChatHandler::HandleGuildUninviteCommand(const char *args)      if (!extractPlayerTarget((char*)args, &target, &target_guid))          return false; -    uint32 glId = target ? target->GetGuildId() : Player::GetGuildIdFromGuid(target_guid); +    uint32 glId = target ? target->GetGuildId() : Player::GetGuildIdFromDB(target_guid);      if (!glId)          return false; @@ -1756,7 +1407,7 @@ bool ChatHandler::HandleGuildRankCommand(const char *args)      if (!extractPlayerTarget(nameStr, &target, &target_guid, &target_name))          return false; -    uint32 glId = target ? target->GetGuildId() : Player::GetGuildIdFromGuid(target_guid); +    uint32 glId = target ? target->GetGuildId() : Player::GetGuildIdFromDB(target_guid);      if (!glId)          return false; @@ -2188,47 +1839,6 @@ void ChatHandler::HandleCharacterLevel(Player* player, uint64 playerGuid, uint32      }  } -bool ChatHandler::HandleCharacterLevelCommand(const char *args) -{ -    char* nameStr; -    char* levelStr; -    extractOptFirstArg((char*)args, &nameStr, &levelStr); -    if (!levelStr) -        return false; - -    // exception opt second arg: .character level $name -    if (isalpha(levelStr[0])) -    { -        nameStr = levelStr; -        levelStr = NULL;                                    // current level will used -    } - -    Player* target; -    uint64 target_guid; -    std::string target_name; -    if (!extractPlayerTarget(nameStr, &target, &target_guid, &target_name)) -        return false; - -    int32 oldlevel = target ? target->getLevel() : Player::GetLevelFromDB(target_guid); -    int32 newlevel = levelStr ? atoi(levelStr) : oldlevel; - -    if (newlevel < 1) -        return false;                                       // invalid level - -    if (newlevel > STRONG_MAX_LEVEL)                         // hardcoded maximum level -        newlevel = STRONG_MAX_LEVEL; - -    HandleCharacterLevel(target, target_guid, oldlevel, newlevel); - -    if (!m_session || m_session->GetPlayer() != target)      // including player == NULL -    { -        std::string nameLink = playerLink(target_name); -        PSendSysMessage(LANG_YOU_CHANGE_LVL, nameLink.c_str(), newlevel); -    } - -    return true; -} -  bool ChatHandler::HandleLevelUpCommand(const char *args)  {      char* nameStr; @@ -2380,457 +1990,6 @@ bool ChatHandler::HandleChangeWeather(const char *args)      return true;  } -bool ChatHandler::HandleListAurasCommand (const char * /*args*/) -{ -    Unit* unit = getSelectedUnit(); -    if (!unit) -    { -        SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); -        SetSentErrorMessage(true); -        return false; -    } - -    char const* talentStr = GetTrinityString(LANG_TALENT); -    char const* passiveStr = GetTrinityString(LANG_PASSIVE); - -    Unit::AuraApplicationMap const& uAuras = unit->GetAppliedAuras(); -    PSendSysMessage(LANG_COMMAND_TARGET_LISTAURAS, uAuras.size()); -    for (Unit::AuraApplicationMap::const_iterator itr = uAuras.begin(); itr != uAuras.end(); ++itr) -    { -        bool talent = GetTalentSpellCost(itr->second->GetBase()->GetId()) > 0; - -        AuraApplication const* aurApp = itr->second; -        Aura const* aura = aurApp->GetBase(); -        char const* name = aura->GetSpellInfo()->SpellName; - -        std::ostringstream ss_name; -        ss_name << "|cffffffff|Hspell:" << aura->GetId() << "|h[" << name << "]|h|r"; - -        PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, aura->GetId(), (m_session ? ss_name.str().c_str() : name), -            aurApp->GetEffectMask(), aura->GetCharges(), aura->GetStackAmount(), aurApp->GetSlot(), -            aura->GetDuration(), aura->GetMaxDuration(), (aura->IsPassive() ? passiveStr : ""), -            (talent ? talentStr : ""), IS_PLAYER_GUID(aura->GetCasterGUID()) ? "player" : "creature", -            GUID_LOPART(aura->GetCasterGUID())); -    } -    for (uint16 i = 0; i < TOTAL_AURAS; ++i) -    { -        Unit::AuraEffectList const& uAuraList = unit->GetAuraEffectsByType(AuraType(i)); -        if (uAuraList.empty()) -            continue; - -        PSendSysMessage(LANG_COMMAND_TARGET_LISTAURATYPE, uAuraList.size(), i); -        for (Unit::AuraEffectList::const_iterator itr = uAuraList.begin(); itr != uAuraList.end(); ++itr) -        { -            PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(), -                (*itr)->GetAmount()); -        } -    } -    return true; -} - -bool ChatHandler::HandleResetAchievementsCommand (const char * args) -{ -    Player* target; -    uint64 target_guid; -    if (!extractPlayerTarget((char*)args, &target, &target_guid)) -        return false; - -    if (target) -        target->GetAchievementMgr().Reset(); -    else -        AchievementMgr::DeleteFromDB(GUID_LOPART(target_guid)); - -    return true; -} - -bool ChatHandler::HandleResetHonorCommand (const char * args) -{ -    Player* target; -    if (!extractPlayerTarget((char*)args, &target)) -        return false; - -    target->SetCurrency(CURRENCY_TYPE_HONOR_POINTS, 0); -    target->SetUInt32Value(PLAYER_FIELD_KILLS, 0); -    target->SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS, 0); -    target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL); - -    return true; -} - -static bool HandleResetStatsOrLevelHelper(Player* player) -{ -    ChrClassesEntry const* cEntry = sChrClassesStore.LookupEntry(player->getClass()); -    if (!cEntry) -    { -        sLog->outError("Class %u not found in DBC (Wrong DBC files?)", player->getClass()); -        return false; -    } - -    uint8 powertype = cEntry->powerType; - -    // reset m_form if no aura -    if (!player->HasAuraType(SPELL_AURA_MOD_SHAPESHIFT)) -        player->SetShapeshiftForm(FORM_NONE); - -    player->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, DEFAULT_WORLD_OBJECT_SIZE); -    player->SetFloatValue(UNIT_FIELD_COMBATREACH, DEFAULT_COMBAT_REACH); - -    player->setFactionForRace(player->getRace()); - -    player->SetUInt32Value(UNIT_FIELD_BYTES_0, ((player->getRace()) | (player->getClass() << 8) | (player->getGender() << 16) | (powertype << 24))); - -    // reset only if player not in some form; -    if (player->GetShapeshiftForm() == FORM_NONE) -        player->InitDisplayIds(); - -    player->SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP); - -    player->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); - -    //-1 is default value -    player->SetUInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, uint32(-1)); - -    //player->SetUInt32Value(PLAYER_FIELD_BYTES, 0xEEE00000); -    return true; -} - -bool ChatHandler::HandleResetLevelCommand(const char * args) -{ -    Player* target; -    if (!extractPlayerTarget((char*)args, &target)) -        return false; - -    if (!HandleResetStatsOrLevelHelper(target)) -        return false; - -    uint8 oldLevel = target->getLevel(); - -    // set starting level -    uint32 start_level = target->getClass() != CLASS_DEATH_KNIGHT -        ? sWorld->getIntConfig(CONFIG_START_PLAYER_LEVEL) -        : sWorld->getIntConfig(CONFIG_START_HEROIC_PLAYER_LEVEL); - -    target->_ApplyAllLevelScaleItemMods(false); -    target->SetLevel(start_level); -    target->InitRunes(); -    target->InitStatsForLevel(true); -    target->InitTaxiNodesForLevel(); -    target->InitGlyphsForLevel(); -    target->InitTalentForLevel(); -    target->SetUInt32Value(PLAYER_XP, 0); - -    target->_ApplyAllLevelScaleItemMods(true); - -    // reset level for pet -    if (Pet* pet = target->GetPet()) -        pet->SynchronizeLevelWithOwner(); - -    sScriptMgr->OnPlayerLevelChanged(target, oldLevel); - -    return true; -} - -bool ChatHandler::HandleResetStatsCommand(const char * args) -{ -    Player* target; -    if (!extractPlayerTarget((char*)args, &target)) -        return false; - -    if (!HandleResetStatsOrLevelHelper(target)) -        return false; - -    target->InitRunes(); -    target->InitStatsForLevel(true); -    target->InitTaxiNodesForLevel(); -    target->InitGlyphsForLevel(); -    target->InitTalentForLevel(); - -    return true; -} - -bool ChatHandler::HandleResetSpellsCommand(const char* args) -{ -    Player* target; -    uint64 targetGuid; -    std::string targetName; -    if (!extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) -        return false; - -    if (target) -    { -        target->resetSpells(/* bool myClassOnly */); - -        ChatHandler(target).SendSysMessage(LANG_RESET_SPELLS); -        if (!m_session || m_session->GetPlayer() != target) -            PSendSysMessage(LANG_RESET_SPELLS_ONLINE, GetNameLink(target).c_str()); -    } -    else -    { -        PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG); - -        stmt->setUInt16(0, uint16(AT_LOGIN_RESET_SPELLS)); -        stmt->setUInt32(1, GUID_LOPART(targetGuid)); - -        CharacterDatabase.Execute(stmt); - -        PSendSysMessage(LANG_RESET_SPELLS_OFFLINE, targetName.c_str()); -    } - -    return true; -} - -bool ChatHandler::HandleResetTalentsCommand(const char* args) -{ -    Player* target; -    uint64 targetGuid; -    std::string targetName; -    if (!extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) -    { -        // Try reset talents as Hunter Pet -        Creature* creature = getSelectedCreature(); -        if (!*args && creature && creature->isPet()) -        { -            Unit* owner = creature->GetOwner(); -            if (owner && owner->GetTypeId() == TYPEID_PLAYER && creature->ToPet()->IsPermanentPetFor(owner->ToPlayer())) -            { -                creature->ToPet()->resetTalents(); -                owner->ToPlayer()->SendTalentsInfoData(true); - -                ChatHandler(owner->ToPlayer()).SendSysMessage(LANG_RESET_PET_TALENTS); -                if (!m_session || m_session->GetPlayer() != owner->ToPlayer()) -                    PSendSysMessage(LANG_RESET_PET_TALENTS_ONLINE, GetNameLink(owner->ToPlayer()).c_str()); -            } -            return true; -        } - -        SendSysMessage(LANG_NO_CHAR_SELECTED); -        SetSentErrorMessage(true); -        return false; -    } - -    if (target) -    { -        target->ResetTalents(true); -        target->SendTalentsInfoData(false); -        ChatHandler(target).SendSysMessage(LANG_RESET_TALENTS); -        if (!m_session || m_session->GetPlayer() != target) -            PSendSysMessage(LANG_RESET_TALENTS_ONLINE, GetNameLink(target).c_str()); - -        Pet* pet = target->GetPet(); -        Pet::resetTalentsForAllPetsOf(target, pet); -        if (pet) -            target->SendTalentsInfoData(true); -        return true; -    } -    else if (targetGuid) -    { -        PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG); - -        stmt->setUInt16(0, uint16(AT_LOGIN_NONE | AT_LOGIN_RESET_PET_TALENTS)); -        stmt->setUInt32(1, GUID_LOPART(targetGuid)); - -        CharacterDatabase.Execute(stmt); - -        std::string nameLink = playerLink(targetName); -        PSendSysMessage(LANG_RESET_TALENTS_OFFLINE, nameLink.c_str()); -        return true; -    } - -    SendSysMessage(LANG_NO_CHAR_SELECTED); -    SetSentErrorMessage(true); -    return false; -} - -bool ChatHandler::HandleResetAllCommand(const char * args) -{ -    if (!*args) -        return false; - -    std::string casename = args; - -    AtLoginFlags atLogin; - -    // Command specially created as single command to prevent using short case names -    if (casename == "spells") -    { -        atLogin = AT_LOGIN_RESET_SPELLS; -        sWorld->SendWorldText(LANG_RESETALL_SPELLS); -        if (!m_session) -            SendSysMessage(LANG_RESETALL_SPELLS); -    } -    else if (casename == "talents") -    { -        atLogin = AtLoginFlags(AT_LOGIN_RESET_TALENTS | AT_LOGIN_RESET_PET_TALENTS); -        sWorld->SendWorldText(LANG_RESETALL_TALENTS); -        if (!m_session) -            SendSysMessage(LANG_RESETALL_TALENTS); -    } -    else -    { -        PSendSysMessage(LANG_RESETALL_UNKNOWN_CASE, args); -        SetSentErrorMessage(true); -        return false; -    } - -    PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ALL_AT_LOGIN_FLAGS); - -    stmt->setUInt16(0, uint16(atLogin)); - -    CharacterDatabase.Execute(stmt); - -    TRINITY_READ_GUARD(HashMapHolder<Player>::LockType, *HashMapHolder<Player>::GetLock()); -    HashMapHolder<Player>::MapType const& plist = sObjectAccessor->GetPlayers(); -    for (HashMapHolder<Player>::MapType::const_iterator itr = plist.begin(); itr != plist.end(); ++itr) -        itr->second->SetAtLoginFlag(atLogin); - -    return true; -} - -bool ChatHandler::HandleServerShutDownCancelCommand(const char* /*args*/) -{ -    sWorld->ShutdownCancel(); -    return true; -} - -bool ChatHandler::HandleServerShutDownCommand(const char *args) -{ -    if (!*args) -        return false; - -    char* time_str = strtok ((char*) args, " "); -    char* exitcode_str = strtok (NULL, ""); - -    int32 time = atoi (time_str); - -    ///- Prevent interpret wrong arg value as 0 secs shutdown time -    if ((time == 0 && (time_str[0] != '0' || time_str[1] != '\0')) || time < 0) -        return false; - -    if (exitcode_str) -    { -        int32 exitcode = atoi (exitcode_str); - -        // Handle atoi() errors -        if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0')) -            return false; - -        // Exit code should be in range of 0-125, 126-255 is used -        // in many shells for their own return codes and code > 255 -        // is not supported in many others -        if (exitcode < 0 || exitcode > 125) -            return false; - -        sWorld->ShutdownServ(time, 0, exitcode); -    } -    else -        sWorld->ShutdownServ(time, 0, SHUTDOWN_EXIT_CODE); -    return true; -} - -bool ChatHandler::HandleServerRestartCommand(const char *args) -{ -    if (!*args) -        return false; - -    char* time_str = strtok ((char*) args, " "); -    char* exitcode_str = strtok (NULL, ""); - -    int32 time = atoi (time_str); - -    ///- Prevent interpret wrong arg value as 0 secs shutdown time -    if ((time == 0 && (time_str[0] != '0' || time_str[1] != '\0')) || time < 0) -        return false; - -    if (exitcode_str) -    { -        int32 exitcode = atoi (exitcode_str); - -        // Handle atoi() errors -        if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0')) -            return false; - -        // Exit code should be in range of 0-125, 126-255 is used -        // in many shells for their own return codes and code > 255 -        // is not supported in many others -        if (exitcode < 0 || exitcode > 125) -            return false; - -        sWorld->ShutdownServ(time, SHUTDOWN_MASK_RESTART, exitcode); -    } -    else -        sWorld->ShutdownServ(time, SHUTDOWN_MASK_RESTART, RESTART_EXIT_CODE); -    return true; -} - -bool ChatHandler::HandleServerIdleRestartCommand(const char *args) -{ -    if (!*args) -        return false; - -    char* time_str = strtok ((char*) args, " "); -    char* exitcode_str = strtok (NULL, ""); - -    int32 time = atoi (time_str); - -    ///- Prevent interpret wrong arg value as 0 secs shutdown time -    if ((time == 0 && (time_str[0] != '0' || time_str[1] != '\0')) || time < 0) -        return false; - -    if (exitcode_str) -    { -        int32 exitcode = atoi (exitcode_str); - -        // Handle atoi() errors -        if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0')) -            return false; - -        // Exit code should be in range of 0-125, 126-255 is used -        // in many shells for their own return codes and code > 255 -        // is not supported in many others -        if (exitcode < 0 || exitcode > 125) -            return false; - -        sWorld->ShutdownServ(time, SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE, exitcode); -    } -    else -        sWorld->ShutdownServ(time, SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE, RESTART_EXIT_CODE); -    return true; -} - -bool ChatHandler::HandleServerIdleShutDownCommand(const char *args) -{ -    if (!*args) -        return false; - -    char* time_str = strtok ((char*) args, " "); -    char* exitcode_str = strtok (NULL, ""); - -    int32 time = atoi (time_str); - -    ///- Prevent interpret wrong arg value as 0 secs shutdown time -    if ((time == 0 && (time_str[0] != '0' || time_str[1] != '\0')) || time < 0) -        return false; - -    if (exitcode_str) -    { -        int32 exitcode = atoi (exitcode_str); - -        // Handle atoi() errors -        if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0')) -            return false; - -        // Exit code should be in range of 0-125, 126-255 is used -        // in many shells for their own return codes and code > 255 -        // is not supported in many others -        if (exitcode < 0 || exitcode > 125) -            return false; - -        sWorld->ShutdownServ(time, SHUTDOWN_MASK_IDLE, exitcode); -    } -    else -        sWorld->ShutdownServ(time, SHUTDOWN_MASK_IDLE, SHUTDOWN_EXIT_CODE); -    return true; -}  bool ChatHandler::HandleBanAccountCommand(const char *args)  { @@ -3752,277 +2911,6 @@ bool ChatHandler::HandleMovegensCommand(const char* /*args*/)      return true;  } -bool ChatHandler::HandleServerPLimitCommand(const char *args) -{ -    if (*args) -    { -        char* param = strtok((char*)args, " "); -        if (!param) -            return false; - -        int l = strlen(param); - -        if (strncmp(param, "player", l) == 0) -            sWorld->SetPlayerSecurityLimit(SEC_PLAYER); -        else if (strncmp(param, "moderator", l) == 0) -            sWorld->SetPlayerSecurityLimit(SEC_MODERATOR); -        else if (strncmp(param, "gamemaster", l) == 0) -            sWorld->SetPlayerSecurityLimit(SEC_GAMEMASTER); -        else if (strncmp(param, "administrator", l) == 0) -            sWorld->SetPlayerSecurityLimit(SEC_ADMINISTRATOR); -        else if (strncmp(param, "reset", l) == 0) -        { -            sWorld->SetPlayerAmountLimit(ConfigMgr::GetIntDefault("PlayerLimit", 100)); -            sWorld->LoadDBAllowedSecurityLevel(); -        } -        else -        { -            int val = atoi(param); -            if (val < 0) -                sWorld->SetPlayerSecurityLimit(AccountTypes(uint32(-val))); -            else -                sWorld->SetPlayerAmountLimit(uint32(val)); -        } -    } - -    uint32 pLimit = sWorld->GetPlayerAmountLimit(); -    AccountTypes allowedAccountType = sWorld->GetPlayerSecurityLimit(); -    char const* secName = ""; -    switch (allowedAccountType) -    { -        case SEC_PLAYER:        secName = "Player";        break; -        case SEC_MODERATOR:     secName = "Moderator";     break; -        case SEC_GAMEMASTER:    secName = "Gamemaster";    break; -        case SEC_ADMINISTRATOR: secName = "Administrator"; break; -        default:                secName = "<unknown>";     break; -    } - -    PSendSysMessage("Player limits: amount %u, min. security level %s.", pLimit, secName); - -    return true; -} - -bool ChatHandler::HandleCastCommand(const char *args) -{ -    if (!*args) -        return false; - -    Unit* target = getSelectedUnit(); - -    if (!target) -    { -        SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); -        SetSentErrorMessage(true); -        return false; -    } - -    // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form -    uint32 spell = extractSpellIdFromLink((char*)args); -    if (!spell) -        return false; - -    SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell); -    if (!spellInfo) -    { -        PSendSysMessage(LANG_COMMAND_NOSPELLFOUND); -        SetSentErrorMessage(true); -        return false; -    } - -    if (!SpellMgr::IsSpellValid(spellInfo, m_session->GetPlayer())) -    { -        PSendSysMessage(LANG_COMMAND_SPELL_BROKEN, spell); -        SetSentErrorMessage(true); -        return false; -    } - -    char* trig_str = strtok(NULL, " "); -    if (trig_str) -    { -        int l = strlen(trig_str); -        if (strncmp(trig_str, "triggered", l) != 0) -            return false; -    } - -    bool triggered = (trig_str != NULL); - -    m_session->GetPlayer()->CastSpell(target, spell, triggered); - -    return true; -} - -bool ChatHandler::HandleCastBackCommand(const char *args) -{ -    Creature* caster = getSelectedCreature(); - -    if (!caster) -    { -        SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); -        SetSentErrorMessage(true); -        return false; -    } - -    // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r -    // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form -    uint32 spell = extractSpellIdFromLink((char*)args); -    if (!spell || !sSpellMgr->GetSpellInfo(spell)) -    { -        PSendSysMessage(LANG_COMMAND_NOSPELLFOUND); -        SetSentErrorMessage(true); -        return false; -    } - -    char* trig_str = strtok(NULL, " "); -    if (trig_str) -    { -        int l = strlen(trig_str); -        if (strncmp(trig_str, "triggered", l) != 0) -            return false; -    } - -    bool triggered = (trig_str != NULL); - -    caster->CastSpell(m_session->GetPlayer(), spell, triggered); - -    return true; -} - -bool ChatHandler::HandleCastDistCommand(const char *args) -{ -    if (!*args) -        return false; - -    // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form -    uint32 spell = extractSpellIdFromLink((char*)args); -    if (!spell) -        return false; - -    SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell); -    if (!spellInfo) -    { -        PSendSysMessage(LANG_COMMAND_NOSPELLFOUND); -        SetSentErrorMessage(true); -        return false; -    } - -    if (!SpellMgr::IsSpellValid(spellInfo, m_session->GetPlayer())) -    { -        PSendSysMessage(LANG_COMMAND_SPELL_BROKEN, spell); -        SetSentErrorMessage(true); -        return false; -    } - -    char *distStr = strtok(NULL, " "); - -    float dist = 0; - -    if (distStr) -        sscanf(distStr, "%f", &dist); - -    char* trig_str = strtok(NULL, " "); -    if (trig_str) -    { -        int l = strlen(trig_str); -        if (strncmp(trig_str, "triggered", l) != 0) -            return false; -    } - -    bool triggered = (trig_str != NULL); - -    float x, y, z; -    m_session->GetPlayer()->GetClosePoint(x, y, z, dist); - -    m_session->GetPlayer()->CastSpell(x, y, z, spell, triggered); -    return true; -} - -bool ChatHandler::HandleCastTargetCommand(const char *args) -{ -    Creature* caster = getSelectedCreature(); - -    if (!caster) -    { -        SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); -        SetSentErrorMessage(true); -        return false; -    } - -    if (!caster->getVictim()) -    { -        SendSysMessage(LANG_SELECTED_TARGET_NOT_HAVE_VICTIM); -        SetSentErrorMessage(true); -        return false; -    } - -    // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form -    uint32 spell = extractSpellIdFromLink((char*)args); -    if (!spell || !sSpellMgr->GetSpellInfo(spell)) -    { -        PSendSysMessage(LANG_COMMAND_NOSPELLFOUND); -        SetSentErrorMessage(true); -        return false; -    } - -    char* trig_str = strtok(NULL, " "); -    if (trig_str) -    { -        int l = strlen(trig_str); -        if (strncmp(trig_str, "triggered", l) != 0) -            return false; -    } - -    bool triggered = (trig_str != NULL); - -    caster->CastSpell(caster->getVictim(), spell, triggered); - -    return true; -} - -bool ChatHandler::HandleCastDestCommand(const char *args) -{ -    Unit* caster = getSelectedUnit(); -    if (!caster) -    { -        SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); -        SetSentErrorMessage(true); -        return false; -    } - -    // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form -    uint32 spell = extractSpellIdFromLink((char*)args); -    if (!spell || !sSpellMgr->GetSpellInfo(spell)) -    { -        PSendSysMessage(LANG_COMMAND_NOSPELLFOUND); -        SetSentErrorMessage(true); -        return false; -    } - -    char* px = strtok(NULL, " "); -    char* py = strtok(NULL, " "); -    char* pz = strtok(NULL, " "); - -    if (!px || !py || !pz) -        return false; - -    float x = (float)atof(px); -    float y = (float)atof(py); -    float z = (float)atof(pz); - -    char* trig_str = strtok(NULL, " "); -    if (trig_str) -    { -        int l = strlen(trig_str); -        if (strncmp(trig_str, "triggered", l) != 0) -            return false; -    } - -    bool triggered = (trig_str != NULL); - -    caster->CastSpell(x, y, z, spell, triggered); - -    return true; -} -  /*  ComeToMe command REQUIRED for 3rd party scripting library to have access to PointMovementGenerator  Without this function 3rd party scripting library will get linking errors (unresolved external) @@ -4049,196 +2937,6 @@ bool ChatHandler::HandleComeToMeCommand(const char *args)      return true;  } -bool ChatHandler::HandleCastSelfCommand(const char *args) -{ -    if (!*args) -        return false; - -    Unit* target = getSelectedUnit(); - -    if (!target) -    { -        SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); -        SetSentErrorMessage(true); -        return false; -    } - -    // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form -    uint32 spell = extractSpellIdFromLink((char*)args); -    if (!spell) -        return false; - -    SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell); -    if (!spellInfo) -        return false; - -    if (!SpellMgr::IsSpellValid(spellInfo, m_session->GetPlayer())) -    { -        PSendSysMessage(LANG_COMMAND_SPELL_BROKEN, spell); -        SetSentErrorMessage(true); -        return false; -    } - -    target->CastSpell(target, spell, false); - -    return true; -} - -std::string GetTimeString(uint64 time) -{ -    uint64 days = time / DAY, hours = (time % DAY) / HOUR, minute = (time % HOUR) / MINUTE; -    std::ostringstream ss; -    if (days) ss << days << "d "; -    if (hours) ss << hours << "h "; -    ss << minute << 'm'; -    return ss.str(); -} - -bool ChatHandler::HandleInstanceListBindsCommand(const char* /*args*/) -{ -    Player* player = getSelectedPlayer(); -    if (!player) player = m_session->GetPlayer(); -    uint32 counter = 0; -    for (uint8 i = 0; i < MAX_DIFFICULTY; ++i) -    { -        Player::BoundInstancesMap &binds = player->GetBoundInstances(Difficulty(i)); -        for (Player::BoundInstancesMap::const_iterator itr = binds.begin(); itr != binds.end(); ++itr) -        { -            InstanceSave* save = itr->second.save; -            std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL)); -            PSendSysMessage("map: %d inst: %d perm: %s diff: %d canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no",  save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str()); -            counter++; -        } -    } -    PSendSysMessage("player binds: %d", counter); -    counter = 0; -    Group* group = player->GetGroup(); -    if (group) -    { -        for (uint8 i = 0; i < MAX_DIFFICULTY; ++i) -        { -            Group::BoundInstancesMap &binds = group->GetBoundInstances(Difficulty(i)); -            for (Group::BoundInstancesMap::const_iterator itr = binds.begin(); itr != binds.end(); ++itr) -            { -                InstanceSave* save = itr->second.save; -                std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL)); -                PSendSysMessage("map: %d inst: %d perm: %s diff: %d canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no",  save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str()); -                counter++; -            } -        } -    } -    PSendSysMessage("group binds: %d", counter); - -    return true; -} - -bool ChatHandler::HandleInstanceUnbindCommand(const char *args) -{ -    if (!*args) -        return false; - -    Player* player = getSelectedPlayer(); -    if (!player) -        player = m_session->GetPlayer(); - -    char* map = strtok((char*)args, " "); -    char* pDiff = strtok(NULL, " "); -    int8 diff = -1; -    if (pDiff) -        diff = atoi(pDiff); -    uint16 counter = 0; -    uint16 MapId = 0; - -    if (strcmp(map, "all")) -    { -        MapId = uint16(atoi(map)); -        if (!MapId) -            return false; -    } - -    for (uint8 i = 0; i < MAX_DIFFICULTY; ++i) -    { -        Player::BoundInstancesMap &binds = player->GetBoundInstances(Difficulty(i)); -        for (Player::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end();) -        { -            InstanceSave* save = itr->second.save; -            if (itr->first != player->GetMapId() && (!MapId || MapId == itr->first) && (diff == -1 || diff == save->GetDifficulty())) -            { -                std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL)); -                PSendSysMessage("unbinding map: %d inst: %d perm: %s diff: %d canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str()); -                player->UnbindInstance(itr, Difficulty(i)); -                counter++; -            } -            else -                ++itr; -        } -    } -    PSendSysMessage("instances unbound: %d", counter); -    return true; -} - -bool ChatHandler::HandleInstanceStatsCommand(const char* /*args*/) -{ -    PSendSysMessage("instances loaded: %d", sMapMgr->GetNumInstances()); -    PSendSysMessage("players in instances: %d", sMapMgr->GetNumPlayersInInstances()); -    PSendSysMessage("instance saves: %d", sInstanceSaveMgr->GetNumInstanceSaves()); -    PSendSysMessage("players bound: %d", sInstanceSaveMgr->GetNumBoundPlayersTotal()); -    PSendSysMessage("groups bound: %d", sInstanceSaveMgr->GetNumBoundGroupsTotal()); -    return true; -} - -bool ChatHandler::HandleInstanceSaveDataCommand(const char * /*args*/) -{ -    Player* player = m_session->GetPlayer(); - -    Map* map = player->GetMap(); -    if (!map->IsDungeon()) -    { -        PSendSysMessage("Map is not a dungeon."); -        SetSentErrorMessage(true); -        return false; -    } - -    if (!((InstanceMap*)map)->GetInstanceScript()) -    { -        PSendSysMessage("Map has no instance data."); -        SetSentErrorMessage(true); -        return false; -    } - -    ((InstanceMap*)map)->GetInstanceScript()->SaveToDB(); -    return true; -} - -/// Define the 'Message of the day' for the realm -bool ChatHandler::HandleServerSetMotdCommand(const char *args) -{ -    sWorld->SetMotd(args); -    PSendSysMessage(LANG_MOTD_NEW, args); -    return true; -} - -/// Set whether we accept new clients -bool ChatHandler::HandleServerSetClosedCommand(const char *args) -{ -    if (strncmp(args, "on", 3) == 0) -    { -        SendSysMessage(LANG_WORLD_CLOSED); -        sWorld->SetClosed(true); -        return true; -    } -    else if (strncmp(args, "off", 4) == 0) -    { -        SendSysMessage(LANG_WORLD_OPENED); -        sWorld->SetClosed(false); -        return true; -    } - -    SendSysMessage(LANG_USE_BOL); -    SetSentErrorMessage(true); -    return false; -} -  //Send items by mail  bool ChatHandler::HandleSendItemsCommand(const char *args)  { diff --git a/src/server/game/Combat/ThreatManager.cpp b/src/server/game/Combat/ThreatManager.cpp index 9737d4584ea..0c43c9ece0e 100755 --- a/src/server/game/Combat/ThreatManager.cpp +++ b/src/server/game/Combat/ThreatManager.cpp @@ -354,7 +354,9 @@ HostileReference* ThreatContainer::selectNextVictim(Creature* attacker, HostileR                  // list sorted and and we check current target, then this is best case                  if (currentVictim == currentRef || currentRef->getThreat() <= 1.1f * currentVictim->getThreat())                  { -                    currentRef = currentVictim;            // for second case +                    if (currentVictim != currentRef && attacker->canCreatureAttack(currentVictim->getTarget())) +                        currentRef = currentVictim;            // for second case, if currentvictim is attackable +                      found = true;                      break;                  } diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index 4176d9f605b..9f534ab697d 100755 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -441,7 +441,7 @@ uint32 Condition::GetSearcherTypeMaskForCondition()  uint32 Condition::GetMaxAvailableConditionTargets()  {      // returns number of targets which are available for given source type -    switch(SourceType) +    switch (SourceType)      {          case CONDITION_SOURCE_TYPE_SPELL:          case CONDITION_SOURCE_TYPE_SPELL_IMPLICIT_TARGET: diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h index dcd189a05cb..e032335c3bc 100755 --- a/src/server/game/DataStores/DBCEnums.h +++ b/src/server/game/DataStores/DBCEnums.h @@ -527,16 +527,27 @@ enum SummonPropFlags  enum VehicleSeatFlags  { +    VEHICLE_SEAT_FLAG_HAS_LOWER_ANIM_FOR_ENTER   = 0x00000001, +    VEHICLE_SEAT_FLAG_HAS_LOWER_ANIM_FOR_RIDE    = 0x00000002, +    VEHICLE_SEAT_FLAG_SHOULD_USE_VEH_SEAT_EXIT_ANIM_ON_VOLUNTARY_EXIT = 0x00000008,      VEHICLE_SEAT_FLAG_HIDE_PASSENGER             = 0x00000200,           // Passenger is hidden -    VEHICLE_SEAT_FLAG_UNK1                       = 0x00000400,           // needed for CGCamera__SyncFreeLookFacing +    VEHICLE_SEAT_FLAG_ALLOW_TURNING              = 0x00000400,           // needed for CGCamera__SyncFreeLookFacing      VEHICLE_SEAT_FLAG_CAN_CONTROL                = 0x00000800,           // Lua_UnitInVehicleControlSeat      VEHICLE_SEAT_FLAG_CAN_CAST_MOUNT_SPELL       = 0x00001000,           // Can cast spells with SPELL_AURA_MOUNTED from seat (possibly 4.x only, 0 seats on 3.3.5a)      VEHICLE_SEAT_FLAG_UNCONTROLLED               = 0x00002000,           // can override !& VEHICLE_SEAT_FLAG_CAN_ENTER_OR_EXIT      VEHICLE_SEAT_FLAG_CAN_ATTACK                 = 0x00004000,           // Can attack, cast spells and use items from vehicle +    VEHICLE_SEAT_FLAG_SHOULD_USE_VEH_SEAT_EXIT_ANIMN_ON_FORCED_EXIT = 0x00008000, +    VEHICLE_SEAT_FLAG_HAS_VEH_EXIT_ANIM_VOLUNTARY_EXIT = 0x00040000, +    VEHICLE_SEAT_FLAG_HAS_VEH_EXIT_ANIM_FORCED_EXIT = 0x00080000, +    VEHICLE_SEAT_FLAG_REC_HAS_VEHICLE_ENTER_ANIM = 0x00400000, +    VEHICLE_SEAT_FLAG_ENABLE_VEHICLE_ZOOM        = 0x01000000,      VEHICLE_SEAT_FLAG_CAN_ENTER_OR_EXIT          = 0x02000000,           // Lua_CanExitVehicle - can enter and exit at free will      VEHICLE_SEAT_FLAG_CAN_SWITCH                 = 0x04000000,           // Lua_CanSwitchVehicleSeats +    VEHICLE_SEAT_FLAG_HAS_START_WARITING_FOR_VEH_TRANSITION_ANIM_ENTER = 0x08000000, +    VEHICLE_SEAT_FLAG_HAS_START_WARITING_FOR_VEH_TRANSITION_ANIM_EXIT = 0x10000000,      VEHICLE_SEAT_FLAG_CAN_CAST                   = 0x20000000,           // Lua_UnitHasVehicleUI      VEHICLE_SEAT_FLAG_UNK2                       = 0x40000000,           // checked in conjunction with 0x800 in CastSpell2 +    VEHICLE_SEAT_FLAG_ALLOWS_INTERACTION         = 0x80000000,  };  enum VehicleSeatFlagsB @@ -548,6 +559,7 @@ enum VehicleSeatFlagsB      VEHICLE_SEAT_FLAG_B_USABLE_FORCED_2          = 0x00000040,      VEHICLE_SEAT_FLAG_B_USABLE_FORCED_3          = 0x00000100,      VEHICLE_SEAT_FLAG_B_USABLE_FORCED_4          = 0x02000000, +    VEHICLE_SEAT_FLAG_B_CAN_SWITCH               = 0x04000000,      VEHICLE_SEAT_FLAG_B_VEHICLE_PLAYERFRAME_UI   = 0x80000000,           // Lua_UnitHasVehiclePlayerFrameUI - actually checked for flagsb &~ 0x80000000  }; diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp index 973421bc2e3..80f62d9cedb 100755 --- a/src/server/game/DataStores/DBCStores.cpp +++ b/src/server/game/DataStores/DBCStores.cpp @@ -635,7 +635,7 @@ void LoadDBCStores(const std::string& dataPath)      // include existed nodes that have at least single not spell base (scripted) path      {          std::set<uint32> spellPaths; -        for (uint32 i = 1; i < sSpellStore.GetNumRows(); ++i) +        for (uint32 i = 1; i < sSpellEffectStore.GetNumRows(); ++i)              if (SpellEffectEntry const* sInfo = sSpellEffectStore.LookupEntry (i))                  if (sInfo->Effect == SPELL_EFFECT_SEND_TAXI)                      spellPaths.insert(sInfo->EffectMiscValue); @@ -1166,11 +1166,3 @@ uint32 ScalingStatValuesEntry::GetDPSAndDamageMultiplier(uint32 subClass, bool i      return 0;  } -// script support functions -DBCStorage <SoundEntriesEntry>  const* GetSoundEntriesStore()   { return &sSoundEntriesStore;   } -DBCStorage <SpellRangeEntry>    const* GetSpellRangeStore()     { return &sSpellRangeStore;     } -DBCStorage <FactionEntry>       const* GetFactionStore()        { return &sFactionStore;        } -DBCStorage <CreatureDisplayInfoEntry> const* GetCreatureDisplayStore() { return &sCreatureDisplayInfoStore; } -DBCStorage <EmotesEntry>        const* GetEmotesStore()         { return &sEmotesStore;         } -DBCStorage <EmotesTextEntry>    const* GetEmotesTextStore()     { return &sEmotesTextStore;     } -DBCStorage <AchievementEntry>   const* GetAchievementStore()    { return &sAchievementStore;    } diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h index c22f2ccd625..d94b60c1384 100755 --- a/src/server/game/DataStores/DBCStores.h +++ b/src/server/game/DataStores/DBCStores.h @@ -214,13 +214,4 @@ extern DBCStorage <WorldSafeLocsEntry>           sWorldSafeLocsStore;  void LoadDBCStores(const std::string& dataPath); -// script support functions - DBCStorage <SoundEntriesEntry>          const* GetSoundEntriesStore(); - DBCStorage <SpellRangeEntry>            const* GetSpellRangeStore(); - DBCStorage <FactionEntry>               const* GetFactionStore(); -// DBCStorage <ItemEntry>                  const* GetItemDisplayStore(); - DBCStorage <CreatureDisplayInfoEntry>   const* GetCreatureDisplayStore(); - DBCStorage <EmotesEntry>                const* GetEmotesStore(); - DBCStorage <EmotesTextEntry>            const* GetEmotesTextStore(); - DBCStorage <AchievementEntry>           const* GetAchievementStore();  #endif diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index 47c298d7467..91f9104b0b1 100755 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -433,8 +433,8 @@ void LFGMgr::InitializeLockedDungeons(Player* player)              locktype = LFG_LOCKSTATUS_RAID_LOCKED;          else if (dungeon->difficulty > DUNGEON_DIFFICULTY_NORMAL && player->GetBoundInstance(dungeon->map, Difficulty(dungeon->difficulty)))          { -            if (!player->GetGroup() || !player->GetGroup()->isLFGGroup() || GetDungeon(player->GetGroup()->GetGUID(), true) != dungeon->ID || GetState(player->GetGroup()->GetGUID()) != LFG_STATE_DUNGEON) -                locktype = LFG_LOCKSTATUS_RAID_LOCKED; +            //if (!player->GetGroup() || !player->GetGroup()->isLFGGroup() || GetDungeon(player->GetGroup()->GetGUID(), true) != dungeon->ID || GetState(player->GetGroup()->GetGUID()) != LFG_STATE_DUNGEON) +            locktype = LFG_LOCKSTATUS_RAID_LOCKED;          }          else if (dungeon->minlevel > level)              locktype = LFG_LOCKSTATUS_TOO_LOW_LEVEL; @@ -791,7 +791,7 @@ LfgProposal* LFGMgr::FindNewGroups(LfgGuidList& check, LfgGuidList& all)      sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::FindNewGroup: (%s) - all(%s)", ConcatenateGuids(check).c_str(), ConcatenateGuids(all).c_str());      LfgProposal* pProposal = NULL; -    if (!check.size() || check.size() > MAXGROUPSIZE || !CheckCompatibility(check, pProposal)) +    if (check.empty() || check.size() > MAXGROUPSIZE || !CheckCompatibility(check, pProposal))          return NULL;      // Try to match with queued groups @@ -1417,6 +1417,10 @@ void LFGMgr::UpdateProposal(uint32 proposalId, uint64 guid, bool accept)                  waitTimesMap[(*it)->GetGUID()] = int32(joinTime - itQueue->second->joinTime);          } +        // Set the dungeon difficulty +        LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(pProposal->dungeonId); +        ASSERT(dungeon); +          // Create a new group (if needed)          LfgUpdateData updateData = LfgUpdateData(LFG_UPDATETYPE_GROUP_FOUND);          Group* grp = pProposal->groupLowGuid ? sGroupMgr->GetGroupByGUID(pProposal->groupLowGuid) : NULL; @@ -1427,6 +1431,7 @@ void LFGMgr::UpdateProposal(uint32 proposalId, uint64 guid, bool accept)              Group* group = player->GetGroup();              if (sendUpdate)                  player->GetSession()->SendLfgUpdateProposal(proposalId, pProposal); +              if (group)              {                  player->GetSession()->SendLfgUpdateParty(updateData); @@ -1478,14 +1483,16 @@ void LFGMgr::UpdateProposal(uint32 proposalId, uint64 guid, bool accept)                      break;                  }              } +              m_teleport.push_back(pguid);              grp->SetLfgRoles(pguid, pProposal->players[pguid]->role);              SetState(pguid, LFG_STATE_DUNGEON); + +            // Add the cooldown spell if queued for a random dungeon +            if (dungeon->type == LFG_TYPE_RANDOM) +                player->CastSpell(player, LFG_SPELL_DUNGEON_COOLDOWN, false);          } -        // Set the dungeon difficulty -        LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(pProposal->dungeonId); -        ASSERT(dungeon);          grp->SetDungeonDifficulty(Difficulty(dungeon->difficulty));          uint64 gguid = grp->GetGUID();          SetDungeon(gguid, dungeon->Entry()); @@ -1626,6 +1633,7 @@ void LFGMgr::InitBoot(Group* grp, uint64 kicker, uint64 victim, std::string reas  {      if (!grp)          return; +      uint64 gguid = grp->GetGUID();      SetState(gguid, LFG_STATE_BOOT); @@ -1635,7 +1643,6 @@ void LFGMgr::InitBoot(Group* grp, uint64 kicker, uint64 victim, std::string reas      pBoot->reason = reason;      pBoot->victim = victim;      pBoot->votedNeeded = GetVotesNeeded(gguid); -    PlayerSet players;      // Set votes      for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) @@ -1651,15 +1658,11 @@ void LFGMgr::InitBoot(Group* grp, uint64 kicker, uint64 victim, std::string reas              else              {                  pBoot->votes[guid] = LFG_ANSWER_PENDING;   // Other members need to vote -                players.insert(plrg); +                plrg->GetSession()->SendLfgBootPlayer(pBoot);              }          }      } -    // Notify players -    for (PlayerSet::const_iterator it = players.begin(); it != players.end(); ++it) -        (*it)->GetSession()->SendLfgBootPlayer(pBoot); -      m_Boots[grp->GetLowGUID()] = pBoot;  } @@ -1748,14 +1751,7 @@ void LFGMgr::UpdateBoot(Player* player, bool accept)  void LFGMgr::TeleportPlayer(Player* player, bool out, bool fromOpcode /*= false*/)  {      sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::TeleportPlayer: [" UI64FMTD "] is being teleported %s", player->GetGUID(), out ? "out" : "in"); -    if (out) -    { -        player->RemoveAurasDueToSpell(LFG_SPELL_LUCK_OF_THE_DRAW); -        player->TeleportToBGEntryPoint(); -        return; -    } -    // TODO Add support for LFG_TELEPORTERROR_FATIGUE      LfgTeleportError error = LFG_TELEPORTERROR_OK;      Group* grp = player->GetGroup(); @@ -1765,10 +1761,25 @@ void LFGMgr::TeleportPlayer(Player* player, bool out, bool fromOpcode /*= false*          error = LFG_TELEPORTERROR_PLAYER_DEAD;      else if (player->IsFalling() || player->HasUnitState(UNIT_STATE_JUMPING))          error = LFG_TELEPORTERROR_FALLING; +    else if (player->IsMirrorTimerActive(FATIGUE_TIMER)) +        error = LFG_TELEPORTERROR_FATIGUE;      else      { -        uint64 gguid = grp->GetGUID(); -        LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(GetDungeon(gguid)); +        LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(GetDungeon(grp->GetGUID())); + +        if (out) +        { +            // Player needs to be inside the LFG dungeon to be able to teleport out +            if (dungeon && player->GetMapId() == uint32(dungeon->map)) +            { +                player->RemoveAurasDueToSpell(LFG_SPELL_LUCK_OF_THE_DRAW); +                player->TeleportToBGEntryPoint(); +            } +            else +                player->GetSession()->SendLfgTeleportError(LFG_TELEPORTERROR_DONT_REPORT); // Not sure which error message to send + +            return; +        }          if (!dungeon)              error = LFG_TELEPORTERROR_INVALID_LOCATION; @@ -1817,7 +1828,7 @@ void LFGMgr::TeleportPlayer(Player* player, bool out, bool fromOpcode /*= false*              if (error == LFG_TELEPORTERROR_OK)              { -                if (!player->GetMap()->IsDungeon() && !player->GetMap()->IsRaid()) +                if (!player->GetMap()->IsDungeon())                      player->SetBattlegroundEntryPoint();                  if (player->isInFlight()) diff --git a/src/server/game/DungeonFinding/LFGMgr.h b/src/server/game/DungeonFinding/LFGMgr.h index d10902b9553..f21818deb64 100755 --- a/src/server/game/DungeonFinding/LFGMgr.h +++ b/src/server/game/DungeonFinding/LFGMgr.h @@ -68,6 +68,7 @@ enum LfgTeleportError      LFG_TELEPORTERROR_OK                         = 0,      // Internal use      LFG_TELEPORTERROR_PLAYER_DEAD                = 1,      LFG_TELEPORTERROR_FALLING                    = 2, +    LFG_TELEPORTERROR_DONT_REPORT                = 3,      LFG_TELEPORTERROR_FATIGUE                    = 4,      LFG_TELEPORTERROR_INVALID_LOCATION           = 6  }; diff --git a/src/server/game/DungeonFinding/LFGScripts.cpp b/src/server/game/DungeonFinding/LFGScripts.cpp index 6175addfae2..1fa7fe0ca9f 100644 --- a/src/server/game/DungeonFinding/LFGScripts.cpp +++ b/src/server/game/DungeonFinding/LFGScripts.cpp @@ -117,13 +117,14 @@ void LFGGroupScript::OnRemoveMember(Group* group, uint64 guid, RemoveMethod meth          return;      } +    uint32 state = sLFGMgr->GetState(gguid);      sLFGMgr->ClearState(guid);      sLFGMgr->SetState(guid, LFG_STATE_NONE);      if (Player* player = ObjectAccessor::FindPlayer(guid))      { +        if (method == GROUP_REMOVEMETHOD_LEAVE && state != LFG_STATE_FINISHED_DUNGEON && player->HasAura(LFG_SPELL_DUNGEON_COOLDOWN)) +            player->CastSpell(player, LFG_SPELL_DUNGEON_DESERTER, false);          /* -        if (method == GROUP_REMOVEMETHOD_LEAVE) -            // Add deserter flag          else if (group->isLfgKickActive())              // Update internal kick cooldown of kicked          */ @@ -134,7 +135,7 @@ void LFGGroupScript::OnRemoveMember(Group* group, uint64 guid, RemoveMethod meth              sLFGMgr->TeleportPlayer(player, true);      } -    if (sLFGMgr->GetState(gguid) != LFG_STATE_FINISHED_DUNGEON)// Need more players to finish the dungeon +    if (state != LFG_STATE_FINISHED_DUNGEON)// Need more players to finish the dungeon          sLFGMgr->OfferContinue(group);  } diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index bbce6cf56c1..c7758bf5e55 100755 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -486,7 +486,7 @@ void Creature::Update(uint32 diff)                      break;                  uint64 dbtableHighGuid = MAKE_NEW_GUID(m_DBTableGuid, GetEntry(), HIGHGUID_UNIT); -                time_t linkedRespawntime = sObjectMgr->GetLinkedRespawnTime(dbtableHighGuid, GetMap()->GetInstanceId()); +                time_t linkedRespawntime = GetMap()->GetLinkedRespawnTime(dbtableHighGuid);                  if (!linkedRespawntime)             // Can respawn                      Respawn();                  else                                // the master is dead @@ -1303,7 +1303,7 @@ bool Creature::LoadCreatureFromDB(uint32 guid, Map* map, bool addToMap)      m_respawnDelay = data->spawntimesecs;      m_deathState = ALIVE; -    m_respawnTime  = sObjectMgr->GetCreatureRespawnTime(m_DBTableGuid, GetInstanceId()); +    m_respawnTime  = GetMap()->GetCreatureRespawnTime(m_DBTableGuid);      if (m_respawnTime)                          // respawn on Update      {          m_deathState = DEAD; @@ -1398,7 +1398,7 @@ void Creature::DeleteFromDB()          return;      } -    sObjectMgr->RemoveCreatureRespawnTime(m_DBTableGuid, GetInstanceId()); +    GetMap()->RemoveCreatureRespawnTime(m_DBTableGuid);      sObjectMgr->DeleteCreatureData(m_DBTableGuid);      SQLTransaction trans = WorldDatabase.BeginTransaction(); @@ -1598,7 +1598,7 @@ void Creature::Respawn(bool force)      if (getDeathState() == DEAD)      {          if (m_DBTableGuid) -            sObjectMgr->RemoveCreatureRespawnTime(m_DBTableGuid, GetInstanceId()); +            GetMap()->RemoveCreatureRespawnTime(m_DBTableGuid);          sLog->outStaticDebug("Respawning creature %s (GuidLow: %u, Full GUID: " UI64FMTD " Entry: %u)", GetName(), GetGUIDLow(), GetGUID(), GetEntry());          m_respawnTime = 0; @@ -1676,11 +1676,15 @@ bool Creature::IsImmunedToSpell(SpellInfo const* spellInfo)      // the check of mechanic immunity on DB (tested) because GetCreatureTemplate()->MechanicImmuneMask and m_spellImmune[IMMUNITY_MECHANIC] don't have same data.      bool immunedToAllEffects = true;      for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) +    { +        if (!spellInfo->Effects[i].IsEffect()) +            continue;          if (!IsImmunedToSpellEffect(spellInfo, i))          {              immunedToAllEffects = false;              break;          } +    }      if (immunedToAllEffects)          return true; @@ -1727,6 +1731,8 @@ SpellInfo const* Creature::reachWithSpellAttack(Unit* victim)                  break;              }          } +        if (bcontinue) +            continue;          if (bcontinue)               continue; @@ -2014,7 +2020,7 @@ void Creature::SaveRespawnTime()      if (isSummon() || !m_DBTableGuid || (m_creatureData && !m_creatureData->dbData))          return; -    sObjectMgr->SaveCreatureRespawnTime(m_DBTableGuid, GetInstanceId(), m_respawnTime); +    GetMap()->SaveCreatureRespawnTime(m_DBTableGuid, m_respawnTime);  }  // this should not be called by petAI or @@ -2458,7 +2464,7 @@ bool Creature::SetWalk(bool enable)      if (!Unit::SetWalk(enable))          return false; -    WorldPacket data(enable ? SMSG_MOVE_SPLINE_SET_WALK_MODE : SMSG_MOVE_SPLINE_SET_RUN_MODE, 9); +    WorldPacket data(enable ? SMSG_SPLINE_MOVE_SET_WALK_MODE : SMSG_SPLINE_MOVE_SET_RUN_MODE, 9);      data.append(GetPackGUID());      SendMessageToSet(&data, false);      return true; @@ -2474,7 +2480,7 @@ bool Creature::SetDisableGravity(bool disable, bool packetOnly/*=false*/)      if (!movespline->Initialized())          return true; -    WorldPacket data(disable ? SMSG_MOVE_SPLINE_DISABLE_GRAVITY : SMSG_MOVE_SPLINE_ENABLE_GRAVITY, 9); +    WorldPacket data(disable ? SMSG_SPLINE_MOVE_GRAVITY_DISABLE : SMSG_SPLINE_MOVE_GRAVITY_ENABLE, 9);      data.append(GetPackGUID());      SendMessageToSet(&data, false);      return true; @@ -2495,7 +2501,7 @@ bool Creature::SetHover(bool enable)          return true;      //! Not always a packet is sent -    WorldPacket data(enable ? SMSG_MOVE_SPLINE_SET_HOVER : SMSG_MOVE_SPLINE_UNSET_HOVER, 9); +    WorldPacket data(enable ? SMSG_SPLINE_MOVE_SET_HOVER : SMSG_SPLINE_MOVE_UNSET_HOVER, 9);      data.append(GetPackGUID());      SendMessageToSet(&data, false);      return true; diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 906dc827d3f..1824e2c1b44 100755 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -679,6 +679,11 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature          void GetHomePosition(float &x, float &y, float &z, float &ori) { m_homePosition.GetPosition(x, y, z, ori); }          Position GetHomePosition() { return m_homePosition; } +        void SetTransportHomePosition(float x, float y, float z, float o) { m_transportHomePosition.Relocate(x, y, z, o); } +        void SetTransportHomePosition(const Position &pos) { m_transportHomePosition.Relocate(pos); } +        void GetTransportHomePosition(float &x, float &y, float &z, float &ori) { m_transportHomePosition.GetPosition(x, y, z, ori); } +        Position GetTransportHomePosition() { return m_transportHomePosition; } +          uint32 GetWaypointPath(){return m_path_id;}          void LoadPath(uint32 pathid) { m_path_id = pathid; } @@ -752,6 +757,7 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature          uint32 m_originalEntry;          Position m_homePosition; +        Position m_transportHomePosition;          bool DisableReputationGain; diff --git a/src/server/game/Entities/Creature/TemporarySummon.h b/src/server/game/Entities/Creature/TemporarySummon.h index 829eb73bf80..537bbd9c099 100755 --- a/src/server/game/Entities/Creature/TemporarySummon.h +++ b/src/server/game/Entities/Creature/TemporarySummon.h @@ -36,6 +36,7 @@ class TempSummon : public Creature          Unit* GetSummoner() const;          uint64 GetSummonerGUID() { return m_summonerGUID; }          TempSummonType const& GetSummonType() { return m_type; } +        uint32 GetTimer() { return m_timer; }          const SummonPropertiesEntry* const m_Properties;      private: diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 7591359230a..2a74d262daf 100755 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -338,7 +338,7 @@ void GameObject::Update(uint32 diff)                  if (m_respawnTime <= now)            // timer expired                  {                      uint64 dbtableHighGuid = MAKE_NEW_GUID(m_DBTableGuid, GetEntry(), HIGHGUID_GAMEOBJECT); -                    time_t linkedRespawntime = sObjectMgr->GetLinkedRespawnTime(dbtableHighGuid, GetMap()->GetInstanceId()); +                    time_t linkedRespawntime = GetMap()->GetLinkedRespawnTime(dbtableHighGuid);                      if (linkedRespawntime)             // Can't respawn, the master is dead                      {                          uint64 targetGuid = sObjectMgr->GetLinkedRespawnGuid(dbtableHighGuid); @@ -761,13 +761,13 @@ bool GameObject::LoadGameObjectFromDB(uint32 guid, Map* map, bool addToMap)          else          {              m_respawnDelayTime = data->spawntimesecs; -            m_respawnTime = sObjectMgr->GetGORespawnTime(m_DBTableGuid, map->GetInstanceId()); +            m_respawnTime = GetMap()->GetGORespawnTime(m_DBTableGuid);              // ready to respawn              if (m_respawnTime && m_respawnTime <= time(NULL))              {                  m_respawnTime = 0; -                sObjectMgr->RemoveGORespawnTime(m_DBTableGuid, GetInstanceId()); +                GetMap()->RemoveGORespawnTime(m_DBTableGuid);              }          }      } @@ -788,7 +788,7 @@ bool GameObject::LoadGameObjectFromDB(uint32 guid, Map* map, bool addToMap)  void GameObject::DeleteFromDB()  { -    sObjectMgr->RemoveGORespawnTime(m_DBTableGuid, GetInstanceId()); +    GetMap()->RemoveGORespawnTime(m_DBTableGuid);      sObjectMgr->DeleteGOData(m_DBTableGuid);      PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_GAMEOBJECT); @@ -863,7 +863,7 @@ Unit* GameObject::GetOwner() const  void GameObject::SaveRespawnTime()  {      if (m_goData && m_goData->dbData && m_respawnTime > time(NULL) && m_spawnedByDefault) -        sObjectMgr->SaveGORespawnTime(m_DBTableGuid, GetInstanceId(), m_respawnTime); +        GetMap()->SaveGORespawnTime(m_DBTableGuid, m_respawnTime);  }  bool GameObject::IsAlwaysVisibleFor(WorldObject const* seer) const @@ -908,7 +908,7 @@ void GameObject::Respawn()      if (m_spawnedByDefault && m_respawnTime > 0)      {          m_respawnTime = time(NULL); -        sObjectMgr->RemoveGORespawnTime(m_DBTableGuid, GetInstanceId()); +        GetMap()->RemoveGORespawnTime(m_DBTableGuid);      }  } @@ -1711,7 +1711,13 @@ bool GameObject::IsInRange(float x, float y, float z, float radius) const  void GameObject::EventInform(uint32 eventId)  { -    if (eventId && m_zoneScript) +    if (!eventId) +        return; + +    if (AI()) +        AI()->EventInform(eventId); + +    if (m_zoneScript)          m_zoneScript->ProcessEvent(this, eventId);  } diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp index d973c3ba4f8..248b080bfdd 100755 --- a/src/server/game/Entities/Item/Item.cpp +++ b/src/server/game/Entities/Item/Item.cpp @@ -274,7 +274,7 @@ bool Item::Create(uint32 guidlow, uint32 itemid, Player const* owner)      for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)          SetSpellCharges(i, itemProto->Spells[i].SpellCharges); -    SetUInt32Value(ITEM_FIELD_DURATION, abs(itemProto->Duration)); +    SetUInt32Value(ITEM_FIELD_DURATION, itemProto->Duration);      SetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME, 0);      return true;  } @@ -420,7 +420,7 @@ bool Item::LoadFromDB(uint32 guid, uint64 owner_guid, Field* fields, uint32 entr      // update duration if need, and remove if not need      if ((proto->Duration == 0) != (duration == 0))      { -        SetUInt32Value(ITEM_FIELD_DURATION, abs(proto->Duration)); +        SetUInt32Value(ITEM_FIELD_DURATION, proto->Duration);          need_save = true;      } diff --git a/src/server/game/Entities/Item/Item.h b/src/server/game/Entities/Item/Item.h index 54570e9b708..d38e8c32e30 100755 --- a/src/server/game/Entities/Item/Item.h +++ b/src/server/game/Entities/Item/Item.h @@ -242,6 +242,7 @@ class Item : public Object          bool IsLocked() const { return !HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_UNLOCKED); }          bool IsBag() const { return GetTemplate()->InventoryType == INVTYPE_BAG; } +        bool IsCurrencyToken() const { return GetTemplate()->IsCurrencyToken(); }          bool IsNotEmptyBag() const;          bool IsBroken() const { return GetUInt32Value(ITEM_FIELD_MAXDURABILITY) > 0 && GetUInt32Value(ITEM_FIELD_DURABILITY) == 0; }          bool CanBeTraded(bool mail = false, bool trade = false) const; diff --git a/src/server/game/Entities/Item/ItemPrototype.h b/src/server/game/Entities/Item/ItemPrototype.h index 048da0b231c..2da0e721a20 100755 --- a/src/server/game/Entities/Item/ItemPrototype.h +++ b/src/server/game/Entities/Item/ItemPrototype.h @@ -202,6 +202,12 @@ enum ItemFlagsExtra      ITEM_FLAGS_EXTRA_BNET_ACCOUNT_BOUND      = 0x00020000,  }; +enum ItemFlagsCustom +{ +    ITEM_FLAGS_CU_DURATION_REAL_TIME    = 0x0001,   // Item duration will tick even if player is offline +    ITEM_FLAGS_CU_IGNORE_QUEST_STATUS   = 0x0002,   // No quest status will be checked when this item drops +}; +  enum BAG_FAMILY_MASK  {      BAG_FAMILY_MASK_NONE                      = 0x00000000, @@ -641,7 +647,7 @@ struct ItemTemplate      uint32 socketBonus;                                     // id from SpellItemEnchantment.dbc      uint32 GemProperties;                                   // id from GemProperties.dbc      float  ArmorDamageModifier; -    int32  Duration;                                        // negative = realtime, positive = ingame time +    uint32 Duration;      uint32 ItemLimitCategory;                               // id from ItemLimitCategory.dbc      uint32 HolidayId;                                       // id from Holidays.dbc      float  StatScalingFactor; @@ -661,6 +667,7 @@ struct ItemTemplate      uint32 FoodType;      uint32 MinMoneyLoot;      uint32 MaxMoneyLoot; +    uint32 FlagsCu;      // helpers      bool CanChangeEquipStateInCombat() const @@ -683,6 +690,8 @@ struct ItemTemplate          return false;      } +    bool IsCurrencyToken() const { return BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS; } +      uint32 GetMaxStackSize() const      {          return (Stackable == 2147483647 || Stackable <= 0) ? uint32(0x7FFFFFFF-1) : uint32(Stackable); diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index 0d18a47885f..1a04f7b3053 100755 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -34,11 +34,11 @@  #define CONTACT_DISTANCE            0.5f  #define INTERACTION_DISTANCE        5.0f  #define ATTACK_DISTANCE             5.0f -#define MAX_VISIBILITY_DISTANCE     500.0f // max distance for visible objects +#define MAX_VISIBILITY_DISTANCE     SIZE_OF_GRIDS           // max distance for visible objects  #define SIGHT_RANGE_UNIT            50.0f -#define DEFAULT_VISIBILITY_DISTANCE 90.0f // default visible distance, 90 yards on continents -#define DEFAULT_VISIBILITY_INSTANCE 120.0f // default visible distance in instances, 120 yards -#define DEFAULT_VISIBILITY_BGARENAS 180.0f // default visible distance in BG/Arenas, 180 yards +#define DEFAULT_VISIBILITY_DISTANCE 90.0f                   // default visible distance, 90 yards on continents +#define DEFAULT_VISIBILITY_INSTANCE 170.0f                  // default visible distance in instances, 170 yards +#define DEFAULT_VISIBILITY_BGARENAS 533.0f                  // default visible distance in BG/Arenas, roughly 533 yards  #define DEFAULT_WORLD_OBJECT_SIZE   0.388999998569489f      // player size, also currently used (correctly?) for any non Unit world objects  #define DEFAULT_COMBAT_REACH        1.5f @@ -500,13 +500,13 @@ struct MovementInfo          t_seat = -1;      } -    uint32 GetMovementFlags() { return flags; } +    uint32 GetMovementFlags() const { return flags; }      void SetMovementFlags(uint32 flag) { flags = flag; }      void AddMovementFlag(uint32 flag) { flags |= flag; }      void RemoveMovementFlag(uint32 flag) { flags &= ~flag; }      bool HasMovementFlag(uint32 flag) const { return flags & flag; } -    uint16 GetExtraMovementFlags() { return flags2; } +    uint16 GetExtraMovementFlags() const { return flags2; }      void AddExtraMovementFlag(uint16 flag) { flags2 |= flag; }      bool HasExtraMovementFlag(uint16 flag) const { return flags2 & flag; } diff --git a/src/server/game/Entities/Pet/Pet.h b/src/server/game/Entities/Pet/Pet.h index 6e988a79c29..5759a58a575 100755 --- a/src/server/game/Entities/Pet/Pet.h +++ b/src/server/game/Entities/Pet/Pet.h @@ -153,6 +153,7 @@ class Pet : public Guardian          bool HaveInDiet(ItemTemplate const* item) const;          uint32 GetCurrentFoodBenefitLevel(uint32 itemlevel);          void SetDuration(int32 dur) { m_duration = dur; } +        int32 GetDuration() { return m_duration; }          /*          bool UpdateStats(Stats stat); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index e8d89110f82..ba7ca524521 100755 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -3403,7 +3403,7 @@ void Player::SendInitialSpells()      uint16 spellCooldowns = m_spellCooldowns.size();      data << uint16(spellCooldowns); -    for (SpellCooldowns::const_iterator itr=m_spellCooldowns.begin(); itr != m_spellCooldowns.end(); ++itr) +    for (SpellCooldowns::const_iterator itr = m_spellCooldowns.begin(); itr != m_spellCooldowns.end(); ++itr)      {          SpellInfo const* sEntry = sSpellMgr->GetSpellInfo(itr->first);          if (!sEntry) @@ -4828,7 +4828,7 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC      // bones will be deleted by corpse/bones deleting thread shortly      sObjectAccessor->ConvertCorpseForPlayer(playerguid); -    if (uint32 guildId = GetGuildIdFromGuid(playerguid)) +    if (uint32 guildId = GetGuildIdFromDB(playerguid))          if (Guild* guild = sGuildMgr->GetGuildById(guildId))              guild->DeleteMember(guid); @@ -5176,8 +5176,8 @@ void Player::SetMovement(PlayerMovementType pType)      {          case MOVE_ROOT:       data.Initialize(SMSG_MOVE_ROOT,   GetPackGUID().size()+4); break;          case MOVE_UNROOT:     data.Initialize(SMSG_MOVE_UNROOT, GetPackGUID().size()+4); break; -        case MOVE_WATER_WALK: data.Initialize(SMSG_MOVE_SPLINE_SET_WATER_WALK,   GetPackGUID().size()+4); break; -        case MOVE_LAND_WALK:  data.Initialize(SMSG_MOVE_SPLINE_SET_LAND_WALK,    GetPackGUID().size()+4); break; +        case MOVE_WATER_WALK: data.Initialize(SMSG_SPLINE_MOVE_SET_WATER_WALK,   GetPackGUID().size()+4); break; +        case MOVE_LAND_WALK:  data.Initialize(SMSG_SPLINE_MOVE_SET_LAND_WALK,    GetPackGUID().size()+4); break;          default:              sLog->outError("Player::SetMovement: Unsupported move type (%d), data not sent to client.", pType);              return; @@ -7270,7 +7270,7 @@ bool Player::RewardHonor(Unit* victim, uint32 groupsize, int32 honor, bool pvpto              uint8 k_level = getLevel();              uint8 k_grey = Trinity::XP::GetGrayLevel(k_level); -            uint8 v_level = plrVictim->getLevel(); +            uint8 v_level = victim->getLevel();              if (v_level <= k_grey)                  return false; @@ -7281,7 +7281,7 @@ bool Player::RewardHonor(Unit* victim, uint32 groupsize, int32 honor, bool pvpto              //  [15..28] Horde honor titles and player name              //  [29..38] Other title and player name              //  [39+]    Nothing -            uint32 victim_title = plrVictim->GetUInt32Value(PLAYER_CHOSEN_TITLE); +            uint32 victim_title = victim->GetUInt32Value(PLAYER_CHOSEN_TITLE);                                                          // Get Killer titles, CharTitlesEntry::bit_index              // Ranks:              //  title[1..14]  -> rank[5..18] @@ -7303,10 +7303,10 @@ bool Player::RewardHonor(Unit* victim, uint32 groupsize, int32 honor, bool pvpto              // and those in a lifetime              ApplyModUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS, 1, true);              UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL); -            UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS, plrVictim->getClass()); -            UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HK_RACE, plrVictim->getRace()); +            UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS, victim->getClass()); +            UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HK_RACE, victim->getRace());              UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA, GetAreaId()); -            UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL, 1, 0, plrVictim); +            UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL, 1, 0, victim);          }          else          { @@ -7548,7 +7548,7 @@ uint32 Player::_GetCurrencyWeekCap(const CurrencyTypesEntry* currency) const     return cap;  } -uint32 Player::GetGuildIdFromGuid(uint64 guid) +uint32 Player::GetGuildIdFromDB(uint64 guid)  {      PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_GET_GUILD_ID);      stmt->setUInt64(0, guid); @@ -8227,7 +8227,6 @@ void Player::_ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply      if (CanUseAttackType(attType))          _ApplyWeaponDamage(slot, proto, ssv, apply); -  }  void Player::_ApplyWeaponDamage(uint8 slot, ItemTemplate const* proto, ScalingStatValuesEntry const* ssv, bool apply) @@ -9157,7 +9156,6 @@ void Player::SendLoot(uint64 guid, LootType loot_type)      loot->loot_type = loot_type;      WorldPacket data(SMSG_LOOT_RESPONSE, 8 + 1 + 50 + 1 + 1);           // we guess size -      data << uint64(guid);      data << uint8(loot_type);      data << LootView(*loot, this, permission); @@ -10734,7 +10732,7 @@ InventoryResult Player::CanStoreItem_InSpecificSlot(uint8 bag, uint8 slot, ItemP                  return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG;              // currencytoken case -            if (slot >= CURRENCYTOKEN_SLOT_START && slot < CURRENCYTOKEN_SLOT_END && !(pProto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS)) +            if (slot >= CURRENCYTOKEN_SLOT_START && slot < CURRENCYTOKEN_SLOT_END && !(pProto->IsCurrencyToken()))                  return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG;              // prevent cheating @@ -11087,7 +11085,7 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des                      return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS;                  }              } -            else if (pProto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS) +            else if (pProto->IsCurrencyToken())              {                  res = CanStoreItem_InInventorySlots(CURRENCYTOKEN_SLOT_START, CURRENCYTOKEN_SLOT_END, dest, pProto, count, false, pItem, bag, slot);                  if (res != EQUIP_ERR_OK) @@ -11254,7 +11252,7 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des                  return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS;              }          } -        else if (pProto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS) +        else if (pProto->IsCurrencyToken())          {              res = CanStoreItem_InInventorySlots(CURRENCYTOKEN_SLOT_START, CURRENCYTOKEN_SLOT_END, dest, pProto, count, false, pItem, bag, slot);              if (res != EQUIP_ERR_OK) @@ -11503,7 +11501,7 @@ InventoryResult Player::CanStoreItems(Item** pItems, int count) const              if (b_found)                  continue; -            if (pProto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS) +            if (pProto->IsCurrencyToken())              {                  for (uint32 t = CURRENCYTOKEN_SLOT_START; t < CURRENCYTOKEN_SLOT_END; ++t)                  { @@ -12755,7 +12753,7 @@ void Player::DestroyItemCount(uint32 item, uint32 count, bool update, bool unequ                  {                      ItemRemovedQuestCheck(pItem->GetEntry(), count - remcount);                      pItem->SetCount(pItem->GetCount() - count + remcount); -                    if (IsInWorld() & update) +                    if (IsInWorld() && update)                          pItem->SendUpdateToPlayer(this);                      pItem->SetState(ITEM_CHANGED, this);                      return; @@ -12783,7 +12781,7 @@ void Player::DestroyItemCount(uint32 item, uint32 count, bool update, bool unequ                  {                      ItemRemovedQuestCheck(pItem->GetEntry(), count - remcount);                      pItem->SetCount(pItem->GetCount() - count + remcount); -                    if (IsInWorld() & update) +                    if (IsInWorld() && update)                          pItem->SendUpdateToPlayer(this);                      pItem->SetState(ITEM_CHANGED, this);                      return; @@ -12849,7 +12847,7 @@ void Player::DestroyItemCount(uint32 item, uint32 count, bool update, bool unequ                  {                      ItemRemovedQuestCheck(pItem->GetEntry(), count - remcount);                      pItem->SetCount(pItem->GetCount() - count + remcount); -                    if (IsInWorld() & update) +                    if (IsInWorld() && update)                          pItem->SendUpdateToPlayer(this);                      pItem->SetState(ITEM_CHANGED, this);                      return; @@ -12924,6 +12922,11 @@ Item* Player::GetItemByEntry(uint32 entry) const              if (pItem->GetEntry() == entry)                  return pItem; +    for (uint8 i = KEYRING_SLOT_START; i < CURRENCYTOKEN_SLOT_END; ++i) +        if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) +            if (pItem->GetEntry() == entry) +                return pItem; +      for (int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i)          if (Bag* pBag = GetBagByPos(i))              for (uint32 j = 0; j < pBag->GetBagSize(); ++j) @@ -12957,7 +12960,7 @@ void Player::DestroyItemCount(Item* pItem, uint32 &count, bool update)          ItemRemovedQuestCheck(pItem->GetEntry(), count);          pItem->SetCount(pItem->GetCount() - count);          count = 0; -        if (IsInWorld() & update) +        if (IsInWorld() && update)              pItem->SendUpdateToPlayer(this);          pItem->SetState(ITEM_CHANGED, this);      } @@ -13545,9 +13548,9 @@ void Player::SendEquipError(InventoryResult msg, Item* pItem, Item* pItem2, uint              }              case EQUIP_ERR_EVENT_AUTOEQUIP_BIND_CONFIRM:    // no idea about this one...              { -                data << uint64(0); -                data << uint32(0); -                data << uint64(0); +                data << uint64(0); // item guid +                data << uint32(0); // slot +                data << uint64(0); // container                  break;              }              case EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_COUNT_EXCEEDED: @@ -13653,7 +13656,7 @@ void Player::UpdateItemDuration(uint32 time, bool realtimeonly)          Item* item = *itr;          ++itr;                                              // current element can be erased in UpdateDuration -        if ((realtimeonly && item->GetTemplate()->Duration < 0) || !realtimeonly) +        if (!realtimeonly || item->GetTemplate()->FlagsCu & ITEM_FLAGS_CU_DURATION_REAL_TIME)              item->UpdateDuration(this, time);      }  } @@ -14226,7 +14229,7 @@ void Player::SendNewItem(Item* item, uint32 count, bool received, bool created,      data << uint64(GetGUID());                              // player GUID      data << uint32(received);                               // 0=looted, 1=from npc      data << uint32(created);                                // 0=received, 1=created -    data << uint32(1);                                      // always 0x01 (probably meant to be count of listed items) +    data << uint32(1);                                      // bool print error to chat      data << uint8(item->GetBagSlot());                      // bagslot                                                              // item slot, but when added to stack: 0xFFFFFFFF      data << uint32((item->GetCount() == count) ? item->GetSlot() : -1); @@ -20160,8 +20163,10 @@ void Player::PetSpellInitialize()      WorldPacket data(SMSG_PET_SPELLS, 8+2+4+4+4*MAX_UNIT_ACTION_BAR_INDEX+1+1);      data << uint64(pet->GetGUID());      data << uint16(pet->GetCreatureTemplate()->family);         // creature family (required for pet talents) -    data << uint32(0); -    data << uint8(pet->GetReactState()) << uint8(charmInfo->GetCommandState()) << uint16(0); +    data << uint32(pet->GetDuration()); +    data << uint8(pet->GetReactState()); +    data << uint8(charmInfo->GetCommandState()); +    data << uint16(0); // Flags, mostly unknown      // action bar loop      charmInfo->BuildActionBar(&data); @@ -20194,22 +20199,33 @@ void Player::PetSpellInitialize()      for (CreatureSpellCooldowns::const_iterator itr = pet->m_CreatureSpellCooldowns.begin(); itr != pet->m_CreatureSpellCooldowns.end(); ++itr)      { -        time_t cooldown = (itr->second > curTime) ? (itr->second - curTime) * IN_MILLISECONDS : 0; - -        data << uint32(itr->first);                         // spellid -        data << uint16(0);                                  // spell category? -        data << uint32(cooldown);                           // cooldown -        data << uint32(0);                                  // category cooldown -    } +        SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first); +        if (!spellInfo) +        { +            data << uint32(0); +            data << uint16(0); +            data << uint32(0); +            data << uint32(0); +            continue; +        } -    for (CreatureSpellCooldowns::const_iterator itr = pet->m_CreatureCategoryCooldowns.begin(); itr != pet->m_CreatureCategoryCooldowns.end(); ++itr) -    {          time_t cooldown = (itr->second > curTime) ? (itr->second - curTime) * IN_MILLISECONDS : 0; +        data << uint32(itr->first);                 // spell ID -        data << uint32(itr->first);                         // spellid -        data << uint16(0);                                  // spell category? -        data << uint32(0);                                  // cooldown -        data << uint32(cooldown);                           // category cooldown +        CreatureSpellCooldowns::const_iterator categoryitr = pet->m_CreatureCategoryCooldowns.find(spellInfo->Category); +        if (categoryitr != pet->m_CreatureCategoryCooldowns.end()) +        { +            time_t categoryCooldown = (categoryitr->second > curTime) ? (categoryitr->second - curTime) * IN_MILLISECONDS : 0; +            data << uint16(spellInfo->Category);    // spell category +            data << uint32(cooldown);               // spell cooldown +            data << uint32(categoryCooldown);       // category cooldown +        } +        else +        { +            data << uint16(0); +            data << uint32(cooldown); +            data << uint32(0); +        }      }      GetSession()->SendPacket(&data); @@ -20245,24 +20261,24 @@ void Player::PossessSpellInitialize()  void Player::VehicleSpellInitialize()  { -    Creature* veh = GetVehicleCreatureBase(); -    if (!veh) +    Creature* vehicle = GetVehicleCreatureBase(); +    if (!vehicle)          return; -    uint8 cooldownCount = veh->m_CreatureSpellCooldowns.size() + veh->m_CreatureCategoryCooldowns.size(); +    uint8 cooldownCount = vehicle->m_CreatureSpellCooldowns.size();      WorldPacket data(SMSG_PET_SPELLS, 8 + 2 + 4 + 4 + 4 * 10 + 1 + 1 + cooldownCount * (4 + 2 + 4 + 4)); -    data << uint64(veh->GetGUID()); -    data << uint16(veh->GetCreatureTemplate()->family); -    data << uint32(0); -    // The following three segments are read as one uint32 -    data << uint8(veh->GetReactState()); -    data << uint8(0);   // CommandState? -    data << uint16(0);  // unk +    data << uint64(vehicle->GetGUID());                     // Guid +    data << uint16(0);                                      // Pet Family (0 for all vehicles) +    data << uint32(vehicle->isSummon() ? vehicle->ToTempSummon()->GetTimer() : 0); // Duration +    // The following three segments are read by the client as one uint32 +    data << uint8(vehicle->GetReactState());                // React State +    data << uint8(0);                                       // Command State +    data << uint16(0x800);                                  // DisableActions (set for all vehicles)      for (uint32 i = 0; i < CREATURE_MAX_SPELLS; ++i)      { -        uint32 spellId = veh->m_spells[i]; +        uint32 spellId = vehicle->m_spells[i];          SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);          if (!spellInfo)          { @@ -20270,54 +20286,59 @@ void Player::VehicleSpellInitialize()              continue;          } -        ConditionList conditions = sConditionMgr->GetConditionsForVehicleSpell(veh->GetEntry(), spellId); -        if (!sConditionMgr->IsObjectMeetToConditions(this, veh, conditions)) +        ConditionList conditions = sConditionMgr->GetConditionsForVehicleSpell(vehicle->GetEntry(), spellId); +        if (!sConditionMgr->IsObjectMeetToConditions(this, vehicle, conditions))          { -            sLog->outDebug(LOG_FILTER_CONDITIONSYS, "VehicleSpellInitialize: conditions not met for Vehicle entry %u spell %u", veh->ToCreature()->GetEntry(), spellId); +            sLog->outDebug(LOG_FILTER_CONDITIONSYS, "VehicleSpellInitialize: conditions not met for Vehicle entry %u spell %u", vehicle->ToCreature()->GetEntry(), spellId);              data << uint16(0) << uint8(0) << uint8(i+8);              continue;          }          if (spellInfo->IsPassive()) -        { -            veh->CastSpell(veh, spellId, true); -            data << uint16(0) << uint8(0) << uint8(i+8); -        } -        else -            data << uint32(MAKE_UNIT_ACTION_BUTTON(spellId, i+8)); +            vehicle->CastSpell(vehicle, spellId, true); + +        data << uint32(MAKE_UNIT_ACTION_BUTTON(spellId, i+8));      }      for (uint32 i = CREATURE_MAX_SPELLS; i < MAX_SPELL_CONTROL_BAR; ++i) -        data << uint16(0) << uint8(0) << uint8(i+8); +        data << uint32(0); -    data << uint8(0); -    /*if (v23 > 0) -    { -        for (uint32 i = 0; i < v23; ++i) -            data << uint32(v16);    // Some spellid? -    }*/ +    data << uint8(0); // Auras?      // Cooldowns -    data << cooldownCount; +    data << uint8(cooldownCount);      time_t now = sWorld->GetGameTime(); -    CreatureSpellCooldowns::const_iterator itr; -    for (itr = veh->m_CreatureSpellCooldowns.begin(); itr != veh->m_CreatureSpellCooldowns.end(); ++itr) -    { -        time_t cooldown = (itr->second > now) ? (itr->second - now) * IN_MILLISECONDS : 0; -        data << uint32(itr->first); // SpellId -        data << uint16(0);          // unk -        data << uint32(cooldown);   // spell cooldown -        data << uint32(0);          // category cooldown -    } -    for (itr = veh->m_CreatureCategoryCooldowns.begin(); itr != veh->m_CreatureCategoryCooldowns.end(); ++itr) +    for (CreatureSpellCooldowns::const_iterator itr = vehicle->m_CreatureSpellCooldowns.begin(); itr != vehicle->m_CreatureSpellCooldowns.end(); ++itr)      { +        SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first); +        if (!spellInfo) +        { +            data << uint32(0); +            data << uint16(0); +            data << uint32(0); +            data << uint32(0); +            continue; +        } +          time_t cooldown = (itr->second > now) ? (itr->second - now) * IN_MILLISECONDS : 0; -        data << uint32(itr->first); // SpellId -        data << uint16(0);          // unk -        data << uint32(0);          // spell cooldown -        data << uint32(cooldown);   // category cooldown +        data << uint32(itr->first);                 // spell ID + +        CreatureSpellCooldowns::const_iterator categoryitr = vehicle->m_CreatureCategoryCooldowns.find(spellInfo->Category); +        if (categoryitr != vehicle->m_CreatureCategoryCooldowns.end()) +        { +            time_t categoryCooldown = (categoryitr->second > now) ? (categoryitr->second - now) * IN_MILLISECONDS : 0; +            data << uint16(spellInfo->Category);    // spell category +            data << uint32(cooldown);               // spell cooldown +            data << uint32(categoryCooldown);       // category cooldown +        } +        else +        { +            data << uint16(0); +            data << uint32(cooldown); +            data << uint32(0); +        }      }      GetSession()->SendPacket(&data); @@ -20356,7 +20377,7 @@ void Player::CharmSpellInitialize()      if (charm->GetTypeId() != TYPEID_PLAYER)          data << uint8(charm->ToCreature()->GetReactState()) << uint8(charmInfo->GetCommandState()) << uint16(0);      else -        data << uint8(0) << uint8(0) << uint16(0); +        data << uint32(0);      charmInfo->BuildActionBar(&data); @@ -20581,7 +20602,7 @@ void Player::RemovePetitionsAndSigns(uint64 guid, uint32 type)      else      {          stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_SIG_BY_GUID_TYPE); -        stmt->setUInt8(0, uint8(type)); +        stmt->setUInt8(1, uint8(type));      }      stmt->setUInt32(0, GUID_LOPART(guid)); @@ -22319,8 +22340,8 @@ void Player::SendInstanceResetWarning(uint32 mapid, Difficulty difficulty, uint3      data << uint32(time);      if (type == RAID_INSTANCE_WELCOME)      { -        data << uint8(0);                                   // is your (1) -        data << uint8(0);                                   // is extended (1), ignored if prev field is 0 +        data << uint8(0);                                   // is locked +        data << uint8(0);                                   // is extended, ignored if prev field is 0      }      GetSession()->SendPacket(&data);  } @@ -23366,7 +23387,7 @@ Player* Player::GetNextRandomRaidMember(float radius)  PartyResult Player::CanUninviteFromGroup() const  { -    const Group* grp = GetGroup(); +    Group const* grp = GetGroup();      if (!grp)          return ERR_NOT_IN_GROUP; @@ -23389,8 +23410,12 @@ PartyResult Player::CanUninviteFromGroup() const          if (grp->isRollLootActive())              return ERR_PARTY_LFG_BOOT_LOOT_ROLLS; +        // TODO: Should also be sent when anyone has recently left combat, with an aprox ~5 seconds timer. +        for (GroupReference const* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) +            if (itr->getSource() && itr->getSource()->isInCombat()) +                return ERR_PARTY_LFG_BOOT_IN_COMBAT; +          /* Missing support for these types -            return ERR_PARTY_LFG_BOOT_IN_COMBAT; // also have a cooldown (some secs after combat finish              return ERR_PARTY_LFG_BOOT_COOLDOWN_S;              return ERR_PARTY_LFG_BOOT_NOT_ELIGIBLE_S;          */ @@ -25639,8 +25664,8 @@ void Player::SendMovementSetCanFly(bool apply)  void Player::SendMovementSetCanTransitionBetweenSwimAndFly(bool apply)  {      WorldPacket data(apply ? -        SMSG_MOVE_ENABLE_TRANSITION_BETWEEN_SWIM_AND_FLY : -        SMSG_MOVE_DISABLE_TRANSITION_BETWEEN_SWIM_AND_FLY, 12); +        SMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY : +        SMSG_MOVE_UNSET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY, 12);      data.append(GetPackGUID());      data << uint32(0);          //! movement counter      SendDirectMessage(&data); @@ -25648,7 +25673,7 @@ void Player::SendMovementSetCanTransitionBetweenSwimAndFly(bool apply)  void Player::SendMovementSetHover(bool apply)  { -    WorldPacket data(apply ? SMSG_MOVE_SET_HOVERING : SMSG_MOVE_SPLINE_UNSET_HOVER, 12); +    WorldPacket data(apply ? SMSG_MOVE_SET_HOVER : SMSG_MOVE_UNSET_HOVER, 12);      data.append(GetPackGUID());      data << uint32(0);          //! movement counter      SendDirectMessage(&data); @@ -25656,7 +25681,7 @@ void Player::SendMovementSetHover(bool apply)  void Player::SendMovementSetWaterWalking(bool apply)  { -    WorldPacket data(apply ? SMSG_MOVE_SET_WATER_WALK : SMSG_MOVE_SET_LAND_WALK, 12); +    WorldPacket data(apply ? SMSG_MOVE_WATER_WALK : SMSG_MOVE_LAND_WALK, 12);      data.append(GetPackGUID());      data << uint32(0);          //! movement counter      SendDirectMessage(&data); @@ -25664,7 +25689,7 @@ void Player::SendMovementSetWaterWalking(bool apply)  void Player::SendMovementSetFeatherFall(bool apply)  { -    WorldPacket data(apply ? SMSG_MOVE_SET_FEATHER_FALL : SMSG_MOVE_SET_NORMAL_FALL, 12); +    WorldPacket data(apply ? SMSG_MOVE_FEATHER_FALL : SMSG_MOVE_NORMAL_FALL, 12);      data.append(GetPackGUID());      data << uint32(0);          //! movement counter      SendDirectMessage(&data); diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 24a1c35b8e2..dbe9cd94a21 100755 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1888,7 +1888,7 @@ class Player : public Unit, public GridObject<Player>              m_guildId = GuildId;          }          uint32 GetGuildId() { return m_guildId; } -        static uint32 GetGuildIdFromGuid(uint64 guid); +        static uint32 GetGuildIdFromDB(uint64 guid);          void SetRank(uint8 rankId) { SetUInt32Value(PLAYER_GUILDRANK, rankId); }          uint8 GetRank() { return uint8(GetUInt32Value(PLAYER_GUILDRANK)); } @@ -2049,6 +2049,7 @@ class Player : public Unit, public GridObject<Player>              StopMirrorTimer(BREATH_TIMER);              StopMirrorTimer(FIRE_TIMER);          } +        bool IsMirrorTimerActive(MirrorTimerType type) { return m_MirrorTimer[type] == getMaxTimer(type); }          void SetMovement(PlayerMovementType pType); diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp index a00fcae1e09..ef3e1331a4c 100755 --- a/src/server/game/Entities/Transport/Transport.cpp +++ b/src/server/game/Entities/Transport/Transport.cpp @@ -656,6 +656,7 @@ uint32 Transport::AddNPCPassenger(uint32 tguid, uint32 entry, float x, float y,          o + GetOrientation());      creature->SetHomePosition(creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ(), creature->GetOrientation()); +    creature->SetTransportHomePosition(creature->m_movementInfo.t_pos);      if (!creature->IsPositionValid())      { @@ -698,11 +699,33 @@ void Transport::UpdateNPCPositions()          Creature* npc = *itr;          float x, y, z, o; -        o = GetOrientation() + npc->m_movementInfo.t_pos.m_orientation; -        x = GetPositionX() + (npc->m_movementInfo.t_pos.m_positionX * cos(GetOrientation()) + npc->m_movementInfo.t_pos.m_positionY * sin(GetOrientation() + M_PI)); -        y = GetPositionY() + (npc->m_movementInfo.t_pos.m_positionY * cos(GetOrientation()) + npc->m_movementInfo.t_pos.m_positionX * sin(GetOrientation())); -        z = GetPositionZ() + npc->m_movementInfo.t_pos.m_positionZ; -        npc->SetHomePosition(x, y, z, o); +        npc->m_movementInfo.t_pos.GetPosition(x, y, z, o); +        CalculatePassengerPosition(x, y, z, o);          GetMap()->CreatureRelocation(npc, x, y, z, o, false); +        npc->GetTransportHomePosition(x, y, z, o); +        CalculatePassengerPosition(x, y, z, o); +        npc->SetHomePosition(x, y, z, o);      }  } + +//! This method transforms supplied transport offsets into global coordinates +void Transport::CalculatePassengerPosition(float& x, float& y, float& z, float& o) +{ +    float inx = x, iny = y, inz = z, ino = o; +    o = GetOrientation() + ino; +    x = GetPositionX() + (inx * cos(GetOrientation()) + iny * sin(GetOrientation() + M_PI)); +    y = GetPositionY() + (iny * cos(GetOrientation()) + inx * sin(GetOrientation())); +    z = GetPositionZ() + inz; +} + +//! This method transforms supplied global coordinates into local offsets +void Transport::CalculatePassengerOffset(float& x, float& y, float& z, float& o) +{ +    o -= GetOrientation(); +    z -= GetPositionZ(); +    y -= GetPositionY();    // y = searchedY * cos(o) + searchedX * sin(o) +    x -= GetPositionX();    // x = searchedX * cos(o) + searchedY * sin(o + pi) +    float inx = x, iny = y; +    y = (iny - inx * tan(GetOrientation())) / (cos(GetOrientation()) - sin(GetOrientation() + M_PI) * tan(GetOrientation())); +    x = (inx - iny * sin(GetOrientation() + M_PI) / cos(GetOrientation())) / (cos(GetOrientation()) - tan(GetOrientation()) * sin(GetOrientation() + M_PI)); +} diff --git a/src/server/game/Entities/Transport/Transport.h b/src/server/game/Entities/Transport/Transport.h index 518dcf6359d..4b0c42c9071 100755 --- a/src/server/game/Entities/Transport/Transport.h +++ b/src/server/game/Entities/Transport/Transport.h @@ -47,6 +47,8 @@ class Transport : public GameObject          uint32 AddNPCPassenger(uint32 tguid, uint32 entry, float x, float y, float z, float o, uint32 anim=0);          void UpdatePosition(MovementInfo* mi);          void UpdateNPCPositions(); +        void CalculatePassengerPosition(float& x, float& y, float& z, float& o); +        void CalculatePassengerOffset(float& x, float& y, float& z, float& o);          void BuildStartMovePacket(Map const* targetMap);          void BuildStopMovePacket(Map const* targetMap);          uint32 GetScriptId() const { return ScriptId; } diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 347a51a67d9..5fe8f0bf657 100755 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -396,10 +396,25 @@ void Unit::UpdateSplineMovement(uint32 t_diff)          m_movesplineTimer.Reset(POSITION_UPDATE_DELAY);          Movement::Location loc = movespline->ComputePosition(); -        if (GetTypeId() == TYPEID_PLAYER) -            ((Player*)this)->UpdatePosition(loc.x,loc.y,loc.z,loc.orientation); -        else -            GetMap()->CreatureRelocation((Creature*)this,loc.x,loc.y,loc.z,loc.orientation); +        if (HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT)) +        { +            Position& pos = m_movementInfo.t_pos; +            pos.m_positionX = loc.x; +            pos.m_positionY = loc.y; +            pos.m_positionZ = loc.z; +            pos.m_orientation = loc.orientation; +            if (Unit* vehicle = GetVehicleBase()) +            { +                loc.x += vehicle->GetPositionX(); +                loc.y += vehicle->GetPositionY(); +                loc.z += vehicle->GetPositionZMinusOffset(); +                loc.orientation = vehicle->GetOrientation(); +            } +            else if (Transport* trans = GetTransport()) +                trans->CalculatePassengerPosition(loc.x, loc.y, loc.z, loc.orientation); +        } + +        UpdatePosition(loc.x, loc.y, loc.z, loc.orientation);      }  } @@ -409,50 +424,6 @@ void Unit::DisableSpline()      movespline->_Interrupt();  } -void Unit::SendMonsterMoveExitVehicle(Position const* newPos) -{ -    WorldPacket data(SMSG_MONSTER_MOVE, 1+12+4+1+4+4+4+12+GetPackGUID().size()); -    data.append(GetPackGUID()); - -    data << uint8(GetTypeId() == TYPEID_PLAYER ? 1 : 0);    // new in 3.1, bool -    data << GetPositionX() << GetPositionY() << GetPositionZ(); -    data << getMSTime(); - -    data << uint8(SPLINETYPE_FACING_ANGLE); -    data << float(GetOrientation());                        // guess -    data << uint32(SPLINEFLAG_EXIT_VEHICLE); -    data << uint32(0);                                      // Time in between points -    data << uint32(1);                                      // 1 single waypoint -    data << newPos->GetPositionX(); -    data << newPos->GetPositionY(); -    data << newPos->GetPositionZ(); - -    SendMessageToSet(&data, true); -} - -void Unit::SendMonsterMoveTransport(Unit* vehicleOwner) -{ -    // TODO: Turn into BuildMonsterMoveTransport packet and allow certain variables (for npc movement aboard vehicles) -    WorldPacket data(SMSG_MONSTER_MOVE_TRANSPORT, GetPackGUID().size()+vehicleOwner->GetPackGUID().size() + 47); -    data.append(GetPackGUID()); -    data.append(vehicleOwner->GetPackGUID()); -    data << int8(GetTransSeat()); -    data << uint8(0); -    data << GetPositionX() - vehicleOwner->GetPositionX(); -    data << GetPositionY() - vehicleOwner->GetPositionY(); -    data << GetPositionZ() - vehicleOwner->GetPositionZ(); -    data << uint32(getMSTime());            // should be an increasing constant that indicates movement packet count -    data << uint8(SPLINETYPE_FACING_ANGLE); -    data << GetTransOffsetO();              // facing angle? -    data << uint32(SPLINEFLAG_TRANSPORT); -    data << uint32(GetTransTime());         // move time -    data << uint32(1);                      // amount of waypoints -    data << uint32(0);                      // waypoint X -    data << uint32(0);                      // waypoint Y -    data << uint32(0);                      // waypoint Z -    SendMessageToSet(&data, true); -} -  void Unit::resetAttackTimer(WeaponAttackType type)  {      m_attackTimer[type] = uint32(GetAttackTime(type) * m_modAttackSpeedPct[type]); @@ -556,13 +527,7 @@ void Unit::DealDamageMods(Unit* victim, uint32 &damage, uint32* absorb)          if (absorb)              *absorb += damage;          damage = 0; -        return;      } - -    uint32 originalDamage = damage; - -    if (absorb && originalDamage > damage) -        *absorb += (originalDamage - damage);  }  uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask, SpellInfo const* spellProto, bool durabilityLoss) @@ -839,11 +804,6 @@ void Unit::CastSpell(SpellCastTargets const& targets, SpellInfo const* spellInfo          return;      } -    // TODO: this is a workaround and needs removal -    if (!originalCaster && GetTypeId() == TYPEID_UNIT && ToCreature()->isTotem() && IsControlledByPlayer()) -        if (Unit* owner = GetOwner()) -            originalCaster=owner->GetGUID(); -      // TODO: this is a workaround - not needed anymore, but required for some scripts :(      if (!originalCaster && triggeredByAura)          originalCaster = triggeredByAura->GetCasterGUID(); @@ -2503,12 +2463,12 @@ SpellMissInfo Unit::MagicSpellHitResult(Unit* victim, SpellInfo const* spell)      // Chance resist debuff      if (!spell->IsPositive())      { -        bool bNegativeAura = false; +        bool bNegativeAura = true;          for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)          { -            if (spell->Effects[i].ApplyAuraName != 0) +            if (spell->Effects[i].ApplyAuraName == 0)              { -                bNegativeAura = true; +                bNegativeAura = false;                  break;              }          } @@ -2931,9 +2891,11 @@ void Unit::SetCurrentCastedSpell(Spell* pSpell)                      InterruptSpell(CURRENT_AUTOREPEAT_SPELL);                  m_AutoRepeatFirstCast = true;              } -            AddUnitState(UNIT_STATE_CASTING); -        } break; +            if (pSpell->m_spellInfo->CalcCastTime(this) > 0) +                AddUnitState(UNIT_STATE_CASTING); +            break; +        }          case CURRENT_CHANNELED_SPELL:          {              // channel spells always break generic non-delayed and any channeled spells @@ -2945,8 +2907,9 @@ void Unit::SetCurrentCastedSpell(Spell* pSpell)                  m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Id != 75)                  InterruptSpell(CURRENT_AUTOREPEAT_SPELL);              AddUnitState(UNIT_STATE_CASTING); -        } break; +            break; +        }          case CURRENT_AUTOREPEAT_SPELL:          {              // only Auto Shoot does not break anything @@ -2958,12 +2921,11 @@ void Unit::SetCurrentCastedSpell(Spell* pSpell)              }              // special action: set first cast flag              m_AutoRepeatFirstCast = true; -        } break; +            break; +        }          default: -        { -            // other spell types don't break anything now -        } break; +            break; // other spell types don't break anything now      }      // current spell (if it is still here) may be safely deleted now @@ -3638,87 +3600,6 @@ void Unit::RemoveAurasDueToSpellByDispel(uint32 spellId, uint32 dispellerSpellId              // Call AfterDispel hook on AuraScript              aura->CallScriptAfterDispel(&dispelInfo); -            switch (aura->GetSpellInfo()->SpellFamilyName) -            { -                case SPELLFAMILY_WARLOCK: -                { -                    // Unstable Affliction (crash if before removeaura?) -                    if (aura->GetSpellInfo()->SpellFamilyFlags[1] & 0x0100) -                    { -                        Unit* caster = aura->GetCaster(); -                        if (!caster) -                            break; -                        if (AuraEffect const* aurEff = aura->GetEffect(EFFECT_0)) -                        { -                            int32 damage = aurEff->GetAmount() * 9; -                            // backfire damage and silence -                            caster->CastCustomSpell(dispeller, 31117, &damage, NULL, NULL, true, NULL, aurEff); -                        } -                    } -                    break; -                } -                case SPELLFAMILY_DRUID: -                { -                    // Lifebloom -                    if (aura->GetSpellInfo()->SpellFamilyFlags[1] & 0x10) -                    { -                        if (AuraEffect const* aurEff = aura->GetEffect(EFFECT_1)) -                        { -                            // final heal -                            int32 healAmount = aurEff->GetAmount(); -                            if (Unit* caster = aura->GetCaster()) -                            { -                                healAmount = caster->SpellHealingBonusDone(this, aura->GetSpellInfo(), healAmount, HEAL, dispelInfo.GetRemovedCharges()); -                                healAmount = this->SpellHealingBonusTaken(caster, aura->GetSpellInfo(), healAmount, HEAL, dispelInfo.GetRemovedCharges()); -                            } -                            CastCustomSpell(this, 33778, &healAmount, NULL, NULL, true, NULL, NULL, aura->GetCasterGUID()); - -                            // mana -                            if (Unit* caster = aura->GetCaster()) -                            { -                                int32 mana = CalculatePctU(caster->GetCreateMana(), aura->GetSpellInfo()->ManaCostPercentage) * chargesRemoved / 2; -                                caster->CastCustomSpell(caster, 64372, &mana, NULL, NULL, true, NULL, NULL, aura->GetCasterGUID()); -                            } -                        } -                    } -                    break; -                } -                case SPELLFAMILY_SHAMAN: -                { -                    // Flame Shock -                    if (aura->GetSpellInfo()->SpellFamilyFlags[0] & 0x10000000) -                    { -                        if (Unit* caster = aura->GetCaster()) -                        { -                            uint32 triggeredSpellId = 0; -                            // Lava Flows -                            if (AuraEffect const* aurEff = caster->GetDummyAuraEffect(SPELLFAMILY_SHAMAN, 3087, 0)) -                            { -                                switch (aurEff->GetId()) -                                { -                                    case 51482: // Rank 3 -                                        triggeredSpellId = 65264; -                                        break; -                                    case 51481: // Rank 2 -                                        triggeredSpellId = 65263; -                                        break; -                                    case 51480: // Rank 1 -                                        triggeredSpellId = 64694; -                                        break; -                                    default: -                                        sLog->outError("Unit::RemoveAurasDueToSpellByDispel: Unknown rank of Lava Flows (%d) found", aurEff->GetId()); -                                } -                            } - -                            if (triggeredSpellId) -                                caster->CastSpell(caster, triggeredSpellId, true); -                        } -                    } -                    break; -                } -                default: -                    break; -            }              return;          }          else @@ -8328,6 +8209,14 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg                              CastSpell(victim, 27526, true, castItem, triggeredByAura);                          return true;                      } +                    // Evasive Maneuvers +                    case 50240: +                    { +                        // Remove a Evasive Charge +                        Aura* charge = GetAura(50241); +                        if (charge->ModStackAmount(-1, AURA_REMOVE_BY_ENEMY_SPELL)) +                            RemoveAurasDueToSpell(50240); +                    }                  }                  break;              case SPELLFAMILY_MAGE: @@ -8982,12 +8871,6 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg                  CastSpell(this, 70721, true);              break;          } -        // Bloodthirst (($m/100)% of max health) -        case 23880: -        { -            basepoints0 = int32(CountPctFromMaxHealth(triggerAmount)); -            break; -        }          // Shamanistic Rage triggered spell          case 30824:          { @@ -10159,7 +10042,7 @@ Unit* Unit::GetMagicHitRedirectTarget(Unit* victim, SpellInfo const* spellInfo)      Unit::AuraEffectList const& magnetAuras = victim->GetAuraEffectsByType(SPELL_AURA_SPELL_MAGNET);      for (Unit::AuraEffectList::const_iterator itr = magnetAuras.begin(); itr != magnetAuras.end(); ++itr)      { -        if (Unit* magnet = (*itr)->GetBase()->GetUnitOwner()) +        if (Unit* magnet = (*itr)->GetBase()->GetCaster())              if (spellInfo->CheckExplicitTarget(this, magnet) == SPELL_CAST_OK                  && spellInfo->CheckTarget(this, magnet, false) == SPELL_CAST_OK                  && _IsValidAttackTarget(magnet, spellInfo) @@ -10801,6 +10684,15 @@ uint32 Unit::SpellDamageBonusTaken(Unit* caster, SpellInfo const* spellProto, ui      int32 TakenTotal = 0;      float TakenTotalMod = 1.0f; +    float TakenTotalCasterMod = 0.0f; + +    // get all auras from caster that allow the spell to ignore resistance (sanctified wrath) +    AuraEffectList const& IgnoreResistAuras = caster->GetAuraEffectsByType(SPELL_AURA_MOD_IGNORE_TARGET_RESIST); +    for (AuraEffectList::const_iterator i = IgnoreResistAuras.begin(); i != IgnoreResistAuras.end(); ++i) +    { +        if ((*i)->GetMiscValue() & spellProto->GetSchoolMask()) +            TakenTotalCasterMod += (float((*i)->GetAmount())/100); +    }      // from positive and negative SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN      // multiplicative bonus, for example Dispersion + Shadowform (0.10*0.85=0.085) @@ -10865,7 +10757,22 @@ uint32 Unit::SpellDamageBonusTaken(Unit* caster, SpellInfo const* spellProto, ui          TakenTotal+= int32(TakenAdvertisedBenefit * coeff * factorMod);      } -    float tmpDamage = (float(pdamage) + TakenTotal) * TakenTotalMod; +    float tmpDamage = 0.0f; + +    if (TakenTotalCasterMod) +    { +        if (TakenTotal < 0) +        { +            if (TakenTotalMod < 1) +                tmpDamage = ((float(CalculatePctF(pdamage, TakenTotalCasterMod) + TakenTotal) * TakenTotalMod) + CalculatePctF(pdamage, TakenTotalCasterMod)); +            else +                tmpDamage = ((float(CalculatePctF(pdamage, TakenTotalCasterMod) + TakenTotal) + CalculatePctF(pdamage, TakenTotalCasterMod)) * TakenTotalMod); +        } +        else if (TakenTotalMod < 1) +            tmpDamage = ((CalculatePctF(float(pdamage) + TakenTotal, TakenTotalCasterMod) * TakenTotalMod) + CalculatePctF(float(pdamage) + TakenTotal, TakenTotalCasterMod)); +    } +    if (!tmpDamage) +        tmpDamage = (float(pdamage) + TakenTotal) * TakenTotalMod;      return uint32(std::max(tmpDamage, 0.0f));  } @@ -11575,6 +11482,8 @@ bool Unit::IsImmunedToSpell(SpellInfo const* spellInfo)      {          // State/effect immunities applied by aura expect full spell immunity          // Ignore effects with mechanic, they are supposed to be checked separately +        if (!spellInfo->Effects[i].IsEffect()) +            continue;          if (!IsImmunedToSpellEffect(spellInfo, i))          {              immuneToAllEffects = false; @@ -11820,6 +11729,16 @@ uint32 Unit::MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage, WeaponAttackT          return 0;      int32 TakenFlatBenefit = 0; +    float TakenTotalCasterMod = 0.0f; + +    // get all auras from caster that allow the spell to ignore resistance (sanctified wrath) +    SpellSchoolMask attackSchoolMask = spellProto ? spellProto->GetSchoolMask() : SPELL_SCHOOL_MASK_NORMAL; +    AuraEffectList const& IgnoreResistAuras = attacker->GetAuraEffectsByType(SPELL_AURA_MOD_IGNORE_TARGET_RESIST); +    for (AuraEffectList::const_iterator i = IgnoreResistAuras.begin(); i != IgnoreResistAuras.end(); ++i) +    { +        if ((*i)->GetMiscValue() & attackSchoolMask) +            TakenTotalCasterMod += (float((*i)->GetAmount())/100); +    }      // ..taken      AuraEffectList const& mDamageTaken = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_TAKEN); @@ -11904,7 +11823,22 @@ uint32 Unit::MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage, WeaponAttackT              AddPctN(TakenTotalMod, (*i)->GetAmount());      } -    float tmpDamage = (float(pdamage) + TakenFlatBenefit) * TakenTotalMod; +    float tmpDamage = 0.0f; + +    if (TakenTotalCasterMod) +    { +        if (TakenFlatBenefit < 0) +        { +            if (TakenTotalMod < 1) +                tmpDamage = ((float(CalculatePctF(pdamage, TakenTotalCasterMod) + TakenFlatBenefit) * TakenTotalMod) + CalculatePctF(pdamage, TakenTotalCasterMod)); +            else +                tmpDamage = ((float(CalculatePctF(pdamage, TakenTotalCasterMod) + TakenFlatBenefit) + CalculatePctF(pdamage, TakenTotalCasterMod)) * TakenTotalMod); +        } +        else if (TakenTotalMod < 1) +            tmpDamage = ((CalculatePctF(float(pdamage) + TakenFlatBenefit, TakenTotalCasterMod) * TakenTotalMod) + CalculatePctF(float(pdamage) + TakenFlatBenefit, TakenTotalCasterMod)); +    } +    if (!tmpDamage) +        tmpDamage = (float(pdamage) + TakenFlatBenefit) * TakenTotalMod;      // bonus result can be negative      return uint32(std::max(tmpDamage, 0.0f)); @@ -12730,7 +12664,7 @@ void Unit::UpdateSpeed(UnitMoveType mtype, bool forced)          {              // Set creature speed rate from CreatureInfo              if (GetTypeId() == TYPEID_UNIT) -                speed *= ToCreature()->GetCreatureTemplate()->speed_walk; +                speed *= ToCreature()->GetCreatureTemplate()->speed_run;    // at this point, MOVE_WALK is never reached              // Normalize speed by 191 aura SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED if need              // TODO: possible affect only on MOVE_RUN @@ -12795,10 +12729,10 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced)          switch (mtype)          {              case MOVE_WALK: -                data.Initialize(SMSG_MOVE_SPLINE_SET_WALK_SPEED, 8+4+2+4+4+4+4+4+4+4); +                data.Initialize(SMSG_SPLINE_MOVE_SET_WALK_SPEED, 8+4+2+4+4+4+4+4+4+4);                  break;              case MOVE_RUN: -                data.Initialize(SMSG_MOVE_SPLINE_SET_RUN_SPEED, 1 + 8 + 4); +                data.Initialize(SMSG_SPLINE_MOVE_SET_RUN_SPEED, 1 + 8 + 4);                  data.WriteByteMask(bytes[7]);                  data.WriteByteMask(bytes[2]);                  data.WriteByteMask(bytes[1]); @@ -12820,7 +12754,7 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced)                  data << float(GetSpeed(mtype));                  break;              case MOVE_RUN_BACK: -                data.Initialize(SMSG_MOVE_SPLINE_SET_RUN_BACK_SPEED, 1 + 8 + 4); +                data.Initialize(SMSG_SPLINE_MOVE_SET_RUN_BACK_SPEED, 1 + 8 + 4);                  data.WriteByteMask(bytes[4]);                  data.WriteByteMask(bytes[0]);                  data.WriteByteMask(bytes[6]); @@ -12842,7 +12776,7 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced)                  data << float(GetSpeed(mtype));                  break;              case MOVE_SWIM: -                data.Initialize(SMSG_MOVE_SPLINE_SET_SWIM_SPEED, 1 + 8 + 4); +                data.Initialize(SMSG_SPLINE_MOVE_SET_SWIM_SPEED, 1 + 8 + 4);                  data.WriteByteMask(bytes[3]);                  data.WriteByteMask(bytes[5]);                  data.WriteByteMask(bytes[7]); @@ -12863,7 +12797,7 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced)                  data.WriteByteSeq(bytes[5]);                  break;              case MOVE_SWIM_BACK: -                data.Initialize(SMSG_MOVE_SPLINE_SET_SWIM_BACK_SPEED, 1 + 8 + 4); +                data.Initialize(SMSG_SPLINE_MOVE_SET_SWIM_BACK_SPEED, 1 + 8 + 4);                  data.WriteByteMask(bytes[3]);                  data.WriteByteMask(bytes[5]);                  data.WriteByteMask(bytes[4]); @@ -12884,7 +12818,7 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced)                  data.WriteByteSeq(bytes[5]);                  break;              case MOVE_TURN_RATE: -                data.Initialize(SMSG_MOVE_SPLINE_SET_TURN_RATE, 1 + 8 + 4); +                data.Initialize(SMSG_SPLINE_MOVE_SET_TURN_RATE, 1 + 8 + 4);                  data.WriteByteMask(bytes[0]);                  data.WriteByteMask(bytes[4]);                  data.WriteByteMask(bytes[5]); @@ -12905,7 +12839,7 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced)                  data.WriteByteSeq(bytes[3]);                  break;              case MOVE_FLIGHT: -                data.Initialize(SMSG_MOVE_SPLINE_SET_FLIGHT_SPEED, 1 + 8 + 4); +                data.Initialize(SMSG_SPLINE_MOVE_SET_FLIGHT_SPEED, 1 + 8 + 4);                  data.WriteByteMask(bytes[2]);                  data.WriteByteMask(bytes[3]);                  data.WriteByteMask(bytes[5]); @@ -12927,7 +12861,7 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced)                  data.WriteByteSeq(bytes[4]);                  break;              case MOVE_FLIGHT_BACK: -                data.Initialize(SMSG_MOVE_SPLINE_SET_FLIGHT_BACK_SPEED, 1 + 8 + 4); +                data.Initialize(SMSG_SPLINE_MOVE_SET_FLIGHT_BACK_SPEED, 1 + 8 + 4);                  data.WriteByteMask(bytes[1]);                  data.WriteByteMask(bytes[6]);                  data.WriteByteMask(bytes[0]); @@ -12948,7 +12882,7 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced)                  data.WriteByteSeq(bytes[3]);                  break;              case MOVE_PITCH_RATE: -                data.Initialize(SMSG_MOVE_SPLINE_SET_PITCH_RATE, 1 + 8 + 4); +                data.Initialize(SMSG_SPLINE_MOVE_SET_PITCH_RATE, 1 + 8 + 4);                  data.WriteByteMask(bytes[7]);                  data.WriteByteMask(bytes[2]);                  data.WriteByteMask(bytes[3]); @@ -13379,8 +13313,7 @@ void Unit::TauntFadeOut(Unit* taunter)          return;      } -    //m_ThreatManager.tauntFadeOut(taunter); -    target = m_ThreatManager.getHostilTarget(); +    target = creature->SelectVictim();  // might have more taunt auras remaining      if (target && target != taunter)      { @@ -13464,7 +13397,7 @@ Unit* Creature::SelectVictim()      else          return NULL; -    if (target && _IsTargetAcceptable(target)) +    if (target && _IsTargetAcceptable(target) && canCreatureAttack(target))      {          SetInFront(target);          return target; @@ -13490,7 +13423,7 @@ Unit* Creature::SelectVictim()      {          target = SelectNearestTargetInAttackDistance(m_CombatDistance ? m_CombatDistance : ATTACK_DISTANCE); -        if (target && _IsTargetAcceptable(target)) +        if (target && _IsTargetAcceptable(target) && canCreatureAttack(target))              return target;      } @@ -13672,7 +13605,7 @@ void Unit::ModSpellCastTime(SpellInfo const* spellProto, int32 & castTime, Spell      if (Player* modOwner = GetSpellModOwner())          modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_CASTING_TIME, castTime, spell); -    if (!(spellProto->Attributes & (SPELL_ATTR0_ABILITY|SPELL_ATTR0_TRADESPELL)) && spellProto->SpellFamilyName) +    if (!(spellProto->Attributes & (SPELL_ATTR0_ABILITY|SPELL_ATTR0_TRADESPELL)) && ((GetTypeId() == TYPEID_PLAYER && spellProto->SpellFamilyName) || GetTypeId() == TYPEID_UNIT))          castTime = int32(float(castTime) * GetFloatValue(UNIT_MOD_CAST_SPEED));      else if (spellProto->Attributes & SPELL_ATTR0_REQ_AMMO && !(spellProto->AttributesEx2 & SPELL_ATTR2_AUTOREPEAT_FLAG))          castTime = int32(float(castTime) * m_modAttackSpeedPct[RANGED_ATTACK]); @@ -15007,6 +14940,11 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u                          if (procSpell && (triggeredByAura->GetMiscValue() & procSpell->SchoolMask))         // School check                              takeCharges = true;                          break; +                    case SPELL_AURA_SPELL_MAGNET: +                        // Skip Melee hits and targets with magnet aura +                        if (procSpell && (triggeredByAura->GetBase()->GetUnitOwner()->ToUnit() == ToUnit()))         // Magnet +                            takeCharges = true; +                        break;                      case SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT:                      case SPELL_AURA_MOD_POWER_COST_SCHOOL:                          // Skip melee hits and spells ws wrong school or zero cost @@ -15235,6 +15173,7 @@ void Unit::StopMoving()          return;      Movement::MoveSplineInit init(*this); +    init.MoveTo(GetPositionX(), GetPositionY(), GetPositionZMinusOffset());      init.SetFacing(GetOrientation());      init.Launch();  } @@ -16347,7 +16286,7 @@ void Unit::SetRooted(bool apply)          }          else          { -            WorldPacket data(SMSG_MOVE_SPLINE_ROOT, 8); +            WorldPacket data(SMSG_SPLINE_MOVE_ROOT, 8);              data.append(GetPackGUID());              SendMessageToSet(&data, true);              ToCreature()->StopMoving(); @@ -16366,7 +16305,7 @@ void Unit::SetRooted(bool apply)              }              else              { -                WorldPacket data(SMSG_MOVE_SPLINE_UNROOT, 8); +                WorldPacket data(SMSG_SPLINE_MOVE_UNROOT, 8);                  data.append(GetPackGUID());                  SendMessageToSet(&data, true);              } @@ -16747,7 +16686,7 @@ Creature* Unit::GetVehicleCreatureBase() const  uint64 Unit::GetTransGUID() const  {      if (GetVehicle()) -        return GetVehicle()->GetBase()->GetGUID(); +        return GetVehicleBase()->GetGUID();      if (GetTransport())          return GetTransport()->GetGUID(); @@ -17529,7 +17468,7 @@ bool Unit::HandleSpellClick(Unit* clicker, int8 seatId)      Creature* creature = ToCreature();      if (creature && creature->IsAIEnabled) -        creature->AI()->DoAction(EVENT_SPELLCLICK); +        creature->AI()->OnSpellClick(clicker);      return true;  } @@ -17649,11 +17588,12 @@ void Unit::_ExitVehicle(Position const* exitPosition)      Vehicle* vehicle = m_vehicle;      m_vehicle = NULL; -    SetControlled(false, UNIT_STATE_ROOT);       // SMSG_MOVE_FORCE_UNROOT, ~MOVEMENTFLAG_ROOT +    SetControlled(false, UNIT_STATE_ROOT);      // SMSG_MOVE_FORCE_UNROOT, ~MOVEMENTFLAG_ROOT      Position pos; -    if (!exitPosition)                           // Exit position not specified -        vehicle->GetBase()->GetPosition(&pos); +    if (!exitPosition)                          // Exit position not specified +        vehicle->GetBase()->GetPosition(&pos);  // This should use passenger's current position, leaving it as it is now +                                                // because we calculate positions incorrect (sometimes under map)      else          pos = *exitPosition; @@ -17663,19 +17603,22 @@ void Unit::_ExitVehicle(Position const* exitPosition)          ToPlayer()->SetFallInformation(0, GetPositionZ());      else if (HasUnitMovementFlag(MOVEMENTFLAG_ROOT))      { -        WorldPacket data(SMSG_MOVE_SPLINE_UNROOT, 8); +        WorldPacket data(SMSG_SPLINE_MOVE_UNROOT, 8);          data.append(GetPackGUID());          SendMessageToSet(&data, false);      } -    SendMonsterMoveExitVehicle(&pos); -    Relocate(&pos); +    Movement::MoveSplineInit init(*this); +    init.MoveTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ()); +    init.SetFacing(GetOrientation()); +    init.SetTransportExit(); +    init.Launch(); + +    //GetMotionMaster()->MoveFall();            // Enable this once passenger positions are calculater properly (see above)      if (Player* player = ToPlayer())          player->ResummonPetTemporaryUnSummonedIfAny(); -    SendMovementFlagUpdate(); -      if (vehicle->GetBase()->HasUnitTypeMask(UNIT_MASK_MINION))          if (((Minion*)vehicle->GetBase())->GetOwner() == this)              vehicle->Dismiss(); @@ -17693,24 +17636,13 @@ void Unit::_ExitVehicle(Position const* exitPosition)  void Unit::BuildMovementPacket(ByteBuffer *data) const  { -    switch (GetTypeId()) -    { -        case TYPEID_UNIT: -            if (CanFly()) -                const_cast<Unit*>(this)->AddUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY); -            break; -        case TYPEID_PLAYER: -            // remove unknown, unused etc flags for now -            const_cast<Unit*>(this)->RemoveUnitMovementFlag(MOVEMENTFLAG_SPLINE_ENABLED); -            if (isInFlight()) -            { -                WPAssert(const_cast<Unit*>(this)->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE); -                const_cast<Unit*>(this)->AddUnitMovementFlag(MOVEMENTFLAG_FORWARD | MOVEMENTFLAG_SPLINE_ENABLED); -            } -            break; -        default: -            break; -    } +    *data << uint32(GetUnitMovementFlags());            // movement flags +    *data << uint16(GetExtraUnitMovementFlags());       // 2.3.0 +    *data << uint32(getMSTime());                       // time / counter +    *data << GetPositionX(); +    *data << GetPositionY(); +    *data << GetPositionZMinusOffset(); +    *data << GetOrientation();      bool onTransport = GetUnitMovementFlags() & MOVEMENTFLAG_ONTRANSPORT;      bool hasInterpolatedMovement = m_movementInfo.flags2 & MOVEMENTFLAG2_INTERPOLATED_MOVEMENT; @@ -18116,6 +18048,7 @@ void Unit::SetInFront(Unit const* target)  void Unit::SetFacingTo(float ori)  {      Movement::MoveSplineInit init(*this); +    init.MoveTo(GetPositionX(), GetPositionY(), GetPositionZMinusOffset());      init.SetFacing(ori);      init.Launch();  } @@ -18187,7 +18120,7 @@ void Unit::SendMovementHover()      if (GetTypeId() == TYPEID_PLAYER)          ToPlayer()->SendMovementSetHover(HasUnitMovementFlag(MOVEMENTFLAG_HOVER)); -    WorldPacket data(MSG_MOVE_HOVER, 64); // SMSG_MOVE_SET_HOVERING? +    WorldPacket data(MSG_MOVE_HOVER, 64);      data.append(GetPackGUID());      BuildMovementPacket(&data);      SendMessageToSet(&data, false); diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 9d6c22ab8b5..6d188fe3593 100755 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -735,19 +735,6 @@ enum MovementFlags2      MOVEMENTFLAG2_UNK16                    = 0x00008000,  }; -enum SplineFlags -{ -    SPLINEFLAG_WALKMODE     = 0x00001000, -    SPLINEFLAG_FLYING       = 0x00002000, -    SPLINEFLAG_TRANSPORT    = 0x00800000, -    SPLINEFLAG_EXIT_VEHICLE = 0x01000000, -}; - -enum SplineType -{ -    SPLINETYPE_FACING_ANGLE  = 4, -}; -  enum UnitTypeMask  {      UNIT_MASK_NONE                  = 0x00000000, @@ -806,8 +793,8 @@ public:      m_dispeller(_dispeller), m_dispellerSpellId(_dispellerSpellId), m_chargesRemoved(_chargesRemoved) {}      Unit* GetDispeller() { return m_dispeller; } -    uint32 GetDispellerSpellId() { return m_dispellerSpellId; } -    uint8 GetRemovedCharges() { return m_chargesRemoved; } +    uint32 GetDispellerSpellId() const { return m_dispellerSpellId; } +    uint8 GetRemovedCharges() const { return m_chargesRemoved; }      void SetRemovedCharges(uint8 amount)      {          m_chargesRemoved = amount; @@ -1350,10 +1337,10 @@ class Unit : public WorldObject          uint32 GetMaxHealth() const { return GetUInt32Value(UNIT_FIELD_MAXHEALTH); }          bool IsFullHealth() const { return GetHealth() == GetMaxHealth(); } -        bool HealthBelowPct(int32 pct) const { return GetHealth() * uint64(100) < GetMaxHealth() * uint64(pct); } -        bool HealthBelowPctDamaged(int32 pct, uint32 damage) const { return (int32(GetHealth()) - damage) * int64(100) < GetMaxHealth() * int64(pct); } -        bool HealthAbovePct(int32 pct) const { return GetHealth() * uint64(100) > GetMaxHealth() * uint64(pct); } -        bool HealthAbovePctHealed(int32 pct, uint32 heal) const { return (GetHealth() + heal) * uint64(100) > GetMaxHealth() * uint64(pct); } +        bool HealthBelowPct(int32 pct) const { return GetHealth() < CountPctFromMaxHealth(pct); } +        bool HealthBelowPctDamaged(int32 pct, uint32 damage) const { return int64(GetHealth()) - int64(damage) < int64(CountPctFromMaxHealth(pct)); } +        bool HealthAbovePct(int32 pct) const { return GetHealth() > CountPctFromMaxHealth(pct); } +        bool HealthAbovePctHealed(int32 pct, uint32 heal) const { return uint64(GetHealth()) + uint64(heal) > CountPctFromMaxHealth(pct); }          float GetHealthPct() const { return GetMaxHealth() ? 100.f * GetHealth() / GetMaxHealth() : 0.0f; }          uint32 CountPctFromMaxHealth(int32 pct) const { return CalculatePctN(GetMaxHealth(), pct); }          uint32 CountPctFromCurHealth(int32 pct) const { return CalculatePctN(GetHealth(), pct); } @@ -1632,9 +1619,7 @@ class Unit : public WorldObject          void MonsterMoveWithSpeed(float x, float y, float z, float speed);          //void SetFacing(float ori, WorldObject* obj = NULL); -        void SendMonsterMoveExitVehicle(Position const* newPos);          //void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 type, uint32 MovementFlags, uint32 Time, Player* player = NULL); -        void SendMonsterMoveTransport(Unit* vehicleOwner);          void SendMovementFlagUpdate();          /*! These methods send the same packet to the client in apply and unapply case. diff --git a/src/server/game/Entities/Vehicle/Vehicle.cpp b/src/server/game/Entities/Vehicle/Vehicle.cpp index 090a1db382a..eb50f3fe229 100755 --- a/src/server/game/Entities/Vehicle/Vehicle.cpp +++ b/src/server/game/Entities/Vehicle/Vehicle.cpp @@ -28,6 +28,7 @@  #include "ZoneScript.h"  #include "SpellMgr.h"  #include "SpellInfo.h" +#include "MoveSplineInit.h"  Vehicle::Vehicle(Unit* unit, VehicleEntry const* vehInfo, uint32 creatureEntry) : _me(unit), _vehicleInfo(vehInfo), _usableSeatNum(0), _creatureEntry(creatureEntry)  { @@ -338,7 +339,7 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId)          }      } -    if (seat->second.SeatInfo->m_flags && !(seat->second.SeatInfo->m_flags & VEHICLE_SEAT_FLAG_UNK1)) +    if (seat->second.SeatInfo->m_flags && !(seat->second.SeatInfo->m_flags & VEHICLE_SEAT_FLAG_ALLOW_TURNING))          unit->AddUnitState(UNIT_STATE_ONVEHICLE);      unit->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT); @@ -364,7 +365,12 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId)          unit->SendClearTarget();                                 // SMSG_BREAK_TARGET          unit->SetControlled(true, UNIT_STATE_ROOT);              // SMSG_FORCE_ROOT - In some cases we send SMSG_SPLINE_MOVE_ROOT here (for creatures)                                                                   // also adds MOVEMENTFLAG_ROOT -        unit->SendMonsterMoveTransport(_me);                     // SMSG_MONSTER_MOVE_TRANSPORT +        Movement::MoveSplineInit init(*unit); +        init.DisableTransportPathTransformations(); +        init.MoveTo(veSeat->m_attachmentOffsetX, veSeat->m_attachmentOffsetY, veSeat->m_attachmentOffsetZ); +        init.SetFacing(0.0f); +        init.SetTransportEnter(); +        init.Launch();          if (_me->GetTypeId() == TYPEID_UNIT)          { @@ -372,7 +378,8 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId)                  _me->ToCreature()->AI()->PassengerBoarded(unit, seat->first, true);              // update all passenger's positions -            RelocatePassengers(_me->GetPositionX(), _me->GetPositionY(), _me->GetPositionZ(), _me->GetOrientation()); +            //Passenger's spline OR vehicle movement will update positions +            //RelocatePassengers(_me->GetPositionX(), _me->GetPositionY(), _me->GetPositionZ(), _me->GetOrientation());          }      } diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 43381267545..71ce341185e 100755 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -461,7 +461,7 @@ void ObjectMgr::LoadCreatureTemplates()          creatureTemplate.SkinLootId        = fields[48].GetUInt32();          for (uint8 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i) -            creatureTemplate.resistance[i] = fields[50 + i -1].GetInt16(); +            creatureTemplate.resistance[i] = fields[49 + i - 1].GetInt16();          for (uint8 i = 0; i < CREATURE_MAX_SPELLS; ++i)              creatureTemplate.spells[i] = fields[55 + i].GetUInt32(); @@ -1884,71 +1884,6 @@ void ObjectMgr::RemoveGameobjectFromGrid(uint32 guid, GameObjectData const* data      }  } -void ObjectMgr::LoadCreatureRespawnTimes() -{ -    uint32 oldMSTime = getMSTime(); - -    uint32 count = 0; - -    PreparedQueryResult result = CharacterDatabase.Query(CharacterDatabase.GetPreparedStatement(CHAR_SEL_CREATURE_RESPAWNS)); -    if (!result) -    { -        sLog->outString(">> Loaded 0 creature respawn time."); -        sLog->outString(); -        return; -    } - -    do -    { -        Field* fields = result->Fetch(); - -        uint32 loguid       = fields[0].GetUInt32(); -        uint32 respawn_time = fields[1].GetUInt32(); -        uint32 instance     = fields[2].GetUInt32(); - -        _creatureRespawnTimes[MAKE_PAIR64(loguid, instance)] = time_t(respawn_time); - -        ++count; -    } while (result->NextRow()); - -    sLog->outString(">> Loaded %lu creature respawn times in %u ms", (unsigned long)_creatureRespawnTimes.size(), GetMSTimeDiffToNow(oldMSTime)); -    sLog->outString(); -} - -void ObjectMgr::LoadGameobjectRespawnTimes() -{ -    uint32 oldMSTime = getMSTime(); - -    // Remove outdated data -    CharacterDatabase.DirectExecute("DELETE FROM gameobject_respawn WHERE respawnTime <= UNIX_TIMESTAMP(NOW())"); - -    uint32 count = 0; - -    PreparedQueryResult result = CharacterDatabase.Query(CharacterDatabase.GetPreparedStatement(CHAR_SEL_GO_RESPAWNS)); -    if (!result) -    { -        sLog->outString(">> Loaded 0 gameobject respawn times. DB table `gameobject_respawn` is empty!"); -        sLog->outString(); -        return; -    } - -    do -    { -        Field* fields = result->Fetch(); - -        uint32 loguid       = fields[0].GetUInt32(); -        uint32 respawn_time = fields[1].GetUInt32(); -        uint32 instance     = fields[2].GetUInt32(); - -        _goRespawnTimes[MAKE_PAIR64(loguid, instance)] = time_t(respawn_time); - -        ++count; -    } while (result->NextRow()); - -    sLog->outString(); -    sLog->outString(">> Loaded %lu gameobject respawn times in %u ms", (unsigned long)_goRespawnTimes.size(), GetMSTimeDiffToNow(oldMSTime)); -} -  Player* ObjectMgr::GetPlayerByLowGUID(uint32 lowguid) const  {      uint64 guid = MAKE_NEW_GUID(lowguid, 0, HIGHGUID_PLAYER); @@ -2613,7 +2548,7 @@ void ObjectMgr::LoadItemTemplateAddon()      uint32 oldMSTime = getMSTime();      uint32 count = 0; -    QueryResult result = WorldDatabase.Query("SELECT Id, FoodType, MinMoneyLoot, MaxMoneyLoot, SpellPPMChance FROM item_template_addon"); +    QueryResult result = WorldDatabase.Query("SELECT Id, FlagsCu, FoodType, MinMoneyLoot, MaxMoneyLoot, SpellPPMChance FROM item_template_addon");      if (result)      {          do @@ -2626,16 +2561,8 @@ void ObjectMgr::LoadItemTemplateAddon()                  continue;              } -            uint8 buyCount = fields[1].GetUInt8(); -            if (!buyCount) -            { -                sLog->outErrorDb("Item %u has BuyCount set to 0, corrected to 1.", itemId); -                buyCount = 1; -            } - -            uint8 foodType = fields[1].GetUInt8(); -            uint32 minMoneyLoot = fields[2].GetUInt32(); -            uint32 maxMoneyLoot = fields[3].GetUInt32(); +            uint32 minMoneyLoot = fields[3].GetUInt32(); +            uint32 maxMoneyLoot = fields[4].GetUInt32();              if (minMoneyLoot > maxMoneyLoot)              {                  sLog->outErrorDb("Minimum money loot specified in `item_template_addon` for item %u was greater than maximum amount, swapping.", itemId); @@ -2643,10 +2570,11 @@ void ObjectMgr::LoadItemTemplateAddon()              }              ItemTemplate& itemTemplate = _itemTemplateStore[itemId]; -            itemTemplate.FoodType = foodType; +            itemTemplate.FlagsCu = fields[1].GetUInt32(); +            itemTemplate.FoodType = fields[2].GetUInt8();              itemTemplate.MinMoneyLoot = minMoneyLoot;              itemTemplate.MaxMoneyLoot = maxMoneyLoot; -            itemTemplate.SpellPPMRate = fields[4].GetFloat(); +            itemTemplate.SpellPPMRate = fields[5].GetFloat();              ++count;          } while (result->NextRow());      } @@ -2739,6 +2667,7 @@ void ObjectMgr::LoadItemSetNames()      }      //                                                  0        1            2 +    //                                                  0        1            2      QueryResult result = WorldDatabase.Query("SELECT `entry`, `name`, `InventoryType` FROM `item_set_names`");      if (!result) @@ -5043,11 +4972,11 @@ void ObjectMgr::LoadSpellScriptNames()          Field* fields = result->Fetch(); -        int32 spellId         = fields[0].GetInt32(); +        int32 spellId          = fields[0].GetInt32();          const char *scriptName = fields[1].GetCString();          bool allRanks = false; -        if (spellId <=0) +        if (spellId <= 0)          {              allRanks = true;              spellId = -spellId; @@ -6783,7 +6712,7 @@ uint32 ObjectMgr::GetBaseXP(uint8 level)      return _baseXPTable[level] ? _baseXPTable[level] : 0;  } -uint32 ObjectMgr::GetXPForLevel(uint8 level) +uint32 ObjectMgr::GetXPForLevel(uint8 level) const  {      if (level < _playerXPperLevel.size())          return _playerXPperLevel[level]; @@ -7340,44 +7269,6 @@ void ObjectMgr::LoadNPCSpellClickSpells()      sLog->outString();  } -void ObjectMgr::SaveCreatureRespawnTime(uint32 loguid, uint32 instance, time_t t) -{ -    if (!t) -    { -        // Delete only -        RemoveCreatureRespawnTime(loguid, instance); -        return; -    } - -    // This function can be called from various map threads concurrently -    { -        _creatureRespawnTimesMutex.acquire(); -        _creatureRespawnTimes[MAKE_PAIR64(loguid, instance)] = t; -        _creatureRespawnTimesMutex.release(); -    } - -    PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_CREATURE_RESPAWN); -    stmt->setUInt32(0, loguid); -    stmt->setUInt32(1, uint32(t)); -    stmt->setUInt32(2, instance); -    CharacterDatabase.Execute(stmt); -} - -void ObjectMgr::RemoveCreatureRespawnTime(uint32 loguid, uint32 instance) -{ -    // This function can be called from various map threads concurrently -    { -        _creatureRespawnTimesMutex.acquire(); -        _creatureRespawnTimes[MAKE_PAIR64(loguid, instance)] = 0; -        _creatureRespawnTimesMutex.release(); -    } - -    PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CREATURE_RESPAWN); -    stmt->setUInt32(0, loguid); -    stmt->setUInt32(1, instance); -    CharacterDatabase.Execute(stmt); -} -  void ObjectMgr::DeleteCreatureData(uint32 guid)  {      // remove mapid*cellid -> guid_set map @@ -7388,81 +7279,6 @@ void ObjectMgr::DeleteCreatureData(uint32 guid)      _creatureDataStore.erase(guid);  } -void ObjectMgr::SaveGORespawnTime(uint32 loguid, uint32 instance, time_t t) -{ -    if (!t) -    { -        // Delete only -        RemoveGORespawnTime(loguid, instance); -        return; -    } - -    // This function can be called from different map threads concurrently -    { -        _goRespawnTimesMutex.acquire(); -        _goRespawnTimes[MAKE_PAIR64(loguid, instance)] = t; -        _goRespawnTimesMutex.release(); -    } - -    PreparedStatement *stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_GO_RESPAWN); -    stmt->setUInt32(0, loguid); -    stmt->setUInt64(1, uint64(t)); -    stmt->setUInt32(2, instance); -    CharacterDatabase.Execute(stmt); -} - -void ObjectMgr::RemoveGORespawnTime(uint32 loguid, uint32 instance) -{ -    // This function can be called from different map threads concurrently -    { -        _goRespawnTimesMutex.acquire(); -        _goRespawnTimes[MAKE_PAIR64(loguid, instance)] = 0; -        _goRespawnTimesMutex.release(); -    } - -    PreparedStatement *stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GO_RESPAWN); -    stmt->setUInt32(0, loguid); -    stmt->setUInt32(1, instance); -    CharacterDatabase.Execute(stmt); -} - -void ObjectMgr::DeleteRespawnTimeForInstance(uint32 instance) -{ -    // This function can be called from different map threads concurrently -    RespawnTimes::iterator next; - -    { -        _goRespawnTimesMutex.acquire(); -        for (RespawnTimes::iterator itr = _goRespawnTimes.begin(); itr != _goRespawnTimes.end(); itr = next) -        { -            next = itr; -            ++next; - -            if (GUID_HIPART(itr->first) == instance) -                _goRespawnTimes.erase(itr); -        } -        _goRespawnTimesMutex.release(); -    } -    { -        _creatureRespawnTimesMutex.acquire(); -        for (RespawnTimes::iterator itr = _creatureRespawnTimes.begin(); itr != _creatureRespawnTimes.end(); itr = next) -        { -            next = itr; -            ++next; - -            if (GUID_HIPART(itr->first) == instance) -                _creatureRespawnTimes.erase(itr); -        } -        _creatureRespawnTimesMutex.release(); -    } -    PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CREATURE_RESPAWN_BY_INSTANCE); -    stmt->setUInt32(0, instance); -    CharacterDatabase.Execute(stmt); -    stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GO_RESPAWN_BY_INSTANCE); -    stmt->setUInt32(0, instance); -    CharacterDatabase.Execute(stmt); -} -  void ObjectMgr::DeleteGOData(uint32 guid)  {      // remove mapid*cellid -> guid_set map diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 9ab7898573f..742259aa536 100755 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -367,8 +367,6 @@ struct CellObjectGuids  typedef UNORDERED_MAP<uint32/*cell_id*/, CellObjectGuids> CellObjectGuidsMap;  typedef UNORDERED_MAP<uint32/*(mapid, spawnMode) pair*/, CellObjectGuidsMap> MapObjectGuids; -typedef UNORDERED_MAP<uint64/*(instance, guid) pair*/, time_t> RespawnTimes; -  // Trinity string ranges  #define MIN_TRINITY_STRING_ID           1                    // 'trinity_string'  #define MAX_TRINITY_STRING_ID           2000000000 @@ -624,14 +622,14 @@ class ObjectMgr          Player* GetPlayerByLowGUID(uint32 lowguid) const;          GameObjectTemplate const* GetGameObjectTemplate(uint32 entry); -        GameObjectTemplateContainer const* GetGameObjectTemplates() { return &_gameObjectTemplateStore; } +        GameObjectTemplateContainer const* GetGameObjectTemplates() const { return &_gameObjectTemplateStore; }          int LoadReferenceVendor(int32 vendor, int32 item_id, std::set<uint32> *skip_vendors);          void LoadGameObjectTemplate();          void AddGameobjectInfo(GameObjectTemplate* goinfo);          CreatureTemplate const* GetCreatureTemplate(uint32 entry); -        CreatureTemplateContainer const* GetCreatureTemplates() { return &_creatureTemplateStore; } +        CreatureTemplateContainer const* GetCreatureTemplates() const { return &_creatureTemplateStore; }          CreatureModelInfo const* GetCreatureModelInfo(uint32 modelId);          CreatureModelInfo const* GetCreatureModelRandomGender(uint32* displayID);          static uint32 ChooseDisplayId(uint32 team, const CreatureTemplate* cinfo, const CreatureData* data = NULL); @@ -640,7 +638,7 @@ class ObjectMgr          CreatureAddon const* GetCreatureAddon(uint32 lowguid);          CreatureAddon const* GetCreatureTemplateAddon(uint32 entry);          ItemTemplate const* GetItemTemplate(uint32 entry); -        ItemTemplateContainer const* GetItemTemplateStore() { return &_itemTemplateStore; } +        ItemTemplateContainer const* GetItemTemplateStore() const { return &_itemTemplateStore; }          ItemSetNameEntry const* GetItemSetNameEntry(uint32 itemId)          { @@ -863,13 +861,11 @@ class ObjectMgr          void LoadCreatures();          void LoadLinkedRespawn();          bool SetCreatureLinkedRespawn(uint32 guid, uint32 linkedGuid); -        void LoadCreatureRespawnTimes();          void LoadCreatureAddons();          void LoadCreatureModelInfo();          void LoadEquipmentTemplates();          void LoadGameObjectLocales();          void LoadGameobjects(); -        void LoadGameobjectRespawnTimes();          void LoadItemTemplates();          void LoadItemTemplateAddon();          void LoadItemScriptNames(); @@ -927,7 +923,7 @@ class ObjectMgr          std::string GeneratePetName(uint32 entry);          uint32 GetBaseXP(uint8 level); -        uint32 GetXPForLevel(uint8 level); +        uint32 GetXPForLevel(uint8 level) const;          int32 GetFishingBaseSkillLevel(uint32 entry) const          { @@ -1059,36 +1055,6 @@ class ObjectMgr          void AddCorpseCellData(uint32 mapid, uint32 cellid, uint32 player_guid, uint32 instance);          void DeleteCorpseCellData(uint32 mapid, uint32 cellid, uint32 player_guid); -        time_t GetLinkedRespawnTime(uint64 guid, uint32 instance) -        { -            uint64 linkedGuid = GetLinkedRespawnGuid(guid); -            switch (GUID_HIPART(linkedGuid)) -            { -                case HIGHGUID_UNIT: -                    return GetCreatureRespawnTime(GUID_LOPART(linkedGuid), instance); -                case HIGHGUID_GAMEOBJECT: -                    return GetGORespawnTime(GUID_LOPART(linkedGuid), instance); -                default: -                    return 0; -             } -        } - -        time_t GetCreatureRespawnTime(uint32 loguid, uint32 instance) -        { -            TRINITY_GUARD(ACE_Thread_Mutex, _creatureRespawnTimesMutex); -            return _creatureRespawnTimes[MAKE_PAIR64(loguid, instance)]; -        } -        void SaveCreatureRespawnTime(uint32 loguid, uint32 instance, time_t t); -        void RemoveCreatureRespawnTime(uint32 loguid, uint32 instance); -        time_t GetGORespawnTime(uint32 loguid, uint32 instance) -        { -            TRINITY_GUARD(ACE_Thread_Mutex, _goRespawnTimesMutex); -            return _goRespawnTimes[MAKE_PAIR64(loguid, instance)]; -        } -        void SaveGORespawnTime(uint32 loguid, uint32 instance, time_t t); -        void RemoveGORespawnTime(uint32 loguid, uint32 instance); -        void DeleteRespawnTimeForInstance(uint32 instance); -          // grid objects          void AddCreatureToGrid(uint32 guid, CreatureData const* data);          void RemoveCreatureFromGrid(uint32 guid, CreatureData const* data); @@ -1143,7 +1109,7 @@ class ObjectMgr          void LoadScriptNames();          ScriptNameContainer &GetScriptNames() { return _scriptNamesStore; } -        const char * GetScriptName(uint32 id) { return id < _scriptNamesStore.size() ? _scriptNamesStore[id].c_str() : ""; } +        const char * GetScriptName(uint32 id) const { return id < _scriptNamesStore.size() ? _scriptNamesStore[id].c_str() : ""; }          uint32 GetScriptId(const char *name);          SpellClickInfoMapBounds GetSpellClickInfoMapBounds(uint32 creature_id) const @@ -1321,10 +1287,6 @@ class ObjectMgr          TrinityStringLocaleContainer _trinityStringLocaleStore;          GossipMenuItemsLocaleContainer _gossipMenuItemsLocaleStore;          PointOfInterestLocaleContainer _pointOfInterestLocaleStore; -        RespawnTimes _creatureRespawnTimes; -        ACE_Thread_Mutex _creatureRespawnTimesMutex; -        RespawnTimes _goRespawnTimes; -        ACE_Thread_Mutex _goRespawnTimesMutex;          CacheVendorItemContainer _cacheVendorItemStore;          CacheTrainerSpellContainer _cacheTrainerSpellStore; @@ -1339,7 +1301,6 @@ class ObjectMgr              GO_TO_GO,              GO_TO_CREATURE,         // GO is dependant on creature          }; -          HotfixData _hotfixData;  }; diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h index 54bc1206e18..75df3e67c5a 100755 --- a/src/server/game/Grids/Notifiers/GridNotifiers.h +++ b/src/server/game/Grids/Notifiers/GridNotifiers.h @@ -1325,11 +1325,16 @@ namespace Trinity      {          public:              UnitAuraCheck(bool present, uint32 spellId, uint64 casterGUID = 0) : _present(present), _spellId(spellId), _casterGUID(casterGUID) {} -            bool operator()(Unit* unit) +            bool operator()(Unit* unit) const              {                  return unit->HasAura(_spellId, _casterGUID) == _present;              } +            bool operator()(WorldObject* object) const +            { +                return object->ToUnit() && object->ToUnit()->HasAura(_spellId, _casterGUID) == _present; +            } +          private:              bool _present;              uint32 _spellId; diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index 4c6b6249887..743d56886f0 100755 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -556,7 +556,7 @@ bool Group::RemoveMember(uint64 guid, const RemoveMethod &method /*= GROUP_REMOV              roll->playerVote.erase(itr2); -            CountRollVote(guid, roll->itemGUID, GetMembersCount()-1, MAX_ROLL_TYPE); +            CountRollVote(guid, roll->itemGUID, MAX_ROLL_TYPE);          }          // Update subgroups @@ -763,7 +763,7 @@ void Group::SendLootStartRoll(uint32 countDown, uint32 mapid, const Roll &r)      WorldPacket data(SMSG_LOOT_START_ROLL, (8+4+4+4+4+4+4+1));      data << uint64(r.itemGUID);                             // guid of rolled item      data << uint32(mapid);                                  // 3.3.3 mapid -    data << uint32(r.itemSlot);                             // slot +    data << uint32(r.itemSlot);                             // itemslot      data << uint32(r.itemid);                               // the itemEntryId for the item that shall be rolled for      data << uint32(r.itemRandomSuffix);                     // randomSuffix      data << uint32(r.itemRandomPropId);                     // item random property ID @@ -791,7 +791,7 @@ void Group::SendLootStartRollToPlayer(uint32 countDown, uint32 mapId, Player* p,      WorldPacket data(SMSG_LOOT_START_ROLL, (8 + 4 + 4 + 4 + 4 + 4 + 4 + 1));      data << uint64(r.itemGUID);                             // guid of rolled item      data << uint32(mapId);                                  // 3.3.3 mapid -    data << uint32(r.totalPlayersRolling);                  // maybe the number of players rolling for it??? +    data << uint32(r.itemSlot);                             // itemslot      data << uint32(r.itemid);                               // the itemEntryId for the item that shall be rolled for      data << uint32(r.itemRandomSuffix);                     // randomSuffix      data << uint32(r.itemRandomPropId);                     // item random property ID @@ -805,20 +805,20 @@ void Group::SendLootStartRollToPlayer(uint32 countDown, uint32 mapId, Player* p,      p->GetSession()->SendPacket(&data);  } -void Group::SendLootRoll(uint64 SourceGuid, uint64 TargetGuid, uint8 RollNumber, uint8 RollType, const Roll &r) +void Group::SendLootRoll(uint64 sourceGuid, uint64 targetGuid, uint8 rollNumber, uint8 rollType, Roll const& roll)  {      WorldPacket data(SMSG_LOOT_ROLL, (8+4+8+4+4+4+1+1+1)); -    data << uint64(SourceGuid);                             // guid of the item rolled -    data << uint32(0);                                      // unknown, maybe amount of players -    data << uint64(TargetGuid); -    data << uint32(r.itemid);                               // the itemEntryId for the item that shall be rolled for -    data << uint32(r.itemRandomSuffix);                     // randomSuffix -    data << uint32(r.itemRandomPropId);                     // Item random property ID -    data << uint8(RollNumber);                              // 0: "Need for: [item name]" > 127: "you passed on: [item name]"      Roll number -    data << uint8(RollType);                                // 0: "Need for: [item name]" 0: "You have selected need for [item name] 1: need roll 2: greed roll -    data << uint8(0);                                       // auto pass on NeedBeforeGreed loot because player cannot use the object +    data << uint64(sourceGuid);                             // guid of the item rolled +    data << uint32(roll.itemSlot);                          // slot +    data << uint64(targetGuid); +    data << uint32(roll.itemid);                            // the itemEntryId for the item that shall be rolled for +    data << uint32(roll.itemRandomSuffix);                  // randomSuffix +    data << uint32(roll.itemRandomPropId);                  // Item random property ID +    data << uint8(rollNumber);                              // 0: "Need for: [item name]" > 127: "you passed on: [item name]"      Roll number +    data << uint8(rollType);                                // 0: "Need for: [item name]" 0: "You have selected need for [item name] 1: need roll 2: greed roll +    data << uint8(0);                                       // 1: "You automatically passed on: %s because you cannot loot that item." - Possibly used in need befor greed -    for (Roll::PlayerVote::const_iterator itr=r.playerVote.begin(); itr != r.playerVote.end(); ++itr) +    for (Roll::PlayerVote::const_iterator itr = roll.playerVote.begin(); itr != roll.playerVote.end(); ++itr)      {          Player* p = ObjectAccessor::FindPlayer(itr->first);          if (!p || !p->GetSession()) @@ -829,19 +829,19 @@ void Group::SendLootRoll(uint64 SourceGuid, uint64 TargetGuid, uint8 RollNumber,      }  } -void Group::SendLootRollWon(uint64 SourceGuid, uint64 TargetGuid, uint8 RollNumber, uint8 RollType, const Roll &r) +void Group::SendLootRollWon(uint64 sourceGuid, uint64 targetGuid, uint8 rollNumber, uint8 rollType, Roll const& roll)  {      WorldPacket data(SMSG_LOOT_ROLL_WON, (8+4+4+4+4+8+1+1)); -    data << uint64(SourceGuid);                             // guid of the item rolled -    data << uint32(0);                                      // unknown, maybe amount of players -    data << uint32(r.itemid);                               // the itemEntryId for the item that shall be rolled for -    data << uint32(r.itemRandomSuffix);                     // randomSuffix -    data << uint32(r.itemRandomPropId);                     // Item random property -    data << uint64(TargetGuid);                             // guid of the player who won. -    data << uint8(RollNumber);                              // rollnumber realted to SMSG_LOOT_ROLL -    data << uint8(RollType);                                // Rolltype related to SMSG_LOOT_ROLL +    data << uint64(sourceGuid);                             // guid of the item rolled +    data << uint32(roll.itemSlot);                          // slot +    data << uint32(roll.itemid);                            // the itemEntryId for the item that shall be rolled for +    data << uint32(roll.itemRandomSuffix);                  // randomSuffix +    data << uint32(roll.itemRandomPropId);                  // Item random property +    data << uint64(targetGuid);                             // guid of the player who won. +    data << uint8(rollNumber);                              // rollnumber realted to SMSG_LOOT_ROLL +    data << uint8(rollType);                                // rollType related to SMSG_LOOT_ROLL -    for (Roll::PlayerVote::const_iterator itr=r.playerVote.begin(); itr != r.playerVote.end(); ++itr) +    for (Roll::PlayerVote::const_iterator itr = roll.playerVote.begin(); itr != roll.playerVote.end(); ++itr)      {          Player* p = ObjectAccessor::FindPlayer(itr->first);          if (!p || !p->GetSession()) @@ -852,11 +852,11 @@ void Group::SendLootRollWon(uint64 SourceGuid, uint64 TargetGuid, uint8 RollNumb      }  } -void Group::SendLootAllPassed(uint32 numberOfPlayers, Roll const& roll) +void Group::SendLootAllPassed(Roll const& roll)  {      WorldPacket data(SMSG_LOOT_ALL_PASSED, (8+4+4+4+4));      data << uint64(roll.itemGUID);                             // Guid of the item rolled -    data << uint32(numberOfPlayers);                           // The number of players rolling for it +    data << uint32(roll.itemSlot);                             // Item loot slot      data << uint32(roll.itemid);                               // The itemEntryId for the item that shall be rolled for      data << uint32(roll.itemRandomPropId);                     // Item random property ID      data << uint32(roll.itemRandomSuffix);                     // Item random suffix ID @@ -1099,7 +1099,7 @@ void Group::MasterLoot(Loot* /*loot*/, WorldObject* pLootedObject)      }  } -void Group::CountRollVote(uint64 playerGUID, uint64 Guid, uint32 NumberOfPlayers, uint8 Choice) +void Group::CountRollVote(uint64 playerGUID, uint64 Guid, uint8 Choice)  {      Rolls::iterator rollI = GetRoll(Guid);      if (rollI == RollId.end()) @@ -1140,7 +1140,7 @@ void Group::CountRollVote(uint64 playerGUID, uint64 Guid, uint32 NumberOfPlayers      }      if (roll->totalPass + roll->totalNeed + roll->totalGreed >= roll->totalPlayersRolling) -        CountTheRoll(rollI, NumberOfPlayers); +        CountTheRoll(rollI);  }  //called when roll timer expires @@ -1149,7 +1149,7 @@ void Group::EndRoll(Loot* pLoot)      for (Rolls::iterator itr = RollId.begin(); itr != RollId.end();)      {          if ((*itr)->getLoot() == pLoot) { -            CountTheRoll(itr, GetMembersCount());           //i don't have to edit player votes, who didn't vote ... he will pass +            CountTheRoll(itr);           //i don't have to edit player votes, who didn't vote ... he will pass              itr = RollId.begin();          }          else @@ -1157,7 +1157,7 @@ void Group::EndRoll(Loot* pLoot)      }  } -void Group::CountTheRoll(Rolls::iterator rollI, uint32 NumberOfPlayers) +void Group::CountTheRoll(Rolls::iterator rollI)  {      Roll* roll = *rollI;      if (!roll->isValid())                                   // is loot already deleted ? @@ -1280,7 +1280,7 @@ void Group::CountTheRoll(Rolls::iterator rollI, uint32 NumberOfPlayers)      }      else      { -        SendLootAllPassed(NumberOfPlayers, *roll); +        SendLootAllPassed(*roll);          // remove is_blocked so that the item is lootable by all players          LootItem* item = &(roll->getLoot()->items[roll->itemSlot]); @@ -2107,20 +2107,6 @@ bool Group::HasFreeSlotSubGroup(uint8 subgroup) const      return (m_subGroupsCounts && m_subGroupsCounts[subgroup] < MAXGROUPSIZE);  } -Group::MemberSlotList const& Group::GetMemberSlots() const -{ -    return m_memberSlots; -} - -GroupReference* Group::GetFirstMember() -{ -    return m_memberMgr.getFirst(); -} - -uint32 Group::GetMembersCount() const -{ -    return m_memberSlots.size(); -}  uint8 Group::GetMemberGroup(uint64 guid) const  { diff --git a/src/server/game/Groups/Group.h b/src/server/game/Groups/Group.h index 08246614627..f909b755829 100755 --- a/src/server/game/Groups/Group.h +++ b/src/server/game/Groups/Group.h @@ -232,9 +232,11 @@ class Group          bool SameSubGroup(Player const* member1, Player const* member2) const;          bool HasFreeSlotSubGroup(uint8 subgroup) const; -        MemberSlotList const& GetMemberSlots() const; -        GroupReference* GetFirstMember(); -        uint32 GetMembersCount() const; +        MemberSlotList const& GetMemberSlots() const { return m_memberSlots; } +        GroupReference* GetFirstMember() { return m_memberMgr.getFirst(); } +        GroupReference const* GetFirstMember() const { return m_memberMgr.getFirst(); } +        uint32 GetMembersCount() const { return m_memberSlots.size(); } +          uint8 GetMemberGroup(uint64 guid) const;          void ConvertToLFG(); @@ -279,14 +281,14 @@ class Group          void SendLootStartRollToPlayer(uint32 countDown, uint32 mapId, Player* p, bool canNeed, Roll const& r);          void SendLootRoll(uint64 SourceGuid, uint64 TargetGuid, uint8 RollNumber, uint8 RollType, const Roll &r);          void SendLootRollWon(uint64 SourceGuid, uint64 TargetGuid, uint8 RollNumber, uint8 RollType, const Roll &r); -        void SendLootAllPassed(uint32 NumberOfPlayers, const Roll &r); +        void SendLootAllPassed(Roll const& roll);          void SendLooter(Creature* creature, Player* pLooter);          void GroupLoot(Loot* loot, WorldObject* pLootedObject);          void NeedBeforeGreed(Loot* loot, WorldObject* pLootedObject);          void MasterLoot(Loot* loot, WorldObject* pLootedObject);          Rolls::iterator GetRoll(uint64 Guid); -        void CountTheRoll(Rolls::iterator roll, uint32 NumberOfPlayers); -        void CountRollVote(uint64 playerGUID, uint64 Guid, uint32 NumberOfPlayers, uint8 Choise); +        void CountTheRoll(Rolls::iterator roll); +        void CountRollVote(uint64 playerGUID, uint64 Guid, uint8 Choise);          void EndRoll(Loot* loot);          // related to disenchant rolls diff --git a/src/server/game/Groups/GroupRefManager.h b/src/server/game/Groups/GroupRefManager.h index 9bcc05f8724..d9fef8611de 100755 --- a/src/server/game/Groups/GroupRefManager.h +++ b/src/server/game/Groups/GroupRefManager.h @@ -28,7 +28,8 @@ class GroupReference;  class GroupRefManager : public RefManager<Group, Player>  {      public: -        GroupReference* getFirst() { return ((GroupReference*) RefManager<Group, Player>::getFirst()); } +        GroupReference* getFirst() { return ((GroupReference*)RefManager<Group, Player>::getFirst()); } +        GroupReference const* getFirst() const { return ((GroupReference const*)RefManager<Group, Player>::getFirst()); }  };  #endif diff --git a/src/server/game/Groups/GroupReference.h b/src/server/game/Groups/GroupReference.h index 2048fd9cb0d..7960dd21035 100755 --- a/src/server/game/Groups/GroupReference.h +++ b/src/server/game/Groups/GroupReference.h @@ -35,6 +35,7 @@ class GroupReference : public Reference<Group, Player>          GroupReference() : Reference<Group, Player>(), iSubGroup(0) {}          ~GroupReference() { unlink(); }          GroupReference* next() { return (GroupReference*)Reference<Group, Player>::next(); } +        GroupReference const* next() const { return (GroupReference const*)Reference<Group, Player>::next(); }          uint8 getSubGroup() const { return iSubGroup; }          void setSubGroup(uint8 pSubGroup) { iSubGroup = pSubGroup; }  }; diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp index dfeb3f7cad9..b57e9970dab 100755 --- a/src/server/game/Guilds/Guild.cpp +++ b/src/server/game/Guilds/Guild.cpp @@ -2093,7 +2093,7 @@ bool Guild::AddMember(uint64 guid, uint8 rankId)          if (player->GetGuildId() != 0)              return false;      } -    else if (Player::GetGuildIdFromGuid(guid) != 0) +    else if (Player::GetGuildIdFromDB(guid) != 0)          return false;      // Remove all player signs from another petitions diff --git a/src/server/game/Handlers/AuctionHouseHandler.cpp b/src/server/game/Handlers/AuctionHouseHandler.cpp index 27eb559fb68..95204dfa353 100755 --- a/src/server/game/Handlers/AuctionHouseHandler.cpp +++ b/src/server/game/Handlers/AuctionHouseHandler.cpp @@ -161,7 +161,7 @@ void WorldSession::HandleAuctionSellItem(WorldPacket & recv_data)      etime *= MINUTE; -    switch(etime) +    switch (etime)      {          case 1*MIN_AUCTION_TIME:          case 2*MIN_AUCTION_TIME: diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 887bebe5656..1c79b20ce81 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -1868,9 +1868,9 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recv_data)              case RACE_NIGHTELF:                  stmt->setUInt16(1, 113);                  break; -        case RACE_WORGEN: -            trans->PAppend("INSERT INTO `character_skills` (guid, skill, value, max) VALUES (%u, 791, 300, 300)", lowGuid); -            break; +            case RACE_WORGEN: +                stmt->setUInt16(1, 791); +                break;              case RACE_UNDEAD_PLAYER:                  stmt->setUInt16(1, 673);                  break; @@ -1883,9 +1883,9 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recv_data)              case RACE_BLOODELF:                  stmt->setUInt16(1, 137);                  break; -        case RACE_GOBLIN: -            trans->PAppend("INSERT INTO `character_skills` (guid, skill, value, max) VALUES (%u, 792, 300, 300)", lowGuid); -            break; +            case RACE_GOBLIN: +                stmt->setUInt16(1, 792); +                break;          }          trans->Append(stmt); diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp index d725419ac84..eadc0958518 100755 --- a/src/server/game/Handlers/GroupHandler.cpp +++ b/src/server/game/Handlers/GroupHandler.cpp @@ -458,24 +458,20 @@ void WorldSession::HandleLootMethodOpcode(WorldPacket & recv_data)      group->SendUpdate();  } -void WorldSession::HandleLootRoll(WorldPacket &recv_data) +void WorldSession::HandleLootRoll(WorldPacket& recvData)  { +    uint64 guid; +    uint32 itemSlot; +    uint8  rollType; +    recvData >> guid;                  // guid of the item rolled +    recvData >> itemSlot; +    recvData >> rollType;              // 0: pass, 1: need, 2: greed +      Group* group = GetPlayer()->GetGroup();      if (!group) -    { -        recv_data.rfinish();          return; -    } -    uint64 Guid; -    uint32 NumberOfPlayers; -    uint8  rollType; -    recv_data >> Guid;                                      //guid of the item rolled -    recv_data >> NumberOfPlayers; -    recv_data >> rollType;                                    //0: pass, 1: need, 2: greed - -    // everything's fine, do it -    group->CountRollVote(GetPlayer()->GetGUID(), Guid, NumberOfPlayers, rollType); +    group->CountRollVote(GetPlayer()->GetGUID(), guid, rollType);      switch (rollType)      { diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp index 2d85a4cb689..5baa54a2779 100755 --- a/src/server/game/Handlers/ItemHandler.cpp +++ b/src/server/game/Handlers/ItemHandler.cpp @@ -1369,6 +1369,7 @@ void WorldSession::HandleSocketOpcode(WorldPacket& recv_data)      _player->ToggleMetaGemsActive(slot, true);              //turn on all metagems (except for target item) +    _player->RemoveTradeableItem(itemTarget);      itemTarget->ClearSoulboundTradeable(_player);           // clear tradeable flag  } diff --git a/src/server/game/Handlers/LFGHandler.cpp b/src/server/game/Handlers/LFGHandler.cpp index 82afdfb9044..9c66ca44383 100755 --- a/src/server/game/Handlers/LFGHandler.cpp +++ b/src/server/game/Handlers/LFGHandler.cpp @@ -529,7 +529,7 @@ void WorldSession::SendLfgBootPlayer(const LfgPlayerBoot* pBoot)      }      sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_BOOT_PROPOSAL_UPDATE [" UI64FMTD "] inProgress: %u - didVote: %u - agree: %u - victim: [" UI64FMTD "] votes: %u - agrees: %u - left: %u - needed: %u - reason %s",          guid, uint8(pBoot->inProgress), uint8(playerVote != LFG_ANSWER_PENDING), uint8(playerVote == LFG_ANSWER_AGREE), pBoot->victim, votesNum, agreeNum, secsleft, pBoot->votedNeeded, pBoot->reason.c_str()); -    WorldPacket data(SMSG_LFG_BOOT_PLAYER, 1 + 1 + 1 + 8 + 4 + 4 + 4 + 4 + pBoot->reason.length()); +    WorldPacket data(SMSG_LFG_BOOT_PROPOSAL_UPDATE, 1 + 1 + 1 + 8 + 4 + 4 + 4 + 4 + pBoot->reason.length());      data << uint8(pBoot->inProgress);                      // Vote in progress      data << uint8(playerVote != LFG_ANSWER_PENDING);       // Did Vote      data << uint8(playerVote == LFG_ANSWER_AGREE);         // Agree diff --git a/src/server/game/Handlers/LootHandler.cpp b/src/server/game/Handlers/LootHandler.cpp index 8e4b41a9be4..339c7a44d9f 100755 --- a/src/server/game/Handlers/LootHandler.cpp +++ b/src/server/game/Handlers/LootHandler.cpp @@ -220,16 +220,18 @@ void WorldSession::HandleLootOpcode(WorldPacket & recv_data)          GetPlayer()->InterruptNonMeleeSpells(false);  } -void WorldSession::HandleLootReleaseOpcode(WorldPacket & recv_data) +void WorldSession::HandleLootReleaseOpcode(WorldPacket& recvData)  {      sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_LOOT_RELEASE");      // cheaters can modify lguid to prevent correct apply loot release code and re-loot      // use internal stored guid -    recv_data.read_skip<uint64>();                          // guid; +    uint64 guid; +    recvData >> guid;      if (uint64 lguid = GetPlayer()->GetLootGUID()) -        DoLootRelease(lguid); +        if (lguid == guid) +            DoLootRelease(lguid);  }  void WorldSession::DoLootRelease(uint64 lguid) diff --git a/src/server/game/Handlers/MailHandler.cpp b/src/server/game/Handlers/MailHandler.cpp index 988857558c9..ce056d2729c 100755 --- a/src/server/game/Handlers/MailHandler.cpp +++ b/src/server/game/Handlers/MailHandler.cpp @@ -107,7 +107,7 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data)      uint32 reqmoney = cost + money; -    if (!player->HasEnoughMoney(reqmoney)) +    if (!player->HasEnoughMoney(reqmoney) && !player->isGameMaster())      {          player->SendMailResult(0, MAIL_SEND, MAIL_ERR_NOT_ENOUGH_MONEY);          return; diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index 247db1975a4..46e40e16c08 100755 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -494,7 +494,7 @@ void WorldSession::HandleZoneUpdateOpcode(WorldPacket & recv_data)      uint32 newZone;      recv_data >> newZone; -    sLog->outDetail("WORLD: Recvd ZONE_UPDATE: %u", newZone); +    sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd ZONE_UPDATE: %u", newZone);      // use server size data      uint32 newzone, newarea; @@ -737,7 +737,7 @@ void WorldSession::HandleBugOpcode(WorldPacket & recv_data)  void WorldSession::HandleReclaimCorpseOpcode(WorldPacket &recv_data)  { -    sLog->outDetail("WORLD: Received CMSG_RECLAIM_CORPSE"); +    sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_RECLAIM_CORPSE");      uint64 guid;      recv_data >> guid; @@ -774,7 +774,7 @@ void WorldSession::HandleReclaimCorpseOpcode(WorldPacket &recv_data)  void WorldSession::HandleResurrectResponseOpcode(WorldPacket & recv_data)  { -    sLog->outDetail("WORLD: Received CMSG_RESURRECT_RESPONSE"); +    sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_RESURRECT_RESPONSE");      uint64 guid;      uint8 status; @@ -945,7 +945,7 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket& recv_data)  void WorldSession::HandleUpdateAccountData(WorldPacket &recv_data)  { -    sLog->outDetail("WORLD: Received CMSG_UPDATE_ACCOUNT_DATA"); +    sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_UPDATE_ACCOUNT_DATA");      uint32 type, timestamp, decompressedSize;      recv_data >> type >> timestamp >> decompressedSize; @@ -1000,7 +1000,7 @@ void WorldSession::HandleUpdateAccountData(WorldPacket &recv_data)  void WorldSession::HandleRequestAccountData(WorldPacket& recv_data)  { -    sLog->outDetail("WORLD: Received CMSG_REQUEST_ACCOUNT_DATA"); +    sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_REQUEST_ACCOUNT_DATA");      uint32 type;      recv_data >> type; @@ -1079,12 +1079,12 @@ void WorldSession::HandleSetActionButtonOpcode(WorldPacket& recv_data)  void WorldSession::HandleCompleteCinematic(WorldPacket & /*recv_data*/)  { -    sLog->outStaticDebug("WORLD: Player is watching cinema"); +    sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_COMPLETE_CINEMATIC");  }  void WorldSession::HandleNextCinematicCamera(WorldPacket & /*recv_data*/)  { -    sLog->outStaticDebug("WORLD: Which movie to play"); +    sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_NEXT_CINEMATIC_CAMERA");  }  void WorldSession::HandleMoveTimeSkippedOpcode(WorldPacket & recv_data) @@ -1127,7 +1127,7 @@ void WorldSession::HandleMoveTimeSkippedOpcode(WorldPacket & recv_data)  void WorldSession::HandleFeatherFallAck(WorldPacket &recv_data)  { -    sLog->outStaticDebug("WORLD: CMSG_MOVE_FEATHER_FALL_ACK"); +    sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_MOVE_FEATHER_FALL_ACK");      // no used      recv_data.rfinish();                       // prevent warnings spam @@ -1215,13 +1215,17 @@ void WorldSession::HandleInspectOpcode(WorldPacket& recv_data)  {      uint64 guid;      recv_data >> guid; -    sLog->outStaticDebug("Inspected guid is " UI64FMTD, guid); + +    sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_INSPECT");      _player->SetSelection(guid);      Player* player = ObjectAccessor::FindPlayer(guid); -    if (!player)                                                // wrong player +    if (!player) +    { +        sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_INSPECT: No player found from GUID: " UI64FMTD, guid);          return; +    }      uint32 talent_points = 41;      WorldPacket data(SMSG_INSPECT_TALENT, 8 + 4 + 1 + 1 + talent_points + 8 + 4 + 8 + 4); @@ -1256,7 +1260,7 @@ void WorldSession::HandleInspectHonorStatsOpcode(WorldPacket& recv_data)      if (!player)      { -        sLog->outError("InspectHonorStats: WTF, player not found..."); +        sLog->outDebug(LOG_FILTER_NETWORKIO, "MSG_INSPECT_HONOR_STATS: No player found from GUID: " UI64FMTD, guid);          return;      } @@ -1270,10 +1274,6 @@ void WorldSession::HandleInspectHonorStatsOpcode(WorldPacket& recv_data)  void WorldSession::HandleWorldTeleportOpcode(WorldPacket& recv_data)  { -    // write in client console: worldport 469 452 6454 2536 180 or /console worldport 469 452 6454 2536 180 -    // Received opcode CMSG_WORLD_TELEPORT -    // Time is ***, map=469, x=452.000000, y=6454.000000, z=2536.000000, orient=3.141593 -      uint32 time;      uint32 mapid;      float PositionX; @@ -1288,20 +1288,20 @@ void WorldSession::HandleWorldTeleportOpcode(WorldPacket& recv_data)      recv_data >> PositionZ;      recv_data >> Orientation;                               // o (3.141593 = 180 degrees) -    //sLog->outDebug("Received opcode CMSG_WORLD_TELEPORT"); +    sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_WORLD_TELEPORT"); +      if (GetPlayer()->isInFlight())      {          sLog->outDebug(LOG_FILTER_NETWORKIO, "Player '%s' (GUID: %u) in flight, ignore worldport command.", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow());          return;      } -    sLog->outStaticDebug("Time %u sec, map=%u, x=%f, y=%f, z=%f, orient=%f", time/1000, mapid, PositionX, PositionY, PositionZ, Orientation); +    sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_WORLD_TELEPORT: Player = %s, Time = %u, map = %u, x = %f, y = %f, z = %f, o = %f", GetPlayer()->GetName(), time, mapid, PositionX, PositionY, PositionZ, Orientation);      if (AccountMgr::IsAdminAccount(GetSecurity()))          GetPlayer()->TeleportTo(mapid, PositionX, PositionY, PositionZ, Orientation);      else          SendNotification(LANG_YOU_NOT_HAVE_PERMISSION); -    sLog->outDebug(LOG_FILTER_NETWORKIO, "Received worldport command from player %s", GetPlayer()->GetName());  }  void WorldSession::HandleWhoisOpcode(WorldPacket& recv_data) diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp index 40d63235af3..598dafb200a 100755 --- a/src/server/game/Handlers/MovementHandler.cpp +++ b/src/server/game/Handlers/MovementHandler.cpp @@ -193,7 +193,7 @@ void WorldSession::HandleMoveTeleportAck(WorldPacket& recv_data)      sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_MOVE_TELEPORT_ACK");      BitStream mask = recv_data.ReadBitStream(8); -     +      uint32 flags, time;      recv_data >> flags >> time; @@ -264,6 +264,7 @@ void WorldSession::HandleMovementOpcodes(WorldPacket & recvData)      // ignore, waiting processing in WorldSession::HandleMoveWorldportAckOpcode and WorldSession::HandleMoveTeleportAck      if (plrMover && plrMover->IsBeingTeleported())      { +        recvData.rfinish();                     // prevent warnings spam          return;      } @@ -302,16 +303,42 @@ void WorldSession::HandleMovementOpcodes(WorldPacket & recvData)          }          // if we boarded a transport, add us to it -        if (plrMover && !plrMover->GetTransport()) +        if (plrMover)          { -            // elevators also cause the client to send MOVEMENTFLAG_ONTRANSPORT - just dismount if the guid can be found in the transport list -            for (MapManager::TransportSet::const_iterator iter = sMapMgr->m_Transports.begin(); iter != sMapMgr->m_Transports.end(); ++iter) +            if (!plrMover->GetTransport())              { -                if ((*iter)->GetGUID() == movementInfo.t_guid) +                // elevators also cause the client to send MOVEMENTFLAG_ONTRANSPORT - just dismount if the guid can be found in the transport list +                for (MapManager::TransportSet::const_iterator iter = sMapMgr->m_Transports.begin(); iter != sMapMgr->m_Transports.end(); ++iter)                  { -                    plrMover->m_transport = (*iter); -                    (*iter)->AddPassenger(plrMover); -                    break; +                    if ((*iter)->GetGUID() == movementInfo.t_guid) +                    { +                        plrMover->m_transport = *iter; +                        (*iter)->AddPassenger(plrMover); +                        break; +                    } +                } +            } +            else if (plrMover->GetTransport()->GetGUID() != movementInfo.t_guid) +            { +                bool foundNewTransport = false; +                plrMover->m_transport->RemovePassenger(plrMover); +                for (MapManager::TransportSet::const_iterator iter = sMapMgr->m_Transports.begin(); iter != sMapMgr->m_Transports.end(); ++iter) +                { +                    if ((*iter)->GetGUID() == movementInfo.t_guid) +                    { +                        foundNewTransport = true; +                        plrMover->m_transport = *iter; +                        (*iter)->AddPassenger(plrMover); +                        break; +                    } +                } + +                if (!foundNewTransport) +                { +                    plrMover->m_transport = NULL; +                    movementInfo.t_pos.Relocate(0.0f, 0.0f, 0.0f, 0.0f); +                    movementInfo.t_time = 0; +                    movementInfo.t_seat = -1;                  }              }          } @@ -971,4 +998,4 @@ void WorldSession::WriteMovementInfo(WorldPacket &data, MovementInfo* mi)             WPError(false, "Incorrect sequence element detected at ReadMovementInfo");         }     } -}
\ No newline at end of file +} diff --git a/src/server/game/Handlers/PetHandler.cpp b/src/server/game/Handlers/PetHandler.cpp index 5f7e4ce04a8..3660bfbfcc7 100755 --- a/src/server/game/Handlers/PetHandler.cpp +++ b/src/server/game/Handlers/PetHandler.cpp @@ -344,9 +344,11 @@ void WorldSession::HandlePetActionHelper(Unit* pet, uint64 guid1, uint16 spellid                      if (unit_target2->GetTypeId() == TYPEID_PLAYER)                          pet->SendUpdateToPlayer((Player*)unit_target2);                  } +                  if (Unit* powner = pet->GetCharmerOrOwner())                      if (powner->GetTypeId() == TYPEID_PLAYER) -              pet->SendUpdateToPlayer(powner->ToPlayer()); +                        pet->SendUpdateToPlayer(powner->ToPlayer()); +                  result = SPELL_CAST_OK;              } @@ -738,7 +740,7 @@ void WorldSession::HandlePetSpellAutocastOpcode(WorldPacket& recvPacket)  void WorldSession::HandlePetCastSpellOpcode(WorldPacket& recvPacket)  { -    sLog->outDetail("WORLD: CMSG_PET_CAST_SPELL"); +    sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_PET_CAST_SPELL");      uint64 guid;      uint8  castCount; diff --git a/src/server/game/Handlers/QueryHandler.cpp b/src/server/game/Handlers/QueryHandler.cpp index f0e681b535c..c22fc309770 100755 --- a/src/server/game/Handlers/QueryHandler.cpp +++ b/src/server/game/Handlers/QueryHandler.cpp @@ -113,7 +113,7 @@ void WorldSession::HandleCreatureQueryOpcode(WorldPacket & recv_data)                  ObjectMgr::GetLocaleString(cl->SubName, loc_idx, SubName);              }          } -        sLog->outDetail("WORLD: CMSG_CREATURE_QUERY '%s' - Entry: %u.", ci->Name.c_str(), entry); +        sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_CREATURE_QUERY '%s' - Entry: %u.", ci->Name.c_str(), entry);                                                              // guess size          WorldPacket data(SMSG_CREATURE_QUERY_RESPONSE, 100);          data << uint32(entry);                              // creature entry @@ -184,7 +184,7 @@ void WorldSession::HandleGameObjectQueryOpcode(WorldPacket & recv_data)                  ObjectMgr::GetLocaleString(gl->CastBarCaption, loc_idx, CastBarCaption);              }          } -        sLog->outDetail("WORLD: CMSG_GAMEOBJECT_QUERY '%s' - Entry: %u. ", info->name.c_str(), entry); +        sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_GAMEOBJECT_QUERY '%s' - Entry: %u. ", info->name.c_str(), entry);          WorldPacket data (SMSG_GAMEOBJECT_QUERY_RESPONSE, 150);          data << uint32(entry);          data << uint32(info->type); @@ -215,7 +215,7 @@ void WorldSession::HandleGameObjectQueryOpcode(WorldPacket & recv_data)  void WorldSession::HandleCorpseQueryOpcode(WorldPacket & /*recv_data*/)  { -    sLog->outDetail("WORLD: Received MSG_CORPSE_QUERY"); +    sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received MSG_CORPSE_QUERY");      Corpse* corpse = GetPlayer()->GetCorpse(); @@ -270,7 +270,7 @@ void WorldSession::HandleNpcTextQueryOpcode(WorldPacket & recv_data)      uint64 guid;      recv_data >> textID; -    sLog->outDetail("WORLD: CMSG_NPC_TEXT_QUERY ID '%u'", textID); +    sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_NPC_TEXT_QUERY ID '%u'", textID);      recv_data >> guid;      GetPlayer()->SetSelection(guid); @@ -350,7 +350,7 @@ void WorldSession::HandleNpcTextQueryOpcode(WorldPacket & recv_data)  /// Only _static_ data is sent in this packet !!!  void WorldSession::HandlePageTextQueryOpcode(WorldPacket & recv_data)  { -    sLog->outDetail("WORLD: Received CMSG_PAGE_TEXT_QUERY"); +    sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_PAGE_TEXT_QUERY");      uint32 pageID;      recv_data >> pageID; diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp index ccd2e178f88..2998b8a1c75 100755 --- a/src/server/game/Handlers/QuestHandler.cpp +++ b/src/server/game/Handlers/QuestHandler.cpp @@ -324,7 +324,7 @@ void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPacket & recv_data)                          // Send next quest                          if (Quest const* nextQuest = _player->GetNextQuest(guid, quest))                          { -                            if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true) && _player->CanTakeQuest(quest, true)) +                            if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true) && _player->CanTakeQuest(nextQuest, true))                              {                                  _player->AddQuest(nextQuest, object);                                  if (_player->CanCompleteQuest(nextQuest->GetQuestId())) @@ -343,7 +343,7 @@ void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPacket & recv_data)                          // Send next quest                          if (Quest const* nextQuest = _player->GetNextQuest(guid, quest))                          { -                            if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true) && _player->CanTakeQuest(quest, true)) +                            if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true) && _player->CanTakeQuest(nextQuest, true))                              {                                  _player->AddQuest(nextQuest, object);                                  if (_player->CanCompleteQuest(nextQuest->GetQuestId())) @@ -496,10 +496,9 @@ void WorldSession::HandleQuestgiverCompleteQuest(WorldPacket& recv_data)      if (!_player->CanInteractWithQuestGiver(object))          return; -    Quest const* quest = sObjectMgr->GetQuestTemplate(questId); -    if (quest) +    if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))      { -        if (!_player->CanSeeStartQuest(quest) && _player->GetQuestStatus(questId)==QUEST_STATUS_NONE) +        if (!_player->CanSeeStartQuest(quest) && _player->GetQuestStatus(questId) == QUEST_STATUS_NONE)          {              sLog->outError("Possible hacking attempt: Player %s [playerGuid: %u] tried to complete questId [entry: %u] without being in possession of the questId!",                            _player->GetName(), _player->GetGUIDLow(), questId); diff --git a/src/server/game/Handlers/SpellHandler.cpp b/src/server/game/Handlers/SpellHandler.cpp index c56d86d11db..5823a38fb42 100755 --- a/src/server/game/Handlers/SpellHandler.cpp +++ b/src/server/game/Handlers/SpellHandler.cpp @@ -100,7 +100,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)          return;      } -    sLog->outDetail("WORLD: CMSG_USE_ITEM packet, bagIndex: %u, slot: %u, castCount: %u, spellId: %u, Item: %u, glyphIndex: %u, data length = %i", bagIndex, slot, castCount, spellId, pItem->GetEntry(), glyphIndex, (uint32)recvPacket.size()); +    sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_USE_ITEM packet, bagIndex: %u, slot: %u, castCount: %u, spellId: %u, Item: %u, glyphIndex: %u, data length = %i", bagIndex, slot, castCount, spellId, pItem->GetEntry(), glyphIndex, (uint32)recvPacket.size());      ItemTemplate const* proto = pItem->GetTemplate();      if (!proto) @@ -176,7 +176,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)  void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket)  { -    sLog->outDetail("WORLD: CMSG_OPEN_ITEM packet, data length = %i", (uint32)recvPacket.size()); +    sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_OPEN_ITEM packet, data length = %i", (uint32)recvPacket.size());      Player* pUser = _player; @@ -669,13 +669,16 @@ void WorldSession::HandleUpdateProjectilePosition(WorldPacket& recvPacket)      recvPacket >> z;      Unit* caster = ObjectAccessor::GetUnit(*_player, casterGuid); -    Spell* spell = caster ? caster->FindCurrentSpellBySpellId(spellId) : NULL; -    if (spell && spell->m_targets.HasDst()) -    { -        Position pos = *spell->m_targets.GetDstPos(); -        pos.Relocate(x, y, z); -        spell->m_targets.ModDst(pos); -    } +    if (!caster) +        return; + +    Spell* spell = caster->FindCurrentSpellBySpellId(spellId); +    if (!spell || !spell->m_targets.HasDst()) +        return; + +    Position pos = *spell->m_targets.GetDstPos(); +    pos.Relocate(x, y, z); +    spell->m_targets.ModDst(pos);      WorldPacket data(SMSG_SET_PROJECTILE_POSITION, 21);      data << uint64(casterGuid); @@ -683,5 +686,5 @@ void WorldSession::HandleUpdateProjectilePosition(WorldPacket& recvPacket)      data << float(x);      data << float(y);      data << float(z); -    SendPacket(&data); +    caster->SendMessageToSet(&data, true);  } diff --git a/src/server/game/Instances/InstanceSaveMgr.cpp b/src/server/game/Instances/InstanceSaveMgr.cpp index 8078a91d082..59bb86cb68e 100755 --- a/src/server/game/Instances/InstanceSaveMgr.cpp +++ b/src/server/game/Instances/InstanceSaveMgr.cpp @@ -543,7 +543,10 @@ void InstanceSaveManager::_ResetInstance(uint32 mapid, uint32 instanceId)      if (iMap && iMap->IsDungeon())          ((InstanceMap*)iMap)->Reset(INSTANCE_RESET_RESPAWN_DELAY); -    sObjectMgr->DeleteRespawnTimeForInstance(instanceId);   // even if map is not loaded +    if (iMap) +        iMap->DeleteRespawnTimes(); +    else +        Map::DeleteRespawnTimesInDB(mapid, instanceId);      // Free up the instance id and allow it to be reused      sMapMgr->FreeInstanceId(instanceId); diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp index 2100eb26346..24338d5f0ad 100755 --- a/src/server/game/Loot/LootMgr.cpp +++ b/src/server/game/Loot/LootMgr.cpp @@ -356,18 +356,14 @@ bool LootItem::AllowedForPlayer(Player const* player) const      if ((pProto->Flags2 & ITEM_FLAGS_EXTRA_ALLIANCE_ONLY) && player->GetTeam() != ALLIANCE)          return false; -    if (needs_quest) -    { -        // Checking quests for quest-only drop (check only quests requirements in this case) -        if (!player->HasQuestForItem(itemid)) -            return false; -    } -    else -    { -        // Not quest only drop (check quest starting items for already accepted non-repeatable quests) -        if (pProto->StartQuest && player->GetQuestStatus(pProto->StartQuest) != QUEST_STATUS_NONE && !player->HasQuestForItem(itemid)) -            return false; -    } +    // check quest requirements +    if (!(pProto->FlagsCu & ITEM_FLAGS_CU_IGNORE_QUEST_STATUS) && ((needs_quest || (pProto->StartQuest && player->GetQuestStatus(pProto->StartQuest) != QUEST_STATUS_NONE)) && !player->HasQuestForItem(itemid))) +        if (Group const* group = player->GetGroup()) +        { +            if (pProto->Flags & ITEM_PROTO_FLAG_PARTY_LOOT || ((pProto->Flags & ITEM_PROTO_FLAG_PARTY_LOOT) == 0 && (group->GetLootMethod() != MASTER_LOOT || group->GetLooterGuid() != player->GetGUID()))) +                return false; +        } +        else return false;      return true;  } @@ -483,7 +479,7 @@ void Loot::FillNotNormalLootFor(Player* player, bool presentAtLooting)          if (!item->is_looted && item->freeforall && item->AllowedForPlayer(player))              if (ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item->itemid)) -                if (proto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS) +                if (proto->IsCurrencyToken())                      player->StoreLootItem(i, this);      }  } @@ -899,6 +895,7 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv)      }      LootSlotType slotType = lv.permission == OWNER_PERMISSION ? LOOT_SLOT_TYPE_OWNER : LOOT_SLOT_TYPE_ALLOW_LOOT; +    LootSlotType partySlotType = lv.permission == MASTER_PERMISSION ? LOOT_SLOT_TYPE_MASTER : (lv.permission == GROUP_PERMISSION ? LOOT_SLOT_TYPE_ROLL_ONGOING : slotType);      QuestItemMap const& lootPlayerQuestItems = l.GetPlayerQuestItems();      QuestItemMap::const_iterator q_itr = lootPlayerQuestItems.find(lv.viewer->GetGUIDLow());      if (q_itr != lootPlayerQuestItems.end()) @@ -911,7 +908,10 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv)              {                  b << uint8(l.items.size() + (qi - q_list->begin()));                  b << item; -                b << uint8(slotType); +                if (!item.freeforall) +                    b << uint8(partySlotType); +                else +                    b << uint8(slotType);                  ++itemsShown;              }          } @@ -929,7 +929,10 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv)              {                  b << uint8(fi->index);                  b << item; -                b << uint8(slotType); +                if (!item.freeforall) +                    b << uint8(partySlotType); +                else +                    b << uint8(slotType);                  ++itemsShown;              }          } @@ -947,7 +950,10 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv)              {                  b << uint8(ci->index);                  b << item; -                b << uint8(slotType); +                if (!item.freeforall) +                    b << uint8(partySlotType); +                else +                    b << uint8(slotType);                  ++itemsShown;              }          } diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 073ceae5b62..8df8feb6cac 100755 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -1230,7 +1230,7 @@ bool GridMap::loadLiquidData(FILE* in, uint32 offset, uint32 /*size*/)      return true;  } -uint16 GridMap::getArea(float x, float y) +uint16 GridMap::getArea(float x, float y) const  {      if (!_areaMap)          return _gridArea; @@ -1463,7 +1463,7 @@ float GridMap::getHeightFromUint16(float x, float y) const      return (float)((a * x) + (b * y) + c)*_gridIntHeightMultiplier + _gridHeight;  } -float GridMap::getLiquidLevel(float x, float y) +float GridMap::getLiquidLevel(float x, float y) const  {      if (!_liquidMap)          return _liquidLevel; @@ -1483,7 +1483,7 @@ float GridMap::getLiquidLevel(float x, float y)  }  // Why does this return LIQUID data? -uint8 GridMap::getTerrainType(float x, float y) +uint8 GridMap::getTerrainType(float x, float y) const  {      if (!_liquidFlags)          return 0; @@ -2633,7 +2633,7 @@ void InstanceMap::UnloadAll()      ASSERT(!HavePlayers());      if (m_resetAfterUnload == true) -        sObjectMgr->DeleteRespawnTimeForInstance(GetInstanceId()); +        DeleteRespawnTimes();      Map::UnloadAll();  } @@ -2782,3 +2782,134 @@ void Map::UpdateIteratorBack(Player* player)      if (m_mapRefIter == player->GetMapRef())          m_mapRefIter = m_mapRefIter->nocheck_prev();  } + +void Map::SaveCreatureRespawnTime(uint32 dbGuid, time_t respawnTime) +{ +    if (!respawnTime) +    { +        // Delete only +        RemoveCreatureRespawnTime(dbGuid); +        return; +    } + +    _creatureRespawnTimes[dbGuid] = respawnTime; + +    PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_CREATURE_RESPAWN); +    stmt->setUInt32(0, dbGuid); +    stmt->setUInt32(1, uint32(respawnTime)); +    stmt->setUInt16(2, GetId()); +    stmt->setUInt32(3, GetInstanceId()); +    CharacterDatabase.Execute(stmt); +} + +void Map::RemoveCreatureRespawnTime(uint32 dbGuid) +{ +    _creatureRespawnTimes.erase(dbGuid); + +    PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CREATURE_RESPAWN); +    stmt->setUInt32(0, dbGuid); +    stmt->setUInt16(1, GetId()); +    stmt->setUInt32(2, GetInstanceId()); +    CharacterDatabase.Execute(stmt); +} + +void Map::SaveGORespawnTime(uint32 dbGuid, time_t respawnTime) +{ +    if (!respawnTime) +    { +        // Delete only +        RemoveGORespawnTime(dbGuid); +        return; +    } + +    _goRespawnTimes[dbGuid] = respawnTime; + +    PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_GO_RESPAWN); +    stmt->setUInt32(0, dbGuid); +    stmt->setUInt32(1, uint32(respawnTime)); +    stmt->setUInt16(2, GetId()); +    stmt->setUInt32(3, GetInstanceId()); +    CharacterDatabase.Execute(stmt); +} + +void Map::RemoveGORespawnTime(uint32 dbGuid) +{ +    _goRespawnTimes.erase(dbGuid); + +    PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GO_RESPAWN); +    stmt->setUInt32(0, dbGuid); +    stmt->setUInt16(1, GetId()); +    stmt->setUInt32(2, GetInstanceId()); +    CharacterDatabase.Execute(stmt); +} + +void Map::LoadRespawnTimes() +{ +    PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CREATURE_RESPAWNS); +    stmt->setUInt16(0, GetId()); +    stmt->setUInt32(1, GetInstanceId()); +    if (PreparedQueryResult result = CharacterDatabase.Query(stmt)) +    { +        do +        { +            Field* fields = result->Fetch(); +            uint32 loguid      = fields[0].GetUInt32(); +            uint32 respawnTime = fields[1].GetUInt32(); + +            _creatureRespawnTimes[loguid] = time_t(respawnTime); +        } while (result->NextRow()); +    } + +    stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GO_RESPAWNS); +    stmt->setUInt16(0, GetId()); +    stmt->setUInt32(1, GetInstanceId()); +    if (PreparedQueryResult result = CharacterDatabase.Query(stmt)) +    { +        do +        { +            Field* fields = result->Fetch(); +            uint32 loguid      = fields[0].GetUInt32(); +            uint32 respawnTime = fields[1].GetUInt32(); + +            _goRespawnTimes[loguid] = time_t(respawnTime); +        } while (result->NextRow()); +    } +} + +void Map::DeleteRespawnTimes() +{ +    _creatureRespawnTimes.clear(); +    _goRespawnTimes.clear(); + +    DeleteRespawnTimesInDB(GetId(), GetInstanceId()); +} + +void Map::DeleteRespawnTimesInDB(uint16 mapId, uint32 instanceId) +{ +    PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CREATURE_RESPAWN_BY_INSTANCE); +    stmt->setUInt16(0, mapId); +    stmt->setUInt32(1, instanceId); +    CharacterDatabase.Execute(stmt); + +    stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GO_RESPAWN_BY_INSTANCE); +    stmt->setUInt16(0, mapId); +    stmt->setUInt32(1, instanceId); +    CharacterDatabase.Execute(stmt); +} + +time_t Map::GetLinkedRespawnTime(uint64 guid) const +{ +    uint64 linkedGuid = sObjectMgr->GetLinkedRespawnGuid(guid); +    switch (GUID_HIPART(linkedGuid)) +    { +        case HIGHGUID_UNIT: +            return GetCreatureRespawnTime(GUID_LOPART(linkedGuid)); +        case HIGHGUID_GAMEOBJECT: +            return GetGORespawnTime(GUID_LOPART(linkedGuid)); +        default: +            break; +    } + +    return time_t(0); +} + diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index 6ba08646f25..6d526f23a94 100755 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -193,10 +193,10 @@ public:      bool loadData(char* filaname);      void unloadData(); -    uint16 getArea(float x, float y); -    inline float getHeight(float x, float y) {return (this->*_gridGetHeight)(x, y);} -    float getLiquidLevel(float x, float y); -    uint8 getTerrainType(float x, float y); +    uint16 getArea(float x, float y) const; +    inline float getHeight(float x, float y) const {return (this->*_gridGetHeight)(x, y);} +    float getLiquidLevel(float x, float y) const; +    uint8 getTerrainType(float x, float y) const;      ZLiquidStatus getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData* data = 0);  }; @@ -443,6 +443,38 @@ class Map : public GridRefManager<NGridType>          void Insert(const GameObjectModel& mdl) { _dynamicTree.insert(mdl); }          bool Contains(const GameObjectModel& mdl) const { return _dynamicTree.contains(mdl);}          bool getObjectHitPos(uint32 phasemask, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float &ry, float& rz, float modifyDist); + +        /* +            RESPAWN TIMES +        */ +        time_t GetLinkedRespawnTime(uint64 guid) const; +        time_t GetCreatureRespawnTime(uint32 dbGuid) const +        { +            UNORDERED_MAP<uint32 /*dbGUID*/, time_t>::const_iterator itr = _creatureRespawnTimes.find(dbGuid); +            if (itr != _creatureRespawnTimes.end()) +                return itr->second; + +            return time_t(0); +        } + +        time_t GetGORespawnTime(uint32 dbGuid) const +        { +            UNORDERED_MAP<uint32 /*dbGUID*/, time_t>::const_iterator itr = _goRespawnTimes.find(dbGuid); +            if (itr != _goRespawnTimes.end()) +                return itr->second; + +            return time_t(0); +        } + +        void SaveCreatureRespawnTime(uint32 dbGuid, time_t respawnTime); +        void RemoveCreatureRespawnTime(uint32 dbGuid); +        void SaveGORespawnTime(uint32 dbGuid, time_t respawnTime); +        void RemoveGORespawnTime(uint32 dbGuid); +        void LoadRespawnTimes(); +        void DeleteRespawnTimes(); + +        static void DeleteRespawnTimesInDB(uint16 mapId, uint32 instanceId); +      private:          void LoadMapAndVMap(int gx, int gy);          void LoadVMap(int gx, int gy); @@ -488,6 +520,7 @@ class Map : public GridRefManager<NGridType>          void ScriptsProcess();          void UpdateActiveCells(const float &x, const float &y, const uint32 t_diff); +      protected:          void SetUnloadReferenceLock(const GridCoord &p, bool on) { getNGrid(p.x_coord, p.y_coord)->setUnloadReferenceLock(on); } @@ -570,6 +603,9 @@ class Map : public GridRefManager<NGridType>              else                  m_activeNonPlayers.erase(obj);          } + +        UNORDERED_MAP<uint32 /*dbGUID*/, time_t> _creatureRespawnTimes; +        UNORDERED_MAP<uint32 /*dbGUID*/, time_t> _goRespawnTimes;  };  enum InstanceResetMethod diff --git a/src/server/game/Maps/MapInstanced.cpp b/src/server/game/Maps/MapInstanced.cpp index 5543251e115..2c1bdb00834 100755 --- a/src/server/game/Maps/MapInstanced.cpp +++ b/src/server/game/Maps/MapInstanced.cpp @@ -211,6 +211,8 @@ InstanceMap* MapInstanced::CreateInstance(uint32 InstanceId, InstanceSave* save,      InstanceMap* map = new InstanceMap(GetId(), GetGridExpiry(), InstanceId, difficulty, this);      ASSERT(map->IsDungeon()); +    map->LoadRespawnTimes(); +      bool load_data = save != NULL;      map->CreateInstanceData(load_data); diff --git a/src/server/game/Maps/MapManager.cpp b/src/server/game/Maps/MapManager.cpp index ce93fe5af1a..8736c8b3782 100755 --- a/src/server/game/Maps/MapManager.cpp +++ b/src/server/game/Maps/MapManager.cpp @@ -110,6 +110,7 @@ Map* MapManager::CreateBaseMap(uint32 id)          else          {              map = new Map(id, i_gridCleanUpDelay, 0, REGULAR_DIFFICULTY); +            map->LoadRespawnTimes();          }          i_maps[id] = map;      } diff --git a/src/server/game/Maps/MapManager.h b/src/server/game/Maps/MapManager.h index 1049325237a..aa07eef2204 100755 --- a/src/server/game/Maps/MapManager.h +++ b/src/server/game/Maps/MapManager.h @@ -71,7 +71,7 @@ class MapManager          void SetMapUpdateInterval(uint32 t)          { -            if (t > MIN_MAP_UPDATE_DELAY) +            if (t < MIN_MAP_UPDATE_DELAY)                  t = MIN_MAP_UPDATE_DELAY;              i_timer.SetInterval(t); @@ -143,7 +143,7 @@ class MapManager          void RegisterInstanceId(uint32 instanceId);          void FreeInstanceId(uint32 instanceId); -        uint32 GetNextInstanceId() { return _nextInstanceId; }; +        uint32 GetNextInstanceId() const { return _nextInstanceId; };          void SetNextInstanceId(uint32 nextInstanceId) { _nextInstanceId = nextInstanceId; };          MapUpdater * GetMapUpdater() { return &m_updater; } diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index 7b77ecaa17e..7d12f94d155 100755 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -3279,8 +3279,6 @@ enum SummonType  enum EventId  { -    EVENT_SPELLCLICK        = 1001, -    EVENT_FALL_GROUND       = 1002,      EVENT_CHARGE            = 1003,  }; diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp index c0e1eb842ae..bc0570bb73b 100755 --- a/src/server/game/Movement/MotionMaster.cpp +++ b/src/server/game/Movement/MotionMaster.cpp @@ -298,7 +298,7 @@ void MotionMaster::MovePoint(uint32 id, float x, float y, float z)      }  } -void MotionMaster::MoveLand(uint32 id, Position const& pos, float speed) +void MotionMaster::MoveLand(uint32 id, Position const& pos)  {      float x, y, z;      pos.GetPosition(x, y, z); @@ -307,13 +307,12 @@ void MotionMaster::MoveLand(uint32 id, Position const& pos, float speed)      Movement::MoveSplineInit init(*_owner);      init.MoveTo(x,y,z); -    init.SetVelocity(speed);      init.SetAnimation(Movement::ToGround);      init.Launch();      Mutate(new EffectMovementGenerator(id), MOTION_SLOT_ACTIVE);  } -void MotionMaster::MoveTakeoff(uint32 id, Position const& pos, float speed) +void MotionMaster::MoveTakeoff(uint32 id, Position const& pos)  {      float x, y, z;      pos.GetPosition(x, y, z); @@ -322,7 +321,6 @@ void MotionMaster::MoveTakeoff(uint32 id, Position const& pos, float speed)      Movement::MoveSplineInit init(*_owner);      init.MoveTo(x,y,z); -    init.SetVelocity(speed);      init.SetAnimation(Movement::ToFly);      init.Launch();      Mutate(new EffectMovementGenerator(id), MOTION_SLOT_ACTIVE); diff --git a/src/server/game/Movement/MotionMaster.h b/src/server/game/Movement/MotionMaster.h index d6144bfcc3a..727f626cdea 100755 --- a/src/server/game/Movement/MotionMaster.h +++ b/src/server/game/Movement/MotionMaster.h @@ -157,8 +157,8 @@ class MotionMaster //: private std::stack<MovementGenerator *>          void MovePoint(uint32 id, float x, float y, float z);          // These two movement types should only be used with creatures having landing/takeoff animations -        void MoveLand(uint32 id, Position const& pos, float speed); -        void MoveTakeoff(uint32 id, Position const& pos, float speed); +        void MoveLand(uint32 id, Position const& pos); +        void MoveTakeoff(uint32 id, Position const& pos);          void MoveCharge(float x, float y, float z, float speed = SPEED_CHARGE, uint32 id = EVENT_CHARGE);          void MoveKnockbackFrom(float srcX, float srcY, float speedXY, float speedZ); diff --git a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp index a922c937b5f..07a5761517e 100755 --- a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp @@ -33,6 +33,7 @@ void PointMovementGenerator<T>::Initialize(T &unit)          unit.StopMoving();      unit.AddUnitState(UNIT_STATE_ROAMING|UNIT_STATE_ROAMING_MOVE); +    i_recalculateSpeed = false;      Movement::MoveSplineInit init(unit);      init.MoveTo(i_x, i_y, i_z);      if (speed > 0.0f) @@ -53,6 +54,17 @@ bool PointMovementGenerator<T>::Update(T &unit, const uint32 & /*diff*/)      }      unit.AddUnitState(UNIT_STATE_ROAMING_MOVE); + +    if (i_recalculateSpeed && !unit.movespline->Finalized()) +    { +        i_recalculateSpeed = false; +        Movement::MoveSplineInit init(unit); +        init.MoveTo(i_x, i_y, i_z); +        if (speed > 0.0f) // Default value for point motion type is 0.0, if 0.0 spline will use GetSpeed on unit +            init.SetVelocity(speed); +        init.Launch(); +    } +      return !unit.movespline->Finalized();  } @@ -81,11 +93,6 @@ void PointMovementGenerator<T>::MovementInform(T & /*unit*/)  template <> void PointMovementGenerator<Creature>::MovementInform(Creature &unit)  { -    //if (id == EVENT_FALL_GROUND) -    //{ -    //    unit.setDeathState(JUST_DIED); -    //    unit.SetFlying(true); -    //}      if (unit.AI())          unit.AI()->MovementInform(POINT_MOTION_TYPE, id);  } diff --git a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h index 13be9fee77b..d2833a5ee10 100755 --- a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h @@ -36,6 +36,8 @@ class PointMovementGenerator : public MovementGeneratorMedium< T, PointMovementG          void MovementInform(T &); +        void unitSpeedChanged() { i_recalculateSpeed = true; } +          MovementGeneratorType GetMovementGeneratorType() { return POINT_MOTION_TYPE; }          bool GetDestination(float& x, float& y, float& z) const { x=i_x; y=i_y; z=i_z; return true; } @@ -43,6 +45,7 @@ class PointMovementGenerator : public MovementGeneratorMedium< T, PointMovementG          uint32 id;          float i_x, i_y, i_z;          float speed; +        bool i_recalculateSpeed;  };  class AssistanceMovementGenerator : public PointMovementGenerator<Creature> diff --git a/src/server/game/Movement/Spline/MoveSpline.cpp b/src/server/game/Movement/Spline/MoveSpline.cpp index 91b4ff08250..b1c25aedfd7 100644 --- a/src/server/game/Movement/Spline/MoveSpline.cpp +++ b/src/server/game/Movement/Spline/MoveSpline.cpp @@ -203,7 +203,7 @@ bool MoveSplineInitArgs::Validate() const          return false;\      }      CHECK(path.size() > 1); -    CHECK(velocity > 0.f); +    CHECK(velocity > 0.1f);      CHECK(time_perc >= 0.f && time_perc <= 1.f);      //CHECK(_checkPathBounds());      return true; diff --git a/src/server/game/Movement/Spline/MoveSplineFlag.h b/src/server/game/Movement/Spline/MoveSplineFlag.h index 33973064e09..cfc2fdee450 100644 --- a/src/server/game/Movement/Spline/MoveSplineFlag.h +++ b/src/server/game/Movement/Spline/MoveSplineFlag.h @@ -34,43 +34,43 @@ namespace Movement      {      public:          enum eFlags{ -            None         = 0x00000000, -                                                 // x00-xFF(first byte) used as animation Ids storage in pair with Animation flag -            Done         = 0x00000100, -            Falling      = 0x00000200,           // Affects elevation computation, can't be combined with Parabolic flag -            No_Spline    = 0x00000400, -            Parabolic    = 0x00000800,           // Affects elevation computation, can't be combined with Falling flag -            Walkmode     = 0x00001000, -            Flying       = 0x00002000,           // Smooth movement(Catmullrom interpolation mode), flying animation -            OrientationFixed = 0x00004000,       // Model orientation fixed -            Final_Point  = 0x00008000, -            Final_Target = 0x00010000, -            Final_Angle  = 0x00020000, -            Catmullrom   = 0x00040000,           // Used Catmullrom interpolation mode -            Cyclic       = 0x00080000,           // Movement by cycled spline -            Enter_Cycle  = 0x00100000,           // Everytimes appears with cyclic flag in monster move packet, erases first spline vertex after first cycle done -            Animation    = 0x00200000,           // Plays animation after some time passed -            Frozen       = 0x00400000,           // Will never arrive -            Unknown5     = 0x00800000, -            Unknown6     = 0x01000000, -            Unknown7     = 0x02000000, -            Unknown8     = 0x04000000, +            None                = 0x00000000, +                                                        // x00-xFF(first byte) used as animation Ids storage in pair with Animation flag +            Done                = 0x00000100, +            Falling             = 0x00000200,           // Affects elevation computation, can't be combined with Parabolic flag +            No_Spline           = 0x00000400, +            Parabolic           = 0x00000800,           // Affects elevation computation, can't be combined with Falling flag +            Walkmode            = 0x00001000, +            Flying              = 0x00002000,           // Smooth movement(Catmullrom interpolation mode), flying animation +            OrientationFixed    = 0x00004000,           // Model orientation fixed +            Final_Point         = 0x00008000, +            Final_Target        = 0x00010000, +            Final_Angle         = 0x00020000, +            Catmullrom          = 0x00040000,           // Used Catmullrom interpolation mode +            Cyclic              = 0x00080000,           // Movement by cycled spline +            Enter_Cycle         = 0x00100000,           // Everytimes appears with cyclic flag in monster move packet, erases first spline vertex after first cycle done +            Animation           = 0x00200000,           // Plays animation after some time passed +            Frozen              = 0x00400000,           // Will never arrive +            TransportEnter      = 0x00800000, +            TransportExit       = 0x01000000, +            Unknown7            = 0x02000000, +            Unknown8            = 0x04000000,              OrientationInversed = 0x08000000, -            Unknown10    = 0x10000000, -            Unknown11    = 0x20000000, -            Unknown12    = 0x40000000, -            Unknown13    = 0x80000000, +            Unknown10           = 0x10000000, +            Unknown11           = 0x20000000, +            Unknown12           = 0x40000000, +            Unknown13           = 0x80000000,              // Masks -            Mask_Final_Facing = Final_Point | Final_Target | Final_Angle, +            Mask_Final_Facing   = Final_Point | Final_Target | Final_Angle,              // animation ids stored here, see AnimType enum, used with Animation flag -            Mask_Animations = 0xFF, +            Mask_Animations     = 0xFF,              // flags that shouldn't be appended into SMSG_MONSTER_MOVE\SMSG_MONSTER_MOVE_TRANSPORT packet, should be more probably              Mask_No_Monster_Move = Mask_Final_Facing | Mask_Animations | Done,              // CatmullRom interpolation mode used -            Mask_CatmullRom = Flying | Catmullrom, +            Mask_CatmullRom     = Flying | Catmullrom,              // Unused, not suported flags -            Mask_Unused = No_Spline|Enter_Cycle|Frozen|Unknown5|Unknown6|Unknown7|Unknown8|Unknown10|Unknown11|Unknown12|Unknown13, +            Mask_Unused         = No_Spline|Enter_Cycle|Frozen|Unknown7|Unknown8|Unknown10|Unknown11|Unknown12|Unknown13,          };          inline uint32& raw() { return (uint32&)*this;} @@ -98,14 +98,16 @@ namespace Movement          void operator &= (uint32 f) { raw() &= f;}          void operator |= (uint32 f) { raw() |= f;} -        void EnableAnimation(uint8 anim) { raw() = (raw() & ~(Mask_Animations|Falling|Parabolic)) | Animation|anim;} -        void EnableParabolic() { raw() = (raw() & ~(Mask_Animations|Falling|Animation)) | Parabolic;} -        void EnableFalling() { raw() = (raw() & ~(Mask_Animations|Parabolic|Animation)) | Falling;} +        void EnableAnimation(uint8 anim) { raw() = (raw() & ~(Mask_Animations | Falling | Parabolic)) | Animation | anim; } +        void EnableParabolic() { raw() = (raw() & ~(Mask_Animations | Falling | Animation)) | Parabolic; } +        void EnableFalling() { raw() = (raw() & ~(Mask_Animations | Parabolic | Animation)) | Falling; }          void EnableFlying() { raw() = (raw() & ~Catmullrom) | Flying; }          void EnableCatmullRom() { raw() = (raw() & ~Flying) | Catmullrom; } -        void EnableFacingPoint() { raw() = (raw() & ~Mask_Final_Facing) | Final_Point;} -        void EnableFacingAngle() { raw() = (raw() & ~Mask_Final_Facing) | Final_Angle;} -        void EnableFacingTarget() { raw() = (raw() & ~Mask_Final_Facing) | Final_Target;} +        void EnableFacingPoint() { raw() = (raw() & ~Mask_Final_Facing) | Final_Point; } +        void EnableFacingAngle() { raw() = (raw() & ~Mask_Final_Facing) | Final_Angle; } +        void EnableFacingTarget() { raw() = (raw() & ~Mask_Final_Facing) | Final_Target; } +        void EnableTransportEnter() { raw() = (raw() & ~TransportExit) | TransportEnter; } +        void EnableTransportExit() { raw() = (raw() & ~TransportEnter) | TransportExit; }          uint8 animId       : 8;          bool done          : 1; @@ -123,8 +125,8 @@ namespace Movement          bool enter_cycle   : 1;          bool animation     : 1;          bool frozen        : 1; -        bool unknown5      : 1; -        bool unknown6      : 1; +        bool transportEnter: 1; +        bool transportExit : 1;          bool unknown7      : 1;          bool unknown8      : 1;          bool orientationInversed : 1; diff --git a/src/server/game/Movement/Spline/MoveSplineInit.cpp b/src/server/game/Movement/Spline/MoveSplineInit.cpp index e586cb4f4f9..c539dd3cc39 100644 --- a/src/server/game/Movement/Spline/MoveSplineInit.cpp +++ b/src/server/game/Movement/Spline/MoveSplineInit.cpp @@ -20,6 +20,8 @@  #include "MoveSpline.h"  #include "MovementPacketBuilder.h"  #include "Unit.h" +#include "Transport.h" +#include "Vehicle.h"  namespace Movement  { @@ -58,17 +60,26 @@ namespace Movement      {          MoveSpline& move_spline = *unit.movespline; -        Location real_position(unit.GetPositionX(),unit.GetPositionY(),unit.GetPositionZMinusOffset(),unit.GetOrientation()); -        // there is a big chane that current position is unknown if current state is not finalized, need compute it +        bool transport = false; +        Location real_position(unit.GetPositionX(), unit.GetPositionY(), unit.GetPositionZMinusOffset(), unit.GetOrientation()); +        // Elevators also use MOVEMENTFLAG_ONTRANSPORT but we do not keep track of their position changes +        if (unit.HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && unit.GetTransGUID()) +        { +            transport = true; +            real_position.x = unit.GetTransOffsetX(); +            real_position.y = unit.GetTransOffsetY(); +            real_position.z = unit.GetTransOffsetZ(); +            real_position.orientation = unit.GetTransOffsetO(); +        } + +        // there is a big chance that current position is unknown if current state is not finalized, need compute it          // this also allows calculate spline position and update map position in much greater intervals          if (!move_spline.Finalized())              real_position = move_spline.ComputePosition(); +        // should i do the things that user should do? - no.          if (args.path.empty()) -        { -            // should i do the things that user should do? -            MoveTo(real_position); -        } +            return;          // corrent first vertex          args.path[0] = real_position; @@ -82,7 +93,7 @@ namespace Movement          moveFlags |= (MOVEMENTFLAG_SPLINE_ENABLED|MOVEMENTFLAG_FORWARD); -        if (args.velocity == 0.f) +        if (!args.HasVelocity)              args.velocity = unit.GetSpeed(SelectSpeedType(moveFlags));          if (!args.Validate()) @@ -94,14 +105,22 @@ namespace Movement          unit.m_movementInfo.SetMovementFlags((MovementFlags)moveFlags);          move_spline.Initialize(args); -        WorldPacket data(SMSG_MONSTER_MOVE, 64); +        WorldPacket data(!transport ? SMSG_MONSTER_MOVE : SMSG_MONSTER_MOVE_TRANSPORT, 64);          data.append(unit.GetPackGUID()); +        if (transport) +        { +            data.appendPackGUID(unit.GetTransGUID()); +            data << int8(unit.GetTransSeat()); +        } +          PacketBuilder::WriteMonsterMove(move_spline, data);          unit.SendMessageToSet(&data,true);      }      MoveSplineInit::MoveSplineInit(Unit& m) : unit(m)      { +        // Elevators also use MOVEMENTFLAG_ONTRANSPORT but we do not keep track of their position changes +        args.TransformForTransport = unit.HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && unit.GetTransGUID();          // mix existing state into new          args.flags.walkmode = unit.m_movementInfo.HasMovementFlag(MOVEMENTFLAG_WALKING);          args.flags.flying = unit.m_movementInfo.HasMovementFlag((MovementFlags)(MOVEMENTFLAG_CAN_FLY|MOVEMENTFLAG_DISABLE_GRAVITY)); @@ -110,13 +129,48 @@ namespace Movement      void MoveSplineInit::SetFacing(const Unit * target)      {          args.flags.EnableFacingTarget(); -        //args.facing.target = target->GetObjectGuid().GetRawValue(); -        args.facing.target = target->GetUInt64Value(OBJECT_FIELD_GUID); +        args.facing.target = target->GetGUID();      }      void MoveSplineInit::SetFacing(float angle)      { +        if (args.TransformForTransport) +        { +            if (Unit* vehicle = unit.GetVehicleBase()) +                angle -= vehicle->GetOrientation(); +            else if (Transport* transport = unit.GetTransport()) +                angle -= transport->GetOrientation(); +        } +          args.facing.angle = G3D::wrap(angle, 0.f, (float)G3D::twoPi());          args.flags.EnableFacingAngle();      } + +    void MoveSplineInit::MoveTo(Vector3 const& dest) +    { +        args.path_Idx_offset = 0; +        args.path.resize(2); +        TransportPathTransform transform(unit, args.TransformForTransport); +        args.path[1] = transform(dest); +    } + +    Vector3 TransportPathTransform::operator()(Vector3 input) +    { +        if (_transformForTransport) +        { +            if (Unit* vehicle = _owner.GetVehicleBase()) +            { +                input.x -= vehicle->GetPositionX(); +                input.y -= vehicle->GetPositionY(); +                input.z -= vehicle->GetPositionZMinusOffset(); +            } +            else if (Transport* transport = _owner.GetTransport()) +            { +                float unused = 0.0f; +                transport->CalculatePassengerOffset(input.x, input.y, input.z, unused); +            } +        } + +        return input; +    }  } diff --git a/src/server/game/Movement/Spline/MoveSplineInit.h b/src/server/game/Movement/Spline/MoveSplineInit.h index 7ef6cd7a120..ef847809ac8 100644 --- a/src/server/game/Movement/Spline/MoveSplineInit.h +++ b/src/server/game/Movement/Spline/MoveSplineInit.h @@ -33,6 +33,19 @@ namespace Movement          FlyToGround = 3, // 463 = FlyToGround      }; +    // Transforms coordinates from global to transport offsets +    class TransportPathTransform +    { +    public: +        TransportPathTransform(Unit& owner, bool transformForTransport) +            : _owner(owner), _transformForTransport(transformForTransport) { } +        Vector3 operator()(Vector3 input); + +    private: +        Unit& _owner; +        bool _transformForTransport; +    }; +      /*  Initializes and launches spline movement       */      class MoveSplineInit @@ -96,6 +109,12 @@ namespace Movement          /* Enables falling mode. Disabled by default           */          void SetFall(); +        /* Enters transport. Disabled by default +         */ +        void SetTransportEnter(); +        /* Exits transport. Disabled by default +         */ +        void SetTransportExit();          /* Inverses unit model orientation. Disabled by default           */          void SetOrientationInversed(); @@ -112,40 +131,39 @@ namespace Movement          PointsArray& Path() { return args.path; } +        /* Disables transport coordinate transformations for cases where raw offsets are available +        */ +        void DisableTransportPathTransformations();      protected:          MoveSplineInitArgs args;          Unit&  unit;      }; -    inline void MoveSplineInit::SetFly() { args.flags.EnableFlying();} +    inline void MoveSplineInit::SetFly() { args.flags.EnableFlying(); }      inline void MoveSplineInit::SetWalk(bool enable) { args.flags.walkmode = enable;}      inline void MoveSplineInit::SetSmooth() { args.flags.EnableCatmullRom();}      inline void MoveSplineInit::SetCyclic() { args.flags.cyclic = true;}      inline void MoveSplineInit::SetFall() { args.flags.EnableFalling();} -    inline void MoveSplineInit::SetVelocity(float vel){  args.velocity = vel;} +    inline void MoveSplineInit::SetVelocity(float vel) { args.velocity = vel; args.HasVelocity = true; }      inline void MoveSplineInit::SetOrientationInversed() { args.flags.orientationInversed = true;} +    inline void MoveSplineInit::SetTransportEnter() { args.flags.EnableTransportEnter(); } +    inline void MoveSplineInit::SetTransportExit() { args.flags.EnableTransportExit(); }      inline void MoveSplineInit::SetOrientationFixed(bool enable) { args.flags.orientationFixed = enable;}      inline void MoveSplineInit::MovebyPath(const PointsArray& controls, int32 path_offset)      {          args.path_Idx_offset = path_offset; -        args.path.assign(controls.begin(),controls.end()); +        args.path.resize(controls.size()); +        std::transform(controls.begin(), controls.end(), args.path.begin(), TransportPathTransform(unit, args.TransformForTransport));      }      inline void MoveSplineInit::MoveTo(float x, float y, float z)      { -        Vector3 v(x,y,z); +        Vector3 v(x, y, z);          MoveTo(v);      } -    inline void MoveSplineInit::MoveTo(const Vector3& dest) -    { -        args.path_Idx_offset = 0; -        args.path.resize(2); -        args.path[1] = dest; -    } -      inline void MoveSplineInit::SetParabolic(float amplitude, float time_shift)      {          args.time_perc = time_shift; @@ -161,10 +179,14 @@ namespace Movement      inline void MoveSplineInit::SetFacing(Vector3 const& spot)      { -        args.facing.f.x = spot.x; -        args.facing.f.y = spot.y; -        args.facing.f.z = spot.z; +        TransportPathTransform transform(unit, args.TransformForTransport); +        Vector3 finalSpot = transform(spot); +        args.facing.f.x = finalSpot.x; +        args.facing.f.y = finalSpot.y; +        args.facing.f.z = finalSpot.z;          args.flags.EnableFacingPoint();      } + +    inline void MoveSplineInit::DisableTransportPathTransformations() { args.TransformForTransport = false; }  }  #endif // TRINITYSERVER_MOVESPLINEINIT_H diff --git a/src/server/game/Movement/Spline/MoveSplineInitArgs.h b/src/server/game/Movement/Spline/MoveSplineInitArgs.h index 26fbbdd0fcc..de02b35d0a0 100644 --- a/src/server/game/Movement/Spline/MoveSplineInitArgs.h +++ b/src/server/game/Movement/Spline/MoveSplineInitArgs.h @@ -42,7 +42,8 @@ namespace Movement      struct MoveSplineInitArgs      {          MoveSplineInitArgs(size_t path_capacity = 16) : path_Idx_offset(0), -            velocity(0.f), parabolic_amplitude(0.f), time_perc(0.f), splineId(0), initialOrientation(0.f) +            velocity(0.f), parabolic_amplitude(0.f), time_perc(0.f), splineId(0), initialOrientation(0.f), +            HasVelocity(false), TransformForTransport(true)          {              path.reserve(path_capacity);          } @@ -56,6 +57,8 @@ namespace Movement          float time_perc;          uint32 splineId;          float initialOrientation; +        bool HasVelocity; +        bool TransformForTransport;          /** Returns true to show that the arguments were configured correctly and MoveSpline initialization will succeed. */          bool Validate() const; diff --git a/src/server/game/Movement/Spline/MovementPacketBuilder.cpp b/src/server/game/Movement/Spline/MovementPacketBuilder.cpp index 0260767dbe2..8aef671d2d1 100644 --- a/src/server/game/Movement/Spline/MovementPacketBuilder.cpp +++ b/src/server/game/Movement/Spline/MovementPacketBuilder.cpp @@ -44,24 +44,12 @@ namespace Movement      void PacketBuilder::WriteCommonMonsterMovePart(const MoveSpline& move_spline, WorldPacket& data)      {          MoveSplineFlag splineflags = move_spline.splineflags; -        /*if (unit->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT)) -        { -            data.SetOpcode(SMSG_MONSTER_MOVE_TRANSPORT); -            if (unit->GetVehicle()) -                data << unit->GetVehicle()->GetBase()->GetPackGUID(); -            else if (unit->GetTransport()) -                data << unit->GetTransport()->GetPackGUID(); -            else -                data << uint64(0); - -            data << int8(unit->GetTransSeat()); -        }*/ -        data << uint8(0); +        data << uint8(0);                                       // sets/unsets MOVEMENTFLAG2_UNK7 (0x40)          data << move_spline.spline.getPoint(move_spline.spline.first());          data << move_spline.GetId(); -        switch(splineflags & MoveSplineFlag::Mask_Final_Facing) +        switch (splineflags & MoveSplineFlag::Mask_Final_Facing)          {              case MoveSplineFlag::Final_Target:                  data << uint8(MonsterMoveFacingTarget); diff --git a/src/server/game/OutdoorPvP/OutdoorPvP.cpp b/src/server/game/OutdoorPvP/OutdoorPvP.cpp index 465fca75030..dfdd4fc4ffc 100755 --- a/src/server/game/OutdoorPvP/OutdoorPvP.cpp +++ b/src/server/game/OutdoorPvP/OutdoorPvP.cpp @@ -166,8 +166,10 @@ bool OPvPCapturePoint::DelCreature(uint32 type)      //if (Map* map = sMapMgr->FindMap(cr->GetMapId()))      //    map->Remove(cr, false);      // delete respawn time for this creature -    PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CREATURE_RESPAWN_BY_GUID); +    PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CREATURE_RESPAWN);      stmt->setUInt32(0, guid); +    stmt->setUInt16(1, cr->GetMapId()); +    stmt->setUInt32(2, 0);  // instance id, always 0 for world maps      CharacterDatabase.Execute(stmt);      cr->AddObjectToRemoveList(); diff --git a/src/server/game/Quests/QuestDef.cpp b/src/server/game/Quests/QuestDef.cpp index 26f4ad71cda..ff351f90f74 100755 --- a/src/server/game/Quests/QuestDef.cpp +++ b/src/server/game/Quests/QuestDef.cpp @@ -132,16 +132,16 @@ Quest::Quest(Field* questRecord)          ObjectiveText[i] = questRecord[128+i].GetString();      for (int i = 0; i < QUEST_REWARD_CURRENCY_COUNT; ++i) -        RewardCurrencyId[i] = questRecord[132+i].GetUInt32(); +        RewardCurrencyId[i] = questRecord[132+i].GetUInt16();      for (int i = 0; i < QUEST_REWARD_CURRENCY_COUNT; ++i) -        RewardCurrencyCount[i] = questRecord[136+i].GetUInt32(); +        RewardCurrencyCount[i] = questRecord[136+i].GetUInt8();      for (int i = 0; i < QUEST_REQUIRED_CURRENCY_COUNT; ++i) -        RequiredCurrencyId[i] = questRecord[140+i].GetUInt32(); +        RequiredCurrencyId[i] = questRecord[140+i].GetUInt16();      for (int i = 0; i < QUEST_REQUIRED_CURRENCY_COUNT; ++i) -        RequiredCurrencyCount[i] = questRecord[144+i].GetUInt32(); +        RequiredCurrencyCount[i] = questRecord[144+i].GetUInt8();      QuestGiverTextWindow = questRecord[148].GetString();      QuestGiverTargetName = questRecord[149].GetString(); diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp index f64d0953e86..58b9c55cdd1 100755 --- a/src/server/game/Scripting/ScriptLoader.cpp +++ b/src/server/game/Scripting/ScriptLoader.cpp @@ -46,21 +46,27 @@ void AddSC_SmartSCripts();  //Commands  void AddSC_account_commandscript();  void AddSC_achievement_commandscript(); +void AddSC_cast_commandscript();  void AddSC_debug_commandscript();  void AddSC_event_commandscript();  void AddSC_gm_commandscript();  void AddSC_go_commandscript();  void AddSC_gobject_commandscript();  void AddSC_honor_commandscript(); +void AddSC_instance_commandscript();  void AddSC_learn_commandscript(); +void AddSC_list_commandscript();  void AddSC_misc_commandscript();  void AddSC_modify_commandscript();  void AddSC_npc_commandscript();  void AddSC_quest_commandscript();  void AddSC_reload_commandscript(); +void AddSC_reset_commandscript();  void AddSC_tele_commandscript(); +void AddSC_server_commandscript();  void AddSC_titles_commandscript();  void AddSC_wp_commandscript(); +void AddSC_character_commandscript();  #ifdef SCRIPTS  //world @@ -648,21 +654,27 @@ void AddCommandScripts()  {      AddSC_account_commandscript();      AddSC_achievement_commandscript(); +    AddSC_cast_commandscript();      AddSC_debug_commandscript();      AddSC_event_commandscript();      AddSC_gm_commandscript();      AddSC_go_commandscript();      AddSC_gobject_commandscript();      AddSC_honor_commandscript(); +    AddSC_instance_commandscript();      AddSC_learn_commandscript(); +    AddSC_list_commandscript();      AddSC_misc_commandscript();      AddSC_modify_commandscript();      AddSC_npc_commandscript();      AddSC_quest_commandscript();      AddSC_reload_commandscript(); +    AddSC_reset_commandscript();      AddSC_tele_commandscript(); +    AddSC_server_commandscript();      AddSC_titles_commandscript();      AddSC_wp_commandscript(); +    AddSC_character_commandscript();  }  void AddWorldScripts() diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index bf701d41ec2..195dd9391bd 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -1041,7 +1041,6 @@ void InitOpcodes()      //DEFINE_OPCODE_HANDLER(SMSG_LEARNED_DANCE_MOVES,                     STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               );      //DEFINE_OPCODE_HANDLER(SMSG_LEARNED_SPELL,                           STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               );      //DEFINE_OPCODE_HANDLER(SMSG_LEVELUP_INFO,                            STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               ); -    //DEFINE_OPCODE_HANDLER(SMSG_LFG_BOOT_PLAYER,                         STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               );      //DEFINE_OPCODE_HANDLER(SMSG_LFG_BOOT_PROPOSAL_UPDATE,                STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               );      //DEFINE_OPCODE_HANDLER(SMSG_LFG_DISABLED,                            STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               );      //DEFINE_OPCODE_HANDLER(SMSG_LFG_JOIN_RESULT,                         STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               ); @@ -1102,9 +1101,9 @@ void InitOpcodes()      //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_CAN_FLY,                        STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               );      //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY, STATUS_NEVER, PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               );      //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_COLLISION_HEIGHT,               STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               ); -    //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_FLIGHT_BACK_SPEED,          STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               ); -    //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_FLIGHT_SPEED,               STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               ); -    //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_HOVERING,                       STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_NULL                     ); +    //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_FLIGHT_BACK_SPEED,              STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               ); +    //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_FLIGHT_SPEED,                   STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               ); +    //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_HOVER,                          STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_NULL                     );      //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_PITCH_RATE,                     STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               );      //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_RUN_BACK_SPEED,                 STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               );      //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_RUN_SPEED,                      STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               ); @@ -1112,30 +1111,12 @@ void InitOpcodes()      //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_SWIM_SPEED,                     STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               );      //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_TURN_RATE,                      STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               );      //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_WALK_SPEED,                     STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               ); -    //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SKIP_TIME,                        STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_NULL                     ); -    //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_ROOT,                        STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               ); -    //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_FEATHER_FALL,            STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               ); -    //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_FLIGHT_BACK_SPEED,               STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_NULL                     ); -    //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_FLIGHT_SPEED,                    STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_NULL                     ); -    //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_HOVER,                   STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               ); -    //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_LAND_WALK,               STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               ); -    //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_NORMAL_FALL,             STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               ); -    //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_PITCH_RATE,              STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               ); -    //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_RUN_BACK_SPEED,          STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_NULL                     ); -    //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_RUN_MODE,                STATUS_LOGGEDIN, PROCESS_THREADSAFE,   &WorldSession::HandleMovementOpcodes           ); -    //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_SWIM_BACK_SPEED,         STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_NULL                     ); -    //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_SWIM_SPEED,              STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_NULL                     ); -    //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_TURN_RATE,               STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_NULL                     ); -    //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_WALK_MODE,               STATUS_LOGGEDIN, PROCESS_THREADSAFE,   &WorldSession::HandleMovementOpcodes           ); -    //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_WALK_SPEED,              STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_NULL                     ); -    //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_WATER_WALK,              STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               ); -    //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_UNROOT,                      STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               ); -    //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_UNSET_FLYING,                      STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               ); -    //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_UNSET_HOVER,                 STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               ); +    //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SKIP_TIME,                          STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_NULL                     );      //DEFINE_OPCODE_HANDLER(SMSG_MOVE_TELEPORT,                           STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_NULL                     );      //DEFINE_OPCODE_HANDLER(SMSG_MOVE_UNROOT,                             STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               ); -    //DEFINE_OPCODE_HANDLER(SMSG_MOVE_UNSET_CAN_FLY,                        STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               ); +    //DEFINE_OPCODE_HANDLER(SMSG_MOVE_UNSET_CAN_FLY,                      STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               );      //DEFINE_OPCODE_HANDLER(SMSG_MOVE_UNSET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY, STATUS_NEVER, PROCESS_INPLACE,    &WorldSession::Handle_ServerSide               ); +    //DEFINE_OPCODE_HANDLER(SMSG_MOVE_UNSET_HOVER,                        STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               );      //DEFINE_OPCODE_HANDLER(SMSG_MOVE_UPDATE_KNOCK_BACK,                  STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_NULL                     );      //DEFINE_OPCODE_HANDLER(SMSG_MULTIPLE_PACKETS,                        STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               );      //DEFINE_OPCODE_HANDLER(SMSG_NAME_QUERY_RESPONSE,                     STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               ); @@ -1297,16 +1278,32 @@ void InitOpcodes()      //DEFINE_OPCODE_HANDLER(SMSG_SPELL_START,                             STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               );      //DEFINE_OPCODE_HANDLER(SMSG_SPELL_UPDATE_CHAIN_TARGETS,              STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               );      //DEFINE_OPCODE_HANDLER(SMSG_SPIRIT_HEALER_CONFIRM,                   STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               ); -    //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_FEATHER_FALL,                STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               ); +    //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_COLLISION_DISABLE,           STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               ); +    //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_COLLISION_ENABLE,            STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               );      //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_GRAVITY_DISABLE,             STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               );      //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_GRAVITY_ENABLE,              STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               );      //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_LAND_WALK,                   STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               );      //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_NORMAL_FALL,                 STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               ); +    //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_ROOT,                        STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               ); +    //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_FEATHER_FALL,            STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               ); +    //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_FLIGHT_BACK_SPEED,       STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_NULL                     ); +    //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_FLIGHT_SPEED,            STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_NULL                     );      //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_FLYING,                  STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               ); +    //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_HOVER,                   STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               ); +    //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_LAND_WALK,               STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               ); +    //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_NORMAL_FALL,             STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               ); +    //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_PITCH_RATE,              STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               ); +    //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_RUN_BACK_SPEED,          STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_NULL                     );      //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_RUN_MODE,                STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               ); +    //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_SWIM_BACK_SPEED,         STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_NULL                     ); +    //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_SWIM_SPEED,              STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_NULL                     ); +    //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_TURN_RATE,               STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_NULL                     );      //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_WALK_MODE,               STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               ); +    //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_WALK_SPEED,              STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_NULL                     ); +    //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_WATER_WALK,              STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               );      //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_START_SWIM,                  STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               );      //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_STOP_SWIM,                   STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               ); +    //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_UNROOT,                      STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               );      //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_UNSET_FLYING,                STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               );      //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_UNSET_HOVER,                 STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               );      //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_WATER_WALK,                  STATUS_NEVER,    PROCESS_INPLACE,      &WorldSession::Handle_ServerSide               ); diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h index 14f9687cdcd..4f6cda222e9 100755 --- a/src/server/game/Server/Protocol/Opcodes.h +++ b/src/server/game/Server/Protocol/Opcodes.h @@ -792,7 +792,7 @@ enum Opcodes      SMSG_LEARNED_DANCE_MOVES                          = 0x0E05,      SMSG_LEARNED_SPELL                                = 0x58A2,      SMSG_LEVELUP_INFO                                 = 0x0000, -    SMSG_LFG_BOOT_PLAYER                              = 0x0000, +    SMSG_LFG_BOOT_PROPOSAL_UPDATE                     = 0x0000,      SMSG_LFG_DISABLED                                 = 0x0000,      SMSG_LFG_JOIN_RESULT                              = 0x0000,      SMSG_LFG_OFFER_CONTINUE                           = 0x0000, @@ -844,22 +844,21 @@ enum Opcodes      SMSG_MOUNTSPECIAL_ANIM                            = 0x0000,      SMSG_MOVE_DISABLE_COLLISION                       = 0x0000,      SMSG_MOVE_DISABLE_GRAVITY                         = 0x0000, -    SMSG_MOVE_DISABLE_TRANSITION_BETWEEN_SWIM_AND_FLY = 0x0000,      SMSG_MOVE_ENABLE_COLLISION                        = 0x0000,      SMSG_MOVE_ENABLE_GRAVITY                          = 0x0000, -    SMSG_MOVE_ENABLE_TRANSITION_BETWEEN_SWIM_AND_FLY  = 0x0000, +    SMSG_MOVE_FEATHER_FALL                            = 0x0000,      SMSG_MOVE_KNOCK_BACK                              = 0x0000, +    SMSG_MOVE_LAND_WALK                               = 0x0000, +    SMSG_MOVE_NORMAL_FALL                             = 0x0000,      SMSG_MOVE_ROOT                                    = 0x0000,      SMSG_MOVE_SET_ACTIVE_MOVER                        = 0x0000,      SMSG_MOVE_SET_CAN_FLY                             = 0x0000, +    SMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY = 0x0000,      SMSG_MOVE_SET_COLLISION_HEIGHT                    = 0x0000,      SMSG_MOVE_SET_COMPOUND_STATE                      = 0x0000, -    SMSG_MOVE_SET_FEATHER_FALL                        = 0x0000,      SMSG_MOVE_SET_FLIGHT_BACK_SPEED                   = 0x0000,      SMSG_MOVE_SET_FLIGHT_SPEED                        = 0x0000, -    SMSG_MOVE_SET_HOVERING                            = 0x0000, -    SMSG_MOVE_SET_LAND_WALK                           = 0x0000, -    SMSG_MOVE_SET_NORMAL_FALL                         = 0x0000, +    SMSG_MOVE_SET_HOVER                               = 0x0000,      SMSG_MOVE_SET_PITCH_RATE                          = 0x0000,      SMSG_MOVE_SET_RUN_BACK_SPEED                      = 0x0000,      SMSG_MOVE_SET_RUN_SPEED                           = 0x0000, @@ -869,42 +868,16 @@ enum Opcodes      SMSG_MOVE_SET_VEHICLE_REC_ID                      = 0x0000,      SMSG_MOVE_SET_WALK_IN_AIR                         = 0x0000,      SMSG_MOVE_SET_WALK_SPEED                          = 0x0000, -    SMSG_MOVE_SET_WATER_WALK                          = 0x0000,      SMSG_MOVE_SKIP_TIME                               = 0x0000, -    SMSG_MOVE_SPLINE_DISABLE_COLLISION                = 0x0000, -    SMSG_MOVE_SPLINE_DISABLE_GRAVITY                  = 0x0000, -    SMSG_MOVE_SPLINE_ENABLE_COLLISION                 = 0x0000, -    SMSG_MOVE_SPLINE_ENABLE_GRAVITY                   = 0x0000, -    SMSG_MOVE_SPLINE_ROOT                             = 0x0000, -    SMSG_MOVE_SPLINE_SET_FEATHER_FALL                 = 0x0000, -    SMSG_MOVE_SPLINE_SET_FLIGHT_BACK_SPEED            = 0x0000, -    SMSG_MOVE_SPLINE_SET_FLIGHT_SPEED                 = 0x0000, -    SMSG_MOVE_SPLINE_SET_FLYING                       = 0x0000, -    SMSG_MOVE_SPLINE_SET_HOVER                        = 0x0000, -    SMSG_MOVE_SPLINE_SET_LAND_WALK                    = 0x0000, -    SMSG_MOVE_SPLINE_SET_NORMAL_FALL                  = 0x0000, -    SMSG_MOVE_SPLINE_SET_PITCH_RATE                   = 0x0000, -    SMSG_MOVE_SPLINE_SET_RUN_BACK_SPEED               = 0x0000, -    SMSG_MOVE_SPLINE_SET_RUN_MODE                     = 0x0000, -    SMSG_MOVE_SPLINE_SET_RUN_SPEED                    = 0x0000, -    SMSG_MOVE_SPLINE_SET_SWIM_BACK_SPEED              = 0x0000, -    SMSG_MOVE_SPLINE_SET_SWIM_SPEED                   = 0x0000, -    SMSG_MOVE_SPLINE_SET_TURN_RATE                    = 0x0000, -    SMSG_MOVE_SPLINE_SET_WALK_MODE                    = 0x0000, -    SMSG_MOVE_SPLINE_SET_WALK_SPEED                   = 0x0000, -    SMSG_MOVE_SPLINE_SET_WATER_WALK                   = 0x0000, -    SMSG_MOVE_SPLINE_START_SWIM                       = 0x0000, -    SMSG_MOVE_SPLINE_STOP_SWIM                        = 0x0000, -    SMSG_MOVE_SPLINE_UNROOT                           = 0x0000, -    SMSG_MOVE_SPLINE_UNSET_FLYING                     = 0x0000, -    SMSG_MOVE_SPLINE_UNSET_HOVER                      = 0x0000,      SMSG_MOVE_TELEPORT                                = 0x0000,      SMSG_MOVE_UNROOT                                  = 0x0000,      SMSG_MOVE_UNSET_CAN_FLY                           = 0x0000, -    SMSG_MOVE_UNSET_HOVERING                          = 0x0000, +    SMSG_MOVE_UNSET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY = 0x0000, +    SMSG_MOVE_UNSET_HOVER                             = 0x0000,      SMSG_MOVE_UNSET_WALK_IN_AIR                       = 0x0000,      SMSG_MOVE_UPDATE_KNOCK_BACK                       = 0x0000,      SMSG_MOVE_UPDATE_TELEPORT                         = 0x0000, +    SMSG_MOVE_WATER_WALK                              = 0x0000,      SMSG_MULTIPLE_PACKETS                             = 0x0000,      SMSG_NAME_QUERY_RESPONSE                          = 0x6E04,      SMSG_NEW_TAXI_PATH                                = 0x0000, @@ -1046,6 +1019,33 @@ enum Opcodes      SMSG_SPELL_START                                  = 0x6415,      SMSG_SPELL_UPDATE_CHAIN_TARGETS                   = 0x0000,      SMSG_SPIRIT_HEALER_CONFIRM                        = 0x0000, +    SMSG_SPLINE_MOVE_COLLISION_DISABLE                = 0x0000, +    SMSG_SPLINE_MOVE_COLLISION_ENABLE                 = 0x0000, +    SMSG_SPLINE_MOVE_GRAVITY_DISABLE                  = 0x0000, +    SMSG_SPLINE_MOVE_GRAVITY_ENABLE                   = 0x0000, +    SMSG_SPLINE_MOVE_ROOT                             = 0x0000, +    SMSG_SPLINE_MOVE_SET_FEATHER_FALL                 = 0x0000, +    SMSG_SPLINE_MOVE_SET_FLIGHT_BACK_SPEED            = 0x0000, +    SMSG_SPLINE_MOVE_SET_FLIGHT_SPEED                 = 0x0000, +    SMSG_SPLINE_MOVE_SET_FLYING                       = 0x0000, +    SMSG_SPLINE_MOVE_SET_HOVER                        = 0x0000, +    SMSG_SPLINE_MOVE_SET_LAND_WALK                    = 0x0000, +    SMSG_SPLINE_MOVE_SET_NORMAL_FALL                  = 0x0000, +    SMSG_SPLINE_MOVE_SET_PITCH_RATE                   = 0x0000, +    SMSG_SPLINE_MOVE_SET_RUN_BACK_SPEED               = 0x0000, +    SMSG_SPLINE_MOVE_SET_RUN_MODE                     = 0x0000, +    SMSG_SPLINE_MOVE_SET_RUN_SPEED                    = 0x0000, +    SMSG_SPLINE_MOVE_SET_SWIM_BACK_SPEED              = 0x0000, +    SMSG_SPLINE_MOVE_SET_SWIM_SPEED                   = 0x0000, +    SMSG_SPLINE_MOVE_SET_TURN_RATE                    = 0x0000, +    SMSG_SPLINE_MOVE_SET_WALK_MODE                    = 0x0000, +    SMSG_SPLINE_MOVE_SET_WALK_SPEED                   = 0x0000, +    SMSG_SPLINE_MOVE_SET_WATER_WALK                   = 0x0000, +    SMSG_SPLINE_MOVE_START_SWIM                       = 0x0000, +    SMSG_SPLINE_MOVE_STOP_SWIM                        = 0x0000, +    SMSG_SPLINE_MOVE_UNROOT                           = 0x0000, +    SMSG_SPLINE_MOVE_UNSET_FLYING                     = 0x0000, +    SMSG_SPLINE_MOVE_UNSET_HOVER                      = 0x0000,      SMSG_STABLE_RESULT                                = 0x0000,      SMSG_STANDSTATE_UPDATE                            = 0x6F04,      SMSG_START_MIRROR_TIMER                           = 0x0000, @@ -1112,7 +1112,7 @@ enum SessionStatus      STATUS_AUTHED = 0,                                      // Player authenticated (_player == NULL, m_playerRecentlyLogout = false or will be reset before handler call, m_GUID have garbage)      STATUS_LOGGEDIN,                                        // Player in game (_player != NULL, m_GUID == _player->GetGUID(), inWorld())      STATUS_TRANSFER,                                        // Player transferring to another map (_player != NULL, m_GUID == _player->GetGUID(), !inWorld()) -    STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT,                    // _player!= NULL or _player == NULL && m_playerRecentlyLogout, m_GUID store last _player guid) +    STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT,                    // _player != NULL or _player == NULL && m_playerRecentlyLogout && m_playerLogout, m_GUID store last _player guid)      STATUS_NEVER,                                           // Opcode not accepted from client (deprecated or server side only)      STATUS_UNHANDLED,                                       // Opcode not handled yet  }; diff --git a/src/server/game/Server/Protocol/PacketLog.cpp b/src/server/game/Server/Protocol/PacketLog.cpp new file mode 100644 index 00000000000..cb6dcdbdb9e --- /dev/null +++ b/src/server/game/Server/Protocol/PacketLog.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2008-2012 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 "PacketLog.h" +#include "Config.h" +#include "ByteBuffer.h" +#include "WorldPacket.h" + +PacketLog::PacketLog() : _file(NULL) +{ +    Initialize(); +} + +PacketLog::~PacketLog() +{ +    if (_file) +        fclose(_file); + +    _file = NULL; +} + +void PacketLog::Initialize() +{ +    std::string logsDir = ConfigMgr::GetStringDefault("LogsDir", ""); + +    if (!logsDir.empty()) +        if ((logsDir.at(logsDir.length()-1) != '/') && (logsDir.at(logsDir.length()-1) != '\\')) +            logsDir.push_back('/'); + +    std::string logname = ConfigMgr::GetStringDefault("PacketLogFile", ""); +    if (!logname.empty()) +        _file = fopen((logsDir + logname).c_str(), "wb"); +} + +void PacketLog::LogPacket(WorldPacket const& packet, Direction direction) +{ +    ByteBuffer data(4+4+4+1+packet.size()); +    data << int32(packet.GetOpcode()); +    data << int32(packet.size()); +    data << uint32(time(NULL)); +    data << uint8(direction); + +    for (uint32 i = 0; i < packet.size(); i++) +        data << const_cast<WorldPacket&>(packet)[i]; + +    fwrite(data.contents(), 1, data.size(), _file); +    fflush(_file); +} diff --git a/src/server/game/Server/Protocol/WorldLog.h b/src/server/game/Server/Protocol/PacketLog.h index fb344f195de..b899daae198 100755..100644 --- a/src/server/game/Server/Protocol/WorldLog.h +++ b/src/server/game/Server/Protocol/PacketLog.h @@ -1,6 +1,5 @@  /*   * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>   *   * This program is free software; you can redistribute it and/or modify it   * under the terms of the GNU General Public License as published by the @@ -16,46 +15,36 @@   * with this program. If not, see <http://www.gnu.org/licenses/>.   */ -/// \addtogroup u2w -/// @{ -/// \file - -#ifndef TRINITY_WORLDLOG_H -#define TRINITY_WORLDLOG_H +#ifndef TRINITY_PACKETLOG_H +#define TRINITY_PACKETLOG_H  #include "Common.h"  #include <ace/Singleton.h> -#include "Errors.h" -#include <stdarg.h> +enum Direction +{ +    CLIENT_TO_SERVER, +    SERVER_TO_CLIENT +}; + +class WorldPacket; -/// %Log packets to a file -class WorldLog +class PacketLog  { -    friend class ACE_Singleton<WorldLog, ACE_Thread_Mutex>; +    friend class ACE_Singleton<PacketLog, ACE_Thread_Mutex>;      private: -        WorldLog(); -        ~WorldLog(); -        WorldLog(const WorldLog &); -        WorldLog& operator=(const WorldLog &); -        ACE_Thread_Mutex Lock; +        PacketLog(); +        ~PacketLog();      public:          void Initialize(); -        /// Is the world logger active? -        bool LogWorld(void) const { return (i_file != NULL); } -        /// %Log to the file -        void outLog(char const* fmt, ...); -        void outTimestampLog(char const* fmt, ...); +        bool CanLogPacket() const { return (_file != NULL); } +        void LogPacket(WorldPacket const& packet, Direction direction);      private: -        FILE* i_file; - -        bool m_dbWorld; +        FILE* _file;  }; -#define sWorldLog ACE_Singleton<WorldLog, ACE_Thread_Mutex>::instance() +#define sPacketLog ACE_Singleton<PacketLog, ACE_Thread_Mutex>::instance()  #endif -/// @} - diff --git a/src/server/game/Server/Protocol/WorldLog.cpp b/src/server/game/Server/Protocol/WorldLog.cpp deleted file mode 100755 index 38b13dff095..00000000000 --- a/src/server/game/Server/Protocol/WorldLog.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/** \file -    \ingroup u2w -*/ - -#include "WorldLog.h" -#include "Config.h" -#include "Log.h" -#include "DatabaseWorkerPool.h" - -WorldLog::WorldLog() : i_file(NULL) -{ -    Initialize(); -} - -WorldLog::~WorldLog() -{ -    if (i_file != NULL) -        fclose(i_file); - -    i_file = NULL; -} - -/// Open the log file (if specified so in the configuration file) -void WorldLog::Initialize() -{ -    std::string logsDir = ConfigMgr::GetStringDefault("LogsDir", ""); - -    if (!logsDir.empty()) -    { -        if ((logsDir.at(logsDir.length()-1) != '/') && (logsDir.at(logsDir.length()-1) != '\\')) -            logsDir.push_back('/'); -    } - -    std::string logname = ConfigMgr::GetStringDefault("WorldLogFile", ""); -    if (!logname.empty()) -    { -        i_file = fopen((logsDir+logname).c_str(), "w"); -    } - -    m_dbWorld = ConfigMgr::GetBoolDefault("LogDB.World", false); // can be VERY heavy if enabled -} - -void WorldLog::outTimestampLog(char const* fmt, ...) -{ -    if (LogWorld()) -    { -        TRINITY_GUARD(ACE_Thread_Mutex, Lock); -        ASSERT(i_file); - -        Log::outTimestamp(i_file); -        va_list args; -        va_start(args, fmt); -        vfprintf(i_file, fmt, args); -        //fprintf(i_file, "\n"); -        va_end(args); - -        fflush(i_file); -    } - -    if (sLog->GetLogDB() && m_dbWorld) -    { -        va_list ap2; -        va_start(ap2, fmt); -        char nnew_str[MAX_QUERY_LEN]; -        vsnprintf(nnew_str, MAX_QUERY_LEN, fmt, ap2); -        sLog->outDB(LOG_TYPE_WORLD, nnew_str); -        va_end(ap2); -    } -} - -void WorldLog::outLog(char const* fmt, ...) -{ -    if (LogWorld()) -    { -        TRINITY_GUARD(ACE_Thread_Mutex, Lock); -        ASSERT(i_file); - -        va_list args; -        va_start(args, fmt); -        vfprintf(i_file, fmt, args); -        //fprintf(i_file, "\n"); -        va_end(args); - -        fflush(i_file); -    } - -    if (sLog->GetLogDB() && m_dbWorld) -    { -        va_list ap2; -        va_start(ap2, fmt); -        char nnew_str[MAX_QUERY_LEN]; -        vsnprintf(nnew_str, MAX_QUERY_LEN, fmt, ap2); -        sLog->outDB(LOG_TYPE_WORLD, nnew_str); -        va_end(ap2); -    } -} diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 0f41ea1ca37..9b6eaaea6c3 100755 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -218,7 +218,7 @@ void WorldSession::QueuePacket(WorldPacket* new_packet)  /// Logging helper for unexpected opcodes  void WorldSession::LogUnexpectedOpcode(WorldPacket* packet, const char* status, const char *reason)  { -    sLog->outError("SESSION (account: %u, guidlow: %u, char: %s): received unexpected opcode %s (0x%.4X, status: %s) %s", +    sLog->outDebug(LOG_FILTER_NETWORKIO, "SESSION (account: %u, guidlow: %u, char: %s): received unexpected opcode %s (0x%.4X, status: %s) %s",          GetAccountId(), m_GUIDLow, _player ? _player->GetName() : "<none>",          LookupOpcodeName(packet->GetOpcode()), packet->GetOpcode(), status, reason);  } @@ -226,7 +226,7 @@ void WorldSession::LogUnexpectedOpcode(WorldPacket* packet, const char* status,  /// Logging helper for unexpected opcodes  void WorldSession::LogUnprocessedTail(WorldPacket* packet)  { -    sLog->outError("SESSION: opcode %s (0x%.4X) have unprocessed tail data (read stop at %u from %u)", +    sLog->outDebug(LOG_FILTER_NETWORKIO, "SESSION: opcode %s (0x%.4X) have unprocessed tail data (read stop at %u from %u)",          LookupOpcodeName(packet->GetOpcode()), packet->GetOpcode(), uint32(packet->rpos()), uint32(packet->wpos()));      packet->print_storage();  } diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index c7c19eeeacd..c1d1cb5d53c 100755 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -333,7 +333,7 @@ class WorldSession          void LoadTutorialsData();          void SendTutorialsData();          void SaveTutorialsData(SQLTransaction& trans); -        uint32 GetTutorialInt(uint8 index) { return m_Tutorials[index]; } +        uint32 GetTutorialInt(uint8 index) const { return m_Tutorials[index]; }          void SetTutorialInt(uint8 index, uint32 value)          {              if (m_Tutorials[index] != value) @@ -400,8 +400,8 @@ class WorldSession          }          // Recruit-A-Friend Handling -        uint32 GetRecruiterId() { return recruiterId; } -        bool IsARecruiter() { return isRecruiter; } +        uint32 GetRecruiterId() const { return recruiterId; } +        bool IsARecruiter() const { return isRecruiter; }      public:                                                 // opcodes handlers diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index 5f55ddbc254..c2a02d6f12c 100755 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -42,7 +42,7 @@  #include "WorldSession.h"  #include "WorldSocketMgr.h"  #include "Log.h" -#include "WorldLog.h" +#include "PacketLog.h"  #include "ScriptMgr.h"  #include "AccountMgr.h" @@ -78,7 +78,7 @@ struct ServerPktHeader          return 2+(isLargePacket()?3:2);      } -    bool isLargePacket() +    bool isLargePacket() const      {          return size > 0x7FFF;      } @@ -152,7 +152,7 @@ const std::string& WorldSocket::GetRemoteAddress (void) const      return m_Address;  } -int WorldSocket::SendPacket(const WorldPacket& pct) +int WorldSocket::SendPacket(WorldPacket const& pct)  {      ACE_GUARD_RETURN (LockType, Guard, m_OutBufferLock, -1); @@ -160,24 +160,8 @@ int WorldSocket::SendPacket(const WorldPacket& pct)          return -1;      // Dump outgoing packet. -    if (sWorldLog->LogWorld()) -    { -        sWorldLog->outTimestampLog ("SERVER:\nSOCKET: %u\nLENGTH: %u\nOPCODE: %s (0x%.4X)\nDATA:\n", -                     (uint32) get_handle(), -                     pct.size(), -                     LookupOpcodeName (pct.GetOpcode()), -                     pct.GetOpcode()); - -        uint32 p = 0; -        while (p < pct.size()) -        { -            for (uint32 j = 0; j < 16 && p < pct.size(); j++) -                sWorldLog->outLog("%.2X ", const_cast<WorldPacket&>(pct)[p++]); - -            sWorldLog->outLog("\n"); -        } -        sWorldLog->outLog("\n"); -    } +    if (sPacketLog->CanLogPacket()) +        sPacketLog->LogPacket(pct, SERVER_TO_CLIENT);      sLog->outOpCode(uint32(pct.GetOpcode()), LookupOpcodeName(pct.GetOpcode()), true); @@ -668,7 +652,7 @@ int WorldSocket::schedule_wakeup_output (GuardType& g)      return 0;  } -int WorldSocket::ProcessIncoming (WorldPacket* new_pct) +int WorldSocket::ProcessIncoming(WorldPacket* new_pct)  {      ACE_ASSERT (new_pct); @@ -681,24 +665,8 @@ int WorldSocket::ProcessIncoming (WorldPacket* new_pct)          return -1;      // Dump received packet. -    if (sWorldLog->LogWorld()) -    { -        sWorldLog->outTimestampLog ("CLIENT:\nSOCKET: %u\nLENGTH: %u\nOPCODE: %s (0x%.4X)\nDATA:\n", -                     (uint32) get_handle(), -                     new_pct->size(), -                     LookupOpcodeName (new_pct->GetOpcode()), -                     new_pct->GetOpcode()); - -        uint32 p = 0; -        while (p < new_pct->size()) -        { -            for (uint32 j = 0; j < 16 && p < new_pct->size(); j++) -                sWorldLog->outLog ("%.2X ", (*new_pct)[p++]); - -            sWorldLog->outLog ("\n"); -        } -        sWorldLog->outLog ("\n"); -    } +    if (sPacketLog->CanLogPacket()) +        sPacketLog->LogPacket(*new_pct, CLIENT_TO_SERVER);      sLog->outOpCode(uint32(Opcodes(opcode)), LookupOpcodeName(Opcodes(opcode)), false); @@ -808,7 +776,7 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket)      LocaleConstant locale;      std::string account;      SHA1Hash sha; -    BigNumber v, s, g, N, k; +    BigNumber k;      WorldPacket addonsData;      recvPacket.read_skip<uint32>(); @@ -891,21 +859,9 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket)      if (expansion > world_expansion)          expansion = world_expansion; -    N.SetHexStr("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7"); -    g.SetDword(7); - -    v.SetHexStr(fields[4].GetCString()); -    s.SetHexStr(fields[5].GetCString()); - -    const char* sStr = s.AsHexStr();                       //Must be freed by OPENSSL_free() -    const char* vStr = v.AsHexStr();                       //Must be freed by OPENSSL_free() -      sLog->outStaticDebug("WorldSocket::HandleAuthSession: (s,v) check s: %s v: %s", -        sStr, -        vStr); - -    OPENSSL_free((void*) sStr); -    OPENSSL_free((void*) vStr); +        fields[5].GetCString(), +        fields[4].GetCString());      ///- Re-check ip locking (same check as in realmd).      if (fields[3].GetUInt8() == 1) // if ip is locked diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 7cff80cf6a0..7817e5e0d4d 100755 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -831,33 +831,18 @@ void AuraEffect::CalculatePeriodic(Unit* caster, bool create, bool load)                  m_amplitude = 1 * IN_MILLISECONDS;          case SPELL_AURA_PERIODIC_DAMAGE:          case SPELL_AURA_PERIODIC_HEAL: -        case SPELL_AURA_PERIODIC_ENERGIZE:          case SPELL_AURA_OBS_MOD_HEALTH: +        case SPELL_AURA_PERIODIC_TRIGGER_SPELL: +        case SPELL_AURA_PERIODIC_ENERGIZE:          case SPELL_AURA_PERIODIC_LEECH:          case SPELL_AURA_PERIODIC_HEALTH_FUNNEL:          case SPELL_AURA_PERIODIC_MANA_LEECH:          case SPELL_AURA_PERIODIC_DAMAGE_PERCENT:          case SPELL_AURA_POWER_BURN: -            m_isPeriodic = true; -            break; -        case SPELL_AURA_PERIODIC_TRIGGER_SPELL: -            if (GetId() == 51912) -                m_amplitude = 3000; -            m_isPeriodic = true; -            break; -        case SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE:          case SPELL_AURA_PERIODIC_DUMMY: +        case SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE:              m_isPeriodic = true;              break; -        case SPELL_AURA_DUMMY: -            // Haunting Spirits - perdiodic trigger demon -            if (GetId() == 7057) -            { -                m_isPeriodic = true; -                m_amplitude = irand (0, 60) + 30; -                m_amplitude *= IN_MILLISECONDS; -            } -            break;          default:              break;      } @@ -1153,14 +1138,6 @@ void AuraEffect::UpdatePeriodic(Unit* caster)  {      switch (GetAuraType())      { -        case SPELL_AURA_DUMMY: -            // Haunting Spirits -            if (GetId() == 7057) -            { -                m_amplitude = irand (0, 60) + 30; -                m_amplitude *= IN_MILLISECONDS; -            } -            break;          case SPELL_AURA_PERIODIC_DUMMY:              switch (GetSpellInfo()->SpellFamilyName)              { @@ -1362,11 +1339,6 @@ void AuraEffect::PeriodicTick(AuraApplication * aurApp, Unit* caster) const          case SPELL_AURA_POWER_BURN:              HandlePeriodicPowerBurnAuraTick(target, caster);              break; -        case SPELL_AURA_DUMMY: -            // Haunting Spirits -            if (GetId() == 7057) -                target->CastSpell((Unit*)NULL, GetAmount(), true); -            break;          default:              break;      } @@ -3352,9 +3324,11 @@ void AuraEffect::HandleAuraModIncreaseFlightSpeed(AuraApplication const* aurApp,          {              target->SetCanFly(apply);              if (!apply) +            {                  target->RemoveUnitMovementFlag(MOVEMENTFLAG_FLYING);                  target->AddUnitMovementFlag(MOVEMENTFLAG_FALLING);                  target->m_movementInfo.SetFallTime(0); +            }              Player* player = target->ToPlayer();              if (!player) @@ -3431,41 +3405,244 @@ void AuraEffect::HandleModStateImmunityMask(AuraApplication const* aurApp, uint8          return;      Unit* target = aurApp->GetTarget(); +    std::list <AuraType> aura_immunity_list; +    uint32 mechanic_immunity_list = 0; +    int32 miscVal = GetMiscValue(); -    std::list <AuraType> immunity_list; -    if (GetMiscValue() & (1<<10)) -        immunity_list.push_back(SPELL_AURA_MOD_STUN); -    if (GetMiscValue() & (1<<1)) -        immunity_list.push_back(SPELL_AURA_TRANSFORM); +    switch (miscVal) +    { +        case 96: +        case 1615: +        { +            if (GetAmount()) +            { +                mechanic_immunity_list = (1 << MECHANIC_SNARE) | (1 << MECHANIC_ROOT) +                    | (1 << MECHANIC_FEAR) | (1 << MECHANIC_STUN) +                    | (1 << MECHANIC_SLEEP) | (1 << MECHANIC_CHARM) +                    | (1 << MECHANIC_SAPPED) | (1 << MECHANIC_HORROR) +                    | (1 << MECHANIC_POLYMORPH) | (1 << MECHANIC_DISORIENTED) +                    | (1 << MECHANIC_FREEZE) | (1 << MECHANIC_TURN); + +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SNARE, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_ROOT, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_FEAR, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_STUN, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SLEEP, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_CHARM, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SAPPED, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_HORROR, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_POLYMORPH, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_DISORIENTED, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_FREEZE, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_TURN, apply); +                aura_immunity_list.push_back(SPELL_AURA_MOD_STUN); +                aura_immunity_list.push_back(SPELL_AURA_TRANSFORM); +                aura_immunity_list.push_back(SPELL_AURA_MOD_DECREASE_SPEED); +                aura_immunity_list.push_back(SPELL_AURA_MOD_ROOT); +                aura_immunity_list.push_back(SPELL_AURA_MOD_CONFUSE); +                aura_immunity_list.push_back(SPELL_AURA_MOD_FEAR); +            } +            break; +        } +        case 679: +        { +            if (GetId() == 57742) +            { +                mechanic_immunity_list = (1 << MECHANIC_SNARE) | (1 << MECHANIC_ROOT) +                    | (1 << MECHANIC_FEAR) | (1 << MECHANIC_STUN) +                    | (1 << MECHANIC_SLEEP) | (1 << MECHANIC_CHARM) +                    | (1 << MECHANIC_SAPPED) | (1 << MECHANIC_HORROR) +                    | (1 << MECHANIC_POLYMORPH) | (1 << MECHANIC_DISORIENTED) +                    | (1 << MECHANIC_FREEZE) | (1 << MECHANIC_TURN); + +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SNARE, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_ROOT, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_FEAR, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_STUN, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SLEEP, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_CHARM, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SAPPED, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_HORROR, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_POLYMORPH, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_DISORIENTED, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_FREEZE, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_TURN, apply); +                aura_immunity_list.push_back(SPELL_AURA_MOD_STUN); +                aura_immunity_list.push_back(SPELL_AURA_TRANSFORM); +                aura_immunity_list.push_back(SPELL_AURA_MOD_DECREASE_SPEED); +                aura_immunity_list.push_back(SPELL_AURA_MOD_ROOT); +                aura_immunity_list.push_back(SPELL_AURA_MOD_CONFUSE); +                aura_immunity_list.push_back(SPELL_AURA_MOD_FEAR); +            } +            break; +        } +        case 1557: +        { +            if (GetId() == 64187) +            { +                mechanic_immunity_list = (1 << MECHANIC_STUN); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_STUN, apply); +                aura_immunity_list.push_back(SPELL_AURA_MOD_STUN); +            } +            else +            { +                mechanic_immunity_list = (1 << MECHANIC_SNARE) | (1 << MECHANIC_ROOT) +                    | (1 << MECHANIC_FEAR) | (1 << MECHANIC_STUN) +                    | (1 << MECHANIC_SLEEP) | (1 << MECHANIC_CHARM) +                    | (1 << MECHANIC_SAPPED) | (1 << MECHANIC_HORROR) +                    | (1 << MECHANIC_POLYMORPH) | (1 << MECHANIC_DISORIENTED) +                    | (1 << MECHANIC_FREEZE) | (1 << MECHANIC_TURN); + +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SNARE, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_ROOT, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_FEAR, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_STUN, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SLEEP, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_CHARM, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SAPPED, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_HORROR, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_POLYMORPH, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_DISORIENTED, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_FREEZE, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_TURN, apply); +                aura_immunity_list.push_back(SPELL_AURA_MOD_STUN); +                aura_immunity_list.push_back(SPELL_AURA_TRANSFORM); +                aura_immunity_list.push_back(SPELL_AURA_MOD_DECREASE_SPEED); +                aura_immunity_list.push_back(SPELL_AURA_MOD_ROOT); +                aura_immunity_list.push_back(SPELL_AURA_MOD_CONFUSE); +                aura_immunity_list.push_back(SPELL_AURA_MOD_FEAR); +            } +            break; +        } +        case 1614: +        case 1694: +        { +            target->ApplySpellImmune(GetId(), IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, apply); +            aura_immunity_list.push_back(SPELL_AURA_MOD_TAUNT); +            break; +        } +        case 1630: +        { +            if (!GetAmount()) +            { +                target->ApplySpellImmune(GetId(), IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, apply); +                aura_immunity_list.push_back(SPELL_AURA_MOD_TAUNT); +            } +            else +            { +                mechanic_immunity_list = (1 << MECHANIC_SNARE) | (1 << MECHANIC_ROOT) +                    | (1 << MECHANIC_FEAR) | (1 << MECHANIC_STUN) +                    | (1 << MECHANIC_SLEEP) | (1 << MECHANIC_CHARM) +                    | (1 << MECHANIC_SAPPED) | (1 << MECHANIC_HORROR) +                    | (1 << MECHANIC_POLYMORPH) | (1 << MECHANIC_DISORIENTED) +                    | (1 << MECHANIC_FREEZE) | (1 << MECHANIC_TURN); + +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SNARE, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_ROOT, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_FEAR, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_STUN, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SLEEP, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_CHARM, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SAPPED, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_HORROR, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_POLYMORPH, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_DISORIENTED, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_FREEZE, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_TURN, apply); +                aura_immunity_list.push_back(SPELL_AURA_MOD_STUN); +                aura_immunity_list.push_back(SPELL_AURA_TRANSFORM); +                aura_immunity_list.push_back(SPELL_AURA_MOD_DECREASE_SPEED); +                aura_immunity_list.push_back(SPELL_AURA_MOD_ROOT); +                aura_immunity_list.push_back(SPELL_AURA_MOD_CONFUSE); +                aura_immunity_list.push_back(SPELL_AURA_MOD_FEAR); +            } +            break; +        } +        case 477: +        case 1733: +        { +            if (!GetAmount()) +            { +                mechanic_immunity_list = (1 << MECHANIC_SNARE) | (1 << MECHANIC_ROOT) +                    | (1 << MECHANIC_FEAR) | (1 << MECHANIC_STUN) +                    | (1 << MECHANIC_SLEEP) | (1 << MECHANIC_CHARM) +                    | (1 << MECHANIC_SAPPED) | (1 << MECHANIC_HORROR) +                    | (1 << MECHANIC_POLYMORPH) | (1 << MECHANIC_DISORIENTED) +                    | (1 << MECHANIC_FREEZE) | (1 << MECHANIC_TURN); + +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SNARE, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_ROOT, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_FEAR, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_STUN, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SLEEP, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_CHARM, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SAPPED, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_HORROR, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_POLYMORPH, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_DISORIENTED, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_FREEZE, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_TURN, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK_DEST, apply); +                aura_immunity_list.push_back(SPELL_AURA_MOD_STUN); +                aura_immunity_list.push_back(SPELL_AURA_TRANSFORM); +                aura_immunity_list.push_back(SPELL_AURA_MOD_DECREASE_SPEED); +                aura_immunity_list.push_back(SPELL_AURA_MOD_ROOT); +                aura_immunity_list.push_back(SPELL_AURA_MOD_CONFUSE); +                aura_immunity_list.push_back(SPELL_AURA_MOD_FEAR); +            } +            break; +        } +        case 878: +        { +            if (GetAmount() == 1) +            { +                mechanic_immunity_list = (1 << MECHANIC_SNARE) | (1 << MECHANIC_STUN) +                    | (1 << MECHANIC_DISORIENTED) | (1 << MECHANIC_FREEZE); + +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SNARE, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_STUN, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_DISORIENTED, apply); +                target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_FREEZE, apply); +                aura_immunity_list.push_back(SPELL_AURA_MOD_STUN); +                aura_immunity_list.push_back(SPELL_AURA_MOD_DECREASE_SPEED); +            } +            break; +        } +        default: +            break; +    } -    // These flag can be recognized wrong: -    if (GetMiscValue() & (1<<6)) -        immunity_list.push_back(SPELL_AURA_MOD_DECREASE_SPEED); -    if (GetMiscValue() & (1<<0)) -        immunity_list.push_back(SPELL_AURA_MOD_ROOT); -    if (GetMiscValue() & (1<<2)) -        immunity_list.push_back(SPELL_AURA_MOD_CONFUSE); -    if (GetMiscValue() & (1<<9)) -        immunity_list.push_back(SPELL_AURA_MOD_FEAR); +    if (aura_immunity_list.empty()) +    { +            if (miscVal & (1<<10)) +                aura_immunity_list.push_back(SPELL_AURA_MOD_STUN); +            if (miscVal & (1<<1)) +                aura_immunity_list.push_back(SPELL_AURA_TRANSFORM); -    // an exception for Bladestorm -    if ((GetMiscValue() & (1<<7)) && (GetId() != 46924)) -        immunity_list.push_back(SPELL_AURA_MOD_DISARM); +            // These flag can be recognized wrong: +            if (miscVal & (1<<6)) +                aura_immunity_list.push_back(SPELL_AURA_MOD_DECREASE_SPEED); +            if (miscVal & (1<<0)) +                aura_immunity_list.push_back(SPELL_AURA_MOD_ROOT); +            if (miscVal & (1<<2)) +                aura_immunity_list.push_back(SPELL_AURA_MOD_CONFUSE); +            if (miscVal & (1<<9)) +                aura_immunity_list.push_back(SPELL_AURA_MOD_FEAR); +            if (miscVal & (1<<7)) +                aura_immunity_list.push_back(SPELL_AURA_MOD_DISARM); +    }      // apply immunities -    for (std::list <AuraType>::iterator iter = immunity_list.begin(); iter != immunity_list.end(); ++iter) +    for (std::list <AuraType>::iterator iter = aura_immunity_list.begin(); iter != aura_immunity_list.end(); ++iter)          target->ApplySpellImmune(GetId(), IMMUNITY_STATE, *iter, apply); -    // Patch 3.0.3 Bladestorm now breaks all snares and roots on the warrior when activated. -    if (apply && GetId() == 46924) -    { -        target->RemoveAurasByType(SPELL_AURA_MOD_ROOT); -        target->RemoveAurasByType(SPELL_AURA_MOD_DECREASE_SPEED); -    } -      if (apply && GetSpellInfo()->AttributesEx & SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY) -        for (std::list <AuraType>::iterator iter = immunity_list.begin(); iter != immunity_list.end(); ++iter) +    { +        target->RemoveAurasWithMechanic(mechanic_immunity_list, AURA_REMOVE_BY_DEFAULT, GetId()); +        for (std::list <AuraType>::iterator iter = aura_immunity_list.begin(); iter != aura_immunity_list.end(); ++iter)              target->RemoveAurasByType(*iter); +    }  }  void AuraEffect::HandleModMechanicImmunity(AuraApplication const* aurApp, uint8 mode, bool apply) const @@ -4861,38 +5038,6 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool                          if (Unit* spellTarget = ObjectAccessor::GetUnit(*target, target->ToPlayer()->GetComboTarget()))                              target->CastSpell(spellTarget, 51699, true);                     break; -                case 28832: // Mark of Korth'azz -                case 28833: // Mark of Blaumeux -                case 28834: // Mark of Rivendare -                case 28835: // Mark of Zeliek -                    if (caster) // actually we can also use cast(this, originalcasterguid) -                    { -                        int32 damage; -                        switch (GetBase()->GetStackAmount()) -                        { -                            case 1: damage = 0;     break; -                            case 2: damage = 500;   break; -                            case 3: damage = 1000;  break; -                            case 4: damage = 1500;  break; -                            case 5: damage = 4000;  break; -                            case 6: damage = 12000; break; -                            default:damage = 20000 + 1000 * (GetBase()->GetStackAmount() - 7); break; -                        } -                        if (damage) -                            caster->CastCustomSpell(28836, SPELLVALUE_BASE_POINT0, damage, target); -                    } -                    break; -                case 63322: // Saronite Vapors -                { -                    if (caster) -                    { -                        int32 mana = int32(GetAmount() * pow(2.0f, GetBase()->GetStackAmount())); // mana restore - bp * 2^stackamount -                        int32 damage = mana * 2; // damage -                        caster->CastCustomSpell(target, 63337, &mana, NULL, NULL, true); -                        caster->CastCustomSpell(target, 63338, &damage, NULL, NULL, true); -                    } -                    break; -                }                  case 71563:                      if (Aura* newAura = target->AddAura(71564, target))                          newAura->SetStackAmount(newAura->GetSpellInfo()->StackAmount); @@ -4986,57 +5131,6 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool                              break;                      }                      break; -                case SPELLFAMILY_MAGE: -                    // Living Bomb -                    if (m_spellInfo->SpellFamilyFlags[1] & 0x20000) -                    { -                        AuraRemoveMode removeMode = aurApp->GetRemoveMode(); -                        if (caster && (removeMode == AURA_REMOVE_BY_ENEMY_SPELL || removeMode == AURA_REMOVE_BY_EXPIRE)) -                            caster->CastSpell(target, GetAmount(), true); -                    } -                    break; -                case SPELLFAMILY_PRIEST: -                    // Vampiric Touch -                    if (m_spellInfo->SpellFamilyFlags[1] & 0x0400 && aurApp->GetRemoveMode() == AURA_REMOVE_BY_ENEMY_SPELL && GetEffIndex() == 0) -                        if (AuraEffect const* aurEff = GetBase()->GetEffect(1)) -                        { -                            int32 damage = aurEff->GetAmount() * 8; -                            // backfire damage -                            target->CastCustomSpell(target, 64085, &damage, NULL, NULL, true, NULL, NULL, GetCasterGUID()); -                        } -                    break; -                case SPELLFAMILY_WARLOCK: -                    // Haunt -                    if (m_spellInfo->SpellFamilyFlags[1] & 0x40000) -                        if (caster) -                            target->CastCustomSpell(caster, 48210, &m_amount, 0, 0, true, NULL, this, GetCasterGUID()); -                    break; -                case SPELLFAMILY_DRUID: -                    // Lifebloom -                    if (GetSpellInfo()->SpellFamilyFlags[1] & 0x10) -                    { -                        // Final heal only on duration end -                        if (aurApp->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE) -                            return; - -                        // final heal -                        int32 stack = GetBase()->GetStackAmount(); -                        int32 heal = m_amount; -                        if (caster) -                        { -                            heal = caster->SpellHealingBonusDone(target, GetSpellInfo(), heal, HEAL, stack); -                            heal = target->SpellHealingBonusTaken(caster, GetSpellInfo(), heal, HEAL, stack); -                        } -                        target->CastCustomSpell(target, 33778, &heal, &stack, NULL, true, NULL, this, GetCasterGUID()); - -                        // restore mana -                        if (caster) -                        { -                            int32 returnmana = CalculatePctU(caster->GetCreateMana(), GetSpellInfo()->ManaCostPercentage) * stack / 2; -                            caster->CastCustomSpell(caster, 64372, &returnmana, NULL, NULL, true, NULL, this, GetCasterGUID()); -                        } -                    } -                    break;                  case SPELLFAMILY_DEATHKNIGHT:                      // Summon Gargoyle (Dismiss Gargoyle at remove)                      if (GetId() == 61777) @@ -5044,7 +5138,7 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool                      break;                  case SPELLFAMILY_ROGUE:                      //  Tricks of the trade -                    switch(GetId()) +                    switch (GetId())                      {                          case 59628: //Tricks of the trade buff on rogue (6sec duration)                              target->SetReducedThreatPercent(0,0); @@ -5112,48 +5206,6 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool                      target->SetEntry(apply ? 17654 : 17326);                      break;                  } -                //Summon Fire Elemental -                case 40133: -                { -                    if (!caster) -                        break; - -                    Unit* owner = caster->GetOwner(); -                    if (owner && owner->GetTypeId() == TYPEID_PLAYER) -                    { -                        if (apply) -                            owner->CastSpell(owner, 8985, true); -                        else -                            owner->ToPlayer()->RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true); -                    } -                    break; -                } -                //Summon Earth Elemental -                case 40132 : -                { -                    if (!caster) -                        break; - -                    Unit* owner = caster->GetOwner(); -                    if (owner && owner->GetTypeId() == TYPEID_PLAYER) -                    { -                        if (apply) -                            owner->CastSpell(owner, 19704, true); -                        else -                            owner->ToPlayer()->RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true); -                    } -                    break; -                } -                case 57723: // Exhaustion -                case 57724: // Sated -                { -                    switch (GetId()) -                    { -                        case 57723: target->ApplySpellImmune(GetId(), IMMUNITY_ID, 32182, apply); break; // Heroism -                        case 57724: target->ApplySpellImmune(GetId(), IMMUNITY_ID, 2825, apply);  break; // Bloodlust -                    } -                    break; -                }                  case 57819: // Argent Champion                  case 57820: // Ebon Champion                  case 57821: // Champion of the Kirin Tor @@ -5246,69 +5298,14 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool          }          case SPELLFAMILY_DRUID:          { -            if (!(mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK)) -                break; -            switch (GetId()) -            { -                case 52610:                                 // Savage Roar -                { -                    uint32 spellId = 62071; -                    if (apply) -                    { -                        if (target->GetShapeshiftForm() != FORM_CAT) -                            break; - -                        target->CastSpell(target, spellId, true, NULL, NULL, GetCasterGUID()); -                        break; -                    } -                    target->RemoveAurasDueToSpell(spellId); -                    break; -                } -                case 61336:                                 // Survival Instincts -                { -                    if (!(mode & AURA_EFFECT_HANDLE_REAL)) -                        break; - -                    if (apply) -                    { -                        if (!target->IsInFeralForm()) -                            break; - -                        int32 bp0 = int32(target->CountPctFromMaxHealth(GetAmount())); -                        target->CastCustomSpell(target, 50322, &bp0, NULL, NULL, true); -                    } -                    else -                        target->RemoveAurasDueToSpell(50322); -                    break; -                } -            } -            // Predatory Strikes -            if (target->GetTypeId() == TYPEID_PLAYER && GetSpellInfo()->SpellIconID == 1563) -            { -                target->ToPlayer()->UpdateAttackPowerAndDamage(); -            } +            //if (!(mode & AURA_EFFECT_HANDLE_REAL)) +                //break;              break;          }          case SPELLFAMILY_SHAMAN:          { -            if (!(mode & AURA_EFFECT_HANDLE_REAL)) -                break; -            // Sentry Totem -            if (GetId() == 6495 && caster && caster->GetTypeId() == TYPEID_PLAYER) -            { -                if (apply) -                { -                    if (uint64 guid = caster->m_SummonSlot[4]) -                    { -                        if (Creature* totem = caster->GetMap()->GetCreature(guid)) -                            if (totem->isTotem()) -                                caster->ToPlayer()->CastSpell(totem, 6277, true); -                    } -                } -                else -                    caster->ToPlayer()->StopCastingBindSight(); -                return; -            } +            //if (!(mode & AURA_EFFECT_HANDLE_REAL)) +                //break;              break;          }          case SPELLFAMILY_PALADIN: @@ -5941,14 +5938,6 @@ void AuraEffect::HandlePeriodicTriggerSpellAuraTick(Unit* target, Unit* caster)                          if (caster)                              caster->CastCustomSpell(29879, SPELLVALUE_BASE_POINT0, int32(target->CountPctFromMaxHealth(21)), target, true, NULL, this);                          return; -                    // Detonate Mana -                    case 27819: -                        if (int32 mana = (int32)(target->GetMaxPower(POWER_MANA) / 10)) -                        { -                            mana = target->ModifyPower(POWER_MANA, -mana); -                            target->CastCustomSpell(27820, SPELLVALUE_BASE_POINT0, -mana*10, target, true, NULL, this); -                        } -                        return;                      // Inoculate Nestlewood Owlkin                      case 29528:                          if (target->GetTypeId() != TYPEID_UNIT) // prevent error reports in case ignored player target @@ -6613,33 +6602,6 @@ void AuraEffect::HandlePeriodicManaLeechAuraTick(Unit* target, Unit* caster) con          target->AddThreat(caster, float(gainedAmount) * 0.5f, GetSpellInfo()->GetSchoolMask(), GetSpellInfo());      } -    // spell-specific code -    switch (GetId()) -    { -        case 31447: // Mark of Kaz'rogal -            if (target->GetPower(powerType) == 0) -            { -                target->CastSpell(target, 31463, true, 0, this); -                // Remove aura -                GetBase()->SetDuration(0); -            } -            break; -        case 32960: // Mark of Kazzak -        { -            int32 modifier = int32(target->GetPower(powerType) * 0.05f); -            target->ModifyPower(powerType, -modifier); - -            if (target->GetPower(powerType) == 0) -            { -                target->CastSpell(target, 32961, true, 0, this); -                // Remove aura -                GetBase()->SetDuration(0); -            } -            break; -        } -        default: -            break; -    }      // Drain Mana      if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK          && m_spellInfo->SpellFamilyFlags[0] & 0x00000010) diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index 58c8ce5c558..6a8ac5d4eef 100755 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -1236,19 +1236,6 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b                          caster->CastCustomSpell(caster, 75999, &heal, NULL, NULL, true, NULL, GetEffect(0));                      }                  } -                // Renew -                else if (GetSpellInfo()->SpellFamilyFlags[0] & 0x00000040 && GetEffect(0)) -                { -                    // Empowered Renew -                    if (AuraEffect const* aurEff = caster->GetDummyAuraEffect(SPELLFAMILY_PRIEST, 3021, 1)) -                    { -                        uint32 damage = caster->SpellHealingBonusDone(target, GetSpellInfo(), GetEffect(0)->GetAmount(), HEAL); -                        damage = target->SpellHealingBonusTaken(caster, GetSpellInfo(), damage, HEAL); - -                        int32 basepoints0 = aurEff->GetAmount() * GetEffect(0)->GetTotalTicks() * int32(damage) / 100; -                        caster->CastCustomSpell(target, 63544, &basepoints0, NULL, NULL, true, NULL, GetEffect(0)); -                    } -                }                  // Power Word: Shield                  else if (m_spellInfo->SpellFamilyFlags[0] & 0x1 && m_spellInfo->SpellFamilyFlags[2] & 0x400 && GetEffect(0))                  { diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index d833782bc76..54b3ae310e2 100755 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -828,7 +828,7 @@ void Spell::SelectEffectImplicitTargets(SpellEffIndex effIndex, SpellImplicitTar              break;      } -    switch(targetType.GetSelectionCategory()) +    switch (targetType.GetSelectionCategory())      {          case TARGET_SELECT_CATEGORY_CHANNEL:              SelectImplicitChannelTargets(effIndex, targetType); @@ -846,7 +846,7 @@ void Spell::SelectEffectImplicitTargets(SpellEffIndex effIndex, SpellImplicitTar              switch (targetType.GetObjectType())              {                  case TARGET_OBJECT_TYPE_SRC: -                    switch(targetType.GetReferenceType()) +                    switch (targetType.GetReferenceType())                      {                          case TARGET_REFERENCE_TYPE_CASTER:                              m_targets.SetSrc(*m_caster); @@ -857,7 +857,7 @@ void Spell::SelectEffectImplicitTargets(SpellEffIndex effIndex, SpellImplicitTar                      }                      break;                  case TARGET_OBJECT_TYPE_DEST: -                     switch(targetType.GetReferenceType()) +                     switch (targetType.GetReferenceType())                       {                           case TARGET_REFERENCE_TYPE_CASTER:                               SelectImplicitCasterDestTargets(effIndex, targetType); @@ -874,7 +874,7 @@ void Spell::SelectEffectImplicitTargets(SpellEffIndex effIndex, SpellImplicitTar                       }                       break;                  default: -                    switch(targetType.GetReferenceType()) +                    switch (targetType.GetReferenceType())                      {                          case TARGET_REFERENCE_TYPE_CASTER:                              SelectImplicitCasterObjectTargets(effIndex, targetType); @@ -915,17 +915,25 @@ void Spell::SelectImplicitChannelTargets(SpellEffIndex effIndex, SpellImplicitTa      switch (targetType.GetTarget())      {          case TARGET_UNIT_CHANNEL_TARGET: +        { +            WorldObject* target = ObjectAccessor::GetUnit(*m_caster, channeledSpell->m_targets.GetUnitTargetGUID()); +            CallScriptObjectTargetSelectHandlers(target, effIndex);              // unit target may be no longer avalible - teleported out of map for example -            if (Unit* target = Unit::GetUnit(*m_caster, channeledSpell->m_targets.GetUnitTargetGUID())) -                AddUnitTarget(target, 1 << effIndex); +            if (target && target->ToUnit()) +                AddUnitTarget(target->ToUnit(), 1 << effIndex);              else                  sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "SPELL: cannot find channel spell target for spell ID %u, effect %u", m_spellInfo->Id, effIndex);              break; +        }          case TARGET_DEST_CHANNEL_TARGET:              if (channeledSpell->m_targets.HasDst())                  m_targets.SetDst(channeledSpell->m_targets);              else if (WorldObject* target = ObjectAccessor::GetWorldObject(*m_caster, channeledSpell->m_targets.GetObjectTargetGUID())) -                m_targets.SetDst(*target); +            { +                CallScriptObjectTargetSelectHandlers(target, effIndex); +                if (target) +                    m_targets.SetDst(*target); +            }              else                  sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "SPELL: cannot find channel spell destination for spell ID %u, effect %u", m_spellInfo->Id, effIndex);              break; @@ -1003,6 +1011,8 @@ void Spell::SelectImplicitNearbyTargets(SpellEffIndex effIndex, SpellImplicitTar          return;      } +    CallScriptObjectTargetSelectHandlers(target, effIndex); +      switch (targetType.GetObjectType())      {          case TARGET_OBJECT_TYPE_UNIT: @@ -1042,7 +1052,9 @@ void Spell::SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTarge      {          Trinity::WorldObjectSpellConeTargetCheck check(coneAngle, radius, m_caster, m_spellInfo, selectionType, condList);          Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellConeTargetCheck> searcher(m_caster, targets, check, containerTypeMask); -        SearchTargets<Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellConeTargetCheck> > (searcher, containerTypeMask, m_caster, m_caster, radius); +        SearchTargets<Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellConeTargetCheck> >(searcher, containerTypeMask, m_caster, m_caster, radius); + +        CallScriptObjectAreaTargetSelectHandlers(targets, effIndex);          if (!targets.empty())          { @@ -1070,8 +1082,6 @@ void Spell::SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTarge                      gObjTargets.push_back(gObjTarget);              } -            CallScriptAfterUnitTargetSelectHandlers(unitTargets, effIndex); -              for (std::list<Unit*>::iterator itr = unitTargets.begin(); itr != unitTargets.end(); ++itr)                  AddUnitTarget(*itr, effMask, false); @@ -1206,6 +1216,9 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge          default:              break;      } + +    CallScriptObjectAreaTargetSelectHandlers(targets, effIndex); +      std::list<Unit*> unitTargets;      std::list<GameObject*> gObjTargets;      // for compability with older code - add only unit and go targets @@ -1287,18 +1300,6 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge                      maxSize = m_caster->HasAura(62970) ? 6 : 5; // Glyph of Wild Growth                      power = POWER_HEALTH;                  } -                else if (m_spellInfo->SpellFamilyFlags[2] == 0x0100) // Starfall -                { -                    // Remove targets not in LoS or in stealth -                    for (std::list<Unit*>::iterator itr = unitTargets.begin(); itr != unitTargets.end();) -                    { -                        if ((*itr)->HasStealthAura() || (*itr)->HasInvisibilityAura() || !(*itr)->IsWithinLOSInMap(m_caster)) -                            itr = unitTargets.erase(itr); -                        else -                            ++itr; -                    } -                    break; -                }                  else                      break; @@ -1339,6 +1340,11 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge              }          } +        // todo: move to scripts, but we must call it before resize list by MaxAffectedTargets +        // Intimidating Shout +        if (m_spellInfo->Id == 5246 && effIndex != EFFECT_0) +            unitTargets.remove(m_targets.GetUnitTarget()); +          // Other special target selection goes here          if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)          { @@ -1347,13 +1353,9 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge                  if ((*j)->IsAffectingSpell(m_spellInfo))                      maxTargets += (*j)->GetAmount(); -            if (m_spellInfo->Id == 5246) //Intimidating Shout -                unitTargets.remove(m_targets.GetUnitTarget());              Trinity::Containers::RandomResizeList(unitTargets, maxTargets);          } -        CallScriptAfterUnitTargetSelectHandlers(unitTargets, effIndex); -          for (std::list<Unit*>::iterator itr = unitTargets.begin(); itr != unitTargets.end(); ++itr)              AddUnitTarget(*itr, effMask, false);      } @@ -1369,6 +1371,7 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge              Trinity::Containers::RandomResizeList(gObjTargets, maxTargets);          } +          for (std::list<GameObject*>::iterator itr = gObjTargets.begin(); itr != gObjTargets.end(); ++itr)              AddGOTarget(*itr, effMask);      } @@ -1376,7 +1379,7 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge  void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType)  { -    switch(targetType.GetTarget()) +    switch (targetType.GetTarget())      {          case TARGET_DEST_CASTER:              m_targets.SetDst(*m_caster); @@ -1441,7 +1444,7 @@ void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplici  void Spell::SelectImplicitTargetDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType)  {      WorldObject* target = m_targets.GetObjectTarget(); -    switch(targetType.GetTarget()) +    switch (targetType.GetTarget())      {          case TARGET_DEST_TARGET_ENEMY:          case TARGET_DEST_TARGET_ANY: @@ -1474,7 +1477,7 @@ void Spell::SelectImplicitDestDestTargets(SpellEffIndex effIndex, SpellImplicitT      if (!m_targets.HasDst())          m_targets.SetDst(*m_caster); -    switch(targetType.GetTarget()) +    switch (targetType.GetTarget())      {          case TARGET_DEST_DYNOBJ_ENEMY:          case TARGET_DEST_DYNOBJ_ALLY: @@ -1500,27 +1503,27 @@ void Spell::SelectImplicitDestDestTargets(SpellEffIndex effIndex, SpellImplicitT  void Spell::SelectImplicitCasterObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType)  { -    switch(targetType.GetTarget()) +    WorldObject* target = NULL; +    bool checkIfValid = true; + +    switch (targetType.GetTarget())      {          case TARGET_UNIT_CASTER: -            AddUnitTarget(m_caster, 1 << effIndex, false); +            target = m_caster; +            checkIfValid = false;              break;          case TARGET_UNIT_MASTER: -            if (Unit* owner = m_caster->GetCharmerOrOwner()) -                AddUnitTarget(owner, 1 << effIndex); +            target = m_caster->GetCharmerOrOwner();              break;          case TARGET_UNIT_PET: -            if (Guardian* pet = m_caster->GetGuardianPet()) -                AddUnitTarget(pet, 1 << effIndex); +            target = m_caster->GetGuardianPet();              break;          case TARGET_UNIT_SUMMONER:              if (m_caster->isSummon()) -                if (Unit* unit = m_caster->ToTempSummon()->GetSummoner()) -                    AddUnitTarget(unit, 1 << effIndex); +                target = m_caster->ToTempSummon()->GetSummoner();              break;          case TARGET_UNIT_VEHICLE: -            if (Unit *vehicle = m_caster->GetVehicleBase()) -                AddUnitTarget(vehicle, 1 << effIndex); +            target = m_caster->GetVehicleBase();              break;          case TARGET_UNIT_PASSENGER_0:          case TARGET_UNIT_PASSENGER_1: @@ -1531,26 +1534,38 @@ void Spell::SelectImplicitCasterObjectTargets(SpellEffIndex effIndex, SpellImpli          case TARGET_UNIT_PASSENGER_6:          case TARGET_UNIT_PASSENGER_7:              if (m_caster->GetTypeId() == TYPEID_UNIT && m_caster->ToCreature()->IsVehicle()) -                if (Unit *unit = m_caster->GetVehicleKit()->GetPassenger(targetType.GetTarget() - TARGET_UNIT_PASSENGER_0)) -                    AddUnitTarget(unit, 1 << effIndex); +                target = m_caster->GetVehicleKit()->GetPassenger(targetType.GetTarget() - TARGET_UNIT_PASSENGER_0);              break;          default:              break;      } + +    CallScriptObjectTargetSelectHandlers(target, effIndex); + +    if (target && target->ToUnit()) +        AddUnitTarget(target->ToUnit(), 1 << effIndex, checkIfValid);  }  void Spell::SelectImplicitTargetObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType)  {      ASSERT((m_targets.GetObjectTarget() || m_targets.GetItemTarget()) && "Spell::SelectImplicitTargetObjectTargets - no explicit object or item target available!"); -    if (Unit* unit = m_targets.GetUnitTarget()) -        AddUnitTarget(unit, 1 << effIndex, true, false); -    else if (GameObject* gobj = m_targets.GetGOTarget()) -        AddGOTarget(gobj, 1 << effIndex); -    else -        AddItemTarget(m_targets.GetItemTarget(), 1 << effIndex); -    if (WorldObject* target = m_targets.GetObjectTarget()) +    WorldObject* target = m_targets.GetObjectTarget(); + +    CallScriptObjectTargetSelectHandlers(target, effIndex); + +    if (target) +    { +        if (Unit* unit = target->ToUnit()) +            AddUnitTarget(unit, 1 << effIndex, true, false); +        else if (GameObject* gobj = target->ToGameObject()) +            AddGOTarget(gobj, 1 << effIndex); +          SelectImplicitChainTargets(effIndex, targetType, target, 1 << effIndex); +    } +    // Script hook can remove object target and we would wrongly land here +    else if (Item* item = m_targets.GetItemTarget()) +        AddItemTarget(item, 1 << effIndex);  }  void Spell::SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType, WorldObject* target, uint32 effMask) @@ -1571,14 +1586,15 @@ void Spell::SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTarg          SearchChainTargets(targets, maxTargets - 1, target, targetType.GetObjectType(), targetType.GetCheckType()              , m_spellInfo->Effects[effIndex].ImplicitTargetConditions, targetType.GetTarget() == TARGET_UNIT_TARGET_CHAINHEAL_ALLY); +        // Chain primary target is added earlier +        CallScriptObjectAreaTargetSelectHandlers(targets, effIndex); +          // for backward compability          std::list<Unit*> unitTargets;          for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)              if (Unit* unitTarget = (*itr)->ToUnit())                  unitTargets.push_back(unitTarget); -        CallScriptAfterUnitTargetSelectHandlers(unitTargets, effIndex); -          for (std::list<Unit*>::iterator itr = unitTargets.begin(); itr != unitTargets.end(); ++itr)              AddUnitTarget(*itr, effMask, false);      } @@ -1741,9 +1757,12 @@ void Spell::SelectEffectTypeImplicitTargets(uint8 effIndex)          case SPELL_EFFECT_SUMMON_PLAYER:              if (m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->ToPlayer()->GetSelection())              { -                Player* target = ObjectAccessor::FindPlayer(m_caster->ToPlayer()->GetSelection()); -                if (target) -                    AddUnitTarget(target, 1 << effIndex, false); +                WorldObject* target = ObjectAccessor::FindPlayer(m_caster->ToPlayer()->GetSelection()); + +                CallScriptObjectTargetSelectHandlers(target, SpellEffIndex(effIndex)); + +                if (target && target->ToPlayer()) +                    AddUnitTarget(target->ToUnit(), 1 << effIndex, false);              }              return;          default: @@ -1759,6 +1778,8 @@ void Spell::SelectEffectTypeImplicitTargets(uint8 effIndex)      if (!targetMask)          return; +    WorldObject* target = NULL; +      switch (m_spellInfo->Effects[effIndex].GetImplicitTargetType())      {          // add explicit object target or self to the target map @@ -1767,40 +1788,46 @@ void Spell::SelectEffectTypeImplicitTargets(uint8 effIndex)              if (targetMask & (TARGET_FLAG_UNIT_MASK | TARGET_FLAG_CORPSE_MASK))              {                  if (Unit* unitTarget = m_targets.GetUnitTarget()) -                    AddUnitTarget(unitTarget, 1 << effIndex, false); +                    target = unitTarget;                  else if (targetMask & TARGET_FLAG_CORPSE_MASK)                  {                      if (Corpse* corpseTarget = m_targets.GetCorpseTarget())                      {                          // TODO: this is a workaround - corpses should be added to spell target map too, but we can't do that so we add owner instead                          if (Player* owner = ObjectAccessor::FindPlayer(corpseTarget->GetOwnerGUID())) -                            AddUnitTarget(owner, 1 << effIndex, false); +                            target = owner;                      }                  }                  else //if (targetMask & TARGET_FLAG_UNIT_MASK) -                { -                    AddUnitTarget(m_caster, 1 << effIndex, false); -                } +                    target = m_caster;              }              if (targetMask & TARGET_FLAG_ITEM_MASK)              {                  if (Item* itemTarget = m_targets.GetItemTarget())                      AddItemTarget(itemTarget, 1 << effIndex); +                return;              }              if (targetMask & TARGET_FLAG_GAMEOBJECT_MASK) -            { -                if (GameObject* gObjTarget = m_targets.GetGOTarget()) -                    AddGOTarget(gObjTarget, 1 << effIndex); -            } +                target = m_targets.GetGOTarget();              break;          // add self to the target map          case EFFECT_IMPLICIT_TARGET_CASTER:              if (targetMask & TARGET_FLAG_UNIT_MASK) -                AddUnitTarget(m_caster, 1 << effIndex, false); +                target = m_caster;              break;          default:              break;      } + +    CallScriptObjectTargetSelectHandlers(target, SpellEffIndex(effIndex)); + +    if (target) +    { +        if (target->ToUnit()) +            AddUnitTarget(target->ToUnit(), 1 << effIndex, false); +        else if (target->ToGameObject()) +            AddGOTarget(target->ToGameObject(), 1 << effIndex); +    }  }  uint32 Spell::GetSearcherTypeMask(SpellTargetObjectTypes objType, ConditionList* condList) @@ -2474,12 +2501,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target)                  caster->ToPlayer()->CastItemCombatSpell(unitTarget, m_attackType, procVictim, procEx);          } -        // Haunt -        if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK && m_spellInfo->SpellFamilyFlags[1] & 0x40000 && m_spellAura && m_spellAura->GetEffect(1)) -        { -            AuraEffect* aurEff = m_spellAura->GetEffect(1); -            aurEff->SetAmount(CalculatePctU(aurEff->GetAmount(), damageInfo.damage)); -        } +          m_damage = damageInfo.damage; @@ -2548,12 +2570,31 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA          return SPELL_MISS_EVADE;      // For delayed spells immunity may be applied between missile launch and hit - check immunity for that case +    if (m_spellInfo->Speed && (unit->IsImmunedToDamage(m_spellInfo) || unit->IsImmunedToSpell(m_spellInfo))) +        return SPELL_MISS_IMMUNE; +      // disable effects to which unit is immune +    SpellMissInfo returnVal = SPELL_MISS_IMMUNE;      for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber) -        if (effectMask & (1 << effectNumber) && unit->IsImmunedToSpellEffect(m_spellInfo, effectNumber)) -            effectMask &= ~(1 << effectNumber); -    if (!effectMask || (m_spellInfo->Speed && (unit->IsImmunedToDamage(m_spellInfo) || unit->IsImmunedToSpell(m_spellInfo)))) -        return SPELL_MISS_IMMUNE; +    { +        if (effectMask & (1 << effectNumber)) +            if (unit->IsImmunedToSpellEffect(m_spellInfo, effectNumber)) +                effectMask &= ~(1 << effectNumber); +            else if (m_spellInfo->Effects[effectNumber].IsAura() && !m_spellInfo->IsPositiveEffect(effectNumber)) +            { +                int32 debuff_resist_chance = unit->GetMaxPositiveAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel)); +                debuff_resist_chance += unit->GetMaxNegativeAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel)); + +                if (debuff_resist_chance > 0) +                    if (irand(0,10000) <= (debuff_resist_chance * 100)) +                    { +                        effectMask &= ~(1 << effectNumber); +                        returnVal = SPELL_MISS_RESIST; +                    } +            } +    } +    if (!effectMask) +        return returnVal;      PrepareScriptHitHandlers();      CallScriptBeforeHitHandlers(); @@ -3855,7 +3896,7 @@ void Spell::SendSpellStart()          data << uint8(0); // unkByte          // if (unkByte == 2)              // data.append(0); -         +      }      m_caster->SendMessageToSet(&data, true); @@ -3876,6 +3917,7 @@ void Spell::SendSpellGo()          castFlags |= CAST_FLAG_PENDING; +      if ((m_caster->GetTypeId() == TYPEID_PLAYER ||          (m_caster->GetTypeId() == TYPEID_UNIT && m_caster->ToCreature()->isPet()))          && m_spellInfo->PowerType != POWER_HEALTH) @@ -4804,19 +4846,9 @@ SpellCastResult Spell::CheckCast(bool strict)                  if (!(m_spellInfo->AttributesEx2 & SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) && VMAP::VMapFactory::checkSpellForLoS(m_spellInfo->Id) && !m_caster->IsWithinLOSInMap(target))                      return SPELL_FAILED_LINE_OF_SIGHT;          } -        else -        { -            if (m_caster->GetTypeId() == TYPEID_PLAYER) // Target - is player caster -            { -                // Lay on Hands - cannot be self-cast on paladin with Forbearance or after using Avenging Wrath -                if (m_spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN && m_spellInfo->SpellFamilyFlags[0] & 0x0008000) -                    if (target->HasAura(61988)) // Immunity shield marker -                        return SPELL_FAILED_TARGET_AURASTATE; -            } -        }      } -    //Check for line of sight for spells with dest +    // Check for line of sight for spells with dest      if (m_targets.HasDst())      {          float x, y, z; @@ -4915,7 +4947,9 @@ SpellCastResult Spell::CheckCast(bool strict)      bool hasDispellableAura = false;      bool hasNonDispelEffect = false; -    for (int i = 0; i < MAX_SPELL_EFFECTS; i++) +    uint32 dispelMask = 0; +    for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) +    {          if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_DISPEL)          {              if (m_spellInfo->Effects[i].IsTargetingArea() || m_spellInfo->AttributesEx & SPELL_ATTR1_MELEE_COMBAT_START) @@ -4923,28 +4957,28 @@ SpellCastResult Spell::CheckCast(bool strict)                  hasDispellableAura = true;                  break;              } -            if (Unit* target = m_targets.GetUnitTarget()) -            { -                DispelChargesList dispelList; -                uint32 dispelMask = SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue)); -                target->GetDispellableAuraList(m_caster, dispelMask, dispelList); -                if (!dispelList.empty()) -                { -                    hasDispellableAura = true; -                    break; -                } -            } + +            dispelMask |= SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue));          }          else if (m_spellInfo->Effects[i].IsEffect())          {              hasNonDispelEffect = true;              break;          } +    } -    if (!hasNonDispelEffect && !hasDispellableAura && m_spellInfo->HasEffect(SPELL_EFFECT_DISPEL) && !IsTriggered()) -        return SPELL_FAILED_NOTHING_TO_DISPEL; +    if (!hasNonDispelEffect && !hasDispellableAura && dispelMask && !IsTriggered()) +    { +        if (Unit* target = m_targets.GetUnitTarget()) +        { +            DispelChargesList dispelList; +            target->GetDispellableAuraList(m_caster, dispelMask, dispelList); +            if (dispelList.empty()) +                return SPELL_FAILED_NOTHING_TO_DISPEL; +        } +    } -    for (int i = 0; i < MAX_SPELL_EFFECTS; i++) +    for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)      {          // for effects of spells that have only one target          switch (m_spellInfo->Effects[i].Effect) @@ -5285,10 +5319,6 @@ SpellCastResult Spell::CheckCast(bool strict)              }              case SPELL_EFFECT_LEAP_BACK:              { -                // Spell 781 (Disengage) requires player to be in combat -                if (m_caster->GetTypeId() == TYPEID_PLAYER && m_spellInfo->Id == 781 && !m_caster->isInCombat()) -                    return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW; -                  if (m_caster->HasUnitState(UNIT_STATE_ROOT))                  {                      if (m_caster->GetTypeId() == TYPEID_PLAYER) @@ -5310,66 +5340,10 @@ SpellCastResult Spell::CheckCast(bool strict)          }      } -    for (int i = 0; i < MAX_SPELL_EFFECTS; i++) +    for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)      {          switch (m_spellInfo->Effects[i].ApplyAuraName)          { -            case SPELL_AURA_DUMMY: -            { -                //custom check -                switch (m_spellInfo->Id) -                { -                    // Tag Murloc -                    case 30877: -                    { -                        Unit* target = m_targets.GetUnitTarget(); -                        if (!target || target->GetEntry() != 17326) -                            return SPELL_FAILED_BAD_TARGETS; -                        break; -                    } -                    case 61336: -                        if (m_caster->GetTypeId() != TYPEID_PLAYER || !m_caster->ToPlayer()->IsInFeralForm()) -                            return SPELL_FAILED_ONLY_SHAPESHIFT; -                        break; -                    case 1515: -                    { -                        if (m_caster->GetTypeId() != TYPEID_PLAYER) -                            return SPELL_FAILED_BAD_TARGETS; - -                        if (!m_targets.GetUnitTarget() || m_targets.GetUnitTarget()->GetTypeId() == TYPEID_PLAYER) -                            return SPELL_FAILED_BAD_IMPLICIT_TARGETS; - -                        Creature* target = m_targets.GetUnitTarget()->ToCreature(); - -                        if (target->getLevel() > m_caster->getLevel()) -                            return SPELL_FAILED_HIGHLEVEL; - -                        // use SMSG_PET_TAME_FAILURE? -                        if (!target->GetCreatureTemplate()->isTameable (m_caster->ToPlayer()->CanTameExoticPets())) -                            return SPELL_FAILED_BAD_TARGETS; - -                        if (m_caster->GetPetGUID()) -                            return SPELL_FAILED_ALREADY_HAVE_SUMMON; - -                        if (m_caster->GetCharmGUID()) -                            return SPELL_FAILED_ALREADY_HAVE_CHARM; - -                        break; -                    } -                    case 44795: // Parachute -                    { -                        float x, y, z; -                        m_caster->GetPosition(x, y, z); -                        float ground_Z = m_caster->GetMap()->GetHeight(m_caster->GetPhaseMask(), x, y, z); -                        if (fabs(ground_Z - z) < 0.1f) -                            return SPELL_FAILED_DONT_REPORT; -                        break; -                    } -                    default: -                        break; -                } -                break; -            }              case SPELL_AURA_MOD_POSSESS_PET:              {                  if (m_caster->GetTypeId() != TYPEID_PLAYER) @@ -7047,15 +7021,29 @@ void Spell::CallScriptAfterHitHandlers()      }  } -void Spell::CallScriptAfterUnitTargetSelectHandlers(std::list<Unit*>& unitTargets, SpellEffIndex effIndex) +void Spell::CallScriptObjectAreaTargetSelectHandlers(std::list<WorldObject*>& targets, SpellEffIndex effIndex)  {      for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)      { -        (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_UNIT_TARGET_SELECT); -        std::list<SpellScript::UnitTargetHandler>::iterator hookItrEnd = (*scritr)->OnUnitTargetSelect.end(), hookItr = (*scritr)->OnUnitTargetSelect.begin(); +        (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT); +        std::list<SpellScript::ObjectAreaTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectAreaTargetSelect.end(), hookItr = (*scritr)->OnObjectAreaTargetSelect.begin();          for (; hookItr != hookItrEnd; ++hookItr)              if ((*hookItr).IsEffectAffected(m_spellInfo, effIndex)) -                (*hookItr).Call(*scritr, unitTargets); +                (*hookItr).Call(*scritr, targets); + +        (*scritr)->_FinishScriptCall(); +    } +} + +void Spell::CallScriptObjectTargetSelectHandlers(WorldObject*& target, SpellEffIndex effIndex) +{ +    for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr) +    { +        (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT); +        std::list<SpellScript::ObjectTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectTargetSelect.end(), hookItr = (*scritr)->OnObjectTargetSelect.begin(); +        for (; hookItr != hookItrEnd; ++hookItr) +            if ((*hookItr).IsEffectAffected(m_spellInfo, effIndex)) +                (*hookItr).Call(*scritr, target);          (*scritr)->_FinishScriptCall();      } @@ -7089,12 +7077,6 @@ void Spell::PrepareTriggersExecutedOnHit()      // todo: move this to scripts      switch (m_spellInfo->SpellFamilyName)      { -        case SPELLFAMILY_GENERIC: -        { -            if (m_spellInfo->Mechanic == MECHANIC_BANDAGE) // Bandages -                m_preCastSpell = 11196;  // Recently Bandaged -            break; -        }          case SPELLFAMILY_MAGE:          {               // Permafrost diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index 777d151440c..50510397056 100755 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -629,7 +629,8 @@ class Spell          void CallScriptBeforeHitHandlers();          void CallScriptOnHitHandlers();          void CallScriptAfterHitHandlers(); -        void CallScriptAfterUnitTargetSelectHandlers(std::list<Unit*>& unitTargets, SpellEffIndex effIndex); +        void CallScriptObjectAreaTargetSelectHandlers(std::list<WorldObject*>& targets, SpellEffIndex effIndex); +        void CallScriptObjectTargetSelectHandlers(WorldObject*& target, SpellEffIndex effIndex);          std::list<SpellScript*> m_loadedScripts;          struct HitTriggerSpell diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index ca3c4197fc3..aba486b0df9 100755 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -366,43 +366,6 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex)                              return;                          break;                      } -                    case 33671: // gruul's shatter -                    case 50811: // krystallus shatter ( Normal ) -                    case 61547: // krystallus shatter ( Heroic ) -                    { -                        // don't damage self and only players -                        if (unitTarget->GetGUID() == m_caster->GetGUID() || unitTarget->GetTypeId() != TYPEID_PLAYER) -                            return; - -                        float radius = m_spellInfo->Effects[EFFECT_0].CalcRadius(m_caster); -                        if (!radius) -                            return; -                        float distance = m_caster->GetDistance2d(unitTarget); -                        damage = (distance > radius) ? 0 : int32(m_spellInfo->Effects[EFFECT_0].CalcValue(m_caster) * ((radius - distance)/radius)); -                        break; -                    } -                    // Loken Pulsing Shockwave -                    case 59837: -                    case 52942: -                    { -                        // don't damage self and only players -                        if (unitTarget->GetGUID() == m_caster->GetGUID() || unitTarget->GetTypeId() != TYPEID_PLAYER) -                            return; - -                        float radius = m_spellInfo->Effects[EFFECT_0].CalcRadius(m_caster); -                        if (!radius) -                            return; -                        float distance = m_caster->GetDistance2d(unitTarget); -                        damage = (distance > radius) ? 0 : int32(m_spellInfo->Effects[EFFECT_0].CalcValue(m_caster) * distance); -                        break; -                    } -                    // TODO: add spell specific target requirement hook for spells -                    // Shadowbolts only affects targets with Shadow Mark (Gothik) -                    case 27831: -                    case 55638: -                        if (!unitTarget->HasAura(27825)) -                            return; -                        break;                      // Gargoyle Strike                      case 51963:                      { @@ -415,11 +378,8 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex)              }              case SPELLFAMILY_WARRIOR:              { -                // Bloodthirst -                if (m_spellInfo->SpellFamilyFlags[1] & 0x400) -                    ApplyPctF(damage, m_caster->GetTotalAttackPowerValue(BASE_ATTACK));                  // Shield Slam -                else if (m_spellInfo->SpellFamilyFlags[1] & 0x200 && m_spellInfo->Category == 1209) +                if (m_spellInfo->SpellFamilyFlags[1] & 0x200 && m_spellInfo->Category == 1209)                  {                      uint8 level = m_caster->getLevel();                      uint32 block_value = m_caster->GetShieldBlockValue(uint32(float(level) * 24.5f), uint32(float(level) * 34.5f)); @@ -2863,6 +2823,7 @@ void Spell::EffectEnchantItemPerm(SpellEffIndex effIndex)          // add new enchanting if equipped          item_owner->ApplyEnchantment(itemTarget, PERM_ENCHANTMENT_SLOT, true); +        item_owner->RemoveTradeableItem(itemTarget);          itemTarget->ClearSoulboundTradeable(item_owner);      }  } @@ -2927,6 +2888,7 @@ void Spell::EffectEnchantItemPrismatic(SpellEffIndex effIndex)      // add new enchanting if equipped      item_owner->ApplyEnchantment(itemTarget, PRISMATIC_ENCHANTMENT_SLOT, true); +    item_owner->RemoveTradeableItem(itemTarget);      itemTarget->ClearSoulboundTradeable(item_owner);  } @@ -3275,6 +3237,14 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex)                      fixed_bonus += (aur->GetStackAmount() - 1) * CalculateDamage(2, unitTarget);                  }              } +            if (m_spellInfo->SpellFamilyFlags[0] & 0x8000000) // Mocking Blow +            { +                if (unitTarget->IsImmunedToSpellEffect(m_spellInfo,EFFECT_1) || unitTarget->GetTypeId() == TYPEID_PLAYER) +                { +                    m_damage = 0; +                    return; +                } +            }              break;          }          case SPELLFAMILY_ROGUE: @@ -3375,7 +3345,11 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex)              // Blood Strike              if (m_spellInfo->SpellFamilyFlags[0] & 0x400000)              { -                AddPctF(totalDamagePercentMod, m_spellInfo->Effects[EFFECT_2].CalcValue() * unitTarget->GetDiseasesByCaster(m_caster->GetGUID()) / 2.0f); +                float bonusPct = m_spellInfo->Effects[EFFECT_2].CalcValue() * unitTarget->GetDiseasesByCaster(m_caster->GetGUID()) / 2.0f; +                // Death Knight T8 Melee 4P Bonus +                if (AuraEffect const* aurEff = m_caster->GetAuraEffect(64736, EFFECT_0)) +                    AddPctF(bonusPct, aurEff->GetAmount()); +                AddPctF(totalDamagePercentMod, bonusPct);                  // Glyph of Blood Strike                  if (m_caster->GetAuraEffect(59332, EFFECT_0)) @@ -3402,7 +3376,11 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex)                      if (roll_chance_i(aurEff->GetAmount()))                          consumeDiseases = false; -                AddPctF(totalDamagePercentMod, m_spellInfo->Effects[EFFECT_2].CalcValue() * unitTarget->GetDiseasesByCaster(m_caster->GetGUID(), consumeDiseases) / 2.0f); +                float bonusPct = m_spellInfo->Effects[EFFECT_2].CalcValue() * unitTarget->GetDiseasesByCaster(m_caster->GetGUID(), consumeDiseases) / 2.0f; +                // Death Knight T8 Melee 4P Bonus +                if (AuraEffect const* aurEff = m_caster->GetAuraEffect(64736, EFFECT_0)) +                    AddPctF(bonusPct, aurEff->GetAmount()); +                AddPctF(totalDamagePercentMod, bonusPct);                  break;              }              // Blood-Caked Strike - Blood-Caked Blade @@ -3414,7 +3392,12 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex)              // Heart Strike              if (m_spellInfo->SpellFamilyFlags[0] & 0x1000000)              { -                AddPctN(totalDamagePercentMod, m_spellInfo->Effects[EFFECT_2].CalcValue() * unitTarget->GetDiseasesByCaster(m_caster->GetGUID())); +                float bonusPct = m_spellInfo->Effects[EFFECT_2].CalcValue() * unitTarget->GetDiseasesByCaster(m_caster->GetGUID()); +                // Death Knight T8 Melee 4P Bonus +                if (AuraEffect const* aurEff = m_caster->GetAuraEffect(64736, EFFECT_0)) +                    AddPctF(bonusPct, aurEff->GetAmount()); + +                AddPctF(totalDamagePercentMod, bonusPct);                  break;              }              break; @@ -3524,15 +3507,6 @@ void Spell::EffectHealMaxHealth(SpellEffIndex /*effIndex*/)          return;      int32 addhealth = 0; -    if (m_spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN) // Lay on Hands -    { -        if (m_caster->GetGUID() == unitTarget->GetGUID()) -        { -            m_caster->CastSpell(m_caster, 25771, true); // Forbearance -            m_caster->CastSpell(m_caster, 61988, true); // Immune shield marker (serverside) -            m_caster->CastSpell(m_caster, 61987, true); // Avenging Wrath marker -        } -    }      // damage == 0 - heal for caster max health      if (damage == 0) @@ -3763,12 +3737,7 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex)                      if (!itemTarget && m_caster->GetTypeId() != TYPEID_PLAYER)                          return; -                    uint32 spell_id = 0; -                    switch (urand(1, 5)) -                    { -                    case 1:  spell_id = 8854; break; -                    default: spell_id = 8855; break; -                    } +                    uint32 spell_id = roll_chance_i(20) ? 8854 : 8855;                      m_caster->CastSpell(m_caster, spell_id, true, NULL);                      return; @@ -3815,10 +3784,6 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex)                      unitTarget->HandleEmoteCommand(EMOTE_STATE_DANCE);                      return;                  } -                // Escape artist -                case 20589: -                    m_caster->RemoveMovementImpairingAuras(); -                    return;                  // Decimate                  case 28374:                  case 54426: @@ -3849,15 +3814,8 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex)                          DoCreateItem(effIndex, item);                      break;                  } -                // Improved Sprint -                case 30918: -                { -                    // Removes snares and roots. -                    unitTarget->RemoveMovementImpairingAuras(); -                    break; -                } -                // Spirit Walk -                case 58876: +                case 20589: // Escape artist +                case 30918: // Improved Sprint                  {                      // Removes snares and roots.                      unitTarget->RemoveMovementImpairingAuras(); @@ -3875,96 +3833,6 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex)                          }                      }                      break; -                case 48025:                                     // Headless Horseman's Mount -                { -                    if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) -                        return; - -                    // Prevent stacking of mounts and client crashes upon dismounting -                    unitTarget->RemoveAurasByType(SPELL_AURA_MOUNTED); - -                    // Triggered spell id dependent on riding skill and zone -                    bool canFly = true; -                    uint32 v_map = GetVirtualMapForMapAndZone(unitTarget->GetMapId(), unitTarget->GetZoneId()); -                    if (v_map != 530 && v_map != 571) -                        canFly = false; - -                    if (canFly && v_map == 571 && !unitTarget->ToPlayer()->HasSpell(54197)) -                        canFly = false; - -                    float x, y, z; -                    unitTarget->GetPosition(x, y, z); -                    uint32 areaFlag = unitTarget->GetBaseMap()->GetAreaFlag(x, y, z); -                    AreaTableEntry const* pArea = sAreaStore.LookupEntry(areaFlag); -                    if (!pArea || (canFly && (pArea->flags & AREA_FLAG_NO_FLY_ZONE))) -                        canFly = false; - -                    switch (unitTarget->ToPlayer()->GetBaseSkillValue(SKILL_RIDING)) -                    { -                    case 75: unitTarget->CastSpell(unitTarget, 51621, true); break; -                    case 150: unitTarget->CastSpell(unitTarget, 48024, true); break; -                    case 225: -                        { -                            if (canFly) -                                unitTarget->CastSpell(unitTarget, 51617, true); -                            else -                                unitTarget->CastSpell(unitTarget, 48024, true); -                        }break; -                    case 300: -                        { -                            if (canFly) -                                unitTarget->CastSpell(unitTarget, 48023, true); -                            else -                                unitTarget->CastSpell(unitTarget, 48024, true); -                        }break; -                    } -                    return; -                } -                case 47977:                                     // Magic Broom -                { -                    if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) -                        return; - -                    // Prevent stacking of mounts and client crashes upon dismounting -                    unitTarget->RemoveAurasByType(SPELL_AURA_MOUNTED); - -                    // Triggered spell id dependent on riding skill and zone -                    bool canFly = true; -                    uint32 v_map = GetVirtualMapForMapAndZone(unitTarget->GetMapId(), unitTarget->GetZoneId()); -                    if (v_map != 530 && v_map != 571) -                        canFly = false; - -                    if (canFly && v_map == 571 && !unitTarget->ToPlayer()->HasSpell(54197)) -                        canFly = false; - -                    float x, y, z; -                    unitTarget->GetPosition(x, y, z); -                    uint32 areaFlag = unitTarget->GetBaseMap()->GetAreaFlag(x, y, z); -                    AreaTableEntry const* pArea = sAreaStore.LookupEntry(areaFlag); -                    if (!pArea || (canFly && (pArea->flags & AREA_FLAG_NO_FLY_ZONE))) -                        canFly = false; - -                    switch (unitTarget->ToPlayer()->GetBaseSkillValue(SKILL_RIDING)) -                    { -                    case 75: unitTarget->CastSpell(unitTarget, 42680, true); break; -                    case 150: unitTarget->CastSpell(unitTarget, 42683, true); break; -                    case 225: -                        { -                            if (canFly) -                                unitTarget->CastSpell(unitTarget, 42667, true); -                            else -                                unitTarget->CastSpell(unitTarget, 42683, true); -                        }break; -                    case 300: -                        { -                            if (canFly) -                                unitTarget->CastSpell(unitTarget, 42668, true); -                            else -                                unitTarget->CastSpell(unitTarget, 42683, true); -                        }break; -                    } -                    return; -                }                  // Mug Transformation                  case 41931:                  { @@ -4156,25 +4024,6 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex)                      if (unitTarget)                          unitTarget->CastSpell(m_caster, damage, true);                      return; -                // Winged Steed of the Ebon Blade -                case 54729: -                { -                    if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) -                        return; - -                    // Prevent stacking of mounts and client crashes upon dismounting -                    unitTarget->RemoveAurasByType(SPELL_AURA_MOUNTED); - -                    // Triggered spell id dependent on riding skill -                    if (uint16 skillval = unitTarget->ToPlayer()->GetSkillValue(SKILL_RIDING)) -                    { -                        if (skillval >= 300) -                            unitTarget->CastSpell(unitTarget, 54727, true); -                        else -                            unitTarget->CastSpell(unitTarget, 54726, true); -                    } -                    return; -                }                  case 57347: // Retrieving (Wintergrasp RP-GG pickup spell)                  {                      if (!unitTarget || unitTarget->GetTypeId() != TYPEID_UNIT || m_caster->GetTypeId() != TYPEID_PLAYER) @@ -4257,188 +4106,6 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex)                          m_caster->CastSpell(m_caster, 63919, true);                      return;                  } -                case 71342:                                     // Big Love Rocket -                { -                    if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) -                        return; - -                    // Prevent stacking of mounts and client crashes upon dismounting -                    unitTarget->RemoveAurasByType(SPELL_AURA_MOUNTED); - -                    // Triggered spell id dependent on riding skill and zone -                    bool canFly = true; -                    uint32 v_map = GetVirtualMapForMapAndZone(unitTarget->GetMapId(), unitTarget->GetZoneId()); -                    if (v_map != 530 && v_map != 571) -                        canFly = false; - -                    if (canFly && v_map == 571 && !unitTarget->ToPlayer()->HasSpell(54197)) -                        canFly = false; - -                    float x, y, z; -                    unitTarget->GetPosition(x, y, z); -                    uint32 areaFlag = unitTarget->GetBaseMap()->GetAreaFlag(x, y, z); -                    AreaTableEntry const* pArea = sAreaStore.LookupEntry(areaFlag); -                    if (!pArea || (canFly && (pArea->flags & AREA_FLAG_NO_FLY_ZONE))) -                        canFly = false; - -                    switch (unitTarget->ToPlayer()->GetBaseSkillValue(SKILL_RIDING)) -                    { -                    case 0: unitTarget->CastSpell(unitTarget, 71343, true); break; -                    case 75: unitTarget->CastSpell(unitTarget, 71344, true); break; -                    case 150: unitTarget->CastSpell(unitTarget, 71345, true); break; -                    case 225: -                        { -                        if (canFly) -                                unitTarget->CastSpell(unitTarget, 71346, true); -                            else -                                unitTarget->CastSpell(unitTarget, 71345, true); -                        }break; -                    case 300: -                        { -                        if (canFly) -                            unitTarget->CastSpell(unitTarget, 71347, true); -                        else -                            unitTarget->CastSpell(unitTarget, 71345, true); -                        }break; -                    } -                    return; -                } -                case 72286:                                     // Invincible -                { -                    if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) -                        return; - -                    // Prevent stacking of mounts and client crashes upon dismounting -                    unitTarget->RemoveAurasByType(SPELL_AURA_MOUNTED); - -                    // Triggered spell id dependent on riding skill and zone -                    bool canFly = true; -                    uint32 v_map = GetVirtualMapForMapAndZone(unitTarget->GetMapId(), unitTarget->GetZoneId()); -                    if (v_map != 530 && v_map != 571) -                        canFly = false; - -                    if (canFly && v_map == 571 && !unitTarget->ToPlayer()->HasSpell(54197)) -                        canFly = false; - -                    float x, y, z; -                    unitTarget->GetPosition(x, y, z); -                    uint32 areaFlag = unitTarget->GetBaseMap()->GetAreaFlag(x, y, z); -                    AreaTableEntry const* pArea = sAreaStore.LookupEntry(areaFlag); -                    if (!pArea || (canFly && (pArea->flags & AREA_FLAG_NO_FLY_ZONE))) -                        canFly = false; - -                    switch (unitTarget->ToPlayer()->GetBaseSkillValue(SKILL_RIDING)) -                    { -                    case 75: unitTarget->CastSpell(unitTarget, 72281, true); break; -                    case 150: unitTarget->CastSpell(unitTarget, 72282, true); break; -                    case 225: -                        { -                        if (canFly) -                                unitTarget->CastSpell(unitTarget, 72283, true); -                            else -                                unitTarget->CastSpell(unitTarget, 72282, true); -                        }break; -                    case 300: -                        { -                        if (canFly) -                            unitTarget->CastSpell(unitTarget, 72284, true); -                        else -                            unitTarget->CastSpell(unitTarget, 72282, true); -                        }break; -                    } -                    return; -                } -                case 74856:                                     // Blazing Hippogryph -                { -                    if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) -                        return; - -                    // Prevent stacking of mounts and client crashes upon dismounting -                    unitTarget->RemoveAurasByType(SPELL_AURA_MOUNTED); - -                    // Triggered spell id dependent on riding skill -                    if (uint16 skillval = unitTarget->ToPlayer()->GetSkillValue(SKILL_RIDING)) -                    { -                        if (skillval >= 300) -                            unitTarget->CastSpell(unitTarget, 74855, true); -                        else -                            unitTarget->CastSpell(unitTarget, 74854, true); -                    } -                    return; -                } -                case 75614:                                     // Celestial Steed -                { -                    if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) -                        return; - -                    // Prevent stacking of mounts and client crashes upon dismounting -                    unitTarget->RemoveAurasByType(SPELL_AURA_MOUNTED); - -                    // Triggered spell id dependent on riding skill and zone -                    bool canFly = true; -                    uint32 v_map = GetVirtualMapForMapAndZone(unitTarget->GetMapId(), unitTarget->GetZoneId()); -                    if (v_map != 530 && v_map != 571) -                        canFly = false; - -                    if (canFly && v_map == 571 && !unitTarget->ToPlayer()->HasSpell(54197)) -                        canFly = false; - -                    float x, y, z; -                    unitTarget->GetPosition(x, y, z); -                    uint32 areaFlag = unitTarget->GetBaseMap()->GetAreaFlag(x, y, z); -                    AreaTableEntry const* pArea = sAreaStore.LookupEntry(areaFlag); -                    if (!pArea || (canFly && (pArea->flags & AREA_FLAG_NO_FLY_ZONE))) -                        canFly = false; - -                    switch (unitTarget->ToPlayer()->GetBaseSkillValue(SKILL_RIDING)) -                    { -                        case 75: unitTarget->CastSpell(unitTarget, 75619, true); break; -                        case 150: unitTarget->CastSpell(unitTarget, 75620, true); break; -                        case 225: -                        { -                            if (canFly) -                                unitTarget->CastSpell(unitTarget, 75617, true); -                            else -                                unitTarget->CastSpell(unitTarget, 75620, true); -                        } -                        break; -                        case 300: -                        { -                            if (canFly) -                                unitTarget->CastSpell(unitTarget, 75618, true); -                            else -                                unitTarget->CastSpell(unitTarget, 75620, true); -                        } -                        break; -                        case 375: -                            if (canFly) -                                unitTarget->CastSpell(unitTarget, 76153, true); -                            else -                                unitTarget->CastSpell(unitTarget, 75620, true); -                            break; -                    } -                    return; -                } -                case 75973:                                     // X-53 Touring Rocket -                { -                    if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) -                        return; - -                    // Prevent stacking of mounts -                    unitTarget->RemoveAurasByType(SPELL_AURA_MOUNTED); - -                    // Triggered spell id dependent on riding skill -                    if (uint16 skillval = unitTarget->ToPlayer()->GetSkillValue(SKILL_RIDING)) -                    { -                        if (skillval >= 375) -                            unitTarget->CastSpell(unitTarget, 76154, true); -                        else if (skillval >= 300) -                            unitTarget->CastSpell(unitTarget, 75972, true); -                        else -                            unitTarget->CastSpell(unitTarget, 75957, true); -                    } -                    return; -                }                  case 59317:                                 // Teleporting                      if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)                          return; @@ -5058,16 +4725,14 @@ void Spell::EffectDisEnchant(SpellEffIndex /*effIndex*/)      if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)          return; -    if (m_caster->GetTypeId() != TYPEID_PLAYER) -        return; - -    Player* p_caster = (Player*)m_caster;      if (!itemTarget || !itemTarget->GetTemplate()->DisenchantID)          return; -    p_caster->UpdateCraftSkill(m_spellInfo->Id); - -    m_caster->ToPlayer()->SendLoot(itemTarget->GetGUID(), LOOT_DISENCHANTING); +    if (Player* caster = m_caster->ToPlayer()) +    { +        caster->UpdateCraftSkill(m_spellInfo->Id); +        caster->SendLoot(itemTarget->GetGUID(), LOOT_DISENCHANTING); +    }      // item will be removed at disenchanting end  } diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 183ca747b37..bb4815d5fc1 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -452,6 +452,7 @@ int32 SpellEffectInfo::CalcValue(Unit const* caster, int32 const* bp, Unit const          if (!basePointsPerLevel && (_spellInfo->Attributes & SPELL_ATTR0_LEVEL_DAMAGE_CALCULATION && _spellInfo->SpellLevel) &&                  Effect != SPELL_EFFECT_WEAPON_PERCENT_DAMAGE &&                  Effect != SPELL_EFFECT_KNOCK_BACK && +                Effect != SPELL_EFFECT_ADD_EXTRA_ATTACKS &&                  ApplyAuraName != SPELL_AURA_MOD_SPEED_ALWAYS &&                  ApplyAuraName != SPELL_AURA_MOD_SPEED_NOT_STACK &&                  ApplyAuraName != SPELL_AURA_MOD_INCREASE_SPEED && @@ -1810,6 +1811,7 @@ AuraStateType SpellInfo::GetAuraState() const      switch (Id)      {          case 71465: // Divine Surge +        case 50241: // Evasive Charges              return AURA_STATE_UNKNOWN22;          default:              break; diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 117953f2bc0..439b0c91324 100755 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -2960,8 +2960,10 @@ void SpellMgr::LoadDbcDataCorrections()          switch (spellInfo->Id)          { -            case 40244: case 40245: // Simon Game Visual -            case 40246: case 40247: // Simon Game Visual +            case 40244: // Simon Game Visual +            case 40245: // Simon Game Visual +            case 40246: // Simon Game Visual +            case 40247: // Simon Game Visual              case 42835: // Spout, remove damage effect, only anim is needed                  spellInfo->Effect[0] = 0;                  break; @@ -2973,7 +2975,6 @@ void SpellMgr::LoadDbcDataCorrections()                  spellInfo->EffectImplicitTargetB[0] = 0;                  break;              case 63665: // Charge (Argent Tournament emote on riders) -            case 31447: // Mark of Kaz'rogal (needs target selection script)              case 31298: // Sleep (needs target selection script)              case 51904: // Summon Ghouls On Scarlet Crusade (this should use conditions table, script for this spell needs to be fixed)              case 2895:  // Wrath of Air Totem rank 1 (Aura) @@ -3045,6 +3046,9 @@ void SpellMgr::LoadDbcDataCorrections()              case 48246: // Ball of Flame                  spellInfo->MaxAffectedTargets = 1;                  break; +            case 36384: // Skartax Purple Beam +                spellInfo->MaxAffectedTargets = 2; +                break;              case 41376: // Spite              case 39992: // Needle Spine              case 29576: // Multi-Shot @@ -3084,7 +3088,7 @@ void SpellMgr::LoadDbcDataCorrections()              case 50312: // Unholy Frenzy                  spellInfo->MaxAffectedTargets = 15;                  break; -            case 33711: //Murmur's Touch +            case 33711: // Murmur's Touch              case 38794:                  spellInfo->MaxAffectedTargets = 1;                  spellInfo->EffectTriggerSpell[0] = 33760; @@ -3125,6 +3129,9 @@ void SpellMgr::LoadDbcDataCorrections()              case 51852: // The Eye of Acherus (no spawn in phase 2 in db)                  spellInfo->EffectMiscValue[0] |= 1;                  break; +            case 51912: // Crafty's Ultra-Advanced Proto-Typical Shortening Blaster +                spellInfo->EffectAmplitude[0] = 3000; +                break;              case 29809: // Desecration Arm - 36 instead of 37 - typo? :/                  spellInfo->EffectRadiusIndex[0] = EFFECT_RADIUS_7_YARDS;                  break; @@ -3238,6 +3245,9 @@ void SpellMgr::LoadDbcDataCorrections()                  spellInfo->EffectDieSides[0] = 0; // was 1, that should probably mean seat 0, but instead it's treated as spell 1                  spellInfo->EffectBasePoints[0] = 52391; // Ride Vehicle (forces seat 0)                  break; +            case 45602: // Ride Carpet +                spellInfo->EffectBasePoints[EFFECT_0] = 0; // force seat 0, vehicle doesn't have the required seat flags for "no seat specified (-1)" +                break;              case 64745: // Item - Death Knight T8 Tank 4P Bonus              case 64936: // Item - Warrior T8 Protection 4P Bonus                  spellInfo->EffectBasePoints[0] = 100; // 100% chance of procc'ing, not -10% (chance calculated in PrepareTriggersExecutedOnHit) @@ -3252,9 +3262,16 @@ void SpellMgr::LoadDbcDataCorrections()              case 53313: // Entangling Roots (Rank 8) -- Nature's Grasp Proc                  spellInfo->CastingTimeIndex = 1;                  break; +            case 59414: // Pulsing Shockwave Aura (Loken) +                // this flag breaks movement, remove it +                spellInfo->AttributesEx &= ~SPELL_ATTR1_CHANNELED_1; +                break;              case 61719: // Easter Lay Noblegarden Egg Aura - Interrupt flags copied from aura which this aura is linked with                  spellInfo->AuraInterruptFlags = AURA_INTERRUPT_FLAG_HITBYSPELL | AURA_INTERRUPT_FLAG_TAKE_DAMAGE;                  break; +            case 70650: // Death Knight T10 Tank 2P Bonus +                spellInfo->EffectApplyAuraName[0] = SPELL_AURA_ADD_PCT_MODIFIER; +                break;              // ULDUAR SPELLS              //              case 62374: // Pursued (Flame Leviathan) @@ -3293,11 +3310,6 @@ void SpellMgr::LoadDbcDataCorrections()                  // that will be clear if we get more spells with problem like this                  spellInfo->AttributesEx |= SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY;                  break; -            case 62584: // Lifebinder's Gift -            case 64185: // Lifebinder's Gift -                spellInfo->EffectImplicitTargetB[1] = TARGET_UNIT_NEARBY_ENTRY; -                spellInfo->EffectImplicitTargetB[2] = TARGET_UNIT_NEARBY_ENTRY; -                break;              case 62301: // Cosmic Smash (Algalon the Observer)                  spellInfo->MaxAffectedTargets = 1;                  break; @@ -3429,7 +3441,7 @@ void SpellMgr::LoadDbcDataCorrections()                  spellInfo->EffectRadiusIndex[0] = EFFECT_RADIUS_200_YARDS;   // 200yd                  break;              case 70598: // Sindragosa's Fury -                spellInfo->EffectImplicitTargetA[0] = TARGET_DEST_CASTER; +                spellInfo->EffectImplicitTargetA[0] = TARGET_DEST_DEST;                  break;              case 69846: // Frost Bomb                  spellInfo->speed = 0.0f;    // This spell's summon happens instantly @@ -3539,11 +3551,6 @@ void SpellMgr::LoadDbcDataCorrections()          switch (spellInfo->SpellFamilyName)          { -            case SPELLFAMILY_DRUID: -                // Starfall Target Selection -                if (spellInfo->SpellFamilyFlags[2] & 0x100) -                    spellInfo->MaxAffectedTargets = 2; -                break;              case SPELLFAMILY_PALADIN:                  // Seals of the Pure should affect Seal of Righteousness                  if (spellInfo->SpellIconID == 25 && spellInfo->Attributes & SPELL_ATTR0_PASSIVE) diff --git a/src/server/game/Spells/SpellScript.cpp b/src/server/game/Spells/SpellScript.cpp index e6ce80c20f0..d0ae6fe3098 100755 --- a/src/server/game/Spells/SpellScript.cpp +++ b/src/server/game/Spells/SpellScript.cpp @@ -203,52 +203,106 @@ void SpellScript::HitHandler::Call(SpellScript* spellScript)      (spellScript->*pHitHandlerScript)();  } -SpellScript::UnitTargetHandler::UnitTargetHandler(SpellUnitTargetFnType _pUnitTargetHandlerScript, uint8 _effIndex, uint16 _targetType) -    : _SpellScript::EffectHook(_effIndex), targetType(_targetType) +SpellScript::TargetHook::TargetHook(uint8 _effectIndex, uint16 _targetType, bool _area) +    : _SpellScript::EffectHook(_effectIndex), targetType(_targetType), area(_area)  { -    pUnitTargetHandlerScript = _pUnitTargetHandlerScript;  } -std::string SpellScript::UnitTargetHandler::ToString() +std::string SpellScript::TargetHook::ToString()  {      std::ostringstream oss;      oss << "Index: " << EffIndexToString() << " Target: " << targetType;      return oss.str();  } -bool SpellScript::UnitTargetHandler::CheckEffect(SpellInfo const* spellEntry, uint8 effIndex) +bool SpellScript::TargetHook::CheckEffect(SpellInfo const* spellEntry, uint8 effIndex)  {      if (!targetType)          return false; -    return (effIndex == EFFECT_ALL) || (spellEntry->Effects[effIndex].TargetA.GetTarget() == targetType || spellEntry->Effects[effIndex].TargetB.GetTarget() == targetType); + +    if (spellEntry->Effects[effIndex].TargetA.GetTarget() != targetType && +        spellEntry->Effects[effIndex].TargetB.GetTarget() != targetType) +        return false; + +    SpellImplicitTargetInfo targetInfo(targetType); +    switch (targetInfo.GetSelectionCategory()) +    { +        case TARGET_SELECT_CATEGORY_CHANNEL: // SINGLE +            return !area; +        case TARGET_SELECT_CATEGORY_NEARBY: // BOTH +            return true; +        case TARGET_SELECT_CATEGORY_CONE: // AREA +        case TARGET_SELECT_CATEGORY_AREA: // AREA +            return area; +        case TARGET_SELECT_CATEGORY_DEFAULT: +            switch (targetInfo.GetObjectType()) +            { +                case TARGET_OBJECT_TYPE_SRC: // EMPTY +                case TARGET_OBJECT_TYPE_DEST: // EMPTY +                    return false; +                default: +                    switch (targetInfo.GetReferenceType()) +                    { +                        case TARGET_REFERENCE_TYPE_CASTER: // SINGLE +                            return !area; +                        case TARGET_REFERENCE_TYPE_TARGET: // BOTH +                            return true; +                    } +                    break; +            } +            break; +    } + +    return false; +} + +SpellScript::ObjectAreaTargetSelectHandler::ObjectAreaTargetSelectHandler(SpellObjectAreaTargetSelectFnType _pObjectAreaTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType) +    : TargetHook(_effIndex, _targetType, true) +{ +    pObjectAreaTargetSelectHandlerScript = _pObjectAreaTargetSelectHandlerScript; +} + +void SpellScript::ObjectAreaTargetSelectHandler::Call(SpellScript* spellScript, std::list<WorldObject*>& targets) +{ +    (spellScript->*pObjectAreaTargetSelectHandlerScript)(targets);  } -void SpellScript::UnitTargetHandler::Call(SpellScript* spellScript, std::list<Unit*>& unitTargets) +SpellScript::ObjectTargetSelectHandler::ObjectTargetSelectHandler(SpellObjectTargetSelectFnType _pObjectTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType) +    : TargetHook(_effIndex, _targetType, false)  { -    (spellScript->*pUnitTargetHandlerScript)(unitTargets); +    pObjectTargetSelectHandlerScript = _pObjectTargetSelectHandlerScript; +} + +void SpellScript::ObjectTargetSelectHandler::Call(SpellScript* spellScript, WorldObject*& target) +{ +    (spellScript->*pObjectTargetSelectHandlerScript)(target);  }  bool SpellScript::_Validate(SpellInfo const* entry)  { -    for (std::list<EffectHandler>::iterator itr = OnEffectLaunch.begin(); itr != OnEffectLaunch.end();  ++itr) +    for (std::list<EffectHandler>::iterator itr = OnEffectLaunch.begin(); itr != OnEffectLaunch.end(); ++itr)          if (!(*itr).GetAffectedEffectsMask(entry))              sLog->outError("TSCR: Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnEffectLaunch` of SpellScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str()); -    for (std::list<EffectHandler>::iterator itr = OnEffectLaunchTarget.begin(); itr != OnEffectLaunchTarget.end();  ++itr) +    for (std::list<EffectHandler>::iterator itr = OnEffectLaunchTarget.begin(); itr != OnEffectLaunchTarget.end(); ++itr)          if (!(*itr).GetAffectedEffectsMask(entry))              sLog->outError("TSCR: Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnEffectLaunchTarget` of SpellScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str()); -    for (std::list<EffectHandler>::iterator itr = OnEffectHit.begin(); itr != OnEffectHit.end();  ++itr) +    for (std::list<EffectHandler>::iterator itr = OnEffectHit.begin(); itr != OnEffectHit.end(); ++itr)          if (!(*itr).GetAffectedEffectsMask(entry))              sLog->outError("TSCR: Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnEffectHit` of SpellScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str()); -    for (std::list<EffectHandler>::iterator itr = OnEffectHitTarget.begin(); itr != OnEffectHitTarget.end();  ++itr) +    for (std::list<EffectHandler>::iterator itr = OnEffectHitTarget.begin(); itr != OnEffectHitTarget.end(); ++itr)          if (!(*itr).GetAffectedEffectsMask(entry))              sLog->outError("TSCR: Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnEffectHitTarget` of SpellScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str()); -    for (std::list<UnitTargetHandler>::iterator itr = OnUnitTargetSelect.begin(); itr != OnUnitTargetSelect.end();  ++itr) +    for (std::list<ObjectAreaTargetSelectHandler>::iterator itr = OnObjectAreaTargetSelect.begin(); itr != OnObjectAreaTargetSelect.end(); ++itr) +        if (!(*itr).GetAffectedEffectsMask(entry)) +            sLog->outError("TSCR: Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnObjectAreaTargetSelect` of SpellScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str()); + +    for (std::list<ObjectTargetSelectHandler>::iterator itr = OnObjectTargetSelect.begin(); itr != OnObjectTargetSelect.end(); ++itr)          if (!(*itr).GetAffectedEffectsMask(entry)) -            sLog->outError("TSCR: Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnUnitTargetSelect` of SpellScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str()); +            sLog->outError("TSCR: Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnObjectTargetSelect` of SpellScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str());      return _SpellScript::_Validate(entry);  } diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h index 7b194b7827f..376e7f18edc 100755 --- a/src/server/game/Spells/SpellScript.h +++ b/src/server/game/Spells/SpellScript.h @@ -131,7 +131,8 @@ enum SpellScriptHookType      SPELL_SCRIPT_HOOK_BEFORE_HIT,      SPELL_SCRIPT_HOOK_HIT,      SPELL_SCRIPT_HOOK_AFTER_HIT, -    SPELL_SCRIPT_HOOK_UNIT_TARGET_SELECT, +    SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT, +    SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT,      SPELL_SCRIPT_HOOK_CHECK_CAST,      SPELL_SCRIPT_HOOK_BEFORE_CAST,      SPELL_SCRIPT_HOOK_ON_CAST, @@ -154,7 +155,8 @@ class SpellScript : public _SpellScript              typedef void(CLASSNAME::*SpellEffectFnType)(SpellEffIndex); \              typedef void(CLASSNAME::*SpellHitFnType)(); \              typedef void(CLASSNAME::*SpellCastFnType)(); \ -            typedef void(CLASSNAME::*SpellUnitTargetFnType)(std::list<Unit*>&); \ +            typedef void(CLASSNAME::*SpellObjectAreaTargetSelectFnType)(std::list<WorldObject*>&); \ +            typedef void(CLASSNAME::*SpellObjectTargetSelectFnType)(WorldObject*&);          SPELLSCRIPT_FUNCTION_TYPE_DEFINES(SpellScript) @@ -196,16 +198,33 @@ class SpellScript : public _SpellScript                  SpellHitFnType pHitHandlerScript;          }; -        class UnitTargetHandler : public _SpellScript::EffectHook +        class TargetHook : public _SpellScript::EffectHook          {              public: -                UnitTargetHandler(SpellUnitTargetFnType _pUnitTargetHandlerScript, uint8 _effIndex, uint16 _targetType); +                TargetHook(uint8 _effectIndex, uint16 _targetType, bool _area); +                bool CheckEffect(SpellInfo const* spellEntry, uint8 effIndex);                  std::string ToString(); -                bool CheckEffect(SpellInfo const* spellEntry, uint8 targetType); -                void Call(SpellScript* spellScript, std::list<Unit*>& unitTargets); -            private: -                SpellUnitTargetFnType pUnitTargetHandlerScript; +            protected:                  uint16 targetType; +                bool area; +        }; + +        class ObjectAreaTargetSelectHandler : public TargetHook +        { +            public: +                ObjectAreaTargetSelectHandler(SpellObjectAreaTargetSelectFnType _pObjectAreaTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType); +                void Call(SpellScript* spellScript, std::list<WorldObject*>& targets); +            private: +                SpellObjectAreaTargetSelectFnType pObjectAreaTargetSelectHandlerScript; +        }; + +        class ObjectTargetSelectHandler : public TargetHook +        { +            public: +                ObjectTargetSelectHandler(SpellObjectTargetSelectFnType _pObjectTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType); +                void Call(SpellScript* spellScript, WorldObject*& targets); +            private: +                SpellObjectTargetSelectFnType pObjectTargetSelectHandlerScript;          };          #define SPELLSCRIPT_FUNCTION_CAST_DEFINES(CLASSNAME) \ @@ -213,7 +232,8 @@ class SpellScript : public _SpellScript          class CheckCastHandlerFunction : public SpellScript::CheckCastHandler { public: CheckCastHandlerFunction(SpellCheckCastFnType _checkCastHandlerScript) : SpellScript::CheckCastHandler((SpellScript::SpellCheckCastFnType)_checkCastHandlerScript) {} }; \          class EffectHandlerFunction : public SpellScript::EffectHandler { public: EffectHandlerFunction(SpellEffectFnType _pEffectHandlerScript, uint8 _effIndex, uint16 _effName) : SpellScript::EffectHandler((SpellScript::SpellEffectFnType)_pEffectHandlerScript, _effIndex, _effName) {} }; \          class HitHandlerFunction : public SpellScript::HitHandler { public: HitHandlerFunction(SpellHitFnType _pHitHandlerScript) : SpellScript::HitHandler((SpellScript::SpellHitFnType)_pHitHandlerScript) {} }; \ -        class UnitTargetHandlerFunction : public SpellScript::UnitTargetHandler { public: UnitTargetHandlerFunction(SpellUnitTargetFnType _pUnitTargetHandlerScript, uint8 _effIndex, uint16 _targetType) : SpellScript::UnitTargetHandler((SpellScript::SpellUnitTargetFnType)_pUnitTargetHandlerScript, _effIndex, _targetType) {} }; \ +        class ObjectAreaTargetSelectHandlerFunction : public SpellScript::ObjectAreaTargetSelectHandler { public: ObjectAreaTargetSelectHandlerFunction(SpellObjectAreaTargetSelectFnType _pObjectAreaTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType) : SpellScript::ObjectAreaTargetSelectHandler((SpellScript::SpellObjectAreaTargetSelectFnType)_pObjectAreaTargetSelectHandlerScript, _effIndex, _targetType) {} }; \ +        class ObjectTargetSelectHandlerFunction : public SpellScript::ObjectTargetSelectHandler { public: ObjectTargetSelectHandlerFunction(SpellObjectTargetSelectFnType _pObjectTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType) : SpellScript::ObjectTargetSelectHandler((SpellScript::SpellObjectTargetSelectFnType)_pObjectTargetSelectHandlerScript, _effIndex, _targetType) {} };          #define PrepareSpellScript(CLASSNAME) SPELLSCRIPT_FUNCTION_TYPE_DEFINES(CLASSNAME) SPELLSCRIPT_FUNCTION_CAST_DEFINES(CLASSNAME)      public: @@ -267,15 +287,21 @@ class SpellScript : public _SpellScript          // where function is: void function()          #define SpellHitFn(F) HitHandlerFunction(&F) -        // example: OnUnitTargetSelect += SpellUnitTargetFn(class::function, EffectIndexSpecifier, TargetsNameSpecifier); -        // where function is void function(std::list<Unit*>& targetList) -        HookList<UnitTargetHandler> OnUnitTargetSelect; -        #define SpellUnitTargetFn(F, I, N) UnitTargetHandlerFunction(&F, I, N) +        // example: OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(class::function, EffectIndexSpecifier, TargetsNameSpecifier); +        // where function is void function(std::list<WorldObject*>& targets) +        HookList<ObjectAreaTargetSelectHandler> OnObjectAreaTargetSelect; +        #define SpellObjectAreaTargetSelectFn(F, I, N) ObjectAreaTargetSelectHandlerFunction(&F, I, N) + +        // example: OnObjectTargetSelect += SpellObjectTargetSelectFn(class::function, EffectIndexSpecifier, TargetsNameSpecifier); +        // where function is void function(WorldObject*& target) +        HookList<ObjectTargetSelectHandler> OnObjectTargetSelect; +        #define SpellObjectTargetSelectFn(F, I, N) ObjectTargetSelectHandlerFunction(&F, I, N)          // hooks are executed in following order, at specified event of spell:          // 1. BeforeCast - executed when spell preparation is finished (when cast bar becomes full) before cast is handled          // 2. OnCheckCast - allows to override result of CheckCast function -        // 3. OnUnitTargetSelect - executed just before adding selected targets to final target list +        // 3a. OnObjectAreaTargetSelect - executed just before adding selected targets to final target list (for area targets) +        // 3b. OnObjectTargetSelect - executed just before adding selected target to final target list (for single unit targets)          // 4. OnCast - executed just before spell is launched (creates missile) or executed          // 5. AfterCast - executed after spell missile is launched and immediate spell actions are done          // 6. OnEffectLaunch - executed just before specified effect handler call - when spell missile is launched @@ -302,7 +328,7 @@ class SpellScript : public _SpellScript          // -shadowstep - explicit target is the unit you want to go behind of          // -chain heal - explicit target is the unit to be healed first          // -holy nova/arcane explosion - explicit target = NULL because target you are selecting doesn't affect how spell targets are selected -        // you can determine if spell requires explicit targets by dbc columns:  +        // you can determine if spell requires explicit targets by dbc columns:          // - Targets - mask of explicit target types          // - ImplicitTargetXX set to TARGET_XXX_TARGET_YYY, _TARGET_ here means that explicit target is used by the effect, so spell needs one too diff --git a/src/server/game/Warden/Warden.cpp b/src/server/game/Warden/Warden.cpp index 0734e0a0f63..54e56174b1a 100644 --- a/src/server/game/Warden/Warden.cpp +++ b/src/server/game/Warden/Warden.cpp @@ -188,11 +188,14 @@ std::string Warden::Penalty(WardenCheck* check /*= NULL*/)              std::string accountName;              AccountMgr::GetName(_session->GetAccountId(), accountName);              std::stringstream banReason; -            banReason << "Warden Anticheat Violation: " << check->Comment << " (CheckId: " << check->CheckId << ")"; +            banReason << "Warden Anticheat Violation"; +            // Check can be NULL, for example if the client sent a wrong signature in the warden packet (CHECKSUM FAIL) +            if (check) +                banReason << ": " << check->Comment << " (CheckId: " << check->CheckId << ")"; +              sWorld->BanAccount(BAN_ACCOUNT, accountName, duration.str(), banReason.str(),"Server");              return "Ban"; -            break;          }      default:          break; @@ -208,7 +211,7 @@ void WorldSession::HandleWardenDataOpcode(WorldPacket& recvData)      sLog->outDebug(LOG_FILTER_WARDEN, "Got packet, opcode %02X, size %u", opcode, uint32(recvData.size()));      recvData.hexlike(); -    switch(opcode) +    switch (opcode)      {          case WARDEN_CMSG_MODULE_MISSING:              _warden->SendModuleToClient(); diff --git a/src/server/game/Warden/WardenCheckMgr.cpp b/src/server/game/Warden/WardenCheckMgr.cpp index f4c7a5069cf..abd7ff8f87d 100644 --- a/src/server/game/Warden/WardenCheckMgr.cpp +++ b/src/server/game/Warden/WardenCheckMgr.cpp @@ -121,7 +121,7 @@ void WardenCheckMgr::LoadWardenChecks()          if (checkType == MPQ_CHECK || checkType == MEM_CHECK)          { -            WardenCheckResult *wr = new WardenCheckResult(); +            WardenCheckResult* wr = new WardenCheckResult();              wr->Result.SetHexStr(checkResult.c_str());              int len = checkResult.size() / 2;              if (wr->Result.GetNumBytes() < len) diff --git a/src/server/game/Warden/WardenMac.cpp b/src/server/game/Warden/WardenMac.cpp index a60ae765013..3cc95b9f3f7 100644 --- a/src/server/game/Warden/WardenMac.cpp +++ b/src/server/game/Warden/WardenMac.cpp @@ -43,8 +43,8 @@ void WardenMac::Init(WorldSession *pClient, BigNumber *K)      _session = pClient;      // Generate Warden Key      SHA1Randx WK(K->AsByteArray(), K->GetNumBytes()); -    WK.generate(_inputKey, 16); -    WK.generate(_outputKey, 16); +    WK.Generate(_inputKey, 16); +    WK.Generate(_outputKey, 16);      /*      Seed: 4D808D2C77D905C41A6380EC08586AFE (0x05 packet)      Hash: <?> (0x04 packet) @@ -222,7 +222,7 @@ void WardenMac::HandleData(ByteBuffer &buff)      //    return;      //} -    bool found = false; +    //bool found = false;      std::string str = "Test string!"; @@ -238,7 +238,7 @@ void WardenMac::HandleData(ByteBuffer &buff)      if (memcmp(sha1Hash, sha1.GetDigest(), 20))      {          sLog->outDebug(LOG_FILTER_WARDEN, "Handle data failed: SHA1 hash is wrong!"); -        found = true; +        //found = true;      }      MD5_CTX ctx; @@ -253,7 +253,7 @@ void WardenMac::HandleData(ByteBuffer &buff)      if (memcmp(ourMD5Hash, theirsMD5Hash, 16))      {          sLog->outDebug(LOG_FILTER_WARDEN, "Handle data failed: MD5 hash is wrong!"); -        found = true; +        //found = true;      }      _session->KickPlayer(); diff --git a/src/server/game/Warden/WardenWin.cpp b/src/server/game/Warden/WardenWin.cpp index a7485d7da51..9aa439ec8c0 100644 --- a/src/server/game/Warden/WardenWin.cpp +++ b/src/server/game/Warden/WardenWin.cpp @@ -47,8 +47,8 @@ void WardenWin::Init(WorldSession* session, BigNumber *k)      _session = session;      // Generate Warden Key      SHA1Randx WK(k->AsByteArray(), k->GetNumBytes()); -    WK.generate(_inputKey, 16); -    WK.generate(_outputKey, 16); +    WK.Generate(_inputKey, 16); +    WK.Generate(_outputKey, 16);      memcpy(_seed, Module.Seed, 16); diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index a3b9054bd68..fc46d8d2d60 100755 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1023,6 +1023,7 @@ void World::LoadConfigSettings(bool reload)      m_bool_configs[CONFIG_BG_XP_FOR_KILL]                            = ConfigMgr::GetBoolDefault("Battleground.GiveXPForKills", false);      m_int_configs[CONFIG_ARENA_MAX_RATING_DIFFERENCE]                = ConfigMgr::GetIntDefault ("Arena.MaxRatingDifference", 150);      m_int_configs[CONFIG_ARENA_RATING_DISCARD_TIMER]                 = ConfigMgr::GetIntDefault ("Arena.RatingDiscardTimer", 10 * MINUTE * IN_MILLISECONDS); +    m_int_configs[CONFIG_ARENA_RATED_UPDATE_TIMER]                   = ConfigMgr::GetIntDefault ("Arena.RatedUpdateTimer", 5 * IN_MILLISECONDS);      m_bool_configs[CONFIG_ARENA_AUTO_DISTRIBUTE_POINTS]              = ConfigMgr::GetBoolDefault("Arena.AutoDistributePoints", false);      m_int_configs[CONFIG_ARENA_AUTO_DISTRIBUTE_INTERVAL_DAYS]        = ConfigMgr::GetIntDefault ("Arena.AutoDistributeInterval", 7);      m_bool_configs[CONFIG_ARENA_QUEUE_ANNOUNCER_ENABLE]              = ConfigMgr::GetBoolDefault("Arena.QueueAnnouncer.Enable", false); @@ -1413,15 +1414,9 @@ void World::SetInitialWorldSettings()      sLog->outString("Loading Creature Addon Data...");      sObjectMgr->LoadCreatureAddons();                            // must be after LoadCreatureTemplates() and LoadCreatures() -    sLog->outString("Loading Creature Respawn Data...");         // must be after PackInstances() -    sObjectMgr->LoadCreatureRespawnTimes(); -      sLog->outString("Loading Gameobject Data...");      sObjectMgr->LoadGameobjects(); -    sLog->outString("Loading Gameobject Respawn Data...");       // must be after PackInstances() -    sObjectMgr->LoadGameobjectRespawnTimes(); -      sLog->outString("Loading Creature Linked Respawn...");      sObjectMgr->LoadLinkedRespawn();                             // must be after LoadCreatures(), LoadGameObjects() diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index 51f384770da..450183226fc 100755 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -289,6 +289,7 @@ enum WorldIntConfigs      CONFIG_BATTLEGROUND_PREMADE_GROUP_WAIT_FOR_MATCH,      CONFIG_ARENA_MAX_RATING_DIFFERENCE,      CONFIG_ARENA_RATING_DISCARD_TIMER, +    CONFIG_ARENA_RATED_UPDATE_TIMER,      CONFIG_ARENA_AUTO_DISTRIBUTE_INTERVAL_DAYS,      CONFIG_ARENA_SEASON_ID,      CONFIG_ARENA_START_RATING, diff --git a/src/server/scripts/Commands/CMakeLists.txt b/src/server/scripts/Commands/CMakeLists.txt index 86fe984e197..c27b51a1ca2 100644 --- a/src/server/scripts/Commands/CMakeLists.txt +++ b/src/server/scripts/Commands/CMakeLists.txt @@ -12,30 +12,30 @@ set(scripts_STAT_SRCS    ${scripts_STAT_SRCS}    Commands/cs_account.cpp    Commands/cs_achievement.cpp +  Commands/cs_cast.cpp +  Commands/cs_character.cpp    Commands/cs_debug.cpp    Commands/cs_event.cpp    Commands/cs_gm.cpp    Commands/cs_go.cpp    Commands/cs_gobject.cpp    Commands/cs_honor.cpp +  Commands/cs_instance.cpp    Commands/cs_learn.cpp +  Commands/cs_list.cpp    Commands/cs_misc.cpp    Commands/cs_modify.cpp    Commands/cs_npc.cpp    Commands/cs_quest.cpp    Commands/cs_reload.cpp +  Commands/cs_reset.cpp    Commands/cs_tele.cpp +  Commands/cs_server.cpp    Commands/cs_titles.cpp    Commands/cs_wp.cpp -#  Commands/cs_character.cpp -#  Commands/cs_list.cpp  #  Commands/cs_lookup.cpp  #  Commands/cs_pdump.cpp  #  Commands/cs_guild.cpp -#  Commands/cs_cast.cpp -#  Commands/cs_reset.cpp -#  Commands/cs_instance.cpp -#  Commands/cs_server.cpp  #  Commands/cs_channel.cpp  #  Commands/cs_pet.cpp  #  Commands/cs_ticket.cpp diff --git a/src/server/scripts/Commands/cs_cast.cpp b/src/server/scripts/Commands/cs_cast.cpp new file mode 100644 index 00000000000..33983411427 --- /dev/null +++ b/src/server/scripts/Commands/cs_cast.cpp @@ -0,0 +1,310 @@ +/* + * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* ScriptData +Name: cast_commandscript +%Complete: 100 +Comment: All cast related commands +Category: commandscripts +EndScriptData */ + +#include "ScriptMgr.h" +#include "Chat.h" + +class cast_commandscript : public CommandScript +{ +public: +    cast_commandscript() : CommandScript("cast_commandscript") { } + +    ChatCommand* GetCommands() const +    { +        static ChatCommand castCommandTable[] = +        {    +            { "back",           SEC_ADMINISTRATOR,  false, &HandleCastBackCommand,              "", NULL }, +            { "dist",           SEC_ADMINISTRATOR,  false, &HandleCastDistCommand,              "", NULL }, +            { "self",           SEC_ADMINISTRATOR,  false, &HandleCastSelfCommand,              "", NULL }, +            { "target",         SEC_ADMINISTRATOR,  false, &HandleCastTargetCommad,             "", NULL }, +            { "dest",           SEC_ADMINISTRATOR,  false, &HandleCastDestCommand,              "", NULL }, +            { "",               SEC_ADMINISTRATOR,  false, &HandleCastCommand,                  "", NULL }, +            { NULL,             0,                  false, NULL,                                "", NULL } +        }; +        static ChatCommand commandTable[] = +        { +            { "cast",           SEC_ADMINISTRATOR,  false, NULL,                                "", castCommandTable }, +            { NULL,             0,                  false, NULL,                                "", NULL } +        }; +        return commandTable; +    } + +    static bool HandleCastCommand(ChatHandler* handler, char const* args) +    { +        if (!*args) +            return false; + +        Unit* target = handler->getSelectedUnit(); +        if (!target) +        { +            handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); +            handler->SetSentErrorMessage(true); +            return false; +        } + +        // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form +        uint32 spellId = handler->extractSpellIdFromLink((char*)args); +        if (!spellId) +            return false; + +        SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); +        if (!spellInfo) +        { +            handler->PSendSysMessage(LANG_COMMAND_NOSPELLFOUND); +            handler->SetSentErrorMessage(true); +            return false; +        } + +        if (!SpellMgr::IsSpellValid(spellInfo, handler->GetSession()->GetPlayer())) +        { +            handler->PSendSysMessage(LANG_COMMAND_SPELL_BROKEN, spellId); +            handler->SetSentErrorMessage(true); +            return false; +        } + +        char* triggeredStr = strtok(NULL, " "); +        if (triggeredStr) +        { +            int l = strlen(triggeredStr); +            if (strncmp(triggeredStr, "triggered", l) != 0) +                return false; +        } + +        bool triggered = (triggeredStr != NULL); + +        handler->GetSession()->GetPlayer()->CastSpell(target, spellId, triggered); + +        return true; +    } + +    static bool HandleCastBackCommand(ChatHandler* handler, char const* args) +    { +        Creature* caster = handler->getSelectedCreature(); +        if (!caster) +        { +            handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); +            handler->SetSentErrorMessage(true); +            return false; +        } + +        // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r +        // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form +        uint32 spellId = handler->extractSpellIdFromLink((char*)args); +        if (!spellId || !sSpellMgr->GetSpellInfo(spellId)) +        { +            handler->PSendSysMessage(LANG_COMMAND_NOSPELLFOUND); +            handler->SetSentErrorMessage(true); +            return false; +        } + +        char* triggeredStr = strtok(NULL, " "); +        if (triggeredStr) +        { +            int l = strlen(triggeredStr); +            if (strncmp(triggeredStr, "triggered", l) != 0) +                return false; +        } + +        bool triggered = (triggeredStr != NULL); + +        caster->CastSpell(handler->GetSession()->GetPlayer(), spellId, triggered); + +        return true; +    } + +    static bool HandleCastDistCommand(ChatHandler* handler, char const* args) +    { +        if (!*args) +            return false; + +        // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form +        uint32 spellId = handler->extractSpellIdFromLink((char*)args); +        if (!spellId) +            return false; + +        SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); +        if (!spellInfo) +        { +            handler->PSendSysMessage(LANG_COMMAND_NOSPELLFOUND); +            handler->SetSentErrorMessage(true); +            return false; +        } + +        if (!SpellMgr::IsSpellValid(spellInfo, handler->GetSession()->GetPlayer())) +        { +            handler->PSendSysMessage(LANG_COMMAND_SPELL_BROKEN, spellId); +            handler->SetSentErrorMessage(true); +            return false; +        } + +        char* distStr = strtok(NULL, " "); + +        float dist = 0; + +        if (distStr) +            sscanf(distStr, "%f", &dist); + +        char* triggeredStr = strtok(NULL, " "); +        if (triggeredStr) +        { +            int l = strlen(triggeredStr); +            if (strncmp(triggeredStr, "triggered", l) != 0) +                return false; +        } + +        bool triggered = (triggeredStr != NULL); + +        float x, y, z; +        handler->GetSession()->GetPlayer()->GetClosePoint(x, y, z, dist); + +        handler->GetSession()->GetPlayer()->CastSpell(x, y, z, spellId, triggered); + +        return true; +    } + +    static bool HandleCastSelfCommand(ChatHandler* handler, char const* args) +    { +        if (!*args) +            return false; + +        Unit* target = handler->getSelectedUnit(); +        if (!target) +        { +            handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); +            handler->SetSentErrorMessage(true); +            return false; +        } + +        // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form +        uint32 spellId = handler->extractSpellIdFromLink((char*)args); +        if (!spellId) +            return false; + +        SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); +        if (!spellInfo) +            return false; + +        if (!SpellMgr::IsSpellValid(spellInfo, handler->GetSession()->GetPlayer())) +        { +            handler->PSendSysMessage(LANG_COMMAND_SPELL_BROKEN, spellId); +            handler->SetSentErrorMessage(true); +            return false; +        } + +        target->CastSpell(target, spellId, false); + +        return true; +    } + +    static bool HandleCastTargetCommad(ChatHandler* handler, char const* args) +    { +        Creature* caster = handler->getSelectedCreature(); +        if (!caster) +        { +            handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); +            handler->SetSentErrorMessage(true); +            return false; +        } + +        if (!caster->getVictim()) +        { +            handler->SendSysMessage(LANG_SELECTED_TARGET_NOT_HAVE_VICTIM); +            handler->SetSentErrorMessage(true); +            return false; +        } + +        // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form +        uint32 spellId = handler->extractSpellIdFromLink((char*)args); +        if (!spellId || !sSpellMgr->GetSpellInfo(spellId)) +        { +            handler->PSendSysMessage(LANG_COMMAND_NOSPELLFOUND); +            handler->SetSentErrorMessage(true); +            return false; +        } + +        char* triggeredStr = strtok(NULL, " "); +        if (triggeredStr) +        { +            int l = strlen(triggeredStr); +            if (strncmp(triggeredStr, "triggered", l) != 0) +                return false; +        } + +        bool triggered = (triggeredStr != NULL); + +        caster->CastSpell(caster->getVictim(), spellId, triggered); + +        return true; +    } + +    static bool HandleCastDestCommand(ChatHandler* handler, char const* args) +    { +        Unit* caster = handler->getSelectedUnit(); +        if (!caster) +        { +            handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); +            handler->SetSentErrorMessage(true); +            return false; +        } + +        // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form +        uint32 spellId = handler->extractSpellIdFromLink((char*)args); +        if (!spellId || !sSpellMgr->GetSpellInfo(spellId)) +        { +            handler->PSendSysMessage(LANG_COMMAND_NOSPELLFOUND); +            handler->SetSentErrorMessage(true); +            return false; +        } + +        char* posX = strtok(NULL, " "); +        char* posY = strtok(NULL, " "); +        char* posZ = strtok(NULL, " "); + +        if (!posX || !posY || !posZ) +            return false; + +        float x = float(atof(posX)); +        float y = float(atof(posY)); +        float z = float(atof(posZ)); + +        char* triggeredStr = strtok(NULL, " "); +        if (triggeredStr) +        { +            int l = strlen(triggeredStr); +            if (strncmp(triggeredStr, "triggered", l) != 0) +                return false; +        } + +        bool triggered = (triggeredStr != NULL); + +        caster->CastSpell(x, y, z, spellId, triggered); + +        return true; +    } +}; + +void AddSC_cast_commandscript() +{ +    new cast_commandscript(); +} diff --git a/src/server/scripts/Commands/cs_character.cpp b/src/server/scripts/Commands/cs_character.cpp new file mode 100644 index 00000000000..e6d397ead2b --- /dev/null +++ b/src/server/scripts/Commands/cs_character.cpp @@ -0,0 +1,679 @@ +/* + * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* ScriptData +Name: character_commandscript +%Complete: 100 +Comment: All character related commands +Category: commandscripts +EndScriptData */ + +#include "ScriptMgr.h" +#include "Chat.h" +#include "AccountMgr.h" +#include "ObjectMgr.h" + +class character_commandscript : public CommandScript +{ +public: +    character_commandscript() : CommandScript("character_commandscript") { } + +    ChatCommand* GetCommands() const +    { +        static ChatCommand characterDeletedCommandTable[] = +        { +            { "delete",         SEC_CONSOLE,        true,  &HandleCharacterDeletedDeleteCommand,   "", NULL }, +            { "list",           SEC_ADMINISTRATOR,  true,  &HandleCharacterDeletedListCommand,     "", NULL }, +            { "restore",        SEC_ADMINISTRATOR,  true,  &HandleCharacterDeletedRestoreCommand,  "", NULL }, +            { "old",            SEC_CONSOLE,        true,  &HandleCharacterDeletedOldCommand,      "", NULL }, +            { NULL,             0,                  false, NULL,                                   "", NULL } +        }; + +        static ChatCommand characterCommandTable[] = +        { +            { "customize",      SEC_GAMEMASTER,     true,  &HandleCharacterCustomizeCommand,       "", NULL }, +            { "changefaction",  SEC_GAMEMASTER,     true,  &HandleCharacterChangeFactionCommand,   "", NULL }, +            { "changerace",     SEC_GAMEMASTER,     true,  &HandleCharacterChangeRaceCommand,      "", NULL }, +            { "deleted",        SEC_GAMEMASTER,     true,  NULL,                                   "", characterDeletedCommandTable}, +            { "erase",          SEC_CONSOLE,        true,  &HandleCharacterEraseCommand,           "", NULL }, +            { "level",          SEC_ADMINISTRATOR,  true,  &HandleCharacterLevelCommand,           "", NULL }, +            { "rename",         SEC_GAMEMASTER,     true,  &HandleCharacterRenameCommand,          "", NULL }, +            { "reputation",     SEC_GAMEMASTER,     true,  &HandleCharacterReputationCommand,      "", NULL }, +            { "titles",         SEC_GAMEMASTER,     true,  &HandleCharacterTitlesCommand,          "", NULL }, +            { NULL,             0,                  false, NULL,                                   "", NULL } +        }; + +        static ChatCommand commandTable[] = +        { +            { "character",      SEC_GAMEMASTER,     true,  NULL,                                   "", characterCommandTable}, +            { NULL,             0,                  false, NULL,                                   "", NULL } +        }; +        return commandTable; +    } + +    // Stores informations about a deleted character +    struct DeletedInfo +    { +        uint32      lowGuid;                            ///< the low GUID from the character +        std::string name;                               ///< the character name +        uint32      accountId;                          ///< the account id +        std::string accountName;                        ///< the account name +        time_t      deleteDate;                         ///< the date at which the character has been deleted +    }; + +    typedef std::list<DeletedInfo> DeletedInfoList; + +    /** +    * Collects all GUIDs (and related info) from deleted characters which are still in the database. +    * +    * @param foundList    a reference to an std::list which will be filled with info data +    * @param searchString the search string which either contains a player GUID or a part fo the character-name +    * @return             returns false if there was a problem while selecting the characters (e.g. player name not normalizeable) +    */ +    static bool GetDeletedCharacterInfoList(DeletedInfoList& foundList, std::string searchString) +    { +        PreparedQueryResult result; +        PreparedStatement* stmt; +        if (!searchString.empty()) +        { +            // search by GUID +            if (isNumeric(searchString.c_str())) +            { +                stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_DEL_INFO_BY_GUID); +                stmt->setUInt32(0, uint32(atoi(searchString.c_str()))); +                result = CharacterDatabase.Query(stmt); +            } +            // search by name +            else +            { +                if (!normalizePlayerName(searchString)) +                    return false; + +                stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_DEL_INFO_BY_NAME); +                stmt->setString(0, searchString); +                result = CharacterDatabase.Query(stmt); +            } +        } +        else +        { +            stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_DEL_INFO); +            result = CharacterDatabase.Query(stmt); +        } + +        if (result) +        { +            do +            { +                Field* fields = result->Fetch(); + +                DeletedInfo info; + +                info.lowGuid    = fields[0].GetUInt32(); +                info.name       = fields[1].GetString(); +                info.accountId  = fields[2].GetUInt32(); + +                // account name will be empty for not existed account +                AccountMgr::GetName(info.accountId, info.accountName); +                info.deleteDate = time_t(fields[3].GetUInt32()); +                foundList.push_back(info); +            } +            while (result->NextRow()); +        } + +        return true; +    } + +    /** +    * Shows all deleted characters which matches the given search string, expected non empty list +    * +    * @see HandleCharacterDeletedListCommand +    * @see HandleCharacterDeletedRestoreCommand +    * @see HandleCharacterDeletedDeleteCommand +    * @see DeletedInfoList +    * +    * @param foundList contains a list with all found deleted characters +    */ +    static void HandleCharacterDeletedListHelper(DeletedInfoList const& foundList, ChatHandler* handler) +    { +        if (!handler->GetSession()) +        { +            handler->SendSysMessage(LANG_CHARACTER_DELETED_LIST_BAR); +            handler->SendSysMessage(LANG_CHARACTER_DELETED_LIST_HEADER); +            handler->SendSysMessage(LANG_CHARACTER_DELETED_LIST_BAR); +        } + +        for (DeletedInfoList::const_iterator itr = foundList.begin(); itr != foundList.end(); ++itr) +        { +            std::string dateStr = TimeToTimestampStr(itr->deleteDate); + +            if (!handler->GetSession()) +                handler->PSendSysMessage(LANG_CHARACTER_DELETED_LIST_LINE_CONSOLE, +                    itr->lowGuid, itr->name.c_str(), itr->accountName.empty() ? "<Not existed>" : itr->accountName.c_str(), +                    itr->accountId, dateStr.c_str()); +            else +                handler->PSendSysMessage(LANG_CHARACTER_DELETED_LIST_LINE_CHAT, +                    itr->lowGuid, itr->name.c_str(), itr->accountName.empty() ? "<Not existed>" : itr->accountName.c_str(), +                    itr->accountId, dateStr.c_str()); +        } + +        if (!handler->GetSession()) +            handler->SendSysMessage(LANG_CHARACTER_DELETED_LIST_BAR); +    } + +    /** +    * Restore a previously deleted character +    * +    * @see HandleCharacterDeletedListHelper +    * @see HandleCharacterDeletedRestoreCommand +    * @see HandleCharacterDeletedDeleteCommand +    * @see DeletedInfoList +    * +    * @param delInfo the informations about the character which will be restored +    */ +    static void HandleCharacterDeletedRestoreHelper(DeletedInfo const& delInfo, ChatHandler* handler) +    { +        if (delInfo.accountName.empty())                    // account not exist +        { +            handler->PSendSysMessage(LANG_CHARACTER_DELETED_SKIP_ACCOUNT, delInfo.name.c_str(), delInfo.lowGuid, delInfo.accountId); +            return; +        } + +        // check character count +        uint32 charcount = AccountMgr::GetCharactersCount(delInfo.accountId); +        if (charcount >= 10) +        { +            handler->PSendSysMessage(LANG_CHARACTER_DELETED_SKIP_FULL, delInfo.name.c_str(), delInfo.lowGuid, delInfo.accountId); +            return; +        } + +        if (sObjectMgr->GetPlayerGUIDByName(delInfo.name)) +        { +            handler->PSendSysMessage(LANG_CHARACTER_DELETED_SKIP_NAME, delInfo.name.c_str(), delInfo.lowGuid, delInfo.accountId); +            return; +        } + +        PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UDP_RESTORE_DELETE_INFO); +        stmt->setString(0, delInfo.name); +        stmt->setUInt32(1, delInfo.accountId); +        stmt->setUInt32(2, delInfo.lowGuid); +        CharacterDatabase.Execute(stmt); + +        stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_NAME_DATA); +        stmt->setUInt32(0, delInfo.lowGuid); +        if (PreparedQueryResult result = CharacterDatabase.Query(stmt)) +            sWorld->AddCharacterNameData(delInfo.lowGuid, delInfo.name, (*result)[2].GetUInt8(), (*result)[0].GetUInt8(), (*result)[1].GetUInt8()); +    } + +    static bool HandleCharacterTitlesCommand(ChatHandler* handler, char const* args) +    { +        if (!*args) +            return false; + +        Player* target; +        if (!handler->extractPlayerTarget((char*)args, &target)) +            return false; + +        LocaleConstant loc = handler->GetSessionDbcLocale(); +        char const* targetName = target->GetName(); +        char const* knownStr = handler->GetTrinityString(LANG_KNOWN); + +        // Search in CharTitles.dbc +        for (uint32 id = 0; id < sCharTitlesStore.GetNumRows(); id++) +        { +            CharTitlesEntry const* titleInfo = sCharTitlesStore.LookupEntry(id); + +            if (titleInfo && target->HasTitle(titleInfo)) +            { +                std::string name = titleInfo->name; +                if (name.empty()) +                    continue; + +                char const* activeStr = target && target->GetUInt32Value(PLAYER_CHOSEN_TITLE) == titleInfo->bit_index +                ? handler->GetTrinityString(LANG_ACTIVE) +                : ""; + +                char titleNameStr[80]; +                snprintf(titleNameStr, 80, name.c_str(), targetName); + +                // send title in "id (idx:idx) - [namedlink locale]" format +                if (handler->GetSession()) +                    handler->PSendSysMessage(LANG_TITLE_LIST_CHAT, id, titleInfo->bit_index, id, titleNameStr, localeNames[loc], knownStr, activeStr); +                else +                    handler->PSendSysMessage(LANG_TITLE_LIST_CONSOLE, id, titleInfo->bit_index, name.c_str(), localeNames[loc], knownStr, activeStr); +            } +        } + +        return true; +    } + +    //rename characters +    static bool HandleCharacterRenameCommand(ChatHandler* handler, char const* args) +    { +        Player* target; +        uint64 targetGuid; +        std::string targetName; +        if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) +            return false; + +        if (target) +        { +            // check online security +            if (handler->HasLowerSecurity(target, 0)) +                return false; + +            handler->PSendSysMessage(LANG_RENAME_PLAYER, handler->GetNameLink(target).c_str()); +            target->SetAtLoginFlag(AT_LOGIN_RENAME); +        } +        else +        { +            // check offline security +            if (handler->HasLowerSecurity(NULL, targetGuid)) +                return false; + +            std::string oldNameLink = handler->playerLink(targetName); +            handler->PSendSysMessage(LANG_RENAME_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGuid)); + +            PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG); +            stmt->setUInt16(0, uint16(AT_LOGIN_RENAME)); +            stmt->setUInt32(1, GUID_LOPART(targetGuid)); +            CharacterDatabase.Execute(stmt); +        } + +        return true; +    } + +    static bool HandleCharacterLevelCommand(ChatHandler* handler, char const* args) +    { +        char* nameStr; +        char* levelStr; +        handler->extractOptFirstArg((char*)args, &nameStr, &levelStr); +        if (!levelStr) +            return false; + +        // exception opt second arg: .character level $name +        if (isalpha(levelStr[0])) +        { +            nameStr = levelStr; +            levelStr = NULL;                                    // current level will used +        } + +        Player* target; +        uint64 targetGuid; +        std::string targetName; +        if (!handler->extractPlayerTarget(nameStr, &target, &targetGuid, &targetName)) +            return false; + +        int32 oldlevel = target ? target->getLevel() : Player::GetLevelFromDB(targetGuid); +        int32 newlevel = levelStr ? atoi(levelStr) : oldlevel; + +        if (newlevel < 1) +            return false;                                       // invalid level + +        if (newlevel > STRONG_MAX_LEVEL)                         // hardcoded maximum level +            newlevel = STRONG_MAX_LEVEL; + +        handler->HandleCharacterLevel(target, targetGuid, oldlevel, newlevel); +        if (!handler->GetSession() || handler->GetSession()->GetPlayer() != target)      // including player == NULL +        { +            std::string nameLink = handler->playerLink(targetName); +            handler->PSendSysMessage(LANG_YOU_CHANGE_LVL, nameLink.c_str(), newlevel); +        } + +        return true; +    } + +    // customize characters +    static bool HandleCharacterCustomizeCommand(ChatHandler* handler, char const* args) +    { +        Player* target; +        uint64 targetGuid; +        std::string targetName; +        if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) +            return false; + +        PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG); +        stmt->setUInt16(0, uint16(AT_LOGIN_CUSTOMIZE)); +        if (target) +        { +            handler->PSendSysMessage(LANG_CUSTOMIZE_PLAYER, handler->GetNameLink(target).c_str()); +            target->SetAtLoginFlag(AT_LOGIN_CUSTOMIZE); +            stmt->setUInt32(1, target->GetGUIDLow()); +        } +        else +        { +            std::string oldNameLink = handler->playerLink(targetName); +            stmt->setUInt32(1, GUID_LOPART(targetGuid)); +            handler->PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGuid)); +        } +        CharacterDatabase.Execute(stmt); + +        return true; +    } + +    static bool HandleCharacterChangeFactionCommand(ChatHandler* handler, char const* args) +    { +        Player* target; +        uint64 targetGuid; +        std::string targetName; + +        if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) +            return false; + +        PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG); +        stmt->setUInt16(0, uint16(AT_LOGIN_CHANGE_FACTION)); +        if (target) +        { +            handler->PSendSysMessage(LANG_CUSTOMIZE_PLAYER, handler->GetNameLink(target).c_str()); +            target->SetAtLoginFlag(AT_LOGIN_CHANGE_FACTION); +            stmt->setUInt32(1, target->GetGUIDLow()); +        } +        else +        { +            std::string oldNameLink = handler->playerLink(targetName); +            handler->PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGuid)); +            stmt->setUInt32(1, GUID_LOPART(targetGuid)); +        } +        CharacterDatabase.Execute(stmt); + +        return true; +    } + +    static bool HandleCharacterChangeRaceCommand(ChatHandler* handler, char const* args) +    { +        Player* target; +        uint64 targetGuid; +        std::string targetName; +        if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) +            return false; + +        PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG); +        stmt->setUInt16(0, uint16(AT_LOGIN_CHANGE_RACE)); +        if (target) +        { +            // TODO : add text into database +            handler->PSendSysMessage(LANG_CUSTOMIZE_PLAYER, handler->GetNameLink(target).c_str()); +            target->SetAtLoginFlag(AT_LOGIN_CHANGE_RACE); +            stmt->setUInt32(1, target->GetGUIDLow()); +        } +        else +        { +            std::string oldNameLink = handler->playerLink(targetName); +            // TODO : add text into database +            handler->PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGuid)); +            stmt->setUInt32(1, GUID_LOPART(targetGuid)); +        } +        CharacterDatabase.Execute(stmt); + +        return true; +    } + +    static bool HandleCharacterReputationCommand(ChatHandler* handler, char const* args) +    { +        Player* target; +        if (!handler->extractPlayerTarget((char*)args, &target)) +            return false; + +        LocaleConstant loc = handler->GetSessionDbcLocale(); + +        FactionStateList const& targetFSL = target->GetReputationMgr().GetStateList(); +        for (FactionStateList::const_iterator itr = targetFSL.begin(); itr != targetFSL.end(); ++itr) +        { +            FactionState const& faction = itr->second; +            FactionEntry const* factionEntry = sFactionStore.LookupEntry(faction.ID); +            char const* factionName = factionEntry ? factionEntry->name : "#Not found#"; +            ReputationRank rank = target->GetReputationMgr().GetRank(factionEntry); +            std::string rankName = handler->GetTrinityString(ReputationRankStrIndex[rank]); +            std::ostringstream ss; +            if (handler->GetSession()) +                ss << faction.ID << " - |cffffffff|Hfaction:" << faction.ID << "|h[" << factionName << ' ' << localeNames[loc] << "]|h|r"; +            else +                ss << faction.ID << " - " << factionName << ' ' << localeNames[loc]; + +            ss << ' ' << rankName << " (" << target->GetReputationMgr().GetReputation(factionEntry) << ')'; + +            if (faction.Flags & FACTION_FLAG_VISIBLE) +                ss << handler->GetTrinityString(LANG_FACTION_VISIBLE); +            if (faction.Flags & FACTION_FLAG_AT_WAR) +                ss << handler->GetTrinityString(LANG_FACTION_ATWAR); +            if (faction.Flags & FACTION_FLAG_PEACE_FORCED) +                ss << handler->GetTrinityString(LANG_FACTION_PEACE_FORCED); +            if (faction.Flags & FACTION_FLAG_HIDDEN) +                ss << handler->GetTrinityString(LANG_FACTION_HIDDEN); +            if (faction.Flags & FACTION_FLAG_INVISIBLE_FORCED) +                ss << handler->GetTrinityString(LANG_FACTION_INVISIBLE_FORCED); +            if (faction.Flags & FACTION_FLAG_INACTIVE) +                ss << handler->GetTrinityString(LANG_FACTION_INACTIVE); + +            handler->SendSysMessage(ss.str().c_str()); +        } + +        return true; +    } + +   /** +    * Handles the '.character deleted list' command, which shows all deleted characters which matches the given search string +    * +    * @see HandleCharacterDeletedListHelper +    * @see HandleCharacterDeletedRestoreCommand +    * @see HandleCharacterDeletedDeleteCommand +    * @see DeletedInfoList +    * +    * @param args the search string which either contains a player GUID or a part fo the character-name +    */ +    static bool HandleCharacterDeletedListCommand(ChatHandler* handler, char const* args) +    { +        DeletedInfoList foundList; +        if (!GetDeletedCharacterInfoList(foundList, args)) +            return false; + +        // if no characters have been found, output a warning +        if (foundList.empty()) +        { +            handler->SendSysMessage(LANG_CHARACTER_DELETED_LIST_EMPTY); +            return false; +        } + +        HandleCharacterDeletedListHelper(foundList, handler); + +        return true; +    } + +    /** +     * Handles the '.character deleted restore' command, which restores all deleted characters which matches the given search string +     * +     * The command automatically calls '.character deleted list' command with the search string to show all restored characters. +     * +     * @see HandleCharacterDeletedRestoreHelper +     * @see HandleCharacterDeletedListCommand +     * @see HandleCharacterDeletedDeleteCommand +     * +     * @param args the search string which either contains a player GUID or a part of the character-name +     */ +    static bool HandleCharacterDeletedRestoreCommand(ChatHandler* handler, char const* args) +    { +        // It is required to submit at least one argument +        if (!*args) +            return false; + +        std::string searchString; +        std::string newCharName; +        uint32 newAccount = 0; + +        // GCC by some strange reason fail build code without temporary variable +        std::istringstream params(args); +        params >> searchString >> newCharName >> newAccount; + +        DeletedInfoList foundList; +        if (!GetDeletedCharacterInfoList(foundList, searchString)) +            return false; + +        if (foundList.empty()) +        { +            handler->SendSysMessage(LANG_CHARACTER_DELETED_LIST_EMPTY); +            return false; +        } + +        handler->SendSysMessage(LANG_CHARACTER_DELETED_RESTORE); +        HandleCharacterDeletedListHelper(foundList, handler); + +        if (newCharName.empty()) +        { +            // Drop not existed account cases +            for (DeletedInfoList::iterator itr = foundList.begin(); itr != foundList.end(); ++itr) +                HandleCharacterDeletedRestoreHelper(*itr, handler); +        } +        else if (foundList.size() == 1 && normalizePlayerName(newCharName)) +        { +            DeletedInfo delInfo = foundList.front(); + +            // update name +            delInfo.name = newCharName; + +            // if new account provided update deleted info +            if (newAccount && newAccount != delInfo.accountId) +            { +                delInfo.accountId = newAccount; +                AccountMgr::GetName(newAccount, delInfo.accountName); +            } + +            HandleCharacterDeletedRestoreHelper(delInfo, handler); +        } +        else +            handler->SendSysMessage(LANG_CHARACTER_DELETED_ERR_RENAME); + +        return true; +    } + +    /** +     * Handles the '.character deleted delete' command, which completely deletes all deleted characters which matches the given search string +     * +     * @see Player::GetDeletedCharacterGUIDs +     * @see Player::DeleteFromDB +     * @see HandleCharacterDeletedListCommand +     * @see HandleCharacterDeletedRestoreCommand +     * +     * @param args the search string which either contains a player GUID or a part fo the character-name +     */ +    static bool HandleCharacterDeletedDeleteCommand(ChatHandler* handler, char const* args) +    { +        // It is required to submit at least one argument +        if (!*args) +            return false; + +        DeletedInfoList foundList; +        if (!GetDeletedCharacterInfoList(foundList, args)) +            return false; + +        if (foundList.empty()) +        { +            handler->SendSysMessage(LANG_CHARACTER_DELETED_LIST_EMPTY); +            return false; +        } + +        handler->SendSysMessage(LANG_CHARACTER_DELETED_DELETE); +        HandleCharacterDeletedListHelper(foundList, handler); + +        // Call the appropriate function to delete them (current account for deleted characters is 0) +        for (DeletedInfoList::const_iterator itr = foundList.begin(); itr != foundList.end(); ++itr) +            Player::DeleteFromDB(itr->lowGuid, 0, false, true); + +        return true; +    } + +    /** +     * Handles the '.character deleted old' command, which completely deletes all deleted characters deleted with some days ago +     * +     * @see Player::DeleteOldCharacters +     * @see Player::DeleteFromDB +     * @see HandleCharacterDeletedDeleteCommand +     * @see HandleCharacterDeletedListCommand +     * @see HandleCharacterDeletedRestoreCommand +     * +     * @param args the search string which either contains a player GUID or a part fo the character-name +     */ +    static bool HandleCharacterDeletedOldCommand(ChatHandler* /*handler*/, char const* args) +    { +        int32 keepDays = sWorld->getIntConfig(CONFIG_CHARDELETE_KEEP_DAYS); + +        char* daysStr = strtok((char*)args, " "); +        if (daysStr) +        { +            if (!isNumeric(daysStr)) +                return false; + +            keepDays = atoi(daysStr); +            if (keepDays < 0) +                return false; +        } +        // config option value 0 -> disabled and can't be used +        else if (keepDays <= 0) +            return false; + +        Player::DeleteOldCharacters(uint32(keepDays)); + +        return true; +    } + +    static bool HandleCharacterEraseCommand(ChatHandler* handler, char const* args) +    { +        if (!*args) +            return false; + +        char* characterName_str = strtok((char*)args, " "); +        if (!characterName_str) +            return false; + +        std::string characterName = characterName_str; +        if (!normalizePlayerName(characterName)) +            return false; + +        uint64 characterGuid; +        uint32 accountId; + +        Player* player = sObjectAccessor->FindPlayerByName(characterName.c_str()); +        if (player) +        { +            characterGuid = player->GetGUID(); +            accountId = player->GetSession()->GetAccountId(); +            player->GetSession()->KickPlayer(); +        } +        else +        { +            characterGuid = sObjectMgr->GetPlayerGUIDByName(characterName); +            if (!characterGuid) +            { +                handler->PSendSysMessage(LANG_NO_PLAYER, characterName.c_str()); +                handler->SetSentErrorMessage(true); +                return false; +            } +            accountId = sObjectMgr->GetPlayerAccountIdByGUID(characterGuid); +        } + +        std::string accountName; +        AccountMgr::GetName(accountId, accountName); + +        Player::DeleteFromDB(characterGuid, accountId, true, true); +        handler->PSendSysMessage(LANG_CHARACTER_DELETED, characterName.c_str(), GUID_LOPART(characterGuid), accountName.c_str(), accountId); + +        return true; +    } +}; + +void AddSC_character_commandscript() +{ +    new character_commandscript(); +} diff --git a/src/server/scripts/Commands/cs_instance.cpp b/src/server/scripts/Commands/cs_instance.cpp new file mode 100644 index 00000000000..f51727af2ef --- /dev/null +++ b/src/server/scripts/Commands/cs_instance.cpp @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* ScriptData +Name: instance_commandscript +%Complete: 100 +Comment: All instance related commands +Category: commandscripts +EndScriptData */ + +#include "ScriptMgr.h" +#include "Chat.h" +#include "Group.h" +#include "InstanceSaveMgr.h" +#include "InstanceScript.h" +#include "MapManager.h" + +class instance_commandscript : public CommandScript +{ +public: +    instance_commandscript() : CommandScript("instance_commandscript") { } + +    ChatCommand* GetCommands() const +    { +        static ChatCommand instanceCommandTable[] = +        { +            { "listbinds",      SEC_ADMINISTRATOR,  false,  &HandleInstanceListBindsCommand,    "", NULL }, +            { "unbind",         SEC_ADMINISTRATOR,  false,  &HandleInstanceUnbindCommand,       "", NULL }, +            { "stats",          SEC_ADMINISTRATOR,  true,   &HandleInstanceStatsCommand,        "", NULL }, +            { "savedata",       SEC_ADMINISTRATOR,  false,  &HandleInstanceSaveDataCommand,     "", NULL }, +            { NULL,             0,                  false,  NULL,                               "", NULL } +        }; + +        static ChatCommand commandTable[] = +        { +            { "instance",       SEC_ADMINISTRATOR,  true,   NULL,                               "", instanceCommandTable }, +            { NULL,             0,                  false,  NULL,                               "", NULL } +        }; + +        return commandTable; +    } + +    static std::string GetTimeString(uint64 time) +    { +        uint64 days = time / DAY, hours = (time % DAY) / HOUR, minute = (time % HOUR) / MINUTE; +        std::ostringstream ss; +        if (days) +            ss << days << "d "; +        if (hours) +            ss << hours << "h "; +        ss << minute << 'm'; +        return ss.str(); +    } + +    static bool HandleInstanceListBindsCommand(ChatHandler* handler, char const* /*args*/) +    { +        Player* player = handler->getSelectedPlayer(); +        if (!player) +            player = handler->GetSession()->GetPlayer(); + +        uint32 counter = 0; +        for (uint8 i = 0; i < MAX_DIFFICULTY; ++i) +        { +            Player::BoundInstancesMap &binds = player->GetBoundInstances(Difficulty(i)); +            for (Player::BoundInstancesMap::const_iterator itr = binds.begin(); itr != binds.end(); ++itr) +            { +                InstanceSave* save = itr->second.save; +                std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL)); +                handler->PSendSysMessage("map: %d inst: %d perm: %s diff: %d canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no",  save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str()); +                counter++; +            } +        } +        handler->PSendSysMessage("player binds: %d", counter); + +        counter = 0; +        if (Group* group = player->GetGroup()) +        { +            for (uint8 i = 0; i < MAX_DIFFICULTY; ++i) +            { +                Group::BoundInstancesMap &binds = group->GetBoundInstances(Difficulty(i)); +                for (Group::BoundInstancesMap::const_iterator itr = binds.begin(); itr != binds.end(); ++itr) +                { +                    InstanceSave* save = itr->second.save; +                    std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL)); +                    handler->PSendSysMessage("map: %d inst: %d perm: %s diff: %d canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no",  save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str()); +                    counter++; +                } +            } +        } +        handler->PSendSysMessage("group binds: %d", counter); + +        return true; +    } + +    static bool HandleInstanceUnbindCommand(ChatHandler* handler, char const* args) +    { +        if (!*args) +            return false; + +        Player* player = handler->getSelectedPlayer(); +        if (!player) +            player = handler->GetSession()->GetPlayer(); + +        char* map = strtok((char*)args, " "); +        char* pDiff = strtok(NULL, " "); +        int8 diff = -1; +        if (pDiff) +            diff = atoi(pDiff); +        uint16 counter = 0; +        uint16 MapId = 0; + +        if (strcmp(map, "all")) +        { +            MapId = uint16(atoi(map)); +            if (!MapId) +                return false; +        } + +        for (uint8 i = 0; i < MAX_DIFFICULTY; ++i) +        { +            Player::BoundInstancesMap &binds = player->GetBoundInstances(Difficulty(i)); +            for (Player::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end();) +            { +                InstanceSave* save = itr->second.save; +                if (itr->first != player->GetMapId() && (!MapId || MapId == itr->first) && (diff == -1 || diff == save->GetDifficulty())) +                { +                    std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL)); +                    handler->PSendSysMessage("unbinding map: %d inst: %d perm: %s diff: %d canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str()); +                    player->UnbindInstance(itr, Difficulty(i)); +                    counter++; +                } +                else +                    ++itr; +            } +        } +        handler->PSendSysMessage("instances unbound: %d", counter); + +        return true; +    } + +    static bool HandleInstanceStatsCommand(ChatHandler* handler, char const* /*args*/) +    { +        handler->PSendSysMessage("instances loaded: %d", sMapMgr->GetNumInstances()); +        handler->PSendSysMessage("players in instances: %d", sMapMgr->GetNumPlayersInInstances()); +        handler->PSendSysMessage("instance saves: %d", sInstanceSaveMgr->GetNumInstanceSaves()); +        handler->PSendSysMessage("players bound: %d", sInstanceSaveMgr->GetNumBoundPlayersTotal()); +        handler->PSendSysMessage("groups bound: %d", sInstanceSaveMgr->GetNumBoundGroupsTotal()); + +        return true; +    } + +    static bool HandleInstanceSaveDataCommand(ChatHandler* handler, char const* /*args*/) +    { +        Player* player = handler->GetSession()->GetPlayer(); +        Map* map = player->GetMap(); +        if (!map->IsDungeon()) +        { +            handler->PSendSysMessage("Map is not a dungeon."); +            handler->SetSentErrorMessage(true); +            return false; +        } + +        if (!((InstanceMap*)map)->GetInstanceScript()) +        { +            handler->PSendSysMessage("Map has no instance data."); +            handler->SetSentErrorMessage(true); +            return false; +        } + +        ((InstanceMap*)map)->GetInstanceScript()->SaveToDB(); + +        return true; +    } +}; + +void AddSC_instance_commandscript() +{ +    new instance_commandscript(); +} diff --git a/src/server/scripts/Commands/cs_list.cpp b/src/server/scripts/Commands/cs_list.cpp new file mode 100644 index 00000000000..8dd7f8e2cde --- /dev/null +++ b/src/server/scripts/Commands/cs_list.cpp @@ -0,0 +1,469 @@ +/* + * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* ScriptData +Name: list_commandscript +%Complete: 100 +Comment: All list related commands +Category: commandscripts +EndScriptData */ + +#include "ScriptMgr.h" +#include "Chat.h" +#include "SpellAuraEffects.h" +#include "ObjectAccessor.h" +#include "ObjectMgr.h" + +class list_commandscript : public CommandScript +{ +public: +    list_commandscript() : CommandScript("list_commandscript") { } + +    ChatCommand* GetCommands() const +    { +        static ChatCommand listCommandTable[] = +        { +            { "creature",       SEC_ADMINISTRATOR,  true,  &HandleListCreatureCommand,          "", NULL }, +            { "item",           SEC_ADMINISTRATOR,  true,  &HandleListItemCommand,              "", NULL }, +            { "object",         SEC_ADMINISTRATOR,  true,  &HandleListObjectCommand,            "", NULL }, +            { "auras",          SEC_ADMINISTRATOR,  false, &HandleListAurasCommand,             "", NULL }, +            { NULL,             0,                  false, NULL,                                "", NULL } +        }; +        static ChatCommand commandTable[] = +        { +            { "list",          SEC_ADMINISTRATOR,   true, NULL,                                 "", listCommandTable }, +            { NULL,            0,                   false, NULL,                                "", NULL } +        }; +        return commandTable; +    } + +    static bool HandleListCreatureCommand(ChatHandler* handler, char const* args) +    { +        if (!*args) +            return false; + +        // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r +        char* id = handler->extractKeyFromLink((char*)args, "Hcreature_entry"); +        if (!id) +            return false; + +        uint32 creatureId = atol(id); +        if (!creatureId) +        { +            handler->PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, creatureId); +            handler->SetSentErrorMessage(true); +            return false; +        } + +        CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(creatureId); +        if (!cInfo) +        { +            handler->PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, creatureId); +            handler->SetSentErrorMessage(true); +            return false; +        } + +        char* countStr = strtok(NULL, " "); +        uint32 count = countStr ? atol(countStr) : 10; + +        if (count < 0) +            return false; + +        QueryResult result; + +        uint32 creatureCount = 0; +        result = WorldDatabase.PQuery("SELECT COUNT(guid) FROM creature WHERE id='%u'", creatureId); +        if (result) +            creatureCount = (*result)[0].GetUInt64(); + +        if (handler->GetSession()) +        { +            Player* player = handler->GetSession()->GetPlayer(); +            result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map, (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ FROM creature WHERE id = '%u' ORDER BY order_ ASC LIMIT %u", +                player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), creatureId, count); +        } +        else +            result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map FROM creature WHERE id = '%u' LIMIT %u", +                creatureId, count); + +        if (result) +        { +            do +            { +                Field* fields   = result->Fetch(); +                uint32 guid     = fields[0].GetUInt32(); +                float x         = fields[1].GetFloat(); +                float y         = fields[2].GetFloat(); +                float z         = fields[3].GetFloat(); +                uint16 mapId    = fields[4].GetUInt16(); + +                if (handler->GetSession()) +                    handler->PSendSysMessage(LANG_CREATURE_LIST_CHAT, guid, guid, cInfo->Name.c_str(), x, y, z, mapId); +                else +                    handler->PSendSysMessage(LANG_CREATURE_LIST_CONSOLE, guid, cInfo->Name.c_str(), x, y, z, mapId); +            } +            while (result->NextRow()); +        } + +        handler->PSendSysMessage(LANG_COMMAND_LISTCREATUREMESSAGE, creatureId, creatureCount); + +        return true; +    } + +    static bool HandleListItemCommand(ChatHandler* handler, char const* args) +    { +        if (!*args) +            return false; + +        char* id = handler->extractKeyFromLink((char*)args, "Hitem"); +        if (!id) +            return false; + +        uint32 itemId = atol(id); +        if (!itemId) +        { +            handler->PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, itemId); +            handler->SetSentErrorMessage(true); +            return false; +        } + +        ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(itemId); +        if (!itemTemplate) +        { +            handler->PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, itemId); +            handler->SetSentErrorMessage(true); +            return false; +        } + +        char* countStr = strtok(NULL, " "); +        uint32 count = countStr ? atol(countStr) : 10; + +        if (count < 0) +            return false; + +        PreparedQueryResult result; + +        // inventory case +        uint32 inventoryCount = 0; + +        PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_INVENTORY_COUNT_ITEM); +        stmt->setUInt32(0, itemId); +        result = CharacterDatabase.Query(stmt); + +        if (result) +            inventoryCount = (*result)[0].GetUInt64(); + +        stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_INVENTORY_ITEM_BY_ENTRY); +        stmt->setUInt32(0, itemId); +        stmt->setUInt32(1, count); +        result = CharacterDatabase.Query(stmt); + +        if (result) +        { +            do +            { +                Field* fields           = result->Fetch(); +                uint32 itemGuid         = fields[0].GetUInt32(); +                uint32 itemBag          = fields[1].GetUInt32(); +                uint8 itemSlot          = fields[2].GetUInt8(); +                uint32 ownerGuid        = fields[3].GetUInt32(); +                uint32 ownerAccountId   = fields[4].GetUInt32(); +                std::string ownerName   = fields[5].GetString(); + +                char const* itemPos = 0; +                if (Player::IsEquipmentPos(itemBag, itemSlot)) +                    itemPos = "[equipped]"; +                else if (Player::IsInventoryPos(itemBag, itemSlot)) +                    itemPos = "[in inventory]"; +                else if (Player::IsBankPos(itemBag, itemSlot)) +                    itemPos = "[in bank]"; +                else +                    itemPos = ""; + +                handler->PSendSysMessage(LANG_ITEMLIST_SLOT, itemGuid, ownerName.c_str(), ownerGuid, ownerAccountId, itemPos); +            } +            while (result->NextRow()); + +            uint32 resultCount = uint32(result->GetRowCount()); + +            if (count > resultCount) +                count -= resultCount; +            else if (count) +                count = 0; +        } + +        // mail case +        uint32 mailCount = 0; + +        stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAIL_COUNT_ITEM); +        stmt->setUInt32(0, itemId); +        result = CharacterDatabase.Query(stmt); + +        if (result) +            mailCount = (*result)[0].GetUInt64(); + +        if (count > 0) +        { +            stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAIL_ITEMS_BY_ENTRY); +            stmt->setUInt32(0, itemId); +            stmt->setUInt32(1, count); +            result = CharacterDatabase.Query(stmt); +        } +        else +            result = PreparedQueryResult(NULL); + +        if (result) +        { +            do +            { +                Field* fields                   = result->Fetch(); +                uint32 itemGuid                 = fields[0].GetUInt32(); +                uint32 itemSender               = fields[1].GetUInt32(); +                uint32 itemReceiver             = fields[2].GetUInt32(); +                uint32 itemSenderAccountId      = fields[3].GetUInt32(); +                std::string itemSenderName      = fields[4].GetString(); +                uint32 itemReceiverAccount      = fields[5].GetUInt32(); +                std::string itemReceiverName    = fields[6].GetString(); + +                char const* itemPos = "[in mail]"; + +                handler->PSendSysMessage(LANG_ITEMLIST_MAIL, itemGuid, itemSenderName.c_str(), itemSender, itemSenderAccountId, itemReceiverName.c_str(), itemReceiver, itemReceiverAccount, itemPos); +            } +            while (result->NextRow()); + +            uint32 resultCount = uint32(result->GetRowCount()); + +            if (count > resultCount) +                count -= resultCount; +            else if (count) +                count = 0; +        } + +        // auction case +        uint32 auctionCount = 0; + +        stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_AUCTIONHOUSE_COUNT_ITEM); +        stmt->setUInt32(0, itemId); +        result = CharacterDatabase.Query(stmt); + +        if (result) +            auctionCount = (*result)[0].GetUInt64(); + +        if (count > 0) +        { +            stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_AUCTIONHOUSE_ITEM_BY_ENTRY); +            stmt->setUInt32(0, itemId); +            stmt->setUInt32(1, count); +            result = CharacterDatabase.Query(stmt); +        } +        else +            result = PreparedQueryResult(NULL); + +        if (result) +        { +            do +            { +                Field* fields           = result->Fetch(); +                uint32 itemGuid         = fields[0].GetUInt32(); +                uint32 owner            = fields[1].GetUInt32(); +                uint32 ownerAccountId   = fields[2].GetUInt32(); +                std::string ownerName   = fields[3].GetString(); + +                char const* itemPos = "[in auction]"; + +                handler->PSendSysMessage(LANG_ITEMLIST_AUCTION, itemGuid, ownerName.c_str(), owner, ownerAccountId, itemPos); +            } +            while (result->NextRow()); +        } + +        // guild bank case +        uint32 guildCount = 0; + +        stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_BANK_COUNT_ITEM); +        stmt->setUInt32(0, itemId); +        result = CharacterDatabase.Query(stmt); + +        if (result) +            guildCount = (*result)[0].GetUInt64(); + +        stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_BANK_ITEM_BY_ENTRY); +        stmt->setUInt32(0, itemId); +        stmt->setUInt32(1, count); +        result = CharacterDatabase.Query(stmt); + +        if (result) +        { +            do +            { +                Field* fields = result->Fetch(); +                uint32 itemGuid = fields[0].GetUInt32(); +                uint32 guildGuid = fields[1].GetUInt32(); +                std::string guildName = fields[2].GetString(); + +                char const* itemPos = "[in guild bank]"; + +                handler->PSendSysMessage(LANG_ITEMLIST_GUILD, itemGuid, guildName.c_str(), guildGuid, itemPos); +            } +            while (result->NextRow()); + +            uint32 resultCount = uint32(result->GetRowCount()); + +            if (count > resultCount) +                count -= resultCount; +            else if (count) +                count = 0; +        } + +        if (inventoryCount + mailCount + auctionCount + guildCount == 0) +        { +            handler->SendSysMessage(LANG_COMMAND_NOITEMFOUND); +            handler->SetSentErrorMessage(true); +            return false; +        } + +        handler->PSendSysMessage(LANG_COMMAND_LISTITEMMESSAGE, itemId, inventoryCount + mailCount + auctionCount + guildCount, inventoryCount, mailCount, auctionCount, guildCount); + +        return true; +    } + +    static bool HandleListObjectCommand(ChatHandler* handler, char const* args) +    { +        if (!*args) +            return false; + +        // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r +        char* id = handler->extractKeyFromLink((char*)args, "Hgameobject_entry"); +        if (!id) +            return false; + +        uint32 gameObjectId = atol(id); +        if (!gameObjectId) +        { +            handler->PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, gameObjectId); +            handler->SetSentErrorMessage(true); +            return false; +        } + +        GameObjectTemplate const* gInfo = sObjectMgr->GetGameObjectTemplate(gameObjectId); +        if (!gInfo) +        { +            handler->PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, gameObjectId); +            handler->SetSentErrorMessage(true); +            return false; +        } + +        char* countStr = strtok(NULL, " "); +        uint32 count = countStr ? atol(countStr) : 10; + +        if (count < 0) +            return false; + +        QueryResult result; + +        uint32 objectCount = 0; +        result = WorldDatabase.PQuery("SELECT COUNT(guid) FROM gameobject WHERE id='%u'", gameObjectId); +        if (result) +            objectCount = (*result)[0].GetUInt64(); + +        if (handler->GetSession()) +        { +            Player* player = handler->GetSession()->GetPlayer(); +            result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map, id, (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ FROM gameobject WHERE id = '%u' ORDER BY order_ ASC LIMIT %u", +                player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), gameObjectId, count); +        } +        else +            result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map, id FROM gameobject WHERE id = '%u' LIMIT %u", +                gameObjectId, count); + +        if (result) +        { +            do +            { +                Field* fields   = result->Fetch(); +                uint32 guid     = fields[0].GetUInt32(); +                float x         = fields[1].GetFloat(); +                float y         = fields[2].GetFloat(); +                float z         = fields[3].GetFloat(); +                uint16 mapId    = fields[4].GetUInt16(); +                uint32 entry    = fields[5].GetUInt32(); + +                if (handler->GetSession()) +                    handler->PSendSysMessage(LANG_GO_LIST_CHAT, guid, entry, guid, gInfo->name.c_str(), x, y, z, mapId); +                else +                    handler->PSendSysMessage(LANG_GO_LIST_CONSOLE, guid, gInfo->name.c_str(), x, y, z, mapId); +            } +            while (result->NextRow()); +        } + +        handler->PSendSysMessage(LANG_COMMAND_LISTOBJMESSAGE, gameObjectId, objectCount); + +        return true; +    } + +    static bool HandleListAurasCommand(ChatHandler* handler, char const* /*args*/) +    { +        Unit* unit = handler->getSelectedUnit(); +        if (!unit) +        { +            handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); +            handler->SetSentErrorMessage(true); +            return false; +        } + +        char const* talentStr = handler->GetTrinityString(LANG_TALENT); +        char const* passiveStr = handler->GetTrinityString(LANG_PASSIVE); + +        Unit::AuraApplicationMap const& auras = unit->GetAppliedAuras(); +        handler->PSendSysMessage(LANG_COMMAND_TARGET_LISTAURAS, auras.size()); +        for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) +        { +            bool talent = GetTalentSpellCost(itr->second->GetBase()->GetId()) > 0; + +            AuraApplication const* aurApp = itr->second; +            Aura const* aura = aurApp->GetBase(); +            char const* name = aura->GetSpellInfo()->SpellName; + +            std::ostringstream ss_name; +            ss_name << "|cffffffff|Hspell:" << aura->GetId() << "|h[" << name << "]|h|r"; + +            handler->PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, aura->GetId(), (handler->GetSession() ? ss_name.str().c_str() : name), +                aurApp->GetEffectMask(), aura->GetCharges(), aura->GetStackAmount(), aurApp->GetSlot(), +                aura->GetDuration(), aura->GetMaxDuration(), (aura->IsPassive() ? passiveStr : ""), +                (talent ? talentStr : ""), IS_PLAYER_GUID(aura->GetCasterGUID()) ? "player" : "creature", +                GUID_LOPART(aura->GetCasterGUID())); +        } + +        for (uint16 i = 0; i < TOTAL_AURAS; ++i) +        { +            Unit::AuraEffectList const& auraList = unit->GetAuraEffectsByType(AuraType(i)); +            if (auraList.empty()) +                continue; + +            handler->PSendSysMessage(LANG_COMMAND_TARGET_LISTAURATYPE, auraList.size(), i); + +            for (Unit::AuraEffectList::const_iterator itr = auraList.begin(); itr != auraList.end(); ++itr) +                handler->PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(), (*itr)->GetAmount()); +        } + +        return true; +    } +}; + +void AddSC_list_commandscript() +{ +    new list_commandscript(); +} diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index 2deac95d287..4aa61bbc297 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -135,15 +135,14 @@ public:          else
              handler->PSendSysMessage("no VMAP available for area info");
 -        /*handler->PSendSysMessage(LANG_MAP_POSITION,
 -            object->GetMapId(), (mapEntry ? mapEntry->name[handler->GetSessionDbcLocale()] : "<unknown>"),
 -            zoneId, (zoneEntry ? zoneEntry->area_name[handler->GetSessionDbcLocale()] : "<unknown>"),
 -            areaId, (areaEntry ? areaEntry->area_name[handler->GetSessionDbcLocale()] : "<unknown>"),
 +        handler->PSendSysMessage(LANG_MAP_POSITION,
 +            object->GetMapId(), (mapEntry ? mapEntry->name : "<unknown>"),
 +            zoneId, (zoneEntry ? zoneEntry->area_name : "<unknown>"),
 +            areaId, (areaEntry ? areaEntry->area_name : "<unknown>"),
              object->GetPhaseMask(),
              object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), object->GetOrientation(),
              cell.GridX(), cell.GridY(), cell.CellX(), cell.CellY(), object->GetInstanceId(),
              zoneX, zoneY, groundZ, floorZ, haveMap, haveVMap);
 -        */
          LiquidData liquidStatus;
          ZLiquidStatus status = map->getLiquidStatus(object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), MAP_ALL_LIQUIDS, &liquidStatus);
 diff --git a/src/server/scripts/Commands/cs_modify.cpp b/src/server/scripts/Commands/cs_modify.cpp index 0de3637586c..57d13fd2fa1 100644 --- a/src/server/scripts/Commands/cs_modify.cpp +++ b/src/server/scripts/Commands/cs_modify.cpp @@ -64,15 +64,14 @@ public:              { "standstate",     SEC_GAMEMASTER,     false, &HandleModifyStandStateCommand,    "", NULL },              { "phase",          SEC_ADMINISTRATOR,  false, &HandleModifyPhaseCommand,         "", NULL },              { "gender",         SEC_GAMEMASTER,     false, &HandleModifyGenderCommand,        "", NULL }, -            { "collision",      SEC_GAMEMASTER,     false, &HandleModifyCollisionCommand,     "", NULL }, -            { "speed",          SEC_MODERATOR,      false, NULL,                              "", modifyspeedCommandTable }, +            { "speed",          SEC_MODERATOR,      false, NULL,           "", modifyspeedCommandTable },              { NULL,             0,                  false, NULL,                                           "", NULL }          };          static ChatCommand commandTable[] =          {              { "morph",          SEC_GAMEMASTER,     false, &HandleModifyMorphCommand,          "", NULL },              { "demorph",        SEC_GAMEMASTER,     false, &HandleDeMorphCommand,              "", NULL }, -            { "modify",         SEC_MODERATOR,      false, NULL,                               "", modifyCommandTable }, +            { "modify",         SEC_MODERATOR,      false, NULL,                 "", modifyCommandTable },              { NULL,             0,                  false, NULL,                               "", NULL }          };          return commandTable; @@ -1391,7 +1390,7 @@ public:          if (!target)              target = handler->GetSession()->GetPlayer(); -		// check online security +        // check online security          else if (target->GetTypeId() == TYPEID_PLAYER && handler->HasLowerSecurity(target->ToPlayer(), 0))              return false; @@ -1399,88 +1398,6 @@ public:          return true;      } - -    static bool HandleModifyCollisionCommand(ChatHandler* handler, const char* args) -    { -        if (!*args) -            return false; - -        Player* target = handler->getSelectedPlayer(); - -        if (!target) -        { -            handler->PSendSysMessage(LANG_PLAYER_NOT_FOUND); -            handler->SetSentErrorMessage(true); -            return false; -        } - -        std::string param = (char*)args; - -        if (param == "on") -        { -            // enable collision -            WorldPacket data; -            uint64 guid = target->GetGUID(); -            uint8* bytes = (uint8*)&guid; - -            data.Initialize(SMSG_MOVE_SPLINE_ENABLE_COLLISION, 1 + 8); -            data.WriteByteMask(bytes[7]); -            data.WriteByteMask(bytes[5]); -            data.WriteByteMask(bytes[4]); -            data.WriteByteMask(bytes[0]); -            data.WriteByteMask(bytes[1]); -            data.WriteByteMask(bytes[6]); -            data.WriteByteMask(bytes[2]); -            data.WriteByteMask(bytes[3]); - -            data.WriteByteSeq(bytes[6]); -            data.WriteByteSeq(bytes[3]); -            data.WriteByteSeq(bytes[2]); -            data.WriteByteSeq(bytes[7]); -            data.WriteByteSeq(bytes[4]); -            data.WriteByteSeq(bytes[1]); -            data.WriteByteSeq(bytes[5]); -            data.WriteByteSeq(bytes[0]); - -            target->SendMessageToSet(&data, true); -            handler->SendSysMessage("Enabled Collision"); -            return true; -        } - -        if (param == "off") -        { -            // disable collision -            WorldPacket data; -            uint64 guid = target->GetGUID(); -            uint8* bytes = (uint8*)&guid; - -            data.Initialize(SMSG_MOVE_SPLINE_DISABLE_COLLISION, 1 + 8); -            data.WriteByteMask(bytes[4]); -            data.WriteByteMask(bytes[7]); -            data.WriteByteMask(bytes[5]); -            data.WriteByteMask(bytes[3]); -            data.WriteByteMask(bytes[2]); -            data.WriteByteMask(bytes[1]); -            data.WriteByteMask(bytes[6]); -            data.WriteByteMask(bytes[0]); - -            data.WriteByteSeq(bytes[6]); -            data.WriteByteSeq(bytes[0]); -            data.WriteByteSeq(bytes[5]); -            data.WriteByteSeq(bytes[4]); -            data.WriteByteSeq(bytes[7]); -            data.WriteByteSeq(bytes[3]); -            data.WriteByteSeq(bytes[1]); -            data.WriteByteSeq(bytes[2]); - -            target->SendMessageToSet(&data, true); -            handler->SendSysMessage("Disabled Collision"); -            return true; -        } - -        return false; -    } -  };  void AddSC_modify_commandscript() diff --git a/src/server/scripts/Commands/cs_reset.cpp b/src/server/scripts/Commands/cs_reset.cpp new file mode 100644 index 00000000000..a8294dc9ddb --- /dev/null +++ b/src/server/scripts/Commands/cs_reset.cpp @@ -0,0 +1,310 @@ +/* + * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* ScriptData +Name: reset_commandscript +%Complete: 100 +Comment: All reset related commands +Category: commandscripts +EndScriptData */ + +#include "ScriptMgr.h" +#include "Chat.h" +#include "ObjectAccessor.h" + +class reset_commandscript : public CommandScript +{ +public: +    reset_commandscript() : CommandScript("reset_commandscript") { } + +    ChatCommand* GetCommands() const +    { +        static ChatCommand resetCommandTable[] = +        { +            { "achievements",   SEC_ADMINISTRATOR,  true,  &HandleResetAchievementsCommand,     "", NULL }, +            { "honor",          SEC_ADMINISTRATOR,  true,  &HandleResetHonorCommand,            "", NULL }, +            { "level",          SEC_ADMINISTRATOR,  true,  &HandleResetLevelCommand,            "", NULL }, +            { "spells",         SEC_ADMINISTRATOR,  true,  &HandleResetSpellsCommand,           "", NULL }, +            { "stats",          SEC_ADMINISTRATOR,  true,  &HandleResetStatsCommand,            "", NULL }, +            { "talents",        SEC_ADMINISTRATOR,  true,  &HandleResetTalentsCommand,          "", NULL }, +            { "all",            SEC_ADMINISTRATOR,  true,  &HandleResetAllCommand,              "", NULL }, +            { NULL,             0,                  false, NULL,                                "", NULL } +        }; +        static ChatCommand commandTable[] = +        { +            { "reset",          SEC_ADMINISTRATOR,  true, NULL,                                 "", resetCommandTable }, +            { NULL,             0,                  false, NULL,                                "", NULL } +        }; +        return commandTable; +    } + +    static bool HandleResetAchievementsCommand(ChatHandler* handler, char const* args) +    { +        Player* target; +        uint64 targetGuid; +        if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid)) +            return false; + +        if (target) +            target->GetAchievementMgr().Reset(); +        else +            AchievementMgr::DeleteFromDB(GUID_LOPART(targetGuid)); + +        return true; +    } + +    static bool HandleResetHonorCommand(ChatHandler* handler, char const* args) +    { +        Player* target; +        if (!handler->extractPlayerTarget((char*)args, &target)) +            return false; + +        target->SetUInt32Value(PLAYER_FIELD_KILLS, 0); +        target->SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS, 0); +        target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL); + +        return true; +    } + +    static bool HandleResetStatsOrLevelHelper(Player* player) +    { +        ChrClassesEntry const* classEntry = sChrClassesStore.LookupEntry(player->getClass()); +        if (!classEntry) +        { +            sLog->outError("Class %u not found in DBC (Wrong DBC files?)", player->getClass()); +            return false; +        } + +        uint8 powerType = classEntry->powerType; + +        // reset m_form if no aura +        if (!player->HasAuraType(SPELL_AURA_MOD_SHAPESHIFT)) +            player->SetShapeshiftForm(FORM_NONE); + +        player->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, DEFAULT_WORLD_OBJECT_SIZE); +        player->SetFloatValue(UNIT_FIELD_COMBATREACH, DEFAULT_COMBAT_REACH); + +        player->setFactionForRace(player->getRace()); + +        player->SetUInt32Value(UNIT_FIELD_BYTES_0, ((player->getRace()) | (player->getClass() << 8) | (player->getGender() << 16) | (powerType << 24))); + +        // reset only if player not in some form; +        if (player->GetShapeshiftForm() == FORM_NONE) +            player->InitDisplayIds(); + +        player->SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP); + +        player->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); + +        //-1 is default value +        player->SetUInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, uint32(-1)); + +        //player->SetUInt32Value(PLAYER_FIELD_BYTES, 0xEEE00000); +        return true; +    } + +    static bool HandleResetLevelCommand(ChatHandler* handler, char const* args) +    { +        Player* target; +        if (!handler->extractPlayerTarget((char*)args, &target)) +            return false; + +        if (!HandleResetStatsOrLevelHelper(target)) +            return false; + +        uint8 oldLevel = target->getLevel(); + +        // set starting level +        uint32 startLevel = target->getClass() != CLASS_DEATH_KNIGHT +            ? sWorld->getIntConfig(CONFIG_START_PLAYER_LEVEL) +            : sWorld->getIntConfig(CONFIG_START_HEROIC_PLAYER_LEVEL); + +        target->_ApplyAllLevelScaleItemMods(false); +        target->SetLevel(startLevel); +        target->InitRunes(); +        target->InitStatsForLevel(true); +        target->InitTaxiNodesForLevel(); +        target->InitGlyphsForLevel(); +        target->InitTalentForLevel(); +        target->SetUInt32Value(PLAYER_XP, 0); + +        target->_ApplyAllLevelScaleItemMods(true); + +        // reset level for pet +        if (Pet* pet = target->GetPet()) +            pet->SynchronizeLevelWithOwner(); + +        sScriptMgr->OnPlayerLevelChanged(target, oldLevel); + +        return true; +    } + +    static bool HandleResetSpellsCommand(ChatHandler* handler, char const* args) +    { +        Player* target; +        uint64 targetGuid; +        std::string targetName; +        if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) +            return false; + +        if (target) +        { +            target->resetSpells(/* bool myClassOnly */); + +            ChatHandler(target).SendSysMessage(LANG_RESET_SPELLS); +            if (!handler->GetSession() || handler->GetSession()->GetPlayer() != target) +                handler->PSendSysMessage(LANG_RESET_SPELLS_ONLINE, handler->GetNameLink(target).c_str()); +        } +        else +        { +            PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG); +            stmt->setUInt16(0, uint16(AT_LOGIN_RESET_SPELLS)); +            stmt->setUInt32(1, GUID_LOPART(targetGuid)); +            CharacterDatabase.Execute(stmt); + +            handler->PSendSysMessage(LANG_RESET_SPELLS_OFFLINE, targetName.c_str()); +        } + +        return true; +    } + +    static bool HandleResetStatsCommand(ChatHandler* handler, char const* args) +    { +        Player* target; +        if (!handler->extractPlayerTarget((char*)args, &target)) +            return false; + +        if (!HandleResetStatsOrLevelHelper(target)) +            return false; + +        target->InitRunes(); +        target->InitStatsForLevel(true); +        target->InitTaxiNodesForLevel(); +        target->InitGlyphsForLevel(); +        target->InitTalentForLevel(); + +        return true; +    } + +    static bool HandleResetTalentsCommand(ChatHandler* handler, char const* args) +    { +        Player* target; +        uint64 targetGuid; +        std::string targetName; +        if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) +        { +            // Try reset talents as Hunter Pet +            Creature* creature = handler->getSelectedCreature(); +            if (!*args && creature && creature->isPet()) +            { +                Unit* owner = creature->GetOwner(); +                if (owner && owner->GetTypeId() == TYPEID_PLAYER && creature->ToPet()->IsPermanentPetFor(owner->ToPlayer())) +                { +                    creature->ToPet()->resetTalents(); +                    owner->ToPlayer()->SendTalentsInfoData(true); + +                    ChatHandler(owner->ToPlayer()).SendSysMessage(LANG_RESET_PET_TALENTS); +                    if (!handler->GetSession() || handler->GetSession()->GetPlayer() != owner->ToPlayer()) +                        handler->PSendSysMessage(LANG_RESET_PET_TALENTS_ONLINE, handler->GetNameLink(owner->ToPlayer()).c_str()); +                } +                return true; +            } + +            handler->SendSysMessage(LANG_NO_CHAR_SELECTED); +            handler->SetSentErrorMessage(true); +            return false; +        } + +        if (target) +        { +            target->ResetTalents(true); +            target->SendTalentsInfoData(false); +            ChatHandler(target).SendSysMessage(LANG_RESET_TALENTS); +            if (!handler->GetSession() || handler->GetSession()->GetPlayer() != target) +                handler->PSendSysMessage(LANG_RESET_TALENTS_ONLINE, handler->GetNameLink(target).c_str()); + +            Pet* pet = target->GetPet(); +            Pet::resetTalentsForAllPetsOf(target, pet); +            if (pet) +                target->SendTalentsInfoData(true); +            return true; +        } +        else if (targetGuid) +        { +            PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG); +            stmt->setUInt16(0, uint16(AT_LOGIN_NONE | AT_LOGIN_RESET_PET_TALENTS)); +            stmt->setUInt32(1, GUID_LOPART(targetGuid)); +            CharacterDatabase.Execute(stmt); + +            std::string nameLink = handler->playerLink(targetName); +            handler->PSendSysMessage(LANG_RESET_TALENTS_OFFLINE, nameLink.c_str()); +            return true; +        } + +        handler->SendSysMessage(LANG_NO_CHAR_SELECTED); +        handler->SetSentErrorMessage(true); +        return false; +    } + +    static bool HandleResetAllCommand(ChatHandler* handler, char const* args) +    { +        if (!*args) +            return false; + +        std::string caseName = args; + +        AtLoginFlags atLogin; + +        // Command specially created as single command to prevent using short case names +        if (caseName == "spells") +        { +            atLogin = AT_LOGIN_RESET_SPELLS; +            sWorld->SendWorldText(LANG_RESETALL_SPELLS); +            if (!handler->GetSession()) +                handler->SendSysMessage(LANG_RESETALL_SPELLS); +        } +        else if (caseName == "talents") +        { +            atLogin = AtLoginFlags(AT_LOGIN_RESET_TALENTS | AT_LOGIN_RESET_PET_TALENTS); +            sWorld->SendWorldText(LANG_RESETALL_TALENTS); +            if (!handler->GetSession()) +               handler->SendSysMessage(LANG_RESETALL_TALENTS); +        } +        else +        { +            handler->PSendSysMessage(LANG_RESETALL_UNKNOWN_CASE, args); +            handler->SetSentErrorMessage(true); +            return false; +        } + +        PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ALL_AT_LOGIN_FLAGS); +        stmt->setUInt16(0, uint16(atLogin)); +        CharacterDatabase.Execute(stmt); + +        TRINITY_READ_GUARD(HashMapHolder<Player>::LockType, *HashMapHolder<Player>::GetLock()); +        HashMapHolder<Player>::MapType const& plist = sObjectAccessor->GetPlayers(); +        for (HashMapHolder<Player>::MapType::const_iterator itr = plist.begin(); itr != plist.end(); ++itr) +            itr->second->SetAtLoginFlag(atLogin); + +        return true; +    } +}; + +void AddSC_reset_commandscript() +{ +    new reset_commandscript(); +} diff --git a/src/server/scripts/Commands/cs_server.cpp b/src/server/scripts/Commands/cs_server.cpp new file mode 100644 index 00000000000..8f10af5fe2a --- /dev/null +++ b/src/server/scripts/Commands/cs_server.cpp @@ -0,0 +1,445 @@ +/* + * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* ScriptData +Name: server_commandscript +%Complete: 100 +Comment: All server related commands +Category: commandscripts +EndScriptData */ + +#include "ScriptMgr.h" +#include "Chat.h" +#include "SystemConfig.h" +#include "Config.h" +#include "ObjectAccessor.h" + +class server_commandscript : public CommandScript +{ +public: +    server_commandscript() : CommandScript("server_commandscript") { } + +    ChatCommand* GetCommands() const +    { +        static ChatCommand serverIdleRestartCommandTable[] = +        { +            { "cancel",         SEC_ADMINISTRATOR,  true,  &HandleServerShutDownCancelCommand,      "", NULL }, +            { ""   ,            SEC_ADMINISTRATOR,  true,  &HandleServerIdleRestartCommand,         "", NULL }, +            { NULL,             0,                  false, NULL,                                    "", NULL } +        }; + +        static ChatCommand serverIdleShutdownCommandTable[] = +        { +            { "cancel",         SEC_ADMINISTRATOR,  true,  &HandleServerShutDownCancelCommand,      "", NULL }, +            { ""   ,            SEC_ADMINISTRATOR,  true,  &HandleServerIdleShutDownCommand,        "", NULL }, +            { NULL,             0,                  false, NULL,                                    "", NULL } +        }; + +        static ChatCommand serverRestartCommandTable[] = +        { +            { "cancel",         SEC_ADMINISTRATOR,  true,  &HandleServerShutDownCancelCommand,      "", NULL }, +            { ""   ,            SEC_ADMINISTRATOR,  true,  &HandleServerRestartCommand,             "", NULL }, +            { NULL,             0,                  false, NULL,                                    "", NULL } +        }; + +        static ChatCommand serverShutdownCommandTable[] = +        { +            { "cancel",         SEC_ADMINISTRATOR,  true,  &HandleServerShutDownCancelCommand,      "", NULL }, +            { ""   ,            SEC_ADMINISTRATOR,  true,  &HandleServerShutDownCommand,            "", NULL }, +            { NULL,             0,                  false, NULL,                                    "", NULL } +        }; + +        static ChatCommand serverSetCommandTable[] = +        { +            { "difftime",       SEC_CONSOLE,        true,  &HandleServerSetDiffTimeCommand,         "", NULL }, +            { "loglevel",       SEC_CONSOLE,        true,  &HandleServerSetLogLevelCommand,         "", NULL }, +            { "logfilelevel",   SEC_CONSOLE,        true,  &HandleServerSetLogFileLevelCommand,     "", NULL }, +            { "motd",           SEC_ADMINISTRATOR,  true,  &HandleServerSetMotdCommand,             "", NULL }, +            { "closed",         SEC_ADMINISTRATOR,  true,  &HandleServerSetClosedCommand,           "", NULL }, +            { NULL,             0,                  false, NULL,                                    "", NULL } +        }; + +        static ChatCommand serverCommandTable[] = +        { +            { "corpses",        SEC_GAMEMASTER,     true,  &HandleServerCorpsesCommand,             "", NULL }, +            { "exit",           SEC_CONSOLE,        true,  &HandleServerExitCommand,                "", NULL }, +            { "idlerestart",    SEC_ADMINISTRATOR,  true,  NULL,                                    "", serverIdleRestartCommandTable }, +            { "idleshutdown",   SEC_ADMINISTRATOR,  true,  NULL,                                    "", serverIdleShutdownCommandTable }, +            { "info",           SEC_PLAYER,         true,  &HandleServerInfoCommand,                "", NULL }, +            { "motd",           SEC_PLAYER,         true,  &HandleServerMotdCommand,                "", NULL }, +            { "plimit",         SEC_ADMINISTRATOR,  true,  &HandleServerPLimitCommand,              "", NULL }, +            { "restart",        SEC_ADMINISTRATOR,  true,  NULL,                                    "", serverRestartCommandTable }, +            { "shutdown",       SEC_ADMINISTRATOR,  true,  NULL,                                    "", serverShutdownCommandTable }, +            { "set",            SEC_ADMINISTRATOR,  true,  NULL,                                    "", serverSetCommandTable }, +            { "togglequerylog", SEC_CONSOLE,        true,  &HandleServerToggleQueryLogging,         "", NULL }, +            { NULL,             0,                  false, NULL,                                    "", NULL } +        }; + +         static ChatCommand commandTable[] = +        { +            { "server",         SEC_ADMINISTRATOR,  true,  NULL,                                    "", serverCommandTable }, +            { NULL,             0,                  false, NULL,                                    "", NULL } +        }; +        return commandTable; +    } + +    // Triggering corpses expire check in world +    static bool HandleServerCorpsesCommand(ChatHandler* /*handler*/, char const* /*args*/) +    { +        sObjectAccessor->RemoveOldCorpses(); +        return true; +    } + +    static bool HandleServerInfoCommand(ChatHandler* handler, char const* /*args*/) +    { +        uint32 playersNum           = sWorld->GetPlayerCount(); +        uint32 maxPlayersNum        = sWorld->GetMaxPlayerCount(); +        uint32 activeClientsNum     = sWorld->GetActiveSessionCount(); +        uint32 queuedClientsNum     = sWorld->GetQueuedSessionCount(); +        uint32 maxActiveClientsNum  = sWorld->GetMaxActiveSessionCount(); +        uint32 maxQueuedClientsNum  = sWorld->GetMaxQueuedSessionCount(); +        std::string uptime          = secsToTimeString(sWorld->GetUptime()); +        uint32 updateTime           = sWorld->GetUpdateTime(); + +        handler->SendSysMessage(_FULLVERSION); +        handler->PSendSysMessage(LANG_CONNECTED_PLAYERS, playersNum, maxPlayersNum); +        handler->PSendSysMessage(LANG_CONNECTED_USERS, activeClientsNum, maxActiveClientsNum, queuedClientsNum, maxQueuedClientsNum); +        handler->PSendSysMessage(LANG_UPTIME, uptime.c_str()); +        handler->PSendSysMessage(LANG_UPDATE_DIFF, updateTime); +        // Can't use sWorld->ShutdownMsg here in case of console command +        if (sWorld->IsShuttingDown()) +            handler->PSendSysMessage(LANG_SHUTDOWN_TIMELEFT, secsToTimeString(sWorld->GetShutDownTimeLeft()).c_str()); + +        return true; +    } +    // Display the 'Message of the day' for the realm +    static bool HandleServerMotdCommand(ChatHandler* handler, char const* /*args*/) +    { +        handler->PSendSysMessage(LANG_MOTD_CURRENT, sWorld->GetMotd()); +        return true; +    } + +    static bool HandleServerPLimitCommand(ChatHandler* handler, char const* args) +    { +        if (*args) +        { +            char* paramStr = strtok((char*)args, " "); +            if (!paramStr) +                return false; + +            int32 limit = strlen(paramStr); + +            if (strncmp(paramStr, "player", limit) == 0) +                sWorld->SetPlayerSecurityLimit(SEC_PLAYER); +            else if (strncmp(paramStr, "moderator", limit) == 0) +                sWorld->SetPlayerSecurityLimit(SEC_MODERATOR); +            else if (strncmp(paramStr, "gamemaster", limit) == 0) +                sWorld->SetPlayerSecurityLimit(SEC_GAMEMASTER); +            else if (strncmp(paramStr, "administrator", limit) == 0) +                sWorld->SetPlayerSecurityLimit(SEC_ADMINISTRATOR); +            else if (strncmp(paramStr, "reset", limit) == 0) +            { +                sWorld->SetPlayerAmountLimit(ConfigMgr::GetIntDefault("PlayerLimit", 100)); +                sWorld->LoadDBAllowedSecurityLevel(); +            } +            else +            { +                int32 value = atoi(paramStr); +                if (value < 0) +                    sWorld->SetPlayerSecurityLimit(AccountTypes(-value)); +                else +                    sWorld->SetPlayerAmountLimit(uint32(value)); +            } +        } + +        uint32 playerAmountLimit = sWorld->GetPlayerAmountLimit(); +        AccountTypes allowedAccountType = sWorld->GetPlayerSecurityLimit(); +        char const* secName = ""; +        switch (allowedAccountType) +        { +            case SEC_PLAYER: +                secName = "Player"; +                break; +            case SEC_MODERATOR: +                secName = "Moderator"; +                break; +            case SEC_GAMEMASTER: +                secName = "Gamemaster"; +                break; +            case SEC_ADMINISTRATOR: +                secName = "Administrator"; +                break; +            default: +                secName = "<unknown>"; +                break; +        } +        handler->PSendSysMessage("Player limits: amount %u, min. security level %s.", playerAmountLimit, secName); + +        return true; +    } + +    static bool HandleServerShutDownCancelCommand(ChatHandler* /*handler*/, char const* /*args*/) +    { +        sWorld->ShutdownCancel(); + +        return true; +    } + +    static bool HandleServerShutDownCommand(ChatHandler* /*handler*/, char const* args) +    { +        if (!*args) +            return false; + +        char* timeStr = strtok((char*) args, " "); +        char* exitCodeStr = strtok(NULL, ""); + +        int32 time = atoi(timeStr); + +        // Prevent interpret wrong arg value as 0 secs shutdown time +        if ((time == 0 && (timeStr[0] != '0' || timeStr[1] != '\0')) || time < 0) +            return false; + +        if (exitCodeStr) +        { +            int32 exitCode = atoi(exitCodeStr); + +            // Handle atoi() errors +            if (exitCode == 0 && (exitCodeStr[0] != '0' || exitCodeStr[1] != '\0')) +                return false; + +            // Exit code should be in range of 0-125, 126-255 is used +            // in many shells for their own return codes and code > 255 +            // is not supported in many others +            if (exitCode < 0 || exitCode > 125) +                return false; + +            sWorld->ShutdownServ(time, 0, exitCode); +        } +        else +            sWorld->ShutdownServ(time, 0, SHUTDOWN_EXIT_CODE); + +        return true; +    } + +    static bool HandleServerRestartCommand(ChatHandler* /*handler*/, char const* args) +    { +        if (!*args) +            return false; + +        char* timeStr = strtok((char*) args, " "); +        char* exitCodeStr = strtok(NULL, ""); + +        int32 time = atoi(timeStr); + +        //  Prevent interpret wrong arg value as 0 secs shutdown time +        if ((time == 0 && (timeStr[0] != '0' || timeStr[1] != '\0')) || time < 0) +            return false; + +        if (exitCodeStr) +        { +            int32 exitCode = atoi(exitCodeStr); + +            // Handle atoi() errors +            if (exitCode == 0 && (exitCodeStr[0] != '0' || exitCodeStr[1] != '\0')) +                return false; + +            // Exit code should be in range of 0-125, 126-255 is used +            // in many shells for their own return codes and code > 255 +            // is not supported in many others +            if (exitCode < 0 || exitCode > 125) +                return false; + +            sWorld->ShutdownServ(time, SHUTDOWN_MASK_RESTART, exitCode); +        } +        else +            sWorld->ShutdownServ(time, SHUTDOWN_MASK_RESTART, RESTART_EXIT_CODE); + +            return true; +    } + +    static bool HandleServerIdleRestartCommand(ChatHandler* /*handler*/, char const* args) +    { +        if (!*args) +            return false; + +        char* timeStr = strtok((char*) args, " "); +        char* exitCodeStr = strtok(NULL, ""); + +        int32 time = atoi(timeStr); + +        // Prevent interpret wrong arg value as 0 secs shutdown time +        if ((time == 0 && (timeStr[0] != '0' || timeStr[1] != '\0')) || time < 0) +            return false; + +        if (exitCodeStr) +        { +            int32 exitCode = atoi(exitCodeStr); + +            // Handle atoi() errors +            if (exitCode == 0 && (exitCodeStr[0] != '0' || exitCodeStr[1] != '\0')) +                return false; + +            // Exit code should be in range of 0-125, 126-255 is used +            // in many shells for their own return codes and code > 255 +            // is not supported in many others +            if (exitCode < 0 || exitCode > 125) +                return false; + +            sWorld->ShutdownServ(time, SHUTDOWN_MASK_RESTART | SHUTDOWN_MASK_IDLE, exitCode); +        } +        else +            sWorld->ShutdownServ(time, SHUTDOWN_MASK_RESTART | SHUTDOWN_MASK_IDLE, RESTART_EXIT_CODE); +        return true; +    } + +    static bool HandleServerIdleShutDownCommand(ChatHandler* /*handler*/, char const* args) +    { +        if (!*args) +            return false; + +        char* timeStr = strtok((char*) args, " "); +        char* exitCodeStr = strtok(NULL, ""); + +        int32 time = atoi(timeStr); + +        // Prevent interpret wrong arg value as 0 secs shutdown time +        if ((time == 0 && (timeStr[0] != '0' || timeStr[1] != '\0')) || time < 0) +            return false; + +        if (exitCodeStr) +        { +            int32 exitCode = atoi(exitCodeStr); + +            // Handle atoi() errors +            if (exitCode == 0 && (exitCodeStr[0] != '0' || exitCodeStr[1] != '\0')) +                return false; + +            // Exit code should be in range of 0-125, 126-255 is used +            // in many shells for their own return codes and code > 255 +            // is not supported in many others +            if (exitCode < 0 || exitCode > 125) +                return false; + +            sWorld->ShutdownServ(time, SHUTDOWN_MASK_IDLE, exitCode); +        } +        else +            sWorld->ShutdownServ(time, SHUTDOWN_MASK_IDLE, SHUTDOWN_EXIT_CODE); +            return true; +    } + +    // Exit the realm +    static bool HandleServerExitCommand(ChatHandler* handler, char const* /*args*/) +    { +        handler->SendSysMessage(LANG_COMMAND_EXIT); +        World::StopNow(SHUTDOWN_EXIT_CODE); +        return true; +    } + +    // Define the 'Message of the day' for the realm +    static bool HandleServerSetMotdCommand(ChatHandler* handler, char const* args) +    { +        sWorld->SetMotd(args); +        handler->PSendSysMessage(LANG_MOTD_NEW, args); +        return true; +    } + +    // Set whether we accept new clients +    static bool HandleServerSetClosedCommand(ChatHandler* handler, char const* args) +    { +        if (strncmp(args, "on", 3) == 0) +        { +            handler->SendSysMessage(LANG_WORLD_CLOSED); +            sWorld->SetClosed(true); +            return true; +        } +        else if (strncmp(args, "off", 4) == 0) +        { +            handler->SendSysMessage(LANG_WORLD_OPENED); +            sWorld->SetClosed(false); +            return true; +        } + +        handler->SendSysMessage(LANG_USE_BOL); +        handler->SetSentErrorMessage(true); +        return false; +    } + +    // Set the level of logging +    static bool HandleServerSetLogFileLevelCommand(ChatHandler* /*handler*/, char const* args) +    { +        if (!*args) +            return false; + +        char* newLevel = strtok((char*)args, " "); +        if (!newLevel) +            return false; + +        sLog->SetLogFileLevel(newLevel); +        return true; +    } + +    // Set the level of logging +    static bool HandleServerSetLogLevelCommand(ChatHandler* /*handler*/, char const* args) +    { +        if (!*args) +            return false; + +        char* newLevel = strtok((char*)args, " "); +        if (!newLevel) +            return false; + +        sLog->SetLogLevel(newLevel); +        return true; +    } + +    // set diff time record interval +    static bool HandleServerSetDiffTimeCommand(ChatHandler* /*handler*/, char const* args) +    { +        if (!*args) +            return false; + +        char* newTimeStr = strtok((char*)args, " "); +        if (!newTimeStr) +            return false; + +        int32 newTime = atoi(newTimeStr); +        if (newTime < 0) +            return false; + +        sWorld->SetRecordDiffInterval(newTime); +        printf("Record diff every %u ms\n", newTime); + +        return true; +    } + +    // toggle sql driver query logging +    static bool HandleServerToggleQueryLogging(ChatHandler* handler, char const* /*args*/) +    { +        sLog->SetSQLDriverQueryLogging(!sLog->GetSQLDriverQueryLogging()); + +        if (sLog->GetSQLDriverQueryLogging()) +            handler->PSendSysMessage(LANG_SQLDRIVER_QUERY_LOGGING_ENABLED); +        else +            handler->PSendSysMessage(LANG_SQLDRIVER_QUERY_LOGGING_DISABLED); +        return true; +    } +}; + +void AddSC_server_commandscript() +{ +    new server_commandscript(); +} diff --git a/src/server/scripts/Commands/cs_tele.cpp b/src/server/scripts/Commands/cs_tele.cpp index ca7c3af7fde..8f390d17cd4 100644 --- a/src/server/scripts/Commands/cs_tele.cpp +++ b/src/server/scripts/Commands/cs_tele.cpp @@ -97,15 +97,16 @@ public:          if (!*args)              return false; -        std::string name = args; - -        if (!sObjectMgr->DeleteGameTele(name)) +         // id, or string, or [name] Shift-click form |color|Htele:id|h[name]|h|r +        GameTele const* tele = handler->extractGameTeleFromLink((char*)args); +        if (!tele)          {              handler->SendSysMessage(LANG_COMMAND_TELE_NOTFOUND);              handler->SetSentErrorMessage(true);              return false;          } - +        std::string name = tele->name; +        sObjectMgr->DeleteGameTele(name);          handler->SendSysMessage(LANG_COMMAND_TP_DELETED);          return true;      } diff --git a/src/server/scripts/EasternKingdoms/BlackrockSpire/boss_pyroguard_emberseer.cpp b/src/server/scripts/EasternKingdoms/BlackrockSpire/boss_pyroguard_emberseer.cpp index 0279f3e2834..015c13d1098 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockSpire/boss_pyroguard_emberseer.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockSpire/boss_pyroguard_emberseer.cpp @@ -64,7 +64,7 @@ public:          void Reset()          { -            if(instance->GetBossState(DATA_PYROGAURD_EMBERSEER) == IN_PROGRESS) +            if (instance->GetBossState(DATA_PYROGAURD_EMBERSEER) == IN_PROGRESS)                  OpenDoors(false);              instance->SetBossState(DATA_PYROGAURD_EMBERSEER,NOT_STARTED);              // respawn any dead Blackhand Incarcerators diff --git a/src/server/scripts/EasternKingdoms/ShadowfangKeep/shadowfang_keep.cpp b/src/server/scripts/EasternKingdoms/ShadowfangKeep/shadowfang_keep.cpp index 63e753a18ba..676cd7be4f0 100644 --- a/src/server/scripts/EasternKingdoms/ShadowfangKeep/shadowfang_keep.cpp +++ b/src/server/scripts/EasternKingdoms/ShadowfangKeep/shadowfang_keep.cpp @@ -27,7 +27,11 @@ EndScriptData */  npc_shadowfang_prisoner  EndContentData */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "SpellScript.h" +#include "SpellAuraEffects.h"  #include "ScriptedEscortAI.h"  #include "shadowfang_keep.h" @@ -193,8 +197,48 @@ public:  }; +class spell_shadowfang_keep_haunting_spirits : public SpellScriptLoader +{ +    public: +        spell_shadowfang_keep_haunting_spirits() : SpellScriptLoader("spell_shadowfang_keep_haunting_spirits") { } + +        class spell_shadowfang_keep_haunting_spirits_AuraScript : public AuraScript +        { +            PrepareAuraScript(spell_shadowfang_keep_haunting_spirits_AuraScript); + +            void CalcPeriodic(AuraEffect const* /*aurEff*/, bool& isPeriodic, int32& amplitude) +            { +                isPeriodic = true; +                amplitude = (irand(0, 60) + 30) * IN_MILLISECONDS; +            } + +            void HandleDummyTick(AuraEffect const* aurEff) +            { +                GetTarget()->CastSpell((Unit*)NULL, aurEff->GetAmount(), true); +            } + +            void HandleUpdatePeriodic(AuraEffect* aurEff) +            { +                aurEff->CalculatePeriodic(GetCaster()); +            } + +            void Register() +            { +                DoEffectCalcPeriodic += AuraEffectCalcPeriodicFn(spell_shadowfang_keep_haunting_spirits_AuraScript::CalcPeriodic, EFFECT_0, SPELL_AURA_DUMMY); +                OnEffectPeriodic += AuraEffectPeriodicFn(spell_shadowfang_keep_haunting_spirits_AuraScript::HandleDummyTick, EFFECT_0, SPELL_AURA_DUMMY); +                OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_shadowfang_keep_haunting_spirits_AuraScript::HandleUpdatePeriodic, EFFECT_0, SPELL_AURA_DUMMY); +            } +        }; + +        AuraScript* GetAuraScript() const +        { +            return new spell_shadowfang_keep_haunting_spirits_AuraScript(); +        } +}; +  void AddSC_shadowfang_keep()  {      new npc_shadowfang_prisoner();      new npc_arugal_voidwalker(); +    new spell_shadowfang_keep_haunting_spirits();  } diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp index b5698d851f8..4fcfa8a046e 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp @@ -23,7 +23,10 @@ SDComment:  SDCategory: Zul'Aman  EndScriptData */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "SpellScript.h" +#include "SpellAuraEffects.h"  #include "zulaman.h"  #define YELL_AGGRO              "Da shadow gonna fall on you... " @@ -47,54 +50,58 @@ EndScriptData */  //Defines for various powers he uses after using soul drain -//Druid -#define SPELL_DR_LIFEBLOOM      43421 -#define SPELL_DR_THORNS         43420 -#define SPELL_DR_MOONFIRE       43545 - -//Hunter -#define SPELL_HU_EXPLOSIVE_TRAP 43444 -#define SPELL_HU_FREEZING_TRAP  43447 -#define SPELL_HU_SNAKE_TRAP     43449 - -//Mage -#define SPELL_MG_FIREBALL       41383 -#define SPELL_MG_FROSTBOLT      43428 -#define SPELL_MG_FROST_NOVA     43426 -#define SPELL_MG_ICE_LANCE      43427 - -//Paladin -#define SPELL_PA_CONSECRATION   43429 -#define SPELL_PA_HOLY_LIGHT     43451 -#define SPELL_PA_AVENGING_WRATH 43430 - -//Priest -#define SPELL_PR_HEAL           41372 -#define SPELL_PR_MIND_CONTROL   43550 -#define SPELL_PR_MIND_BLAST     41374 -#define SPELL_PR_SW_DEATH       41375 -#define SPELL_PR_PSYCHIC_SCREAM 43432 -#define SPELL_PR_PAIN_SUPP      44416 - -//Rogue -#define SPELL_RO_BLIND          43433 -#define SPELL_RO_SLICE_DICE     43457 -#define SPELL_RO_WOUND_POISON   39665 - -//Shaman -#define SPELL_SH_FIRE_NOVA      43436 -#define SPELL_SH_HEALING_WAVE   43548 -#define SPELL_SH_CHAIN_LIGHT    43435 - -//Warlock -#define SPELL_WL_CURSE_OF_DOOM  43439 -#define SPELL_WL_RAIN_OF_FIRE   43440 -#define SPELL_WL_UNSTABLE_AFFL  35183 - -//Warrior -#define SPELL_WR_SPELL_REFLECT  43443 -#define SPELL_WR_WHIRLWIND      43442 -#define SPELL_WR_MORTAL_STRIKE  43441 +enum Spells +{ +    // Druid +    SPELL_DR_THORNS                 = 43420, +    SPELL_DR_LIFEBLOOM              = 43421, +    SPELL_DR_MOONFIRE               = 43545, + +    // Hunter +    SPELL_HU_EXPLOSIVE_TRAP         = 43444, +    SPELL_HU_FREEZING_TRAP          = 43447, +    SPELL_HU_SNAKE_TRAP             = 43449, + +    // Mage +    SPELL_MG_FIREBALL               = 41383, +    SPELL_MG_FROST_NOVA             = 43426, +    SPELL_MG_ICE_LANCE              = 43427, +    SPELL_MG_FROSTBOLT              = 43428, + +    // Paladin +    SPELL_PA_CONSECRATION           = 43429, +    SPELL_PA_AVENGING_WRATH         = 43430, +    SPELL_PA_HOLY_LIGHT             = 43451, + +    // Priest +    SPELL_PR_HEAL                   = 41372, +    SPELL_PR_MIND_BLAST             = 41374, +    SPELL_PR_SW_DEATH               = 41375, +    SPELL_PR_PSYCHIC_SCREAM         = 43432, +    SPELL_PR_MIND_CONTROL           = 43550, +    SPELL_PR_PAIN_SUPP              = 44416, + +    // Rogue +    SPELL_RO_BLIND                  = 43433, +    SPELL_RO_SLICE_DICE             = 43457, +    SPELL_RO_WOUND_POISON           = 43461, + +    // Shaman +    SPELL_SH_CHAIN_LIGHT            = 43435, +    SPELL_SH_FIRE_NOVA              = 43436, +    SPELL_SH_HEALING_WAVE           = 43548, + +    // Warlock +    SPELL_WL_CURSE_OF_DOOM          = 43439, +    SPELL_WL_RAIN_OF_FIRE           = 43440, +    SPELL_WL_UNSTABLE_AFFL          = 43522, +    SPELL_WL_UNSTABLE_AFFL_DISPEL   = 43523, + +    // Warrior +    SPELL_WR_MORTAL_STRIKE          = 43441, +    SPELL_WR_WHIRLWIND              = 43442, +    SPELL_WR_SPELL_REFLECT          = 43443 +};  #define ORIENT                  1.5696f  #define POS_Y                   921.2795f @@ -936,6 +943,40 @@ class boss_koragg : public CreatureScript          }  }; +class spell_hexlord_unstable_affliction : public SpellScriptLoader +{ +    public: +        spell_hexlord_unstable_affliction() : SpellScriptLoader("spell_hexlord_unstable_affliction") { } + +        class spell_hexlord_unstable_affliction_AuraScript : public AuraScript +        { +            PrepareAuraScript(spell_hexlord_unstable_affliction_AuraScript); + +            bool Validate(SpellInfo const* /*spell*/) +            { +                if (!sSpellMgr->GetSpellInfo(SPELL_WL_UNSTABLE_AFFL_DISPEL)) +                    return false; +                return true; +            } + +            void HandleDispel(DispelInfo* dispelInfo) +            { +                if (Unit* caster = GetCaster()) +                    caster->CastSpell(dispelInfo->GetDispeller(), SPELL_WL_UNSTABLE_AFFL_DISPEL, true, NULL, GetEffect(EFFECT_0)); +            } + +            void Register() +            { +                AfterDispel += AuraDispelFn(spell_hexlord_unstable_affliction_AuraScript::HandleDispel); +            } +        }; + +        AuraScript* GetAuraScript() const +        { +            return new spell_hexlord_unstable_affliction_AuraScript(); +        } +}; +  void AddSC_boss_hex_lord_malacrass()  {      new boss_hexlord_malacrass(); @@ -947,5 +988,6 @@ void AddSC_boss_hex_lord_malacrass()      new boss_fenstalker();      new boss_koragg();      new boss_alyson_antille(); +    new spell_hexlord_unstable_affliction();  } diff --git a/src/server/scripts/Kalimdor/BlackfathomDeeps/blackfathom_deeps.cpp b/src/server/scripts/Kalimdor/BlackfathomDeeps/blackfathom_deeps.cpp index a86b2b8b17a..a70d05fa0ef 100644 --- a/src/server/scripts/Kalimdor/BlackfathomDeeps/blackfathom_deeps.cpp +++ b/src/server/scripts/Kalimdor/BlackfathomDeeps/blackfathom_deeps.cpp @@ -15,11 +15,13 @@   * with this program. If not, see <http://www.gnu.org/licenses/>.   */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h"  #include "blackfathom_deeps.h"  #include "ScriptedEscortAI.h" -enum eSpells +enum Spells  {      SPELL_BLESSING_OF_BLACKFATHOM                           = 8733,      SPELL_RAVAGE                                            = 8391, @@ -94,11 +96,11 @@ public:          uint32 frostNovaTimer;          uint32 frostBoltVolleyTimer; -        bool bFlee; +        bool Flee;          void Reset()          { -            bFlee = false; +            Flee = false;              ravageTimer           = urand(5000, 8000);              frostNovaTimer        = urand(9000, 12000); @@ -140,7 +142,7 @@ public:                  {                      if (ravageTimer <= diff)                      { -                        DoCast(me->getVictim(), SPELL_RAVAGE); +                        DoCastVictim(SPELL_RAVAGE);                          ravageTimer = urand(9000, 14000);                      } else ravageTimer -= diff;                      break; @@ -148,9 +150,9 @@ public:                  case NPC_MURKSHALLOW_SOFTSHELL:                  case NPC_BARBED_CRUSTACEAN:                  { -                    if (!bFlee && HealthBelowPct(15)) +                    if (!Flee && HealthBelowPct(15))                      { -                        bFlee = true; +                        Flee = true;                          me->DoFleeToGetAssistance();                      }                      break; @@ -160,10 +162,7 @@ public:                      if (frostBoltVolleyTimer <= diff)                      {                          if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) -                        { -                            if (target) -                                DoCast(target, SPELL_FROST_BOLT_VOLLEY); -                        } +                            DoCast(target, SPELL_FROST_BOLT_VOLLEY);                          frostBoltVolleyTimer = urand(5000, 8000);                      }                      else frostBoltVolleyTimer -= diff; @@ -190,7 +189,7 @@ public:      };  }; -enum eMorridune +enum Morridune  {      SAY_MORRIDUNE_1 = -1048003,      SAY_MORRIDUNE_2 = -1048004 diff --git a/src/server/scripts/Kalimdor/BlackfathomDeeps/boss_aku_mai.cpp b/src/server/scripts/Kalimdor/BlackfathomDeeps/boss_aku_mai.cpp index 32a6bcbde77..7071395812e 100644 --- a/src/server/scripts/Kalimdor/BlackfathomDeeps/boss_aku_mai.cpp +++ b/src/server/scripts/Kalimdor/BlackfathomDeeps/boss_aku_mai.cpp @@ -15,7 +15,8 @@   * with this program. If not, see <http://www.gnu.org/licenses/>.   */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h"  #include "blackfathom_deeps.h"  enum Spells @@ -42,14 +43,14 @@ public:          }          uint32 poisonCloudTimer; -        bool bIsEnraged; +        bool IsEnraged;          InstanceScript* instance;          void Reset()          {              poisonCloudTimer = urand(5000, 9000); -            bIsEnraged = false; +            IsEnraged = false;              if (instance)                  instance->SetData(TYPE_AKU_MAI, NOT_STARTED);          } @@ -77,10 +78,10 @@ public:                  poisonCloudTimer = urand(25000, 50000);              } else poisonCloudTimer -= diff; -            if (!bIsEnraged && HealthBelowPct(30)) +            if (!IsEnraged && HealthBelowPct(30))              {                  DoCast(me, SPELL_FRENZIED_RAGE); -                bIsEnraged = true; +                IsEnraged = true;              }              DoMeleeAttackIfReady(); diff --git a/src/server/scripts/Kalimdor/BlackfathomDeeps/boss_gelihast.cpp b/src/server/scripts/Kalimdor/BlackfathomDeeps/boss_gelihast.cpp index 5a60a849b75..1488772dc8a 100644 --- a/src/server/scripts/Kalimdor/BlackfathomDeeps/boss_gelihast.cpp +++ b/src/server/scripts/Kalimdor/BlackfathomDeeps/boss_gelihast.cpp @@ -15,7 +15,8 @@   * with this program. If not, see <http://www.gnu.org/licenses/>.   */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h"  #include "blackfathom_deeps.h"  enum Spells diff --git a/src/server/scripts/Kalimdor/BlackfathomDeeps/boss_kelris.cpp b/src/server/scripts/Kalimdor/BlackfathomDeeps/boss_kelris.cpp index 7ee17172102..1c754b78672 100644 --- a/src/server/scripts/Kalimdor/BlackfathomDeeps/boss_kelris.cpp +++ b/src/server/scripts/Kalimdor/BlackfathomDeeps/boss_kelris.cpp @@ -15,7 +15,8 @@   * with this program. If not, see <http://www.gnu.org/licenses/>.   */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h"  #include "blackfathom_deeps.h"  enum Spells diff --git a/src/server/scripts/Kalimdor/BlackfathomDeeps/instance_blackfathom_deeps.cpp b/src/server/scripts/Kalimdor/BlackfathomDeeps/instance_blackfathom_deeps.cpp index ea33499a960..236c7b1ba69 100644 --- a/src/server/scripts/Kalimdor/BlackfathomDeeps/instance_blackfathom_deeps.cpp +++ b/src/server/scripts/Kalimdor/BlackfathomDeeps/instance_blackfathom_deeps.cpp @@ -23,7 +23,8 @@ SDComment:  SDCategory: Blackfathom Deeps  EndScriptData */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "InstanceScript.h"  #include "blackfathom_deeps.h"  #define MAX_ENCOUNTER 4 diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp index 85f82c62079..222626240ea 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp @@ -15,42 +15,30 @@   * with this program. If not, see <http://www.gnu.org/licenses/>.   */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h"  #include "hyjal.h"  #include "hyjal_trash.h" -#define SPELL_CARRION_SWARM 31306 -#define SPELL_SLEEP 31298 -#define SPELL_VAMPIRIC_AURA 38196 -#define SPELL_INFERNO 31299 - -#define SAY_ONDEATH "The clock... is still... ticking." -#define SOUND_ONDEATH 10982 - -#define SAY_ONSLAY1 "Your hopes are lost!" -#define SAY_ONSLAY2 "Scream for me!" -#define SAY_ONSLAY3 "Pity, no time for a slow death!" -#define SOUND_ONSLAY1 10981 -#define SOUND_ONSLAY2 11038 -#define SOUND_ONSLAY3 11039 - -#define SAY_SWARM1 "The swarm is eager to feed!" -#define SAY_SWARM2 "Pestilence upon you!" -#define SOUND_SWARM1 10979 -#define SOUND_SWARM2 11037 - -#define SAY_SLEEP1 "You look tired..." -#define SAY_SLEEP2 "Sweet dreams..." -#define SOUND_SLEEP1 10978 -#define SOUND_SLEEP2 11545 - -#define SAY_INFERNO1 "Let fire rain from above!" -#define SAY_INFERNO2 "Earth and sky shall burn!" -#define SOUND_INFERNO1 10980 -#define SOUND_INFERNO2 11036 +enum Spells +{ +    SPELL_CARRION_SWARM     = 31306, +    SPELL_SLEEP             = 31298, +    SPELL_VAMPIRIC_AURA     = 38196, +    SPELL_INFERNO           = 31299, +    SPELL_IMMOLATION        = 31303, +    SPELL_INFERNO_EFFECT    = 31302, +}; -#define SAY_ONAGGRO "You are defenders of a doomed world! Flee here, and perhaps you will prolong your pathetic lives!" -#define SOUND_ONAGGRO 10977 +enum Texts +{ +    SAY_ONDEATH         = 0, +    SAY_ONSLAY          = 1, +    SAY_SWARM           = 2, +    SAY_SLEEP           = 3, +    SAY_INFERNO         = 4, +    SAY_ONAGGRO         = 5, +};  class boss_anetheron : public CreatureScript  { @@ -92,27 +80,12 @@ public:          {              if (instance && IsEvent)                  instance->SetData(DATA_ANETHERONEVENT, IN_PROGRESS); -            DoPlaySoundToSet(me, SOUND_ONAGGRO); -            me->MonsterYell(SAY_ONAGGRO, LANG_UNIVERSAL, 0); +            Talk(SAY_ONAGGRO);          }          void KilledUnit(Unit* /*victim*/)          { -            switch (urand(0, 2)) -            { -                case 0: -                    DoPlaySoundToSet(me, SOUND_ONSLAY1); -                    me->MonsterYell(SAY_ONSLAY1, LANG_UNIVERSAL, 0); -                    break; -                case 1: -                    DoPlaySoundToSet(me, SOUND_ONSLAY2); -                    me->MonsterYell(SAY_ONSLAY2, LANG_UNIVERSAL, 0); -                    break; -                case 2: -                    DoPlaySoundToSet(me, SOUND_ONSLAY3); -                    me->MonsterYell(SAY_ONSLAY3, LANG_UNIVERSAL, 0); -                    break; -            } +            Talk(SAY_ONSLAY);          }          void WaypointReached(uint32 waypointId) @@ -130,8 +103,7 @@ public:              hyjal_trashAI::JustDied(killer);              if (instance && IsEvent)                  instance->SetData(DATA_ANETHERONEVENT, DONE); -            DoPlaySoundToSet(me, SOUND_ONDEATH); -            me->MonsterYell(SAY_ONDEATH, LANG_UNIVERSAL, 0); +            Talk(SAY_ONDEATH);          }          void UpdateAI(const uint32 diff) @@ -169,17 +141,7 @@ public:                      DoCast(target, SPELL_CARRION_SWARM);                  SwarmTimer = urand(45000, 60000); -                switch (urand(0, 1)) -                { -                    case 0: -                        DoPlaySoundToSet(me, SOUND_SWARM1); -                        me->MonsterYell(SAY_SWARM1, LANG_UNIVERSAL, 0); -                        break; -                    case 1: -                        DoPlaySoundToSet(me, SOUND_SWARM2); -                        me->MonsterYell(SAY_SWARM2, LANG_UNIVERSAL, 0); -                        break; -                } +                Talk(SAY_SWARM);              } else SwarmTimer -= diff;              if (SleepTimer <= diff) @@ -190,17 +152,7 @@ public:                          target->CastSpell(target, SPELL_SLEEP, true);                  }                  SleepTimer = 60000; -                switch (urand(0, 1)) -                { -                    case 0: -                        DoPlaySoundToSet(me, SOUND_SLEEP1); -                        me->MonsterYell(SAY_SLEEP1, LANG_UNIVERSAL, 0); -                        break; -                    case 1: -                        DoPlaySoundToSet(me, SOUND_SLEEP2); -                        me->MonsterYell(SAY_SLEEP2, LANG_UNIVERSAL, 0); -                        break; -                } +                Talk(SAY_SLEEP);              } else SleepTimer -= diff;              if (AuraTimer <= diff)              { @@ -211,17 +163,7 @@ public:              {                  DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true), SPELL_INFERNO);                  InfernoTimer = 45000; -                switch (urand(0, 1)) -                { -                    case 0: -                        DoPlaySoundToSet(me, SOUND_INFERNO1); -                        me->MonsterYell(SAY_INFERNO1, LANG_UNIVERSAL, 0); -                        break; -                    case 1: -                        DoPlaySoundToSet(me, SOUND_INFERNO2); -                        me->MonsterYell(SAY_INFERNO2, LANG_UNIVERSAL, 0); -                        break; -                } +                Talk(SAY_INFERNO);              } else InfernoTimer -= diff;              DoMeleeAttackIfReady(); @@ -230,9 +172,6 @@ public:  }; -#define SPELL_IMMOLATION     31303 -#define SPELL_INFERNO_EFFECT 31302 -  class mob_towering_infernal : public CreatureScript  {  public: diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp index f07aaaa1f2a..ee988accbac 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp @@ -23,56 +23,57 @@ SDComment: Doomfires not completely offlike due to core limitations for random m  SDCategory: Caverns of Time, Mount Hyjal  EndScriptData */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h"  #include "hyjal.h"  #include "SpellAuras.h"  #include "hyjal_trash.h" -//text id -1534018 are the text used when previous events complete. Not part of this script. -#define SAY_AGGRO                   -1534019 -#define SAY_DOOMFIRE1               -1534020 -#define SAY_DOOMFIRE2               -1534021 -#define SAY_AIR_BURST1              -1534022 -#define SAY_AIR_BURST2              -1534023 -#define SAY_SLAY1                   -1534024 -#define SAY_SLAY2                   -1534025 -#define SAY_SLAY3                   -1534026 -#define SAY_ENRAGE                  -1534027 -#define SAY_DEATH                   -1534028 -#define SAY_SOUL_CHARGE1            -1534029 -#define SAY_SOUL_CHARGE2            -1534030 - -#define SPELL_DENOUEMENT_WISP       32124 -#define SPELL_ANCIENT_SPARK         39349 -#define SPELL_PROTECTION_OF_ELUNE   38528 - -#define SPELL_DRAIN_WORLD_TREE      39140 -#define SPELL_DRAIN_WORLD_TREE_2    39141 - -#define SPELL_FINGER_OF_DEATH       31984 -#define SPELL_HAND_OF_DEATH         35354 -#define SPELL_AIR_BURST             32014 -#define SPELL_GRIP_OF_THE_LEGION    31972 -#define SPELL_DOOMFIRE_STRIKE       31903                   //summons two creatures -#define SPELL_DOOMFIRE_SPAWN        32074 -#define SPELL_DOOMFIRE              31945 -#define SPELL_SOUL_CHARGE_YELLOW    32045 -#define SPELL_SOUL_CHARGE_GREEN     32051 -#define SPELL_SOUL_CHARGE_RED       32052 -#define SPELL_UNLEASH_SOUL_YELLOW   32054 -#define SPELL_UNLEASH_SOUL_GREEN    32057 -#define SPELL_UNLEASH_SOUL_RED      32053 -#define SPELL_FEAR                  31970 - -#define CREATURE_ARCHIMONDE             17968 -#define CREATURE_DOOMFIRE               18095 -#define CREATURE_DOOMFIRE_SPIRIT        18104 -#define CREATURE_ANCIENT_WISP           17946 -#define CREATURE_CHANNEL_TARGET         22418 - -#define NORDRASSIL_X        5503.713f -#define NORDRASSIL_Y       -3523.436f -#define NORDRASSIL_Z        1608.781f +enum Texts +{ +    SAY_AGGRO       = 1, +    SAY_DOOMFIRE    = 2, +    SAY_AIR_BURST   = 3, +    SAY_SLAY        = 4, +    SAY_ENRAGE      = 5, +    SAY_DEATH       = 6, +    SAY_SOUL_CHARGE = 7, +}; + +enum Spells +{ +    SPELL_DENOUEMENT_WISP       = 32124, +    SPELL_ANCIENT_SPARK         = 39349, +    SPELL_PROTECTION_OF_ELUNE   = 38528, + +    SPELL_DRAIN_WORLD_TREE      = 39140, +    SPELL_DRAIN_WORLD_TREE_2    = 39141, + +    SPELL_FINGER_OF_DEATH       = 31984, +    SPELL_HAND_OF_DEATH         = 35354, +    SPELL_AIR_BURST             = 32014, +    SPELL_GRIP_OF_THE_LEGION    = 31972, +    SPELL_DOOMFIRE_STRIKE       = 31903,    //summons two creatures +    SPELL_DOOMFIRE_SPAWN        = 32074, +    SPELL_DOOMFIRE              = 31945, +    SPELL_SOUL_CHARGE_YELLOW    = 32045, +    SPELL_SOUL_CHARGE_GREEN     = 32051, +    SPELL_SOUL_CHARGE_RED       = 32052, +    SPELL_UNLEASH_SOUL_YELLOW   = 32054, +    SPELL_UNLEASH_SOUL_GREEN    = 32057, +    SPELL_UNLEASH_SOUL_RED      = 32053, +    SPELL_FEAR                  = 31970, +}; + +enum Summons +{ +    CREATURE_DOOMFIRE               = 18095, +    CREATURE_DOOMFIRE_SPIRIT        = 18104, +    CREATURE_ANCIENT_WISP           = 17946, +    CREATURE_CHANNEL_TARGET         = 22418, +}; + +Position const NordrassilLoc = {5503.713f, -3523.436f, 1608.781f, 0.0f};  class mob_ancient_wisp : public CreatureScript  { @@ -258,11 +259,11 @@ public:          uint32 GripOfTheLegionTimer;          uint32 DoomfireTimer;          uint32 SoulChargeTimer; -        uint32 SoulChargeCount; +        uint8 SoulChargeCount;          uint32 MeleeRangeCheckTimer;          uint32 HandOfDeathTimer;          uint32 SummonWispTimer; -        uint32 WispCount; +        uint8 WispCount;          uint32 EnrageTimer;          uint32 CheckDistanceTimer; @@ -303,7 +304,7 @@ public:          void EnterCombat(Unit* /*who*/)          {              me->InterruptSpell(CURRENT_CHANNELED_SPELL); -            DoScriptText(SAY_AGGRO, me); +            Talk(SAY_AGGRO);              DoZoneInCombat();              if (instance) @@ -312,7 +313,7 @@ public:          void KilledUnit(Unit* victim)          { -            DoScriptText(RAND(SAY_SLAY1, SAY_SLAY2, SAY_SLAY3), me); +            Talk(SAY_SLAY);              if (victim && (victim->GetTypeId() == TYPEID_PLAYER))                  GainSoulCharge(CAST_PLR(victim)); @@ -346,7 +347,7 @@ public:          void JustDied(Unit* killer)          {              hyjal_trashAI::JustDied(killer); -            DoScriptText(SAY_DEATH, me); +            Talk(SAY_DEATH);              if (instance)                  instance->SetData(DATA_ARCHIMONDEEVENT, DONE); @@ -488,7 +489,7 @@ public:                  {                      if (!IsChanneling)                      { -                        Creature* temp = me->SummonCreature(CREATURE_CHANNEL_TARGET, NORDRASSIL_X, NORDRASSIL_Y, NORDRASSIL_Z, 0, TEMPSUMMON_TIMED_DESPAWN, 1200000); +                        Creature* temp = me->SummonCreature(CREATURE_CHANNEL_TARGET, NordrassilLoc, TEMPSUMMON_TIMED_DESPAWN, 1200000);                          if (temp)                              WorldTreeGUID = temp->GetGUID(); @@ -525,14 +526,14 @@ public:                          me->GetMotionMaster()->Clear(false);                          me->GetMotionMaster()->MoveIdle();                          Enraged = true; -                        DoScriptText(SAY_ENRAGE, me); +                        Talk(SAY_ENRAGE);                      }                  } else EnrageTimer -= diff;                  if (CheckDistanceTimer <= diff)                  {                      // To simplify the check, we simply summon a Creature in the location and then check how far we are from the creature -                    Creature* Check = me->SummonCreature(CREATURE_CHANNEL_TARGET, NORDRASSIL_X, NORDRASSIL_Y, NORDRASSIL_Z, 0, TEMPSUMMON_TIMED_DESPAWN, 2000); +                    Creature* Check = me->SummonCreature(CREATURE_CHANNEL_TARGET, NordrassilLoc, TEMPSUMMON_TIMED_DESPAWN, 2000);                      if (Check)                      {                          Check->SetVisible(false); @@ -542,7 +543,7 @@ public:                              me->GetMotionMaster()->Clear(false);                              me->GetMotionMaster()->MoveIdle();                              Enraged = true; -                            DoScriptText(SAY_ENRAGE, me); +                            Talk(SAY_ENRAGE);                          }                      }                      CheckDistanceTimer = 5000; @@ -598,11 +599,7 @@ public:              if (AirBurstTimer <= diff)              { -                if (urand(0, 1)) -                    DoScriptText(SAY_AIR_BURST1, me); -                else -                    DoScriptText(SAY_AIR_BURST2, me); - +                Talk(SAY_AIR_BURST);                  DoCast(SelectTarget(SELECT_TARGET_RANDOM, 1), SPELL_AIR_BURST);//not on tank                  AirBurstTimer = urand(25000, 40000);              } else AirBurstTimer -= diff; @@ -615,11 +612,7 @@ public:              if (DoomfireTimer <= diff)              { -                if (urand(0, 1)) -                    DoScriptText(SAY_DOOMFIRE1, me); -                else -                    DoScriptText(SAY_DOOMFIRE2, me); - +                Talk(SAY_DOOMFIRE);                  Unit* temp = SelectTarget(SELECT_TARGET_RANDOM, 1);                  if (!temp)                      temp = me->getVictim(); diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp index a9e0c866ab9..bfdaed35dd4 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp @@ -15,33 +15,31 @@   * with this program. If not, see <http://www.gnu.org/licenses/>.   */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h"  #include "hyjal.h"  #include "hyjal_trash.h" -#define SPELL_RAIN_OF_FIRE 31340 -#define SPELL_DOOM 31347 -#define SPELL_HOWL_OF_AZGALOR 31344 -#define SPELL_CLEAVE 31345 -#define SPELL_BERSERK 26662 - -#define SAY_ONDEATH "Your time is almost... up" -#define SOUND_ONDEATH 11002 - -#define SAY_ONSLAY1 "Reesh, hokta!" -#define SAY_ONSLAY2 "Don't fight it" -#define SAY_ONSLAY3 "No one is going to save you" -#define SOUND_ONSLAY1 11001 -#define SOUND_ONSLAY2 11048 -#define SOUND_ONSLAY3 11047 - -#define SAY_DOOM1 "Just a taste... of what awaits you" -#define SAY_DOOM2 "Suffer you despicable insect!" -#define SOUND_DOOM1 11046 -#define SOUND_DOOM2 11000 +enum Spells +{ +    SPELL_RAIN_OF_FIRE          = 31340, +    SPELL_DOOM                  = 31347, +    SPELL_HOWL_OF_AZGALOR       = 31344, +    SPELL_CLEAVE                = 31345, +    SPELL_BERSERK               = 26662, + +    SPELL_THRASH                = 12787, +    SPELL_CRIPPLE               = 31406, +    SPELL_WARSTOMP              = 31408, +}; -#define SAY_ONAGGRO "Abandon all hope! The legion has returned to finish what was begun so many years ago. This time there will be no escape!" -#define SOUND_ONAGGRO 10999 +enum Texts +{ +    SAY_ONDEATH             = 0, +    SAY_ONSLAY              = 1, +    SAY_DOOM                = 2, // Not used? +    SAY_ONAGGRO             = 3, +};  class boss_azgalor : public CreatureScript  { @@ -88,27 +86,12 @@ public:          {              if (instance && IsEvent)                  instance->SetData(DATA_AZGALOREVENT, IN_PROGRESS); -            DoPlaySoundToSet(me, SOUND_ONAGGRO); -            me->MonsterYell(SAY_ONAGGRO, LANG_UNIVERSAL, 0); +            Talk(SAY_ONAGGRO);          }          void KilledUnit(Unit* /*victim*/)          { -            switch (urand(0, 2)) -            { -                case 0: -                    DoPlaySoundToSet(me, SOUND_ONSLAY1); -                    me->MonsterYell(SAY_ONSLAY1, LANG_UNIVERSAL, 0); -                    break; -                case 1: -                    DoPlaySoundToSet(me, SOUND_ONSLAY2); -                    me->MonsterYell(SAY_ONSLAY2, LANG_UNIVERSAL, 0); -                    break; -                case 2: -                    DoPlaySoundToSet(me, SOUND_ONSLAY3); -                    me->MonsterYell(SAY_ONSLAY3, LANG_UNIVERSAL, 0); -                    break; -            } +            Talk(SAY_ONSLAY);          }          void WaypointReached(uint32 waypointId) @@ -126,7 +109,7 @@ public:              hyjal_trashAI::JustDied(killer);              if (instance && IsEvent)                  instance->SetData(DATA_AZGALOREVENT, DONE); -            DoPlaySoundToSet(me, SOUND_ONDEATH); +            Talk(SAY_ONDEATH);          }          void UpdateAI(const uint32 diff) @@ -196,10 +179,6 @@ public:  }; -#define SPELL_THRASH 12787 -#define SPELL_CRIPPLE 31406 -#define SPELL_WARSTOMP 31408 -  class mob_lesser_doomguard : public CreatureScript  {  public: diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp index 407faa19eaa..29eff68dfbd 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp @@ -15,30 +15,32 @@   * with this program. If not, see <http://www.gnu.org/licenses/>.   */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "SpellAuraEffects.h" +#include "SpellScript.h"  #include "hyjal.h"  #include "hyjal_trash.h" -#define SPELL_CLEAVE 31436 -#define SPELL_WARSTOMP 31480 -#define SPELL_MARK 31447 - -#define SOUND_ONDEATH 11018 - -#define SAY_ONSLAY1 "Shaza-Kiel!" -#define SAY_ONSLAY2 "You... are nothing!" -#define SAY_ONSLAY3 "Miserable nuisance!" -#define SOUND_ONSLAY1 11017 -#define SOUND_ONSLAY2 11053 -#define SOUND_ONSLAY3 11054 +enum Spells +{ +    SPELL_CLEAVE        = 31436, +    SPELL_WARSTOMP      = 31480, +    SPELL_MARK          = 31447, +    SPELL_MARK_DAMAGE   = 31463 +}; -#define SAY_MARK1 "Your death will be a painful one." -#define SAY_MARK2 "You... are marked." -#define SOUND_MARK1 11016 -#define SOUND_MARK2 11052 +enum Texts +{ +    SAY_ONSLAY          = 0, +    SAY_MARK            = 1, +    SAY_ONAGGRO         = 2, +}; -#define SAY_ONAGGRO "Cry for mercy! Your meaningless lives will soon be forfeit." -#define SOUND_ONAGGRO 11015 +enum Sounds +{ +    SOUND_ONDEATH       = 11018, +};  class boss_kazrogal : public CreatureScript  { @@ -80,27 +82,12 @@ public:          {              if (instance && IsEvent)                  instance->SetData(DATA_KAZROGALEVENT, IN_PROGRESS); -            DoPlaySoundToSet(me, SOUND_ONAGGRO); -            me->MonsterYell(SAY_ONAGGRO, LANG_UNIVERSAL, 0); +            Talk(SAY_ONAGGRO);          }          void KilledUnit(Unit* /*victim*/)          { -            switch (urand(0, 2)) -            { -                case 0: -                    DoPlaySoundToSet(me, SOUND_ONSLAY1); -                    me->MonsterYell(SAY_ONSLAY1, LANG_UNIVERSAL, 0); -                    break; -                case 1: -                    DoPlaySoundToSet(me, SOUND_ONSLAY2); -                    me->MonsterYell(SAY_ONSLAY2, LANG_UNIVERSAL, 0); -                    break; -                case 2: -                    DoPlaySoundToSet(me, SOUND_ONSLAY3); -                    me->MonsterYell(SAY_ONSLAY3, LANG_UNIVERSAL, 0); -                    break; -            } +            Talk(SAY_ONSLAY);          }          void WaypointReached(uint32 waypointId) @@ -162,37 +149,15 @@ public:                  WarStompTimer = 60000;              } else WarStompTimer -= diff; -            if (me->HasAura(SPELL_MARK)) -                me->RemoveAurasDueToSpell(SPELL_MARK);              if (MarkTimer <= diff)              { -                //cast dummy, useful for bos addons -                me->CastCustomSpell(me, SPELL_MARK, NULL, NULL, NULL, false, NULL, NULL, me->GetGUID()); +                DoCastAOE(SPELL_MARK); -                std::list<HostileReference*> t_list = me->getThreatManager().getThreatList(); -                for (std::list<HostileReference*>::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr) -                { -                    Unit* target = Unit::GetUnit(*me, (*itr)->getUnitGuid()); -                    if (target && target->GetTypeId() == TYPEID_PLAYER && target->getPowerType() == POWER_MANA) -                    { -                        target->CastSpell(target, SPELL_MARK, true);//only cast on mana users -                    } -                }                  MarkTimerBase -= 5000;                  if (MarkTimerBase < 5500)                      MarkTimerBase = 5500;                  MarkTimer = MarkTimerBase; -                switch (urand(0, 2)) -                { -                    case 0: -                        DoPlaySoundToSet(me, SOUND_MARK1); -                        me->MonsterYell(SAY_MARK1, LANG_UNIVERSAL, 0); -                        break; -                    case 1: -                        DoPlaySoundToSet(me, SOUND_MARK2); -                        me->MonsterYell(SAY_MARK2, LANG_UNIVERSAL, 0); -                        break; -                } +                Talk(SAY_MARK);              } else MarkTimer -= diff;              DoMeleeAttackIfReady(); @@ -201,7 +166,79 @@ public:  }; +class MarkTargetFilter +{ +    public: +        bool operator()(WorldObject* target) const +        { +            if (Unit* unit = target->ToUnit()) +                return unit->getPowerType() != POWER_MANA; +            return false; +        } +}; + +class spell_mark_of_kazrogal : public SpellScriptLoader +{ +    public: +        spell_mark_of_kazrogal() : SpellScriptLoader("spell_mark_of_kazrogal") { } + +        class spell_mark_of_kazrogal_SpellScript : public SpellScript +        { +            PrepareSpellScript(spell_mark_of_kazrogal_SpellScript); + +            void FilterTargets(std::list<WorldObject*>& targets) +            { +                targets.remove_if(MarkTargetFilter()); +            } + +            void Register() +            { +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mark_of_kazrogal_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); +            } +        }; + +        class spell_mark_of_kazrogal_AuraScript : public AuraScript +        { +            PrepareAuraScript(spell_mark_of_kazrogal_AuraScript); + +            bool Validate(SpellInfo const* /*spell*/) +            { +                if (!sSpellMgr->GetSpellInfo(SPELL_MARK_DAMAGE)) +                    return false; +                return true; +            } + +            void OnPeriodic(AuraEffect const* aurEff) +            { +                Unit* target = GetTarget(); + +                if (target->GetPower(POWER_MANA) == 0) +                { +                    target->CastSpell(target, SPELL_MARK_DAMAGE, true, NULL, aurEff); +                    // Remove aura +                    SetDuration(0); +                } +            } + +            void Register() +            { +                OnEffectPeriodic += AuraEffectPeriodicFn(spell_mark_of_kazrogal_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_MANA_LEECH); +            } +        }; + +        SpellScript* GetSpellScript() const +        { +            return new spell_mark_of_kazrogal_SpellScript(); +        } + +        AuraScript* GetAuraScript() const +        { +            return new spell_mark_of_kazrogal_AuraScript(); +        } +}; +  void AddSC_boss_kazrogal()  {      new boss_kazrogal(); +    new spell_mark_of_kazrogal();  } diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_rage_winterchill.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_rage_winterchill.cpp index 5d7ee1fe194..09c8c1605b3 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_rage_winterchill.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_rage_winterchill.cpp @@ -15,36 +15,27 @@   * with this program. If not, see <http://www.gnu.org/licenses/>.   */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h"  #include "hyjal.h"  #include "hyjal_trash.h" -#define SPELL_FROST_ARMOR 31256 -#define SPELL_DEATH_AND_DECAY 31258 - -#define SPELL_FROST_NOVA 31250 -#define SPELL_ICEBOLT 31249 - -#define SAY_ONDEATH "You have won this battle, but not... the... war" -#define SOUND_ONDEATH 11026 - -#define SAY_ONSLAY1 "All life must perish!" -#define SAY_ONSLAY2 "Victory to the Legion!" -#define SOUND_ONSLAY1 11025 -#define SOUND_ONSLAY2 11057 - -#define SAY_DECAY1 "Crumble and rot!" -#define SAY_DECAY2 "Ashes to ashes, dust to dust" -#define SOUND_DECAY1 11023 -#define SOUND_DECAY2 11055 - -#define SAY_NOVA1 "Succumb to the icy chill... of death!" -#define SAY_NOVA2 "It will be much colder in your grave" -#define SOUND_NOVA1 11024 -#define SOUND_NOVA2 11058 +enum Spells +{ +    SPELL_FROST_ARMOR           = 31256, +    SPELL_DEATH_AND_DECAY       = 31258, +    SPELL_FROST_NOVA            = 31250, +    SPELL_ICEBOLT               = 31249, +}; -#define SAY_ONAGGRO "The Legion's final conquest has begun! Once again the subjugation of this world is within our grasp. Let none survive!" -#define SOUND_ONAGGRO 11022 +enum Texts +{ +    SAY_ONDEATH         = 0, +    SAY_ONSLAY          = 1, +    SAY_DECAY           = 2, +    SAY_NOVA            = 3, +    SAY_ONAGGRO         = 4, +};  class boss_rage_winterchill : public CreatureScript  { @@ -86,23 +77,12 @@ public:          {              if (instance && IsEvent)                  instance->SetData(DATA_RAGEWINTERCHILLEVENT, IN_PROGRESS); -            DoPlaySoundToSet(me, SOUND_ONAGGRO); -            me->MonsterYell(SAY_ONAGGRO, LANG_UNIVERSAL, 0); +            Talk(SAY_ONAGGRO);          }          void KilledUnit(Unit* /*victim*/)          { -            switch (urand(0, 1)) -            { -                case 0: -                    DoPlaySoundToSet(me, SOUND_ONSLAY1); -                    me->MonsterYell(SAY_ONSLAY1, LANG_UNIVERSAL, 0); -                    break; -                case 1: -                    DoPlaySoundToSet(me, SOUND_ONSLAY2); -                    me->MonsterYell(SAY_ONSLAY2, LANG_UNIVERSAL, 0); -                    break; -            } +            Talk(SAY_ONSLAY);          }          void WaypointReached(uint32 waypointId) @@ -120,8 +100,7 @@ public:              hyjal_trashAI::JustDied(killer);              if (instance && IsEvent)                  instance->SetData(DATA_RAGEWINTERCHILLEVENT, DONE); -            DoPlaySoundToSet(me, SOUND_ONDEATH); -            me->MonsterYell(SAY_ONDEATH, LANG_UNIVERSAL, 0); +            Talk(SAY_ONDEATH);          }          void UpdateAI(const uint32 diff) @@ -162,33 +141,13 @@ public:              {                  DoCast(me->getVictim(), SPELL_DEATH_AND_DECAY);                  DecayTimer = 60000+rand()%20000; -                switch (urand(0, 1)) -                { -                    case 0: -                        DoPlaySoundToSet(me, SOUND_DECAY1); -                        me->MonsterYell(SAY_DECAY1, LANG_UNIVERSAL, 0); -                        break; -                    case 1: -                        DoPlaySoundToSet(me, SOUND_DECAY2); -                        me->MonsterYell(SAY_DECAY2, LANG_UNIVERSAL, 0); -                        break; -                } +                Talk(SAY_DECAY);              } else DecayTimer -= diff;              if (NovaTimer <= diff)              {                  DoCast(me->getVictim(), SPELL_FROST_NOVA);                  NovaTimer = 30000+rand()%15000; -                switch (urand(0, 1)) -                { -                    case 0: -                        DoPlaySoundToSet(me, SOUND_NOVA1); -                        me->MonsterYell(SAY_NOVA1, LANG_UNIVERSAL, 0); -                        break; -                    case 1: -                        DoPlaySoundToSet(me, SOUND_NOVA2); -                        me->MonsterYell(SAY_NOVA2, LANG_UNIVERSAL, 0); -                        break; -                } +                Talk(SAY_NOVA);              } else NovaTimer -= diff;              if (IceboltTimer <= diff)              { diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.cpp index 22307468f14..1be8f8e058f 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.cpp @@ -29,7 +29,9 @@ npc_thrall  npc_tyrande_whisperwind  EndContentData */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h"  #include "hyjalAI.h"  #define GOSSIP_ITEM_BEGIN_ALLY      "My companions and I are with you, Lady Proudmoore." diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.h b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.h index e045d3cbf05..6d62072608d 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.h +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.h @@ -21,7 +21,7 @@  #define ERROR_INST_DATA     "TSCR: Instance data not set properly for Mount Hyjal. Encounters will be buggy." -enum eTypes +enum Types  {      WORLD_STATE_WAVES         = 2842,      WORLD_STATE_ENEMY         = 2453, diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp index 2f6bbb7edb5..a407f86ba70 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp @@ -23,17 +23,22 @@ SDComment:  SDCategory: Caverns of Time, Mount Hyjal  EndScriptData */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedEscortAI.h" +#include "GridNotifiers.h" +#include "GridNotifiersImpl.h" +#include "Cell.h" +#include "CellImpl.h"  #include "hyjalAI.h"  #include "hyjal_trash.h" -#include "MapManager.h" -#include "Language.h" -#include "Chat.h" -#include "Object.h" - -#define SPAWN_GARG_GATE 0 -#define SPAWN_WYRM_GATE 1 -#define SPAWN_NEAR_TOWER 2 + +enum Spawns +{ +    SPAWN_GARG_GATE     = 0, +    SPAWN_WYRM_GATE     = 1, +    SPAWN_NEAR_TOWER    = 2, +};  #define YELL_HURRY  "Hurry, we don't have much time" diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.h b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.h index b32288ca43a..68efa94d98b 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.h +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.h @@ -24,43 +24,49 @@  #define HYJAL_AI_MAX_SPELLS 3 -// Trash Mobs summoned in waves -#define NECROMANCER         17899//done -#define ABOMINATION         17898//done -#define GHOUL               17895//done -#define BANSHEE             17905//done -#define CRYPT_FIEND         17897//done -#define GARGOYLE            17906//done -#define FROST_WYRM          17907//done -#define GIANT_INFERNAL      17908//done -#define FEL_STALKER         17916//done - -#define JAINA               17772 -#define THRALL              17852 -#define TYRANDE             17948 - -#define ANCIENT_VEIN        185557 -#define FLAMEOBJECT         182592 - -// Bosses summoned after every 8 waves -#define RAGE_WINTERCHILL    17767 -#define ANETHERON           17808 -#define KAZROGAL            17888 -#define AZGALOR             17842 -#define ARCHIMONDE          17968 - -#define SPELL_TELEPORT_VISUAL     41232 -#define SPELL_MASS_TELEPORT       16807 - -//Spells for Jaina -#define SPELL_BRILLIANCE_AURA     31260                     // The database must handle this spell via creature_addon(it should, but is removed in evade..) -#define SPELL_BLIZZARD            31266 -#define SPELL_PYROBLAST           31263 -#define SPELL_SUMMON_ELEMENTALS   31264 - -//Thrall spells -#define SPELL_CHAIN_LIGHTNING     31330 -#define SPELL_SUMMON_DIRE_WOLF    31331 +enum CreaturesIds +{ +    // Trash Mobs summoned in waves +    NECROMANCER         = 17899, +    ABOMINATION         = 17898, +    GHOUL               = 17895, +    BANSHEE             = 17905, +    CRYPT_FIEND         = 17897, +    GARGOYLE            = 17906, +    FROST_WYRM          = 17907, +    GIANT_INFERNAL      = 17908, +    FEL_STALKER         = 17916, + +    JAINA               = 17772, +    THRALL              = 17852, +    TYRANDE             = 17948, + +    ANCIENT_VEIN        = 185557, +    FLAMEOBJECT         = 182592, + +    // Bosses summoned after every 8 waves +    RAGE_WINTERCHILL    = 17767, +    ANETHERON           = 17808, +    KAZROGAL            = 17888, +    AZGALOR             = 17842, +    ARCHIMONDE          = 17968, +}; + +enum SpellIds +{ +    SPELL_TELEPORT_VISUAL     = 41232, +    SPELL_MASS_TELEPORT       = 16807, + +    //Spells for Jaina +    SPELL_BRILLIANCE_AURA     = 31260,   // The database must handle this spell via creature_addon(it should, but is removed in evade..) +    SPELL_BLIZZARD            = 31266, +    SPELL_PYROBLAST           = 31263, +    SPELL_SUMMON_ELEMENTALS   = 31264, + +    //Thrall spells +    SPELL_CHAIN_LIGHTNING     = 31330, +    SPELL_SUMMON_DIRE_WOLF    = 31331, +};  struct Wave  { diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp index 840aa5de081..d3218e1729e 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp @@ -15,16 +15,35 @@   * with this program. If not, see <http://www.gnu.org/licenses/>.   */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h"  #include "hyjal.h"  #include "hyjal_trash.h"  #include "hyjalAI.h" -#define SPELL_METEOR 33814 //infernal visual -#define SPELL_IMMOLATION 37059 -#define SPELL_FLAME_BUFFET 31724 -#define NPC_TRIGGER  21987 //World Trigger (Tiny) -#define MODEL_INVIS  11686 //invisible model +enum Spells +{ +    SPELL_METEOR            = 33814, //infernal visual +    SPELL_IMMOLATION        = 37059, +    SPELL_FLAME_BUFFET      = 31724, +    NPC_TRIGGER             = 21987, //World Trigger (Tiny) +    MODEL_INVIS             = 11686, //invisible model +    SPELL_DISEASE_CLOUD     = 31607, +    SPELL_KNOCKDOWN         = 31610, +    SPELL_FRENZY            = 31540, +    SPELL_RAISE_DEAD_1      = 31617, +    SPELL_RAISE_DEAD_2      = 31624, +    SPELL_RAISE_DEAD_3      = 31625, +    SPELL_SHADOW_BOLT       = 31627, +    SPELL_BANSHEE_CURSE     = 31651, +    SPELL_BANSHEE_WAIL      = 38183, +    SPELL_ANTI_MAGIC_SHELL  = 31662, +    SPELL_WEB               = 28991,     +    SPELL_MANA_BURN         = 31729, +    SPELL_FROST_BREATH      = 31688, +    SPELL_GARGOYLE_STRIKE   = 31664, +    SPELL_EXPLODING_SHOT    = 7896, +};  float HordeWPs[8][3]=//basic waypoints from spawn to leader  { @@ -522,9 +541,6 @@ public:      }  }; -#define SPELL_DISEASE_CLOUD 31607 -#define SPELL_KNOCKDOWN 31610 -  class mob_abomination : public CreatureScript  {  public: @@ -623,8 +639,6 @@ public:  }; -#define SPELL_FRENZY 31540 -  class mob_ghoul : public CreatureScript  {  public: @@ -727,11 +741,6 @@ public:  }; -#define SPELL_RAISE_DEAD_1 31617 -#define SPELL_RAISE_DEAD_2 31624 -#define SPELL_RAISE_DEAD_3 31625 -#define SPELL_SHADOW_BOLT 31627 -  class mob_necromancer : public CreatureScript  {  public: @@ -859,10 +868,6 @@ public:  }; -#define SPELL_BANSHEE_CURSE 31651 -#define SPELL_BANSHEE_WAIL 38183 -#define SPELL_ANTI_MAGIC_SHELL 31662 -  class mob_banshee : public CreatureScript  {  public: @@ -966,8 +971,6 @@ public:  }; -#define SPELL_WEB 28991 -  class mob_crypt_fiend : public CreatureScript  {  public: @@ -1058,8 +1061,6 @@ public:  }; -#define SPELL_MANA_BURN 31729 -  class mob_fel_stalker : public CreatureScript  {  public: @@ -1150,8 +1151,6 @@ public:  }; -#define SPELL_FROST_BREATH 31688 -  class mob_frost_wyrm : public CreatureScript  {  public: @@ -1264,8 +1263,6 @@ public:  }; -#define SPELL_GARGOYLE_STRIKE 31664 -  class mob_gargoyle : public CreatureScript  {  public: @@ -1402,8 +1399,6 @@ public:  }; -#define SPELL_EXPLODING_SHOT 7896 -  class alliance_rifleman : public CreatureScript  {  public: diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp index ad8ebdb370a..69bb8285404 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp @@ -23,15 +23,16 @@ SDComment: Instance Data Scripts and functions to acquire mobs and set encounter  SDCategory: Caverns of Time, Mount Hyjal  EndScriptData */ -#include "ScriptPCH.h" -#include "hyjal.h" +#include "ScriptMgr.h" +#include "InstanceScript.h" +#include "ScriptedCreature.h"  #include "hyjal_trash.h" -enum eEnums +enum Misc  {      MAX_ENCOUNTER       = 5, -    GO_ANCIENT_GEM      = 185557 +    GO_ANCIENT_GEM      = 185557,  };  /* Battle of Mount Hyjal encounters:  0 - Rage Winterchill event diff --git a/src/server/scripts/Kalimdor/Maraudon/boss_celebras_the_cursed.cpp b/src/server/scripts/Kalimdor/Maraudon/boss_celebras_the_cursed.cpp index d7043965271..b23d15cd1b5 100644 --- a/src/server/scripts/Kalimdor/Maraudon/boss_celebras_the_cursed.cpp +++ b/src/server/scripts/Kalimdor/Maraudon/boss_celebras_the_cursed.cpp @@ -23,7 +23,8 @@ SDComment:  SDCategory: Maraudon  EndScriptData */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h"  enum Spells  { @@ -46,15 +47,15 @@ public:      {          celebras_the_cursedAI(Creature* creature) : ScriptedAI(creature) {} -        uint32 Wrath_Timer; -        uint32 EntanglingRoots_Timer; -        uint32 CorruptForces_Timer; +        uint32 WrathTimer; +        uint32 EntanglingRootsTimer; +        uint32 CorruptForcesTimer;          void Reset()          { -            Wrath_Timer = 8000; -            EntanglingRoots_Timer = 2000; -            CorruptForces_Timer = 30000; +            WrathTimer = 8000; +            EntanglingRootsTimer = 2000; +            CorruptForcesTimer = 30000;          }          void EnterCombat(Unit* /*who*/) { } @@ -70,32 +71,30 @@ public:                  return;              //Wrath -            if (Wrath_Timer <= diff) +            if (WrathTimer <= diff)              { -                Unit* target = NULL; -                target = SelectTarget(SELECT_TARGET_RANDOM, 0); -                if (target) +                if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))                      DoCast(target, SPELL_WRATH); -                Wrath_Timer = 8000; +                WrathTimer = 8000;              } -            else Wrath_Timer -= diff; +            else WrathTimer -= diff;              //EntanglingRoots -            if (EntanglingRoots_Timer <= diff) +            if (EntanglingRootsTimer <= diff)              { -                DoCast(me->getVictim(), SPELL_ENTANGLINGROOTS); -                EntanglingRoots_Timer = 20000; +                DoCastVictim(SPELL_ENTANGLINGROOTS); +                EntanglingRootsTimer = 20000;              } -            else EntanglingRoots_Timer -= diff; +            else EntanglingRootsTimer -= diff;              //CorruptForces -            if (CorruptForces_Timer <= diff) +            if (CorruptForcesTimer <= diff)              {                  me->InterruptNonMeleeSpells(false);                  DoCast(me, SPELL_CORRUPT_FORCES); -                CorruptForces_Timer = 20000; +                CorruptForcesTimer = 20000;              } -            else CorruptForces_Timer -= diff; +            else CorruptForcesTimer -= diff;              DoMeleeAttackIfReady();          } diff --git a/src/server/scripts/Kalimdor/Maraudon/boss_landslide.cpp b/src/server/scripts/Kalimdor/Maraudon/boss_landslide.cpp index ea419793ae8..b4128ea80ee 100644 --- a/src/server/scripts/Kalimdor/Maraudon/boss_landslide.cpp +++ b/src/server/scripts/Kalimdor/Maraudon/boss_landslide.cpp @@ -23,7 +23,8 @@ SDComment:  SDCategory: Maraudon  EndScriptData */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h"  enum Spells  { @@ -46,15 +47,15 @@ public:      {          boss_landslideAI(Creature* creature) : ScriptedAI(creature) {} -        uint32 KnockAway_Timer; -        uint32 Trample_Timer; -        uint32 Landslide_Timer; +        uint32 KnockAwayTimer; +        uint32 TrampleTimer; +        uint32 LandslideTimer;          void Reset()          { -            KnockAway_Timer = 8000; -            Trample_Timer = 2000; -            Landslide_Timer = 0; +            KnockAwayTimer = 8000; +            TrampleTimer = 2000; +            LandslideTimer = 0;          }          void EnterCombat(Unit* /*who*/) @@ -66,32 +67,32 @@ public:              if (!UpdateVictim())                  return; -            //KnockAway_Timer -            if (KnockAway_Timer <= diff) +            //KnockAwayTimer +            if (KnockAwayTimer <= diff)              { -                DoCast(me->getVictim(), SPELL_KNOCKAWAY); -                KnockAway_Timer = 15000; +                DoCastVictim(SPELL_KNOCKAWAY); +                KnockAwayTimer = 15000;              } -            else KnockAway_Timer -= diff; +            else KnockAwayTimer -= diff; -            //Trample_Timer -            if (Trample_Timer <= diff) +            //TrampleTimer +            if (TrampleTimer <= diff)              {                  DoCast(me, SPELL_TRAMPLE); -                Trample_Timer = 8000; +                TrampleTimer = 8000;              } -            else Trample_Timer -= diff; +            else TrampleTimer -= diff;              //Landslide              if (HealthBelowPct(50))              { -                if (Landslide_Timer <= diff) +                if (LandslideTimer <= diff)                  {                      me->InterruptNonMeleeSpells(false);                      DoCast(me, SPELL_LANDSLIDE); -                    Landslide_Timer = 60000; +                    LandslideTimer = 60000;                  } -                else Landslide_Timer -= diff; +                else LandslideTimer -= diff;              }              DoMeleeAttackIfReady(); diff --git a/src/server/scripts/Kalimdor/Maraudon/boss_noxxion.cpp b/src/server/scripts/Kalimdor/Maraudon/boss_noxxion.cpp index 18ce7be0f0a..ece3ff83776 100644 --- a/src/server/scripts/Kalimdor/Maraudon/boss_noxxion.cpp +++ b/src/server/scripts/Kalimdor/Maraudon/boss_noxxion.cpp @@ -23,7 +23,9 @@ SDComment:  SDCategory: Maraudon  EndScriptData */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +  enum Spells  {      SPELL_TOXICVOLLEY           = 21687, @@ -44,24 +46,22 @@ public:      {          boss_noxxionAI(Creature* creature) : ScriptedAI(creature) {} -        uint32 ToxicVolley_Timer; -        uint32 Uppercut_Timer; -        uint32 Adds_Timer; -        uint32 Invisible_Timer; +        uint32 ToxicVolleyTimer; +        uint32 UppercutTimer; +        uint32 AddsTimer; +        uint32 InvisibleTimer;          bool Invisible;          void Reset()          { -            ToxicVolley_Timer = 7000; -            Uppercut_Timer = 16000; -            Adds_Timer = 19000; -            Invisible_Timer = 15000;                            //Too much too low? +            ToxicVolleyTimer = 7000; +            UppercutTimer = 16000; +            AddsTimer = 19000; +            InvisibleTimer = 15000;                            //Too much too low?              Invisible = false;          } -        void EnterCombat(Unit* /*who*/) -        { -        } +        void EnterCombat(Unit* /*who*/) {}          void SummonAdds(Unit* victim)          { @@ -71,7 +71,7 @@ public:          void UpdateAI(const uint32 diff)          { -            if (Invisible && Invisible_Timer <= diff) +            if (Invisible && InvisibleTimer <= diff)              {                  //Become visible again                  me->setFaction(14); @@ -83,7 +83,7 @@ public:              }              else if (Invisible)              { -                Invisible_Timer -= diff; +                InvisibleTimer -= diff;                  //Do nothing while invisible                  return;              } @@ -92,24 +92,24 @@ public:              if (!UpdateVictim())                  return; -            //ToxicVolley_Timer -            if (ToxicVolley_Timer <= diff) +            //ToxicVolleyTimer +            if (ToxicVolleyTimer <= diff)              { -                DoCast(me->getVictim(), SPELL_TOXICVOLLEY); -                ToxicVolley_Timer = 9000; +                DoCastVictim(SPELL_TOXICVOLLEY); +                ToxicVolleyTimer = 9000;              } -            else ToxicVolley_Timer -= diff; +            else ToxicVolleyTimer -= diff; -            //Uppercut_Timer -            if (Uppercut_Timer <= diff) +            //UppercutTimer +            if (UppercutTimer <= diff)              { -                DoCast(me->getVictim(), SPELL_UPPERCUT); -                Uppercut_Timer = 12000; +                DoCastVictim(SPELL_UPPERCUT); +                UppercutTimer = 12000;              } -            else Uppercut_Timer -= diff; +            else UppercutTimer -= diff; -            //Adds_Timer -            if (!Invisible && Adds_Timer <= diff) +            //AddsTimer +            if (!Invisible && AddsTimer <= diff)              {                  //Interrupt any spell casting                  //me->m_canMove = true; @@ -124,11 +124,11 @@ public:                  SummonAdds(me->getVictim());                  SummonAdds(me->getVictim());                  Invisible = true; -                Invisible_Timer = 15000; +                InvisibleTimer = 15000; -                Adds_Timer = 40000; +                AddsTimer = 40000;              } -            else Adds_Timer -= diff; +            else AddsTimer -= diff;              DoMeleeAttackIfReady();          } diff --git a/src/server/scripts/Kalimdor/Maraudon/boss_princess_theradras.cpp b/src/server/scripts/Kalimdor/Maraudon/boss_princess_theradras.cpp index 039d30071d2..1f887d7ce64 100644 --- a/src/server/scripts/Kalimdor/Maraudon/boss_princess_theradras.cpp +++ b/src/server/scripts/Kalimdor/Maraudon/boss_princess_theradras.cpp @@ -23,7 +23,8 @@ SDComment:  SDCategory: Maraudon  EndScriptData */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h"  enum Spells  { @@ -47,17 +48,17 @@ public:      {          boss_ptheradrasAI(Creature* creature) : ScriptedAI(creature) {} -        uint32 Dustfield_Timer; -        uint32 Boulder_Timer; -        uint32 Thrash_Timer; -        uint32 RepulsiveGaze_Timer; +        uint32 DustfieldTimer; +        uint32 BoulderTimer; +        uint32 ThrashTimer; +        uint32 RepulsiveGazeTimer;          void Reset()          { -            Dustfield_Timer = 8000; -            Boulder_Timer = 2000; -            Thrash_Timer = 5000; -            RepulsiveGaze_Timer = 23000; +            DustfieldTimer = 8000; +            BoulderTimer = 2000; +            ThrashTimer = 5000; +            RepulsiveGazeTimer = 23000;          }          void EnterCombat(Unit* /*who*/) {} @@ -72,40 +73,38 @@ public:              if (!UpdateVictim())                  return; -            //Dustfield_Timer -            if (Dustfield_Timer <= diff) +            //DustfieldTimer +            if (DustfieldTimer <= diff)              {                  DoCast(me, SPELL_DUSTFIELD); -                Dustfield_Timer = 14000; +                DustfieldTimer = 14000;              } -            else Dustfield_Timer -= diff; +            else DustfieldTimer -= diff; -            //Boulder_Timer -            if (Boulder_Timer <= diff) +            //BoulderTimer +            if (BoulderTimer <= diff)              { -                Unit* target = NULL; -                target = SelectTarget(SELECT_TARGET_RANDOM, 0); -                if (target) +                if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))                      DoCast(target, SPELL_BOULDER); -                Boulder_Timer = 10000; +                BoulderTimer = 10000;              } -            else Boulder_Timer -= diff; +            else BoulderTimer -= diff; -            //RepulsiveGaze_Timer -            if (RepulsiveGaze_Timer <= diff) +            //RepulsiveGazeTimer +            if (RepulsiveGazeTimer <= diff)              { -                DoCast(me->getVictim(), SPELL_REPULSIVEGAZE); -                RepulsiveGaze_Timer = 20000; +                DoCastVictim(SPELL_REPULSIVEGAZE); +                RepulsiveGazeTimer = 20000;              } -            else RepulsiveGaze_Timer -= diff; +            else RepulsiveGazeTimer -= diff; -            //Thrash_Timer -            if (Thrash_Timer <= diff) +            //ThrashTimer +            if (ThrashTimer <= diff)              {                  DoCast(me, SPELL_THRASH); -                Thrash_Timer = 18000; +                ThrashTimer = 18000;              } -            else Thrash_Timer -= diff; +            else ThrashTimer -= diff;              DoMeleeAttackIfReady();          } diff --git a/src/server/scripts/Kalimdor/OnyxiasLair/boss_onyxia.cpp b/src/server/scripts/Kalimdor/OnyxiasLair/boss_onyxia.cpp index 6e6e089ba02..1fdf941d75c 100644 --- a/src/server/scripts/Kalimdor/OnyxiasLair/boss_onyxia.cpp +++ b/src/server/scripts/Kalimdor/OnyxiasLair/boss_onyxia.cpp @@ -25,10 +25,15 @@ SDComment: <Known bugs>  SDCategory: Onyxia's Lair  EndScriptData */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "Cell.h" +#include "CellImpl.h" +#include "GridNotifiers.h" +#include "GridNotifiersImpl.h"  #include "onyxias_lair.h" -enum eYells +enum Yells  {      SAY_AGGRO                   = -1249000,      SAY_KILL                    = -1249001, @@ -37,7 +42,7 @@ enum eYells      EMOTE_BREATH                = -1249004,  }; -enum eSpells +enum Spells  {      // Phase 1 spells      SPELL_WING_BUFFET           = 18500, @@ -67,15 +72,15 @@ enum eSpells      SPELL_BELLOWING_ROAR         = 18431,  }; -struct sOnyxMove +struct OnyxMove  { -    uint32 uiLocId; -    uint32 uiLocIdEnd; -    uint32 uiSpellId; +    uint8 LocId; +    uint8 LocIdEnd; +    uint32 SpellId;      float fX, fY, fZ;  }; -static sOnyxMove aMoveData[]= +static OnyxMove MoveData[8]=  {      {0, 1, SPELL_BREATH_WEST_TO_EAST,   -33.5561f, -182.682f, -56.9457f}, //west      {1, 0, SPELL_BREATH_EAST_TO_WEST,   -31.4963f, -250.123f, -55.1278f}, //east @@ -87,11 +92,11 @@ static sOnyxMove aMoveData[]=      {7, 6, SPELL_BREATH_NORTH_TO_SOUTH,  22.8763f, -217.152f, -55.0548f}, //north  }; -const Position MiddleRoomLocation = {-23.6155f, -215.357f, -55.7344f, 0.0f}; +Position const MiddleRoomLocation = {-23.6155f, -215.357f, -55.7344f, 0.0f}; -const Position Phase2Location = {-80.924f, -214.299f, -82.942f, 0.0f}; +Position const Phase2Location = {-80.924f, -214.299f, -82.942f, 0.0f}; -static Position aSpawnLocations[3]= +Position const SpawnLocations[3]=  {      //Whelps      {-30.127f, -254.463f, -89.440f, 0.0f}, @@ -121,58 +126,58 @@ public:          InstanceScript* instance;          SummonList Summons; -        uint32 m_uiPhase; +        uint32 Phase; -        uint32 m_uiFlameBreathTimer; -        uint32 m_uiCleaveTimer; -        uint32 m_uiTailSweepTimer; -        uint32 m_uiWingBuffetTimer; +        uint32 FlameBreathTimer; +        uint32 CleaveTimer; +        uint32 TailSweepTimer; +        uint32 WingBuffetTimer; -        uint32 m_uiMovePoint; -        uint32 m_uiMovementTimer; -        sOnyxMove* m_pPointData; +        uint8 MovePoint; +        uint32 MovementTimer; +        OnyxMove* PointData; -        uint32 m_uiFireballTimer; -        uint32 m_uiWhelpTimer; -        uint32 m_uiLairGuardTimer; -        uint32 m_uiDeepBreathTimer; +        uint32 FireballTimer; +        uint32 WhelpTimer; +        uint32 LairGuardTimer; +        uint32 DeepBreathTimer; -        uint32 m_uiBellowingRoarTimer; +        uint32 BellowingRoarTimer; -        uint8 m_uiSummonWhelpCount; -        bool m_bIsMoving; +        uint8 SummonWhelpCount; +        bool IsMoving;          void Reset()          {              if (!IsCombatMovementAllowed())                  SetCombatMovement(true); -            m_uiPhase = PHASE_START; +            Phase = PHASE_START; -            m_uiFlameBreathTimer = urand(10000, 20000); -            m_uiTailSweepTimer = urand(15000, 20000); -            m_uiCleaveTimer = urand(2000, 5000); -            m_uiWingBuffetTimer = urand(10000, 20000); +            FlameBreathTimer = urand(10000, 20000); +            TailSweepTimer = urand(15000, 20000); +            CleaveTimer = urand(2000, 5000); +            WingBuffetTimer = urand(10000, 20000); -            m_uiMovePoint = urand(0, 5); -            m_uiMovementTimer = 14000; -            m_pPointData = GetMoveData(); +            MovePoint = urand(0, 5); +            MovementTimer = 14000; +            PointData = GetMoveData(); -            m_uiFireballTimer = 15000; -            m_uiWhelpTimer = 60000; -            m_uiLairGuardTimer = 60000; -            m_uiDeepBreathTimer = 85000; +            FireballTimer = 15000; +            WhelpTimer = 60000; +            LairGuardTimer = 60000; +            DeepBreathTimer = 85000; -            m_uiBellowingRoarTimer = 30000; +            BellowingRoarTimer = 30000;              Summons.DespawnAll(); -            m_uiSummonWhelpCount = 0; -            m_bIsMoving = false; +            SummonWhelpCount = 0; +            IsMoving = false;              if (instance)              {                  instance->SetData(DATA_ONYXIA, NOT_STARTED); -                instance->SetData(DATA_ONYXIA_PHASE, m_uiPhase); +                instance->SetData(DATA_ONYXIA_PHASE, Phase);                  instance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT,  ACHIEV_TIMED_START_EVENT);              }          } @@ -206,7 +211,7 @@ public:              switch (summoned->GetEntry())              {                  case NPC_WHELP: -                    ++m_uiSummonWhelpCount; +                    ++SummonWhelpCount;                      break;                  case NPC_LAIRGUARD:                      summoned->setActive(true); @@ -225,17 +230,17 @@ public:              DoScriptText(SAY_KILL, me);          } -        void SpellHit(Unit* /*pCaster*/, const SpellInfo* pSpell) +        void SpellHit(Unit* /*pCaster*/, const SpellInfo* Spell)          { -            if (pSpell->Id == SPELL_BREATH_EAST_TO_WEST || -                pSpell->Id == SPELL_BREATH_WEST_TO_EAST || -                pSpell->Id == SPELL_BREATH_SE_TO_NW || -                pSpell->Id == SPELL_BREATH_NW_TO_SE || -                pSpell->Id == SPELL_BREATH_SW_TO_NE || -                pSpell->Id == SPELL_BREATH_NE_TO_SW) +            if (Spell->Id == SPELL_BREATH_EAST_TO_WEST || +                Spell->Id == SPELL_BREATH_WEST_TO_EAST || +                Spell->Id == SPELL_BREATH_SE_TO_NW || +                Spell->Id == SPELL_BREATH_NW_TO_SE || +                Spell->Id == SPELL_BREATH_SW_TO_NE || +                Spell->Id == SPELL_BREATH_NE_TO_SW)              { -                m_pPointData = GetMoveData(); -                m_uiMovePoint = m_pPointData->uiLocIdEnd; +                PointData = GetMoveData(); +                MovePoint = PointData->LocIdEnd;                  me->SetSpeed(MOVE_FLIGHT, 1.5f);                  me->GetMotionMaster()->MovePoint(8, MiddleRoomLocation); @@ -249,16 +254,16 @@ public:                  switch (id)                  {                      case 8: -                        m_pPointData = GetMoveData(); -                        if (m_pPointData) +                        PointData = GetMoveData(); +                        if (PointData)                          {                              me->SetSpeed(MOVE_FLIGHT, 1.0f); -                            me->GetMotionMaster()->MovePoint(m_pPointData->uiLocId, m_pPointData->fX, m_pPointData->fY, m_pPointData->fZ); +                            me->GetMotionMaster()->MovePoint(PointData->LocId, PointData->fX, PointData->fY, PointData->fZ);                          }                          break;                      case 9:                          me->GetMotionMaster()->MoveChase(me->getVictim()); -                        m_uiBellowingRoarTimer = 1000; +                        BellowingRoarTimer = 1000;                          break;                      case 10:                          me->SetCanFly(true); @@ -266,39 +271,39 @@ public:                          me->SetSpeed(MOVE_FLIGHT, 1.0f);                          DoScriptText(SAY_PHASE_2_TRANS, me);                          if (instance) -                            instance->SetData(DATA_ONYXIA_PHASE, m_uiPhase); -                        m_uiWhelpTimer = 5000; -                        m_uiLairGuardTimer = 15000; +                            instance->SetData(DATA_ONYXIA_PHASE, Phase); +                        WhelpTimer = 5000; +                        LairGuardTimer = 15000;                          break;                      case 11: -                        if (m_pPointData) -                            me->GetMotionMaster()->MovePoint(m_pPointData->uiLocId, m_pPointData->fX, m_pPointData->fY, m_pPointData->fZ); +                        if (PointData) +                            me->GetMotionMaster()->MovePoint(PointData->LocId, PointData->fX, PointData->fY, PointData->fZ);                          me->GetMotionMaster()->Clear(false);                          me->GetMotionMaster()->MoveIdle();                          break;                      default: -                        m_bIsMoving = false; +                        IsMoving = false;                          break;                  }              }          } -        void SpellHitTarget(Unit* target, const SpellInfo* pSpell) +        void SpellHitTarget(Unit* target, const SpellInfo* Spell)          {              //Workaround - Couldn't find a way to group this spells (All Eruption) -            if (((pSpell->Id >= 17086 && pSpell->Id <= 17095) || -                (pSpell->Id == 17097) || -                (pSpell->Id >= 18351 && pSpell->Id <= 18361) || -                (pSpell->Id >= 18564 && pSpell->Id <= 18576) || -                (pSpell->Id >= 18578 && pSpell->Id <= 18607) || -                (pSpell->Id == 18609) || -                (pSpell->Id >= 18611 && pSpell->Id <= 18628) || -                (pSpell->Id >= 21132 && pSpell->Id <= 21133) || -                (pSpell->Id >= 21135 && pSpell->Id <= 21139) || -                (pSpell->Id >= 22191 && pSpell->Id <= 22202) || -                (pSpell->Id >= 22267 && pSpell->Id <= 22268)) && +            if (((Spell->Id >= 17086 && Spell->Id <= 17095) || +                (Spell->Id == 17097) || +                (Spell->Id >= 18351 && Spell->Id <= 18361) || +                (Spell->Id >= 18564 && Spell->Id <= 18576) || +                (Spell->Id >= 18578 && Spell->Id <= 18607) || +                (Spell->Id == 18609) || +                (Spell->Id >= 18611 && Spell->Id <= 18628) || +                (Spell->Id >= 21132 && Spell->Id <= 21133) || +                (Spell->Id >= 21135 && Spell->Id <= 21139) || +                (Spell->Id >= 22191 && Spell->Id <= 22202) || +                (Spell->Id >= 22267 && Spell->Id <= 22268)) &&                  (target->GetTypeId() == TYPEID_PLAYER))              {                  if (instance) @@ -308,14 +313,14 @@ public:              }          } -        sOnyxMove* GetMoveData() +        OnyxMove* GetMoveData()          { -            uint32 uiMaxCount = sizeof(aMoveData)/sizeof(sOnyxMove); +            uint8 MaxCount = sizeof(MoveData)/sizeof(OnyxMove); -            for (uint32 i = 0; i < uiMaxCount; ++i) +            for (uint8 i = 0; i < MaxCount; ++i)              { -                if (aMoveData[i].uiLocId == m_uiMovePoint) -                    return &aMoveData[i]; +                if (MoveData[i].LocId == MovePoint) +                    return &MoveData[i];              }              return NULL; @@ -323,84 +328,84 @@ public:          void SetNextRandomPoint()          { -            uint32 uiMaxCount = sizeof(aMoveData)/sizeof(sOnyxMove); +            uint8 MaxCount = sizeof(MoveData)/sizeof(OnyxMove); -            uint32 iTemp = rand()%(uiMaxCount-1); +            uint8 iTemp = urand(0, MaxCount-1); -            if (iTemp >= m_uiMovePoint) +            if (iTemp >= MovePoint)                  ++iTemp; -            m_uiMovePoint = iTemp; +            MovePoint = iTemp;          } -        void UpdateAI(const uint32 uiDiff) +        void UpdateAI(const uint32 Diff)          {              if (!UpdateVictim())                  return;              //Common to PHASE_START && PHASE_END -            if (m_uiPhase == PHASE_START || m_uiPhase == PHASE_END) +            if (Phase == PHASE_START || Phase == PHASE_END)              {                  //Specific to PHASE_START || PHASE_END -                if (m_uiPhase == PHASE_START) +                if (Phase == PHASE_START)                  {                      if (HealthBelowPct(60))                      {                          SetCombatMovement(false); -                        m_uiPhase = PHASE_BREATH; +                        Phase = PHASE_BREATH;                          me->GetMotionMaster()->MovePoint(10, Phase2Location);                          return;                      }                  }                  else                  { -                    if (m_uiBellowingRoarTimer <= uiDiff) +                    if (BellowingRoarTimer <= Diff)                      {                          DoCastVictim(SPELL_BELLOWING_ROAR);                          // Eruption -                        GameObject* pFloor = NULL; +                        GameObject* Floor = NULL;                          Trinity::GameObjectInRangeCheck check(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 15); -                        Trinity::GameObjectLastSearcher<Trinity::GameObjectInRangeCheck> searcher(me, pFloor, check); +                        Trinity::GameObjectLastSearcher<Trinity::GameObjectInRangeCheck> searcher(me, Floor, check);                          me->VisitNearbyGridObject(30, searcher); -                        if (instance && pFloor) -                            instance->SetData64(DATA_FLOOR_ERUPTION_GUID, pFloor->GetGUID()); -                        m_uiBellowingRoarTimer = 30000; +                        if (instance && Floor) +                            instance->SetData64(DATA_FLOOR_ERUPTION_GUID, Floor->GetGUID()); +                        BellowingRoarTimer = 30000;                      }                      else -                        m_uiBellowingRoarTimer -= uiDiff; +                        BellowingRoarTimer -= Diff;                  } -                if (m_uiFlameBreathTimer <= uiDiff) +                if (FlameBreathTimer <= Diff)                  {                      DoCastVictim(SPELL_FLAME_BREATH); -                    m_uiFlameBreathTimer = urand(10000, 20000); +                    FlameBreathTimer = urand(10000, 20000);                  }                  else -                    m_uiFlameBreathTimer -= uiDiff; +                    FlameBreathTimer -= Diff; -                if (m_uiTailSweepTimer <= uiDiff) +                if (TailSweepTimer <= Diff)                  {                      DoCastAOE(SPELL_TAIL_SWEEP); -                    m_uiTailSweepTimer = urand(15000, 20000); +                    TailSweepTimer = urand(15000, 20000);                  }                  else -                    m_uiTailSweepTimer -= uiDiff; +                    TailSweepTimer -= Diff; -                if (m_uiCleaveTimer <= uiDiff) +                if (CleaveTimer <= Diff)                  {                      DoCastVictim(SPELL_CLEAVE); -                    m_uiCleaveTimer = urand(2000, 5000); +                    CleaveTimer = urand(2000, 5000);                  }                  else -                    m_uiCleaveTimer -= uiDiff; +                    CleaveTimer -= Diff; -                if (m_uiWingBuffetTimer <= uiDiff) +                if (WingBuffetTimer <= Diff)                  {                      DoCastVictim(SPELL_WING_BUFFET); -                    m_uiWingBuffetTimer = urand(15000, 30000); +                    WingBuffetTimer = urand(15000, 30000);                  }                  else -                    m_uiWingBuffetTimer -= uiDiff; +                    WingBuffetTimer -= Diff;                  DoMeleeAttackIfReady();              } @@ -408,86 +413,86 @@ public:              {                  if (HealthBelowPct(40))                  { -                    m_uiPhase = PHASE_END; +                    Phase = PHASE_END;                      if (instance) -                        instance->SetData(DATA_ONYXIA_PHASE, m_uiPhase); +                        instance->SetData(DATA_ONYXIA_PHASE, Phase);                      DoScriptText(SAY_PHASE_3_TRANS, me);                      SetCombatMovement(true);                      me->SetCanFly(false); -                    m_bIsMoving = false; +                    IsMoving = false;                      me->GetMotionMaster()->MovePoint(9, me->GetHomePosition());                      return;                  } -                if (m_uiDeepBreathTimer <= uiDiff) +                if (DeepBreathTimer <= Diff)                  { -                    if (!m_bIsMoving) +                    if (!IsMoving)                      {                          if (me->IsNonMeleeSpellCasted(false))                              me->InterruptNonMeleeSpells(false);                          DoScriptText(EMOTE_BREATH, me); -                        DoCast(me, m_pPointData->uiSpellId); -                        m_uiDeepBreathTimer = 70000; +                        DoCast(me, PointData->SpellId); +                        DeepBreathTimer = 70000;                      }                  }                  else -                    m_uiDeepBreathTimer -= uiDiff; +                    DeepBreathTimer -= Diff; -                if (m_uiMovementTimer <= uiDiff) +                if (MovementTimer <= Diff)                  { -                    if (!m_bIsMoving) +                    if (!IsMoving)                      {                          SetNextRandomPoint(); -                        m_pPointData = GetMoveData(); +                        PointData = GetMoveData(); -                        if (!m_pPointData) +                        if (!PointData)                              return; -                        me->GetMotionMaster()->MovePoint(m_pPointData->uiLocId, m_pPointData->fX, m_pPointData->fY, m_pPointData->fZ); -                        m_bIsMoving = true; -                        m_uiMovementTimer = 25000; +                        me->GetMotionMaster()->MovePoint(PointData->LocId, PointData->fX, PointData->fY, PointData->fZ); +                        IsMoving = true; +                        MovementTimer = 25000;                      }                  }                  else -                    m_uiMovementTimer -= uiDiff; +                    MovementTimer -= Diff; -                if (m_uiFireballTimer <= uiDiff) +                if (FireballTimer <= Diff)                  {                      if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != POINT_MOTION_TYPE)                      {                          if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))                              DoCast(target, SPELL_FIREBALL); -                        m_uiFireballTimer = 8000; +                        FireballTimer = 8000;                      }                  }                  else -                    m_uiFireballTimer -= uiDiff; +                    FireballTimer -= Diff; -                if (m_uiLairGuardTimer <= uiDiff) +                if (LairGuardTimer <= Diff)                  { -                    me->SummonCreature(NPC_LAIRGUARD, aSpawnLocations[2].GetPositionX(), aSpawnLocations[2].GetPositionY(), aSpawnLocations[2].GetPositionZ(), 0.0f, TEMPSUMMON_CORPSE_DESPAWN); -                    m_uiLairGuardTimer = 30000; +                    me->SummonCreature(NPC_LAIRGUARD, SpawnLocations[2], TEMPSUMMON_CORPSE_DESPAWN); +                    LairGuardTimer = 30000;                  }                  else -                    m_uiLairGuardTimer -= uiDiff; +                    LairGuardTimer -= Diff; -                if (m_uiWhelpTimer <= uiDiff) +                if (WhelpTimer <= Diff)                  { -                    me->SummonCreature(NPC_WHELP, aSpawnLocations[0].GetPositionX(), aSpawnLocations[0].GetPositionY(), aSpawnLocations[0].GetPositionZ(), 0.0f, TEMPSUMMON_CORPSE_DESPAWN); -                    me->SummonCreature(NPC_WHELP, aSpawnLocations[1].GetPositionX(), aSpawnLocations[1].GetPositionY(), aSpawnLocations[1].GetPositionZ(), 0.0f, TEMPSUMMON_CORPSE_DESPAWN); -                    if (m_uiSummonWhelpCount >= RAID_MODE(20, 40)) +                    me->SummonCreature(NPC_WHELP, SpawnLocations[0], TEMPSUMMON_CORPSE_DESPAWN); +                    me->SummonCreature(NPC_WHELP, SpawnLocations[1], TEMPSUMMON_CORPSE_DESPAWN); +                    if (SummonWhelpCount >= RAID_MODE(20, 40))                      { -                        m_uiSummonWhelpCount = 0; -                        m_uiWhelpTimer = 90000; +                        SummonWhelpCount = 0; +                        WhelpTimer = 90000;                      }                      else -                        m_uiWhelpTimer = 500; +                        WhelpTimer = 500;                  }                  else -                    m_uiWhelpTimer -= uiDiff; +                    WhelpTimer -= Diff;              }          }      }; diff --git a/src/server/scripts/Kalimdor/OnyxiasLair/instance_onyxias_lair.cpp b/src/server/scripts/Kalimdor/OnyxiasLair/instance_onyxias_lair.cpp index 1c599ce7c6f..0689a8872bb 100644 --- a/src/server/scripts/Kalimdor/OnyxiasLair/instance_onyxias_lair.cpp +++ b/src/server/scripts/Kalimdor/OnyxiasLair/instance_onyxias_lair.cpp @@ -22,7 +22,12 @@ SDComment:  SDCategory: Onyxia's Lair  EndScriptData */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "InstanceScript.h" +#include "Cell.h" +#include "CellImpl.h" +#include "GridNotifiers.h" +#include "GridNotifiersImpl.h"  #include "onyxias_lair.h"  class instance_onyxias_lair : public InstanceMapScript @@ -44,27 +49,27 @@ public:          std::map<uint64, uint32> FloorEruptionGUID[2];          std::queue<uint64> FloorEruptionGUIDQueue; -        uint64 m_uiOnyxiasGUID; -        uint32 m_uiOnyxiaLiftoffTimer; -        uint32 m_uiManyWhelpsCounter; -        uint32 m_uiEruptTimer; +        uint64 OnyxiasGUID; +        uint32 OnyxiaLiftoffTimer; +        uint32 ManyWhelpsCounter; +        uint32 EruptTimer; -        uint8  m_auiEncounter[MAX_ENCOUNTER]; +        uint8  Encounter[MAX_ENCOUNTER]; -        bool   m_bAchievManyWhelpsHandleIt; -        bool   m_bAchievSheDeepBreathMore; +        bool   AchievManyWhelpsHandleIt; +        bool   AchievSheDeepBreathMore;          void Initialize()          { -            memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); +            memset(&Encounter, 0, sizeof(Encounter)); -            m_uiOnyxiasGUID = 0; -            m_uiOnyxiaLiftoffTimer = 0; -            m_uiManyWhelpsCounter = 0; -            m_bAchievManyWhelpsHandleIt = false; -            m_bAchievSheDeepBreathMore = true; +            OnyxiasGUID = 0; +            OnyxiaLiftoffTimer = 0; +            ManyWhelpsCounter = 0; +            AchievManyWhelpsHandleIt = false; +            AchievSheDeepBreathMore = true; -            m_uiEruptTimer = 0; +            EruptTimer = 0;          }          void OnCreatureCreate(Creature* creature) @@ -72,7 +77,7 @@ public:              switch (creature->GetEntry())              {                  case NPC_ONYXIA: -                    m_uiOnyxiasGUID = creature->GetGUID(); +                    OnyxiasGUID = creature->GetGUID();                      break;              }          } @@ -93,7 +98,7 @@ public:                      if (Creature* temp = go->SummonCreature(NPC_WHELP, goPos, TEMPSUMMON_CORPSE_DESPAWN))                      {                          temp->SetInCombatWithZone(); -                        ++m_uiManyWhelpsCounter; +                        ++ManyWhelpsCounter;                      }                      break;              } @@ -139,88 +144,88 @@ public:              FloorEruptionGUID[1].erase(floorEruptedGUID);          } -        void SetData(uint32 uiType, uint32 uiData) +        void SetData(uint32 Type, uint32 Data)          { -            switch (uiType) +            switch (Type)              {                  case DATA_ONYXIA: -                    m_auiEncounter[0] = uiData; -                    if (uiData == IN_PROGRESS) +                    Encounter[0] = Data; +                    if (Data == IN_PROGRESS)                          SetData(DATA_SHE_DEEP_BREATH_MORE, IN_PROGRESS);                      break;                  case DATA_ONYXIA_PHASE: -                    if (uiData == PHASE_BREATH) //Used to mark the liftoff phase +                    if (Data == PHASE_BREATH) //Used to mark the liftoff phase                      { -                        m_bAchievManyWhelpsHandleIt = false; -                        m_uiManyWhelpsCounter = 0; -                        m_uiOnyxiaLiftoffTimer = 10*IN_MILLISECONDS; +                        AchievManyWhelpsHandleIt = false; +                        ManyWhelpsCounter = 0; +                        OnyxiaLiftoffTimer = 10*IN_MILLISECONDS;                      }                      break;                  case DATA_SHE_DEEP_BREATH_MORE: -                    if (uiData == IN_PROGRESS) +                    if (Data == IN_PROGRESS)                      { -                        m_bAchievSheDeepBreathMore = true; +                        AchievSheDeepBreathMore = true;                      } -                    else if (uiData == FAIL) +                    else if (Data == FAIL)                      { -                        m_bAchievSheDeepBreathMore = false; +                        AchievSheDeepBreathMore = false;                      }                      break;              } -            if (uiType < MAX_ENCOUNTER && uiData == DONE) +            if (Type < MAX_ENCOUNTER && Data == DONE)                  SaveToDB();          } -        void SetData64(uint32 uiType, uint64 uiData) +        void SetData64(uint32 Type, uint64 Data)          { -            switch (uiType) +            switch (Type)              {                  case DATA_FLOOR_ERUPTION_GUID:                      FloorEruptionGUID[1] = FloorEruptionGUID[0]; -                    FloorEruptionGUIDQueue.push(uiData); -                    m_uiEruptTimer = 2500; +                    FloorEruptionGUIDQueue.push(Data); +                    EruptTimer = 2500;                      break;              }          } -        uint32 GetData(uint32 uiType) +        uint32 GetData(uint32 Type)          { -            switch (uiType) +            switch (Type)              {                  case DATA_ONYXIA: -                    return m_auiEncounter[0]; +                    return Encounter[0];              }              return 0;          } -        uint64 GetData64(uint32 uiData) +        uint64 GetData64(uint32 Data)          { -            switch (uiData) +            switch (Data)              {                  case DATA_ONYXIA_GUID: -                    return m_uiOnyxiasGUID; +                    return OnyxiasGUID;              }              return 0;          } -        void Update(uint32 uiDiff) +        void Update(uint32 Diff)          {              if (GetData(DATA_ONYXIA) == IN_PROGRESS)              { -                if (m_uiOnyxiaLiftoffTimer && m_uiOnyxiaLiftoffTimer <= uiDiff) +                if (OnyxiaLiftoffTimer && OnyxiaLiftoffTimer <= Diff)                  { -                    m_uiOnyxiaLiftoffTimer = 0; -                    if (m_uiManyWhelpsCounter >= 50) -                        m_bAchievManyWhelpsHandleIt = true; -                } else m_uiOnyxiaLiftoffTimer -= uiDiff; +                    OnyxiaLiftoffTimer = 0; +                    if (ManyWhelpsCounter >= 50) +                        AchievManyWhelpsHandleIt = true; +                } else OnyxiaLiftoffTimer -= Diff;              }              if (!FloorEruptionGUIDQueue.empty())              { -                if (m_uiEruptTimer <= uiDiff) +                if (EruptTimer <= Diff)                  {                      uint32 treeHeight = 0;                      do @@ -229,10 +234,10 @@ public:                          FloorEruption(FloorEruptionGUIDQueue.front());                          FloorEruptionGUIDQueue.pop();                      } while (!FloorEruptionGUIDQueue.empty() && (*FloorEruptionGUID[1].find(FloorEruptionGUIDQueue.front())).second == treeHeight); -                    m_uiEruptTimer = 1000; +                    EruptTimer = 1000;                  }                  else -                    m_uiEruptTimer -= uiDiff; +                    EruptTimer -= Diff;              }          } @@ -242,10 +247,10 @@ public:              {                  case ACHIEV_CRITERIA_MANY_WHELPS_10_PLAYER:  // Criteria for achievement 4403: Many Whelps! Handle It! (10 player) Hatch 50 eggs in 10s                  case ACHIEV_CRITERIA_MANY_WHELPS_25_PLAYER:  // Criteria for achievement 4406: Many Whelps! Handle It! (25 player) Hatch 50 eggs in 10s -                    return m_bAchievManyWhelpsHandleIt; +                    return AchievManyWhelpsHandleIt;                  case ACHIEV_CRITERIA_DEEP_BREATH_10_PLAYER:  // Criteria for achievement 4404: She Deep Breaths More (10 player) Everybody evade Deep Breath                  case ACHIEV_CRITERIA_DEEP_BREATH_25_PLAYER:  // Criteria for achievement 4407: She Deep Breaths More (25 player) Everybody evade Deep Breath -                    return m_bAchievSheDeepBreathMore; +                    return AchievSheDeepBreathMore;              }              return false;          } diff --git a/src/server/scripts/Kalimdor/OnyxiasLair/onyxias_lair.h b/src/server/scripts/Kalimdor/OnyxiasLair/onyxias_lair.h index eaf6cac43af..26fd9284ea2 100644 --- a/src/server/scripts/Kalimdor/OnyxiasLair/onyxias_lair.h +++ b/src/server/scripts/Kalimdor/OnyxiasLair/onyxias_lair.h @@ -18,13 +18,13 @@  #ifndef DEF_ONYXIAS_LAIR_H  #define DEF_ONYXIAS_LAIR_H -enum eData64 +enum Data64  {      DATA_ONYXIA_GUID,      DATA_FLOOR_ERUPTION_GUID  }; -enum eInstanceData +enum InstanceData  {      DATA_ONYXIA,      MAX_ENCOUNTER, @@ -34,7 +34,7 @@ enum eInstanceData      DATA_MANY_WHELPS_COUNT  }; -enum eCreatures +enum Creatures  {      NPC_WHELP                   = 11262,      NPC_LAIRGUARD               = 36561, @@ -42,20 +42,20 @@ enum eCreatures      NPC_ONYXIA                  = 10184  }; -enum eOnyxiaPhases +enum OnyxiaPhases  {      PHASE_START                 = 1,      PHASE_BREATH                = 2,      PHASE_END                   = 3  }; -enum eGameObjects +enum GameObjects  {      GO_WHELP_SPAWNER            = 176510,      GO_WHELP_EGG                = 176511  }; -enum eAchievementData +enum AchievementData  {      ACHIEV_CRITERIA_MANY_WHELPS_10_PLAYER                   = 12565, // Criteria for achievement 4403: Many Whelps! Handle It! (10 player) Hatch 50 eggs in 10s      ACHIEV_CRITERIA_MANY_WHELPS_25_PLAYER                   = 12568, // Criteria for achievement 4406: Many Whelps! Handle It! (25 player) Hatch 50 eggs in 10s diff --git a/src/server/scripts/Kalimdor/ashenvale.cpp b/src/server/scripts/Kalimdor/ashenvale.cpp index e28665c038e..9e8cdaa8b92 100644 --- a/src/server/scripts/Kalimdor/ashenvale.cpp +++ b/src/server/scripts/Kalimdor/ashenvale.cpp @@ -169,15 +169,15 @@ class npc_torek : public CreatureScript  # npc_ruul_snowhoof  ####*/ -enum RuulSnowhoof	 -{	 +enum RuulSnowhoof +{      NPC_THISTLEFUR_URSA         = 3921,      NPC_THISTLEFUR_TOTEMIC      = 3922,      NPC_THISTLEFUR_PATHFINDER   = 3926,      QUEST_FREEDOM_TO_RUUL       = 6482, -    GO_CAGE                     = 178147	 +    GO_CAGE                     = 178147  };  Position const RuulSnowhoofSummonsCoord[6] = diff --git a/src/server/scripts/Kalimdor/dustwallow_marsh.cpp b/src/server/scripts/Kalimdor/dustwallow_marsh.cpp index 45e1c1808c1..5800a6a58a0 100644 --- a/src/server/scripts/Kalimdor/dustwallow_marsh.cpp +++ b/src/server/scripts/Kalimdor/dustwallow_marsh.cpp @@ -25,7 +25,6 @@ EndScriptData */  /* ContentData  mobs_risen_husk_spirit -npc_deserter_agitator  npc_lady_jaina_proudmoore  npc_nat_pagle  npc_private_hendel @@ -132,93 +131,7 @@ class mobs_risen_husk_spirit : public CreatureScript  };  /*###### -## npc_deserter_agitator -######*/ - -enum Deserter -{ -    QUEST_TRAITORS_AMONG_US                      = 11126, -    NPC_THERAMORE_DESERTER                       = 23602, -}; - -const Position DeserterDisappearPos = {-3609.03f, -4332.91f, 9.39354f, 3.73862f}; - -#define GOSSIP_ITEM_DESERTER "Your propaganda wont`t work on me. Spout your treasonous filth elsewhere traitor!" - -class npc_deserter_agitator : public CreatureScript -{ -public: -    npc_deserter_agitator() : CreatureScript("npc_deserter_agitator") { } - -    bool OnGossipHello(Player* player, Creature* creature) -    { -        if (player->GetQuestStatus(QUEST_TRAITORS_AMONG_US) == QUEST_STATUS_INCOMPLETE) -            player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_DESERTER, GOSSIP_SENDER_MAIN, GOSSIP_SENDER_INFO); - -        player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - -        return true; -    } - -    bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) -    { -        player->PlayerTalkClass->ClearMenus(); - -        if (action == GOSSIP_SENDER_INFO) -        { -            player->CLOSE_GOSSIP_MENU(); -            switch (urand(0, 1)) -            { -                case 0: -                    creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); -                    creature->setFaction(14); -                    creature->AI()->AttackStart(player); -                    break; -                case 1: -                    player->KilledMonsterCredit(NPC_THERAMORE_DESERTER, 0); -                    creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); -                    creature->SetSpeed(MOVE_RUN, creature->GetSpeedRate(MOVE_RUN), true); -                    creature->setFaction(35); -                    creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NON_ATTACKABLE); -                    creature->SetReactState(REACT_PASSIVE); -                    creature->GetMotionMaster()->MovePoint(1, DeserterDisappearPos); -                    break; -            } -        } - -        return true; -    } - -    CreatureAI* GetAI(Creature* creature) const -    { -        return new npc_deserter_agitatorAI(creature); -    } - -    struct npc_deserter_agitatorAI : public ScriptedAI -    { -        npc_deserter_agitatorAI(Creature* creature) : ScriptedAI(creature) { } - -        void Reset() -        { -            me->RestoreFaction(); -            me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NON_ATTACKABLE); -            me->SetReactState(REACT_AGGRESSIVE); -            me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); -        } - -        void MovementInform(uint32 Type, uint32 Id) -        { -            if (Type != POINT_MOTION_TYPE) -                return; - -            if (Id == 1) -                me->DisappearAndDie(); -        } -    }; -}; - -/*###### -## npc_deserter_agitator +## npc_theramor_guard  ######*/  enum TheramoreGuard @@ -794,16 +707,16 @@ class spell_energize_aoe : public SpellScriptLoader                  return true;              } -            void FilterTargets(std::list<Unit*>& unitList) +            void FilterTargets(std::list<WorldObject*>& targets)              { -                for (std::list<Unit*>::iterator itr = unitList.begin(); itr != unitList.end();) +                for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end();)                  {                      if ((*itr)->GetTypeId() == TYPEID_PLAYER && (*itr)->ToPlayer()->GetQuestStatus(GetSpellInfo()->Effects[EFFECT_1].CalcValue()) == QUEST_STATUS_INCOMPLETE)                          ++itr;                      else -                        unitList.erase(itr++); +                        targets.erase(itr++);                  } -                unitList.push_back(GetCaster()); +                targets.push_back(GetCaster());              }              void HandleScript(SpellEffIndex effIndex) @@ -815,8 +728,8 @@ class spell_energize_aoe : public SpellScriptLoader              void Register()              {                  OnEffectHitTarget += SpellEffectFn(spell_energize_aoe_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); -                OnUnitTargetSelect += SpellUnitTargetFn(spell_energize_aoe_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); -                OnUnitTargetSelect += SpellUnitTargetFn(spell_energize_aoe_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENTRY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_energize_aoe_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_energize_aoe_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENTRY);              }          }; @@ -865,7 +778,6 @@ void AddSC_dustwallow_marsh()      new npc_zelfrax();      new npc_stinky();      new npc_theramore_guard(); -    new npc_deserter_agitator();      new spell_ooze_zap();      new spell_ooze_zap_channel_end();      new spell_energize_aoe(); diff --git a/src/server/scripts/Kalimdor/winterspring.cpp b/src/server/scripts/Kalimdor/winterspring.cpp index a02156ee110..2c4da0fdf7c 100644 --- a/src/server/scripts/Kalimdor/winterspring.cpp +++ b/src/server/scripts/Kalimdor/winterspring.cpp @@ -18,15 +18,13 @@  /* ScriptData  SDName: Winterspring -SD%Complete: 90 -SDComment: Quest support: 5126 (Loraxs' tale missing proper gossip items text). Vendor Rivern Frostwind. Obtain Cache of Mau'ari +SD%Complete: Almost Completely Emptied +SDComment: Vendor Rivern Frostwind.  SDCategory: Winterspring  EndScriptData */  /* ContentData -npc_lorax  npc_rivern_frostwind -npc_witch_doctor_mauari  EndContentData */  #include "ScriptMgr.h" @@ -34,71 +32,6 @@ EndContentData */  #include "ScriptedGossip.h"  /*###### -## npc_lorax -######*/ - -#define GOSSIP_HL "Talk to me" - -#define GOSSIP_SL1 "What do you do here?" -#define GOSSIP_SL2 "I can help you" -#define GOSSIP_SL3 "What deal?" -#define GOSSIP_SL4 "Then what happened?" -#define GOSSIP_SL5 "He is not safe, i'll make sure of that." - -class npc_lorax : public CreatureScript -{ -public: -    npc_lorax() : CreatureScript("npc_lorax") { } - -    bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) -    { -        player->PlayerTalkClass->ClearMenus(); -        switch (action) -        { -            case GOSSIP_ACTION_INFO_DEF: -                player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SL1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); -                player->SEND_GOSSIP_MENU(3759, creature->GetGUID()); -                break; -            case GOSSIP_ACTION_INFO_DEF+1: -                player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SL2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); -                player->SEND_GOSSIP_MENU(3760, creature->GetGUID()); -                break; -            case GOSSIP_ACTION_INFO_DEF+2: -                player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SL3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); -                player->SEND_GOSSIP_MENU(3761, creature->GetGUID()); -                break; -            case GOSSIP_ACTION_INFO_DEF+3: -                player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SL4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4); -                player->SEND_GOSSIP_MENU(3762, creature->GetGUID()); -                break; -            case GOSSIP_ACTION_INFO_DEF+4: -                player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SL5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5); -                player->SEND_GOSSIP_MENU(3763, creature->GetGUID()); -                break; -            case GOSSIP_ACTION_INFO_DEF+5: -                player->CLOSE_GOSSIP_MENU(); -                player->AreaExploredOrEventHappens(5126); -                break; -        } -        return true; -    } - -    bool OnGossipHello(Player* player, Creature* creature) -    { -        if (creature->isQuestGiver()) -            player->PrepareQuestMenu(creature->GetGUID()); - -        if (player->GetQuestStatus(5126) == QUEST_STATUS_INCOMPLETE) -            player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HL, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - -        player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - -        return true; -    } - -}; - -/*######  ## npc_rivern_frostwind  ######*/ @@ -131,49 +64,7 @@ public:  }; -/*###### -## npc_witch_doctor_mauari -######*/ - -#define GOSSIP_HWDM "I'd like you to make me a new Cache of Mau'ari please." - -class npc_witch_doctor_mauari : public CreatureScript -{ -public: -    npc_witch_doctor_mauari() : CreatureScript("npc_witch_doctor_mauari") { } - -    bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) -    { -        player->PlayerTalkClass->ClearMenus(); -        if (action == GOSSIP_ACTION_INFO_DEF+1) -        { -            player->CLOSE_GOSSIP_MENU(); -            creature->CastSpell(player, 16351, false); -        } - -        return true; -    } - -    bool OnGossipHello(Player* player, Creature* creature) -    { -        if (creature->isQuestGiver()) -            player->PrepareQuestMenu(creature->GetGUID()); - -        if (player->GetQuestRewardStatus(975)) -        { -            player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HWDM, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); -            player->SEND_GOSSIP_MENU(3377, creature->GetGUID()); -        } -        else -            player->SEND_GOSSIP_MENU(3375, creature->GetGUID()); - -        return true; -    } -}; -  void AddSC_winterspring()  { -    new npc_lorax();      new npc_rivern_frostwind(); -    new npc_witch_doctor_mauari();  } diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_saviana_ragefire.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_saviana_ragefire.cpp index 4e5e01cc745..5a7809dbe70 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_saviana_ragefire.cpp +++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_saviana_ragefire.cpp @@ -186,7 +186,7 @@ class ConflagrationTargetSelector      public:          ConflagrationTargetSelector() { } -        bool operator()(Unit* unit) +        bool operator()(WorldObject* unit) const          {              return unit->GetTypeId() != TYPEID_PLAYER;          } @@ -201,12 +201,12 @@ class spell_saviana_conflagration_init : public SpellScriptLoader          {              PrepareSpellScript(spell_saviana_conflagration_init_SpellScript); -            void FilterTargets(std::list<Unit*>& unitList) +            void FilterTargets(std::list<WorldObject*>& targets)              { -                unitList.remove_if (ConflagrationTargetSelector()); +                targets.remove_if(ConflagrationTargetSelector());                  uint8 maxSize = uint8(GetCaster()->GetMap()->GetSpawnMode() & 1 ? 6 : 3); -                if (unitList.size() > maxSize) -                    Trinity::Containers::RandomResizeList(unitList, maxSize); +                if (targets.size() > maxSize) +                    Trinity::Containers::RandomResizeList(targets, maxSize);              }              void HandleDummy(SpellEffIndex effIndex) @@ -218,7 +218,7 @@ class spell_saviana_conflagration_init : public SpellScriptLoader              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_saviana_conflagration_init_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_saviana_conflagration_init_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);                  OnEffectHitTarget += SpellEffectFn(spell_saviana_conflagration_init_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);              }          }; diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_argent_challenge.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_argent_challenge.cpp index 305266ee628..e96408acc09 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_argent_challenge.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_argent_challenge.cpp @@ -60,9 +60,9 @@ class OrientationCheck : public std::unary_function<Unit*, bool>  {      public:          explicit OrientationCheck(Unit* _caster) : caster(_caster) { } -        bool operator() (Unit* unit) +        bool operator()(WorldObject* object)          { -            return !unit->isInFront(caster, 2.5f) || !unit->IsWithinDist(caster, 40.0f); +            return !object->isInFront(caster, 2.5f) || !object->IsWithinDist(caster, 40.0f);          }      private: @@ -76,15 +76,16 @@ class spell_eadric_radiance : public SpellScriptLoader          class spell_eadric_radiance_SpellScript : public SpellScript          {              PrepareSpellScript(spell_eadric_radiance_SpellScript); -            void FilterTargets(std::list<Unit*>& unitList) + +            void FilterTargets(std::list<WorldObject*>& unitList)              { -                unitList.remove_if (OrientationCheck(GetCaster())); +                unitList.remove_if(OrientationCheck(GetCaster()));              }              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_eadric_radiance_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); -                OnUnitTargetSelect += SpellUnitTargetFn(spell_eadric_radiance_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_eadric_radiance_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_eadric_radiance_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);              }          }; diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp index 79bbb470edf..3b0aeb958cb 100755 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp @@ -27,7 +27,10 @@ EndScriptData */  // All - untested  // Pets aren't being summoned by their masters -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "SpellScript.h" +#include "SpellAuraEffects.h"  #include "trial_of_the_crusader.h"  enum eYell @@ -945,18 +948,18 @@ public:  }; -enum eWarlockSpells +enum WarlockSpells  { -    SPELL_HELLFIRE              = 65816, -    SPELL_CORRUPTION            = 65810, -    SPELL_CURSE_OF_AGONY        = 65814, -    SPELL_CURSE_OF_EXHAUSTION   = 65815, -    SPELL_FEAR                  = 65809, //8s -    SPELL_SEARING_PAIN          = 65819, -    SPELL_SHADOW_BOLT           = 65821, -    SPELL_UNSTABLE_AFFLICTION   = 65812, -    SPELL_SUMMON_FELHUNTER      = 67514, -    H_SPELL_UNSTABLE_AFFLICTION  = 68155, //15s +    SPELL_HELLFIRE                   = 65816, +    SPELL_CORRUPTION                 = 65810, +    SPELL_CURSE_OF_AGONY             = 65814, +    SPELL_CURSE_OF_EXHAUSTION        = 65815, +    SPELL_FEAR                       = 65809, // 8s +    SPELL_SEARING_PAIN               = 65819, +    SPELL_SHADOW_BOLT                = 65821, +    SPELL_UNSTABLE_AFFLICTION        = 65812, // 15s +    SPELL_UNSTABLE_AFFLICTION_DISPEL = 65813, +    SPELL_SUMMON_FELHUNTER           = 67514,  };  class mob_toc_warlock : public CreatureScript @@ -2030,6 +2033,40 @@ public:      };  }; +class spell_faction_champion_warl_unstable_affliction : public SpellScriptLoader +{ +    public: +        spell_faction_champion_warl_unstable_affliction() : SpellScriptLoader("spell_faction_champion_warl_unstable_affliction") { } + +        class spell_faction_champion_warl_unstable_affliction_AuraScript : public AuraScript +        { +            PrepareAuraScript(spell_faction_champion_warl_unstable_affliction_AuraScript); + +            bool Validate(SpellInfo const* /*spell*/) +            { +                if (!sSpellMgr->GetSpellInfo(SPELL_UNSTABLE_AFFLICTION_DISPEL)) +                    return false; +                return true; +            } + +            void HandleDispel(DispelInfo* dispelInfo) +            { +                if (Unit* caster = GetCaster()) +                    caster->CastSpell(dispelInfo->GetDispeller(), SPELL_UNSTABLE_AFFLICTION_DISPEL, true, NULL, GetEffect(EFFECT_0)); +            } + +            void Register() +            { +                AfterDispel += AuraDispelFn(spell_faction_champion_warl_unstable_affliction_AuraScript::HandleDispel); +            } +        }; + +        AuraScript* GetAuraScript() const +        { +            return new spell_faction_champion_warl_unstable_affliction_AuraScript(); +        } +}; +  void AddSC_boss_faction_champions()  {      new boss_toc_champion_controller(); @@ -2049,4 +2086,5 @@ void AddSC_boss_faction_champions()      new mob_toc_retro_paladin();      new mob_toc_pet_warlock();      new mob_toc_pet_hunter(); +    new spell_faction_champion_warl_unstable_affliction();  } diff --git a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp index 4a28ebe6495..5b6bf14c29e 100644 --- a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp @@ -359,7 +359,7 @@ class DistanceCheck      public:          explicit DistanceCheck(Unit* _caster) : caster(_caster) { } -        bool operator() (Unit* unit) +        bool operator() (WorldObject* unit) const          {              if (caster->GetExactDist2d(unit) <= 10.0f)                  return true; @@ -378,25 +378,25 @@ class spell_bronjahm_soulstorm_targeting : public SpellScriptLoader          {              PrepareSpellScript(spell_bronjahm_soulstorm_targeting_SpellScript); -            void FilterTargetsInitial(std::list<Unit*>& unitList) +            void FilterTargetsInitial(std::list<WorldObject*>& targets)              { -                unitList.remove_if (DistanceCheck(GetCaster())); -                sharedUnitList = unitList; +                targets.remove_if(DistanceCheck(GetCaster())); +                sharedTargets = targets;              }              // use the same target for first and second effect -            void FilterTargetsSubsequent(std::list<Unit*>& unitList) +            void FilterTargetsSubsequent(std::list<WorldObject*>& targets)              { -                unitList = sharedUnitList; +                targets = sharedTargets;              }              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_bronjahm_soulstorm_targeting_SpellScript::FilterTargetsInitial, EFFECT_1, TARGET_UNIT_DEST_AREA_ENEMY); -                OnUnitTargetSelect += SpellUnitTargetFn(spell_bronjahm_soulstorm_targeting_SpellScript::FilterTargetsSubsequent, EFFECT_2, TARGET_UNIT_DEST_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_bronjahm_soulstorm_targeting_SpellScript::FilterTargetsInitial, EFFECT_1, TARGET_UNIT_DEST_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_bronjahm_soulstorm_targeting_SpellScript::FilterTargetsSubsequent, EFFECT_2, TARGET_UNIT_DEST_AREA_ENEMY);              } -            std::list<Unit*> sharedUnitList; +            std::list<WorldObject*> sharedTargets;          };          SpellScript* GetSpellScript() const diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp index ee966256e2b..0d092ec86b2 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp @@ -631,9 +631,9 @@ class BloodboltHitCheck      public:          explicit BloodboltHitCheck(LanaThelAI* ai) : _ai(ai) {} -        bool operator()(Unit* unit) +        bool operator()(WorldObject* object) const          { -            return _ai->WasBloodbolted(unit->GetGUID()); +            return _ai->WasBloodbolted(object->GetGUID());          }      private: @@ -661,13 +661,13 @@ class spell_blood_queen_bloodbolt : public SpellScriptLoader                  return GetCaster()->GetEntry() == NPC_BLOOD_QUEEN_LANA_THEL;              } -            void FilterTargets(std::list<Unit*>& targets) +            void FilterTargets(std::list<WorldObject*>& targets)              {                  uint32 targetCount = (targets.size() + 2) / 3; -                targets.remove_if (BloodboltHitCheck(static_cast<LanaThelAI*>(GetCaster()->GetAI()))); +                targets.remove_if(BloodboltHitCheck(static_cast<LanaThelAI*>(GetCaster()->GetAI())));                  Trinity::Containers::RandomResizeList(targets, targetCount);                  // mark targets now, effect hook has missile travel time delay (might cast next in that time) -                for (std::list<Unit*>::const_iterator itr = targets.begin(); itr != targets.end(); ++itr) +                for (std::list<WorldObject*>::const_iterator itr = targets.begin(); itr != targets.end(); ++itr)                      GetCaster()->GetAI()->SetGUID((*itr)->GetGUID(), GUID_BLOODBOLT);              } @@ -679,7 +679,7 @@ class spell_blood_queen_bloodbolt : public SpellScriptLoader              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_blood_queen_bloodbolt_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_blood_queen_bloodbolt_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);                  OnEffectHitTarget += SpellEffectFn(spell_blood_queen_bloodbolt_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);              }          }; @@ -699,19 +699,19 @@ class spell_blood_queen_pact_of_the_darkfallen : public SpellScriptLoader          {              PrepareSpellScript(spell_blood_queen_pact_of_the_darkfallen_SpellScript); -            void FilterTargets(std::list<Unit*>& unitList) +            void FilterTargets(std::list<WorldObject*>& targets)              { -                unitList.remove_if (Trinity::UnitAuraCheck(false, SPELL_PACT_OF_THE_DARKFALLEN)); +                targets.remove_if(Trinity::UnitAuraCheck(false, SPELL_PACT_OF_THE_DARKFALLEN));                  bool remove = true; -                std::list<Unit*>::const_iterator itrEnd = unitList.end(), itr, itr2; +                std::list<WorldObject*>::const_iterator itrEnd = targets.end(), itr, itr2;                  // we can do this, unitList is MAX 4 in size -                for (itr = unitList.begin(); itr != itrEnd && remove; ++itr) +                for (itr = targets.begin(); itr != itrEnd && remove; ++itr)                  {                      if (!GetCaster()->IsWithinDist(*itr, 5.0f, false))                          remove = false; -                    for (itr2 = unitList.begin(); itr2 != itrEnd && remove; ++itr2) +                    for (itr2 = targets.begin(); itr2 != itrEnd && remove; ++itr2)                          if (itr != itr2 && !(*itr2)->IsWithinDist(*itr, 5.0f, false))                              remove = false;                  } @@ -721,14 +721,14 @@ class spell_blood_queen_pact_of_the_darkfallen : public SpellScriptLoader                      if (InstanceScript* instance = GetCaster()->GetInstanceScript())                      {                          instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_PACT_OF_THE_DARKFALLEN); -                        unitList.clear(); +                        targets.clear();                      }                  }              }              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_blood_queen_pact_of_the_darkfallen_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_blood_queen_pact_of_the_darkfallen_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);              }          }; @@ -785,15 +785,15 @@ class spell_blood_queen_pact_of_the_darkfallen_dmg_target : public SpellScriptLo          {              PrepareSpellScript(spell_blood_queen_pact_of_the_darkfallen_dmg_SpellScript); -            void FilterTargets(std::list<Unit*>& unitList) +            void FilterTargets(std::list<WorldObject*>& unitList)              { -                unitList.remove_if (Trinity::UnitAuraCheck(true, SPELL_PACT_OF_THE_DARKFALLEN)); +                unitList.remove_if(Trinity::UnitAuraCheck(true, SPELL_PACT_OF_THE_DARKFALLEN));                  unitList.push_back(GetCaster());              }              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_blood_queen_pact_of_the_darkfallen_dmg_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_blood_queen_pact_of_the_darkfallen_dmg_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);              }          }; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp index 494be259baa..9017509781f 100755 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp @@ -1198,34 +1198,34 @@ class spell_deathbringer_blood_nova_targeting : public SpellScriptLoader                  return true;              } -            void FilterTargetsInitial(std::list<Unit*>& unitList) +            void FilterTargetsInitial(std::list<WorldObject*>& targets)              { -                if (unitList.empty()) +                if (targets.empty())                      return;                  // select one random target, with preference of ranged targets                  uint32 targetsAtRange = 0;                  uint32 const minTargets = uint32(GetCaster()->GetMap()->GetSpawnMode() & 1 ? 10 : 4); -                unitList.sort(Trinity::ObjectDistanceOrderPred(GetCaster(), false)); +                targets.sort(Trinity::ObjectDistanceOrderPred(GetCaster(), false));                  // get target count at range -                for (std::list<Unit*>::iterator itr = unitList.begin(); itr != unitList.end(); ++itr, ++targetsAtRange) +                for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr, ++targetsAtRange)                      if ((*itr)->GetDistance(GetCaster()) < 12.0f)                          break;                  // set the upper cap                  if (targetsAtRange < minTargets) -                    targetsAtRange = std::min<uint32>(unitList.size() - 1, minTargets); +                    targetsAtRange = std::min<uint32>(targets.size() - 1, minTargets); -                std::list<Unit*>::const_iterator itr = unitList.begin(); +                std::list<WorldObject*>::const_iterator itr = targets.begin();                  std::advance(itr, urand(0, targetsAtRange));                  target = *itr; -                unitList.clear(); -                unitList.push_back(target); +                targets.clear(); +                targets.push_back(target);              }              // use the same target for first and second effect -            void FilterTargetsSubsequent(std::list<Unit*>& unitList) +            void FilterTargetsSubsequent(std::list<WorldObject*>& unitList)              {                  if (!target)                      return; @@ -1241,12 +1241,13 @@ class spell_deathbringer_blood_nova_targeting : public SpellScriptLoader              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_deathbringer_blood_nova_targeting_SpellScript::FilterTargetsInitial, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); -                OnUnitTargetSelect += SpellUnitTargetFn(spell_deathbringer_blood_nova_targeting_SpellScript::FilterTargetsSubsequent, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_deathbringer_blood_nova_targeting_SpellScript::FilterTargetsInitial, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_deathbringer_blood_nova_targeting_SpellScript::FilterTargetsSubsequent, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY); +                OnEffectHitTarget += SpellEffectFn(spell_deathbringer_blood_nova_targeting_SpellScript::HandleForceCast, EFFECT_0, SPELL_EFFECT_FORCE_CAST);                  OnEffectHitTarget += SpellEffectFn(spell_deathbringer_blood_nova_targeting_SpellScript::HandleForceCast, EFFECT_0, SPELL_EFFECT_FORCE_CAST);              } -            Unit* target; +            WorldObject* target;          };          SpellScript* GetSpellScript() const @@ -1269,20 +1270,20 @@ class spell_deathbringer_boiling_blood : public SpellScriptLoader                  return GetCaster()->GetTypeId() == TYPEID_UNIT;              } -            void FilterTargets(std::list<Unit*>& unitList) +            void FilterTargets(std::list<WorldObject*>& targets)              { -                unitList.remove(GetCaster()->getVictim()); -                if (unitList.empty()) +                targets.remove(GetCaster()->getVictim()); +                if (targets.empty())                      return; -                Unit* target = Trinity::Containers::SelectRandomContainerElement(unitList); -                unitList.clear(); -                unitList.push_back(target); +                WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets); +                targets.clear(); +                targets.push_back(target);              }              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_deathbringer_boiling_blood_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_deathbringer_boiling_blood_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);              }          }; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp index 1672d8b2d87..0c5cb0aba52 100755 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp @@ -416,7 +416,7 @@ class spell_marrowgar_coldflame : public SpellScriptLoader          {              PrepareSpellScript(spell_marrowgar_coldflame_SpellScript); -            void SelectTarget(std::list<Unit*>& targets) +            void SelectTarget(std::list<WorldObject*>& targets)              {                  targets.clear();                  // select any unit but not the tank (by owners threatlist) @@ -438,7 +438,7 @@ class spell_marrowgar_coldflame : public SpellScriptLoader              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_marrowgar_coldflame_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_marrowgar_coldflame_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);                  OnEffectHitTarget += SpellEffectFn(spell_marrowgar_coldflame_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);              }          }; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp index a0fca522f61..a9ba0baa86f 100755 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp @@ -296,6 +296,7 @@ class boss_professor_putricide : public CreatureScript                          summon->ModifyAuraState(AURA_STATE_UNKNOWN22, true);                          summon->CastSpell(summon, SPELL_GASEOUS_BLOAT_PROC, true);                          summon->CastCustomSpell(SPELL_GASEOUS_BLOAT, SPELLVALUE_AURA_STACK, 10, summon, false); +                        summon->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true);                          summon->SetReactState(REACT_PASSIVE);                          return;                      case NPC_VOLATILE_OOZE: @@ -303,6 +304,7 @@ class boss_professor_putricide : public CreatureScript                          summon->ModifyAuraState(AURA_STATE_UNKNOWN19, true);                          summon->CastSpell(summon, SPELL_OOZE_ERUPTION_SEARCH_PERIODIC, true);                          summon->CastSpell(summon, SPELL_VOLATILE_OOZE_ADHESIVE, false); +                        summon->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true);                          summon->SetReactState(REACT_PASSIVE);                          return;                      case NPC_CHOKING_GAS_BOMB: @@ -868,26 +870,26 @@ class spell_putricide_ooze_channel : public SpellScriptLoader                  return GetCaster()->GetTypeId() == TYPEID_UNIT;              } -            void SelectTarget(std::list<Unit*>& targetList) +            void SelectTarget(std::list<WorldObject*>& targets)              { -                if (targetList.empty()) +                if (targets.empty())                  {                      FinishCast(SPELL_FAILED_NO_VALID_TARGETS);                      GetCaster()->ToCreature()->DespawnOrUnsummon(1);    // despawn next update                      return;                  } -                Unit* target = Trinity::Containers::SelectRandomContainerElement(targetList); -                targetList.clear(); -                targetList.push_back(target); +                WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets); +                targets.clear(); +                targets.push_back(target);                  _target = target;              } -            void SetTarget(std::list<Unit*>& targetList) +            void SetTarget(std::list<WorldObject*>& targets)              { -                targetList.clear(); +                targets.clear();                  if (_target) -                    targetList.push_back(_target); +                    targets.push_back(_target);              }              void StartAttack() @@ -910,14 +912,14 @@ class spell_putricide_ooze_channel : public SpellScriptLoader              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_putricide_ooze_channel_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); -                OnUnitTargetSelect += SpellUnitTargetFn(spell_putricide_ooze_channel_SpellScript::SetTarget, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY); -                OnUnitTargetSelect += SpellUnitTargetFn(spell_putricide_ooze_channel_SpellScript::SetTarget, EFFECT_2, TARGET_UNIT_SRC_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_putricide_ooze_channel_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_putricide_ooze_channel_SpellScript::SetTarget, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_putricide_ooze_channel_SpellScript::SetTarget, EFFECT_2, TARGET_UNIT_SRC_AREA_ENEMY);                  AfterHit += SpellHitFn(spell_putricide_ooze_channel_SpellScript::StartAttack);                  OnCast += SpellCastFn(spell_putricide_ooze_channel_SpellScript::CheckTarget);              } -            Unit* _target; +            WorldObject* _target;          };          SpellScript* GetSpellScript() const @@ -931,7 +933,7 @@ class ExactDistanceCheck      public:          ExactDistanceCheck(Unit* source, float dist) : _source(source), _dist(dist) {} -        bool operator()(Unit* unit) +        bool operator()(WorldObject* unit) const          {              return _source->GetExactDist2d(unit) > _dist;          } @@ -950,15 +952,15 @@ class spell_putricide_slime_puddle : public SpellScriptLoader          {              PrepareSpellScript(spell_putricide_slime_puddle_SpellScript); -            void ScaleRange(std::list<Unit*>& targets) +            void ScaleRange(std::list<WorldObject*>& targets)              {                  targets.remove_if(ExactDistanceCheck(GetCaster(), 2.5f * GetCaster()->GetFloatValue(OBJECT_FIELD_SCALE_X)));              }              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_putricide_slime_puddle_SpellScript::ScaleRange, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY); -                OnUnitTargetSelect += SpellUnitTargetFn(spell_putricide_slime_puddle_SpellScript::ScaleRange, EFFECT_1, TARGET_UNIT_DEST_AREA_ENTRY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_putricide_slime_puddle_SpellScript::ScaleRange, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_putricide_slime_puddle_SpellScript::ScaleRange, EFFECT_1, TARGET_UNIT_DEST_AREA_ENTRY);              }          }; @@ -1176,13 +1178,13 @@ class spell_putricide_eat_ooze : public SpellScriptLoader          {              PrepareSpellScript(spell_putricide_eat_ooze_SpellScript); -            void SelectTarget(std::list<Unit*>& targets) +            void SelectTarget(std::list<WorldObject*>& targets)              {                  if (targets.empty())                      return;                  targets.sort(Trinity::ObjectDistanceOrderPred(GetCaster())); -                Unit* target = targets.front(); +                WorldObject* target = targets.front();                  targets.clear();                  targets.push_back(target);              } @@ -1209,7 +1211,7 @@ class spell_putricide_eat_ooze : public SpellScriptLoader              void Register()              {                  OnEffectHitTarget += SpellEffectFn(spell_putricide_eat_ooze_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); -                OnUnitTargetSelect += SpellUnitTargetFn(spell_putricide_eat_ooze_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_DEST_AREA_ENTRY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_putricide_eat_ooze_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_DEST_AREA_ENTRY);              }          }; @@ -1456,15 +1458,15 @@ class spell_putricide_mutated_transformation_dmg : public SpellScriptLoader          {              PrepareSpellScript(spell_putricide_mutated_transformation_dmg_SpellScript); -            void FilterTargetsInitial(std::list<Unit*>& unitList) +            void FilterTargetsInitial(std::list<WorldObject*>& targets)              {                  if (Unit* owner = ObjectAccessor::GetUnit(*GetCaster(), GetCaster()->GetCreatorGUID())) -                    unitList.remove(owner); +                    targets.remove(owner);              }              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_putricide_mutated_transformation_dmg_SpellScript::FilterTargetsInitial, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_putricide_mutated_transformation_dmg_SpellScript::FilterTargetsInitial, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);              }          }; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp index a4ab13f6ada..5a0560293da 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp @@ -449,23 +449,23 @@ class spell_rotface_ooze_flood : public SpellScriptLoader                  GetHitUnit()->CastSpell(triggers.back(), uint32(GetEffectValue()), false, NULL, NULL, GetOriginalCaster() ? GetOriginalCaster()->GetGUID() : 0);              } -            void FilterTargets(std::list<Unit*>& targetList) +            void FilterTargets(std::list<WorldObject*>& targets)              {                  // get 2 targets except 2 nearest -                targetList.sort(Trinity::ObjectDistanceOrderPred(GetCaster())); +                targets.sort(Trinity::ObjectDistanceOrderPred(GetCaster()));                  // .resize() runs pop_back(); -                if (targetList.size() > 4) -                    targetList.resize(4); +                if (targets.size() > 4) +                    targets.resize(4); -                while (targetList.size() > 2) -                    targetList.pop_front(); +                while (targets.size() > 2) +                    targets.pop_front();              }              void Register()              {                  OnEffectHitTarget += SpellEffectFn(spell_rotface_ooze_flood_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); -                OnUnitTargetSelect += SpellUnitTargetFn(spell_rotface_ooze_flood_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_rotface_ooze_flood_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);              }          }; @@ -490,21 +490,21 @@ class spell_rotface_mutated_infection : public SpellScriptLoader                  return true;              } -            void FilterTargets(std::list<Unit*>& targets) +            void FilterTargets(std::list<WorldObject*>& targets)              {                  // remove targets with this aura already                  // tank is not on this list -                targets.remove_if (Trinity::UnitAuraCheck(true, GetSpellInfo()->Id)); +                targets.remove_if(Trinity::UnitAuraCheck(true, GetSpellInfo()->Id));                  if (targets.empty())                      return; -                Unit* target = Trinity::Containers::SelectRandomContainerElement(targets); +                WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets);                  targets.clear();                  targets.push_back(target);                  _target = target;              } -            void ReplaceTargets(std::list<Unit*>& targets) +            void ReplaceTargets(std::list<WorldObject*>& targets)              {                  targets.clear();                  if (_target) @@ -520,13 +520,13 @@ class spell_rotface_mutated_infection : public SpellScriptLoader              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_rotface_mutated_infection_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); -                OnUnitTargetSelect += SpellUnitTargetFn(spell_rotface_mutated_infection_SpellScript::ReplaceTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY); -                OnUnitTargetSelect += SpellUnitTargetFn(spell_rotface_mutated_infection_SpellScript::ReplaceTargets, EFFECT_2, TARGET_UNIT_SRC_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_rotface_mutated_infection_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_rotface_mutated_infection_SpellScript::ReplaceTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_rotface_mutated_infection_SpellScript::ReplaceTargets, EFFECT_2, TARGET_UNIT_SRC_AREA_ENEMY);                  AfterHit += SpellHitFn(spell_rotface_mutated_infection_SpellScript::NotifyTargets);              } -            Unit* _target; +            WorldObject* _target;          };          SpellScript* GetSpellScript() const diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp index 6039ace44ab..e3c0f2260df 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp @@ -19,6 +19,7 @@  #include "ScriptMgr.h"  #include "ScriptedCreature.h"  #include "SpellAuraEffects.h" +#include "GridNotifiers.h"  #include "icecrown_citadel.h"  enum Texts @@ -167,7 +168,7 @@ class FrostwyrmLandEvent : public BasicEvent          bool Execute(uint64 /*eventTime*/, uint32 /*updateTime*/)          { -            _owner.GetMotionMaster()->MoveLand(POINT_FROSTWYRM_LAND, _dest, 8.247422f); +            _owner.GetMotionMaster()->MoveLand(POINT_FROSTWYRM_LAND, _dest);              return true;          } @@ -183,7 +184,7 @@ class FrostBombExplosion : public BasicEvent          bool Execute(uint64 /*eventTime*/, uint32 /*updateTime*/)          { -            _owner->CastSpell((Unit*)NULL, SPELL_FROST_BOMB, true, NULL, NULL, _sindragosaGUID); +            _owner->CastSpell((Unit*)NULL, SPELL_FROST_BOMB, false, NULL, NULL, _sindragosaGUID);              _owner->RemoveAurasDueToSpell(SPELL_FROST_BOMB_VISUAL);              return true;          } @@ -200,7 +201,7 @@ class boss_sindragosa : public CreatureScript          struct boss_sindragosaAI : public BossAI          { -            boss_sindragosaAI(Creature* creature) : BossAI(creature, DATA_SINDRAGOSA) +            boss_sindragosaAI(Creature* creature) : BossAI(creature, DATA_SINDRAGOSA), _summoned(false)              {              } @@ -220,7 +221,7 @@ class boss_sindragosa : public CreatureScript                  _isInAirPhase = false;                  _isThirdPhase = false; -                if (instance->GetData(DATA_SINDRAGOSA_FROSTWYRMS) != 255) +                if (!_summoned)                  {                      me->SetCanFly(true);                      me->SetDisableGravity(true); @@ -266,10 +267,13 @@ class boss_sindragosa : public CreatureScript              {                  if (action == ACTION_START_FROSTWYRM)                  { +                    if (_summoned) +                        return; + +                    _summoned = true;                      if (TempSummon* summon = me->ToTempSummon())                          summon->SetTempSummonType(TEMPSUMMON_DEAD_DESPAWN); -                    instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, 255);                      if (me->isDead())                          return; @@ -481,7 +485,7 @@ class boss_sindragosa : public CreatureScript                              Position pos;                              pos.Relocate(me);                              pos.m_positionZ += 17.0f; -                            me->GetMotionMaster()->MoveTakeoff(POINT_TAKEOFF, pos, 8.30078125f); +                            me->GetMotionMaster()->MoveTakeoff(POINT_TAKEOFF, pos);                              events.CancelEventGroup(EVENT_GROUP_LAND_PHASE);                              events.ScheduleEvent(EVENT_AIR_PHASE, 110000);                              break; @@ -523,7 +527,7 @@ class boss_sindragosa : public CreatureScript                              events.ScheduleEvent(EVENT_FROST_BREATH, urand(10000, 15000), EVENT_GROUP_LAND_PHASE);                              events.ScheduleEvent(EVENT_UNCHAINED_MAGIC, urand(12000, 17000), EVENT_GROUP_LAND_PHASE);                              events.ScheduleEvent(EVENT_ICY_GRIP, urand(35000, 40000), EVENT_GROUP_LAND_PHASE); -                            me->GetMotionMaster()->MoveLand(POINT_LAND_GROUND, SindragosaLandPos, 0.0f); +                            me->GetMotionMaster()->MoveLand(POINT_LAND_GROUND, SindragosaLandPos);                              break;                          case EVENT_THIRD_PHASE_CHECK:                          { @@ -550,6 +554,7 @@ class boss_sindragosa : public CreatureScript              uint8 _mysticBuffetStack;              bool _isInAirPhase;              bool _isThirdPhase; +            bool _summoned;          };          CreatureAI* GetAI(Creature* creature) const @@ -642,7 +647,7 @@ class npc_spinestalker : public CreatureScript          struct npc_spinestalkerAI : public ScriptedAI          { -            npc_spinestalkerAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) +            npc_spinestalkerAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()), _summoned(false)              {              } @@ -651,7 +656,7 @@ class npc_spinestalker : public CreatureScript                  // Increase add count                  if (!me->isDead())                  { -                    _instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, 1);  // this cannot be in Reset because reset also happens on evade +                    _instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, me->GetDBTableGUIDLow());  // this cannot be in Reset because reset also happens on evade                      Reset();                  }              } @@ -664,7 +669,7 @@ class npc_spinestalker : public CreatureScript                  _events.ScheduleEvent(EVENT_TAIL_SWEEP, urand(8000, 12000));                  me->SetReactState(REACT_DEFENSIVE); -                if (_instance->GetData(DATA_SPINESTALKER) != 255) +                if (!_summoned)                  {                      me->SetCanFly(true);                      me->SetDisableGravity(true); @@ -674,20 +679,22 @@ class npc_spinestalker : public CreatureScript              void JustRespawned()              {                  ScriptedAI::JustRespawned(); -                _instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, 1);  // this cannot be in Reset because reset also happens on evade +                _instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, me->GetDBTableGUIDLow());  // this cannot be in Reset because reset also happens on evade              }              void JustDied(Unit* /*killer*/)              {                  _events.Reset(); -                _instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, 0);              }              void DoAction(int32 const action)              {                  if (action == ACTION_START_FROSTWYRM)                  { -                    _instance->SetData(DATA_SPINESTALKER, 255); +                    if (_summoned) +                        return; + +                    _summoned = true;                      if (me->isDead())                          return; @@ -754,6 +761,7 @@ class npc_spinestalker : public CreatureScript          private:              EventMap _events;              InstanceScript* _instance; +            bool _summoned;          };          CreatureAI* GetAI(Creature* creature) const @@ -769,7 +777,7 @@ class npc_rimefang : public CreatureScript          struct npc_rimefangAI : public ScriptedAI          { -            npc_rimefangAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) +            npc_rimefangAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()), _summoned(false)              {              } @@ -778,7 +786,7 @@ class npc_rimefang : public CreatureScript                  // Increase add count                  if (!me->isDead())                  { -                    _instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, 1);  // this cannot be in Reset because reset also happens on evade +                    _instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, me->GetDBTableGUIDLow());  // this cannot be in Reset because reset also happens on evade                      Reset();                  }              } @@ -791,7 +799,7 @@ class npc_rimefang : public CreatureScript                  me->SetReactState(REACT_DEFENSIVE);                  _icyBlastCounter = 0; -                if (_instance->GetData(DATA_RIMEFANG) != 255) +                if (!_summoned)                  {                      me->SetCanFly(true);                      me->SetDisableGravity(true); @@ -801,20 +809,22 @@ class npc_rimefang : public CreatureScript              void JustRespawned()              {                  ScriptedAI::JustRespawned(); -                _instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, 1);  // this cannot be in Reset because reset also happens on evade +                _instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, me->GetDBTableGUIDLow());  // this cannot be in Reset because reset also happens on evade              }              void JustDied(Unit* /*killer*/)              {                  _events.Reset(); -                _instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, 0);              }              void DoAction(int32 const action)              {                  if (action == ACTION_START_FROSTWYRM)                  { -                    _instance->SetData(DATA_RIMEFANG, 255); +                    if (_summoned) +                        return; + +                    _summoned = true;                      if (me->isDead())                          return; @@ -908,6 +918,7 @@ class npc_rimefang : public CreatureScript              EventMap _events;              InstanceScript* _instance;              uint8 _icyBlastCounter; +            bool _summoned;          };          CreatureAI* GetAI(Creature* creature) const @@ -934,7 +945,8 @@ class npc_sindragosa_trash : public CreatureScript                  // Increase add count                  if (!me->isDead())                  { -                    _instance->SetData(_frostwyrmId, 1);  // this cannot be in Reset because reset also happens on evade +                    if (me->GetEntry() == NPC_FROSTWING_WHELP) +                        _instance->SetData(_frostwyrmId, me->GetDBTableGUIDLow());  // this cannot be in Reset because reset also happens on evade                      Reset();                  }              } @@ -956,13 +968,8 @@ class npc_sindragosa_trash : public CreatureScript                  ScriptedAI::JustRespawned();                  // Increase add count -                _instance->SetData(_frostwyrmId, 1);  // this cannot be in Reset because reset also happens on evade -            } - -            void JustDied(Unit* /*killer*/) -            { -                // Decrease add count -                _instance->SetData(_frostwyrmId, 0); +                if (me->GetEntry() == NPC_FROSTWING_WHELP) +                    _instance->SetData(_frostwyrmId, me->GetDBTableGUIDLow());  // this cannot be in Reset because reset also happens on evade              }              void SetData(uint32 type, uint32 data) @@ -1035,12 +1042,31 @@ class spell_sindragosa_s_fury : public SpellScriptLoader              bool Load()              {                  _targetCount = 0; -                return true; + +                // This script should execute only in Icecrown Citadel +                if (InstanceMap* instance = GetCaster()->GetMap()->ToInstanceMap()) +                    if (instance->GetInstanceScript()) +                        if (instance->GetScriptId() == sObjectMgr->GetScriptId(ICCScriptName)) +                            return true; + +                return false; +            } + +            void SelectDest() +            { +                if (Position* dest = const_cast<WorldLocation*>(GetExplTargetDest())) +                { +                    float destX = float(rand_norm()) * 75.0f + 4350.0f; +                    float destY = float(rand_norm()) * 75.0f + 2450.0f; +                    float destZ = 205.0f; // random number close to ground, get exact in next call +                    GetCaster()->UpdateGroundPositionZ(destX, destY, destZ); +                    dest->Relocate(destX, destY, destZ); +                }              } -            void CountTargets(std::list<Unit*>& unitList) +            void CountTargets(std::list<WorldObject*>& targets)              { -                _targetCount = unitList.size(); +                _targetCount = targets.size();              }              void HandleDummy(SpellEffIndex effIndex) @@ -1051,10 +1077,10 @@ class spell_sindragosa_s_fury : public SpellScriptLoader                      return;                  float resistance = float(GetHitUnit()->GetResistance(SpellSchoolMask(GetSpellInfo()->SchoolMask))); -                uint32 minResistFactor = uint32((resistance / (resistance + 510.0f))* 10.0f) * 2; -                uint32 randomResist = urand(0, (9 - minResistFactor) * 100)/100 + minResistFactor; +                uint32 minResistFactor = uint32((resistance / (resistance + 510.0f)) * 10.0f) * 2; +                uint32 randomResist = urand(0, (9 - minResistFactor) * 100) / 100 + minResistFactor; -                uint32 damage = (uint32(GetEffectValue()/_targetCount) * randomResist) / 10; +                uint32 damage = (uint32(GetEffectValue() / _targetCount) * randomResist) / 10;                  SpellNonMeleeDamage damageInfo(GetCaster(), GetHitUnit(), GetSpellInfo()->Id, GetSpellInfo()->SchoolMask);                  damageInfo.damage = damage; @@ -1064,8 +1090,9 @@ class spell_sindragosa_s_fury : public SpellScriptLoader              void Register()              { +                BeforeCast += SpellCastFn(spell_sindragosa_s_fury_SpellScript::SelectDest); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sindragosa_s_fury_SpellScript::CountTargets, EFFECT_1, TARGET_UNIT_DEST_AREA_ENTRY);                  OnEffectHitTarget += SpellEffectFn(spell_sindragosa_s_fury_SpellScript::HandleDummy, EFFECT_1, SPELL_EFFECT_DUMMY); -                OnUnitTargetSelect += SpellUnitTargetFn(spell_sindragosa_s_fury_SpellScript::CountTargets, EFFECT_1, TARGET_UNIT_DEST_AREA_ENTRY);              }              uint32 _targetCount; @@ -1082,9 +1109,11 @@ class UnchainedMagicTargetSelector      public:          UnchainedMagicTargetSelector() { } -        bool operator()(Unit* unit) +        bool operator()(WorldObject* object) const          { -            return unit->getPowerType() != POWER_MANA; +            if (Unit* unit = object->ToUnit()) +                return unit->getPowerType() != POWER_MANA; +            return true;          }  }; @@ -1097,7 +1126,7 @@ class spell_sindragosa_unchained_magic : public SpellScriptLoader          {              PrepareSpellScript(spell_sindragosa_unchained_magic_SpellScript); -            void FilterTargets(std::list<Unit*>& unitList) +            void FilterTargets(std::list<WorldObject*>& unitList)              {                  unitList.remove_if(UnchainedMagicTargetSelector());                  uint32 maxSize = uint32(GetCaster()->GetMap()->GetSpawnMode() & 1 ? 6 : 2); @@ -1107,7 +1136,7 @@ class spell_sindragosa_unchained_magic : public SpellScriptLoader              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_sindragosa_unchained_magic_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sindragosa_unchained_magic_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);              }          }; @@ -1290,7 +1319,7 @@ class MysticBuffetTargetFilter      public:          explicit MysticBuffetTargetFilter(Unit* caster) : _caster(caster) { } -        bool operator()(Unit* unit) +        bool operator()(WorldObject* unit) const          {              return !unit->IsWithinLOSInMap(_caster);          } @@ -1308,14 +1337,14 @@ class spell_sindragosa_mystic_buffet : public SpellScriptLoader          {              PrepareSpellScript(spell_sindragosa_mystic_buffet_SpellScript); -            void FilterTargets(std::list<Unit*>& unitList) +            void FilterTargets(std::list<WorldObject*>& targets)              { -                unitList.remove_if(MysticBuffetTargetFilter(GetCaster())); +                targets.remove_if(MysticBuffetTargetFilter(GetCaster()));              }              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_sindragosa_mystic_buffet_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sindragosa_mystic_buffet_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);              }          }; @@ -1393,22 +1422,15 @@ class spell_frostwarden_handler_order_whelp : public SpellScriptLoader                  return true;              } -            void FilterTargets(std::list<Unit*>& unitList) +            void FilterTargets(std::list<WorldObject*>& targets)              { -                for (std::list<Unit*>::iterator itr = unitList.begin(); itr != unitList.end();) -                { -                    if ((*itr)->GetTypeId() != TYPEID_PLAYER) -                        unitList.erase(itr++); -                    else -                        ++itr; -                } - -                if (unitList.empty()) +                targets.remove_if(Trinity::ObjectTypeIdCheck(TYPEID_PLAYER, false)); +                if (targets.empty())                      return; -                Unit* target = Trinity::Containers::SelectRandomContainerElement(unitList); -                unitList.clear(); -                unitList.push_back(target); +                WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets); +                targets.clear(); +                targets.push_back(target);              }              void HandleForcedCast(SpellEffIndex effIndex) @@ -1429,7 +1451,7 @@ class spell_frostwarden_handler_order_whelp : public SpellScriptLoader              void Register()              {                  OnEffectHitTarget += SpellEffectFn(spell_frostwarden_handler_order_whelp_SpellScript::HandleForcedCast, EFFECT_0, SPELL_EFFECT_FORCE_CAST); -                OnUnitTargetSelect += SpellUnitTargetFn(spell_frostwarden_handler_order_whelp_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_frostwarden_handler_order_whelp_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);              }          }; @@ -1509,7 +1531,7 @@ class at_sindragosa_lair : public AreaTriggerScript                      if (Creature* rimefang = ObjectAccessor::GetCreature(*player, instance->GetData64(DATA_RIMEFANG)))                          rimefang->AI()->DoAction(ACTION_START_FROSTWYRM); -                if (!instance->GetData(DATA_SINDRAGOSA_FROSTWYRMS) && instance->GetBossState(DATA_SINDRAGOSA) != DONE) +                if (!instance->GetData(DATA_SINDRAGOSA_FROSTWYRMS) && !instance->GetData64(DATA_SINDRAGOSA) && instance->GetBossState(DATA_SINDRAGOSA) != DONE)                  {                      if (player->GetMap()->IsHeroic() && !instance->GetData(DATA_HEROIC_ATTEMPTS))                          return true; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp index 4dab215d1da..a8657925131 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp @@ -138,7 +138,7 @@ enum Spells      SPELL_IN_FROSTMOURNE_ROOM           = 74276,      SPELL_KILL_FROSTMOURNE_PLAYERS      = 75127,      SPELL_HARVESTED_SOUL                = 72679, -    SPELL_TRIGGER_VILE_SPIRIT_HEROIC    = 73582, +    SPELL_TRIGGER_VILE_SPIRIT_HEROIC    = 73582,    // TODO: Cast every 3 seconds during Frostmourne phase, targets a Wicked Spirit amd activates it      // Frostmourne      SPELL_LIGHTS_FAVOR                  = 69382, @@ -152,6 +152,7 @@ enum Spells      SPELL_SUMMON_SPIRIT_BOMB_1          = 73581,    // (Heroic)      SPELL_SUMMON_SPIRIT_BOMB_2          = 74299,    // (Heroic)      SPELL_EXPLOSION                     = 73576,    // Spirit Bomb (Heroic) +    SPELL_HARVEST_SOUL_DAMAGE_AURA      = 73655,      // Outro      SPELL_FURY_OF_FROSTMOURNE           = 72350, @@ -221,7 +222,7 @@ enum Events      EVENT_QUAKE_2                   = 27,      EVENT_VILE_SPIRITS              = 28,      EVENT_HARVEST_SOULS             = 29,   // heroic only -    EVENT_WICKED_SPIRITS            = 30, +    EVENT_BERSERK                   = 30,      EVENT_SOUL_RIP                  = 31,      EVENT_DESTROY_SOUL              = 32,      EVENT_FROSTMOURNE_TALK_1        = 33, @@ -249,19 +250,18 @@ enum Events      EVENT_OUTRO_TERENAS_TALK_2      = 55,      EVENT_OUTRO_TALK_7              = 56,      EVENT_OUTRO_TALK_8              = 57, -    EVENT_BERSERK                   = 58,      // Shambling Horror -    EVENT_SHOCKWAVE                 = 59, -    EVENT_ENRAGE                    = 60, +    EVENT_SHOCKWAVE                 = 58, +    EVENT_ENRAGE                    = 59,      // Raging Spirit -    EVENT_SOUL_SHRIEK               = 61, +    EVENT_SOUL_SHRIEK               = 60,      // Strangulate Vehicle (Harvest Soul) -    EVENT_TELEPORT                  = 62, -    EVENT_MOVE_TO_LICH_KING         = 63, -    EVENT_DESPAWN_SELF              = 64, +    EVENT_TELEPORT                  = 61, +    EVENT_MOVE_TO_LICH_KING         = 62, +    EVENT_DESPAWN_SELF              = 63,  };  enum EventGroups @@ -391,7 +391,7 @@ class HeightDifferenceCheck          {          } -        bool operator()(Unit* unit) const +        bool operator()(WorldObject* unit) const          {              return (unit->GetPositionZ() - _baseObject->GetPositionZ() > _difference) != _reverse;          } @@ -475,6 +475,32 @@ class VileSpiritActivateEvent : public BasicEvent          Creature* _owner;  }; +class TriggerWickedSpirit : public BasicEvent +{ +    public: +        explicit TriggerWickedSpirit(Creature* owner) +            : _owner(owner), _counter(13) +        { +        } + +        bool Execute(uint64 /*time*/, uint32 /*diff*/) +        { +            _owner->CastCustomSpell(SPELL_TRIGGER_VILE_SPIRIT_HEROIC, SPELLVALUE_MAX_TARGETS, 1, NULL, true); + +            if (--_counter) +            { +                _owner->m_Events.AddEvent(this, _owner->m_Events.CalculateTime(3000)); +                return false; +            } + +            return true; +        } + +    private: +        Creature* _owner; +        uint32 _counter; +}; +  class boss_the_lich_king : public CreatureScript  {      public: @@ -503,6 +529,8 @@ class boss_the_lich_king : public CreatureScript                  me->SetDisableGravity(false);                  me->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER);                  me->GetMotionMaster()->MoveFall(); +                if (Creature* frostmourne = me->FindNearestCreature(NPC_FROSTMOURNE_TRIGGER, 50.0f)) +                    frostmourne->DespawnOrUnsummon();              }              void EnterCombat(Unit* target) @@ -601,8 +629,6 @@ class boss_the_lich_king : public CreatureScript                          summons.DoAction(ACTION_TELEPORT_BACK, pred);                          if (!IsHeroic())                              Talk(SAY_LK_FROSTMOURNE_ESCAPE); -                        else -                            DoCastAOE(SPELL_TRIGGER_VILE_SPIRIT_HEROIC);                          break;                      }                      default: @@ -645,6 +671,8 @@ class boss_the_lich_king : public CreatureScript                  if (events.GetPhaseMask() & PHASE_MASK_ONE && !HealthAbovePct(70))                  {                      events.SetPhase(PHASE_TRANSITION); +                    me->SetReactState(REACT_PASSIVE); +                    me->AttackStop();                      me->GetMotionMaster()->MovePoint(POINT_CENTER_1, CenterPosition);                      return;                  } @@ -652,6 +680,8 @@ class boss_the_lich_king : public CreatureScript                  if (events.GetPhaseMask() & PHASE_MASK_TWO && !HealthAbovePct(40))                  {                      events.SetPhase(PHASE_TRANSITION); +                    me->SetReactState(REACT_PASSIVE); +                    me->AttackStop();                      me->GetMotionMaster()->MovePoint(POINT_CENTER_2, CenterPosition);                      return;                  } @@ -664,7 +694,8 @@ class boss_the_lich_king : public CreatureScript                      events.SetPhase(PHASE_OUTRO);                      summons.DespawnAll();                      SendMusicToPlayers(MUSIC_FURY_OF_FROSTMOURNE); -                    DoCastAOE(SPELL_FURY_OF_FROSTMOURNE); +                    me->InterruptNonMeleeSpells(true); +                    me->CastSpell((Unit*)NULL, SPELL_FURY_OF_FROSTMOURNE, TRIGGERED_NONE);                      me->SetWalk(true);                      events.ScheduleEvent(EVENT_OUTRO_TALK_1, 2600, 0, PHASE_OUTRO);                      events.ScheduleEvent(EVENT_OUTRO_EMOTE_TALK, 6600, 0, PHASE_OUTRO); @@ -712,7 +743,6 @@ class boss_the_lich_king : public CreatureScript                          break;                      case NPC_FROSTMOURNE_TRIGGER:                      { -                        summons.Summon(summon);                          summon->CastSpell((Unit*)NULL, SPELL_BROKEN_FROSTMOURNE, true);                          SendLightOverride(LIGHT_SOULSTORM, 10000); @@ -724,16 +754,11 @@ class boss_the_lich_king : public CreatureScript                      case NPC_VILE_SPIRIT:                      {                          summons.Summon(summon); -                        if (events.GetPhaseMask() & PHASE_MASK_FROSTMOURNE) -                        { -                            TeleportSpirit(summon); -                            return; -                        } -                          summon->SetReactState(REACT_PASSIVE);                          summon->SetSpeed(MOVE_FLIGHT, 0.5f);                          summon->GetMotionMaster()->MoveRandom(10.0f); -                        summon->m_Events.AddEvent(new VileSpiritActivateEvent(summon), summon->m_Events.CalculateTime(15000)); +                        if (!(events.GetPhaseMask() & PHASE_MASK_FROSTMOURNE)) +                            summon->m_Events.AddEvent(new VileSpiritActivateEvent(summon), summon->m_Events.CalculateTime(15000));                          return;                      }                      case NPC_STRANGULATE_VEHICLE: @@ -756,7 +781,6 @@ class boss_the_lich_king : public CreatureScript                      case NPC_VALKYR_SHADOWGUARD:                      case NPC_RAGING_SPIRIT:                      case NPC_VILE_SPIRIT: -                    case NPC_WICKED_SPIRIT:                          summon->ToTempSummon()->SetTempSummonType(TEMPSUMMON_CORPSE_DESPAWN);                          break;                      default: @@ -802,8 +826,6 @@ class boss_the_lich_king : public CreatureScript                          me->SetFacingTo(0.0f);                          Talk(SAY_LK_REMORSELESS_WINTER);                          SendMusicToPlayers(MUSIC_SPECIAL); -                        me->SetReactState(REACT_PASSIVE); -                        me->AttackStop();                          DoCast(me, SPELL_REMORSELESS_WINTER_1);                          events.DelayEvents(62500, EVENT_GROUP_BERSERK); // delay berserk timer, its not ticking during phase transitions                          events.ScheduleEvent(EVENT_QUAKE, 62500, 0, PHASE_TRANSITION); @@ -819,8 +841,6 @@ class boss_the_lich_king : public CreatureScript                          me->SetFacingTo(0.0f);                          Talk(SAY_LK_REMORSELESS_WINTER);                          SendMusicToPlayers(MUSIC_SPECIAL); -                        me->SetReactState(REACT_PASSIVE); -                        me->AttackStop();                          DoCast(me, SPELL_REMORSELESS_WINTER_2);                          summons.DespawnEntry(NPC_VALKYR_SHADOWGUARD);                          events.DelayEvents(62500, EVENT_GROUP_BERSERK); // delay berserk timer, its not ticking during phase transitions @@ -992,10 +1012,6 @@ class boss_the_lich_king : public CreatureScript                              DoCastAOE(SPELL_VILE_SPIRITS);                              events.ScheduleEvent(EVENT_VILE_SPIRITS, urand(35000, 40000), EVENT_GROUP_VILE_SPIRITS, PHASE_THREE);                              break; -                        case EVENT_WICKED_SPIRITS: -                            DoCastAOE(SPELL_VILE_SPIRITS); -                            events.ScheduleEvent(EVENT_WICKED_SPIRITS, urand(35000, 40000), 0, PHASE_FROSTMOURNE); -                            break;                          case EVENT_HARVEST_SOULS:                              Talk(SAY_LK_HARVEST_SOUL);                              DoCastAOE(SPELL_HARVEST_SOULS); @@ -1003,7 +1019,6 @@ class boss_the_lich_king : public CreatureScript                              events.SetPhase(PHASE_FROSTMOURNE); // will stop running UpdateVictim (no evading)                              me->SetReactState(REACT_PASSIVE);                              me->AttackStop(); -                            events.ScheduleEvent(EVENT_WICKED_SPIRITS, events.GetNextEventTime(EVENT_VILE_SPIRITS) - events.GetTimer(), 0, PHASE_FROSTMOURNE);                              events.DelayEvents(50000, EVENT_GROUP_VILE_SPIRITS);                              events.RescheduleEvent(EVENT_DEFILE, 50000, 0, PHASE_THREE);                              events.RescheduleEvent(EVENT_SOUL_REAPER, urand(57000, 62000), 0, PHASE_THREE); @@ -1019,16 +1034,22 @@ class boss_the_lich_king : public CreatureScript                                  if (!triggers.empty())                                  {                                      triggers.sort(Trinity::ObjectDistanceOrderPred(terenas, true)); -                                    Unit* spawner = triggers.front(); +                                    Creature* spawner = triggers.front();                                      spawner->CastSpell(spawner, SPELL_SUMMON_SPIRIT_BOMB_1, true);  // summons bombs randomly                                      spawner->CastSpell(spawner, SPELL_SUMMON_SPIRIT_BOMB_2, true);  // summons bombs on players +                                    spawner->m_Events.AddEvent(new TriggerWickedSpirit(spawner), spawner->m_Events.CalculateTime(3000));                                  }                                  for (SummonList::iterator i = summons.begin(); i != summons.end(); ++i)                                  {                                      Creature* summon = ObjectAccessor::GetCreature(*me, *i);                                      if (summon && summon->GetEntry() == NPC_VILE_SPIRIT) -                                        TeleportSpirit(summon); +                                    { +                                        summon->m_Events.KillAllEvents(true); +                                        summon->m_Events.AddEvent(new VileSpiritActivateEvent(summon), summon->m_Events.CalculateTime(50000)); +                                        summon->GetMotionMaster()->MoveRandom(10.0f); +                                        summon->SetReactState(REACT_PASSIVE); +                                    }                                  }                              }                              break; @@ -1099,22 +1120,6 @@ class boss_the_lich_king : public CreatureScript              }          private: - -            void TeleportSpirit(Creature* summon) -            { -                float dist = me->GetObjectSize() + (15.0f - me->GetObjectSize()) * float(rand_norm()); -                float angle = float(rand_norm()) * float(2.0f * M_PI); -                Position dest = TerenasSpawnHeroic; -                me->MovePosition(dest, dist, angle); -                dest.m_positionZ += 15.0f; -                summon->UpdateEntry(NPC_WICKED_SPIRIT); -                summon->SetReactState(REACT_PASSIVE); -                summon->NearTeleportTo(dest.GetPositionX(), dest.GetPositionY(), dest.GetPositionZ(), dest.GetOrientation()); -                summon->SetSpeed(MOVE_FLIGHT, 0.5f); -                summon->m_Events.KillAllEvents(true); -                summon->m_Events.AddEvent(new VileSpiritActivateEvent(summon), summon->m_Events.CalculateTime(1000)); -            } -              void SendMusicToPlayers(uint32 musicId) const              {                  WorldPacket data(SMSG_PLAY_MUSIC, 4); @@ -1635,8 +1640,13 @@ class npc_strangulate_vehicle : public CreatureScript                      return;                  if (TempSummon* summ = me->ToTempSummon()) +                {                      if (Unit* summoner = summ->GetSummoner()) +                    {                          DoCast(summoner, SPELL_HARVEST_SOUL_TELEPORT_BACK); +                        summoner->RemoveAurasDueToSpell(SPELL_HARVEST_SOUL_DAMAGE_AURA); +                    } +                }                  if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_THE_LICH_KING)))                      lichKing->AI()->SummonedCreatureDespawn(me); @@ -1993,6 +2003,10 @@ class npc_broken_frostmourne : public CreatureScript                      _events.ScheduleEvent(EVENT_OUTRO_SUMMON_TERENAS, 6000, 0, PHASE_OUTRO);              } +            void EnterEvadeMode() +            { +            } +              void UpdateAI(uint32 const diff)              {                  UpdateVictim(); @@ -2274,7 +2288,7 @@ class spell_the_lich_king_shadow_trap_periodic : public SpellScriptLoader          {              PrepareSpellScript(spell_the_lich_king_shadow_trap_periodic_SpellScript); -            void CheckTargetCount(std::list<Unit*>& targets) +            void CheckTargetCount(std::list<WorldObject*>& targets)              {                  if (targets.empty())                      return; @@ -2284,7 +2298,7 @@ class spell_the_lich_king_shadow_trap_periodic : public SpellScriptLoader              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_the_lich_king_shadow_trap_periodic_SpellScript::CheckTargetCount, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_shadow_trap_periodic_SpellScript::CheckTargetCount, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);              }          }; @@ -2308,10 +2322,10 @@ class spell_the_lich_king_quake : public SpellScriptLoader                  return GetCaster()->GetInstanceScript() != NULL;              } -            void FilterTargets(std::list<Unit*>& unitList) +            void FilterTargets(std::list<WorldObject*>& targets)              {                  if (GameObject* platform = ObjectAccessor::GetGameObject(*GetCaster(), GetCaster()->GetInstanceScript()->GetData64(DATA_ARTHAS_PLATFORM))) -                    unitList.remove_if(HeightDifferenceCheck(platform, 5.0f, false)); +                    targets.remove_if(HeightDifferenceCheck(platform, 5.0f, false));              }              void HandleSendEvent(SpellEffIndex /*effIndex*/) @@ -2322,7 +2336,7 @@ class spell_the_lich_king_quake : public SpellScriptLoader              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_the_lich_king_quake_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_quake_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);                  OnEffectHit += SpellEffectFn(spell_the_lich_king_quake_SpellScript::HandleSendEvent, EFFECT_1, SPELL_EFFECT_SEND_EVENT);              }          }; @@ -2349,7 +2363,7 @@ class spell_the_lich_king_ice_burst_target_search : public SpellScriptLoader                  return true;              } -            void CheckTargetCount(std::list<Unit*>& unitList) +            void CheckTargetCount(std::list<WorldObject*>& unitList)              {                  if (unitList.empty())                      return; @@ -2357,12 +2371,16 @@ class spell_the_lich_king_ice_burst_target_search : public SpellScriptLoader                  // if there is at least one affected target cast the explosion                  GetCaster()->CastSpell(GetCaster(), SPELL_ICE_BURST, true);                  if (GetCaster()->GetTypeId() == TYPEID_UNIT) +                { +                    GetCaster()->ToCreature()->SetReactState(REACT_PASSIVE); +                    GetCaster()->AttackStop();                      GetCaster()->ToCreature()->DespawnOrUnsummon(500); +                }              }              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_the_lich_king_ice_burst_target_search_SpellScript::CheckTargetCount, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_ice_burst_target_search_SpellScript::CheckTargetCount, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);              }          }; @@ -2411,7 +2429,7 @@ class ExactDistanceCheck      public:          ExactDistanceCheck(Unit* source, float dist) : _source(source), _dist(dist) {} -        bool operator()(Unit* unit) +        bool operator()(WorldObject* unit)          {              return _source->GetExactDist2d(unit) > _dist;          } @@ -2430,7 +2448,7 @@ class spell_the_lich_king_defile : public SpellScriptLoader          {              PrepareSpellScript(spell_the_lich_king_defile_SpellScript); -            void CorrectRange(std::list<Unit*>& targets) +            void CorrectRange(std::list<WorldObject*>& targets)              {                  targets.remove_if(ExactDistanceCheck(GetCaster(), 10.0f * GetCaster()->GetFloatValue(OBJECT_FIELD_SCALE_X)));              } @@ -2446,8 +2464,8 @@ class spell_the_lich_king_defile : public SpellScriptLoader              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_the_lich_king_defile_SpellScript::CorrectRange, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); -                OnUnitTargetSelect += SpellUnitTargetFn(spell_the_lich_king_defile_SpellScript::CorrectRange, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_defile_SpellScript::CorrectRange, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_defile_SpellScript::CorrectRange, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);                  OnHit += SpellHitFn(spell_the_lich_king_defile_SpellScript::ChangeDamageAndGrow);              }          }; @@ -2472,14 +2490,18 @@ class spell_the_lich_king_summon_into_air : public SpellScriptLoader                  static Position const offset = {0.0f, 0.0f, 15.0f, 0.0f};                  WorldLocation* dest = const_cast<WorldLocation*>(GetExplTargetDest());                  dest->RelocateOffset(offset); +                GetHitDest()->RelocateOffset(offset);                  // spirit bombs get higher                  if (GetSpellInfo()->Effects[effIndex].MiscValue == NPC_SPIRIT_BOMB) +                {                      dest->RelocateOffset(offset); +                    GetHitDest()->RelocateOffset(offset); +                }              }              void Register()              { -                OnEffectLaunch += SpellEffectFn(spell_the_lich_king_summon_into_air_SpellScript::ModDestHeight, EFFECT_0, SPELL_EFFECT_SUMMON); +                OnEffectHit += SpellEffectFn(spell_the_lich_king_summon_into_air_SpellScript::ModDestHeight, EFFECT_0, SPELL_EFFECT_SUMMON);              }          }; @@ -2545,26 +2567,26 @@ class spell_the_lich_king_valkyr_target_search : public SpellScriptLoader                  return true;              } -            void SelectTarget(std::list<Unit*>& unitList) +            void SelectTarget(std::list<WorldObject*>& targets)              { -                if (unitList.empty()) +                if (targets.empty())                      return; -                unitList.remove_if(Trinity::UnitAuraCheck(true, GetSpellInfo()->Id)); -                if (unitList.empty()) +                targets.remove_if(Trinity::UnitAuraCheck(true, GetSpellInfo()->Id)); +                if (targets.empty())                      return; -                _target = Trinity::Containers::SelectRandomContainerElement(unitList); -                unitList.clear(); -                unitList.push_back(_target); +                _target = Trinity::Containers::SelectRandomContainerElement(targets); +                targets.clear(); +                targets.push_back(_target);                  GetCaster()->GetAI()->SetGUID(_target->GetGUID());              } -            void ReplaceTarget(std::list<Unit*>& unitList) +            void ReplaceTarget(std::list<WorldObject*>& targets)              { -                unitList.clear(); +                targets.clear();                  if (_target) -                    unitList.push_back(_target); +                    targets.push_back(_target);              }              void HandleScript(SpellEffIndex effIndex) @@ -2575,12 +2597,12 @@ class spell_the_lich_king_valkyr_target_search : public SpellScriptLoader              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_the_lich_king_valkyr_target_search_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); -                OnUnitTargetSelect += SpellUnitTargetFn(spell_the_lich_king_valkyr_target_search_SpellScript::ReplaceTarget, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_valkyr_target_search_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_valkyr_target_search_SpellScript::ReplaceTarget, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);                  OnEffectHitTarget += SpellEffectFn(spell_the_lich_king_valkyr_target_search_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);              } -            Unit* _target; +            WorldObject* _target;          };          SpellScript* GetSpellScript() const @@ -2757,7 +2779,7 @@ class spell_the_lich_king_vile_spirit_move_target_search : public SpellScriptLoa                  return GetCaster()->GetTypeId() == TYPEID_UNIT;              } -            void SelectTarget(std::list<Unit*>& targets) +            void SelectTarget(std::list<WorldObject*>& targets)              {                  if (targets.empty())                      return; @@ -2778,11 +2800,11 @@ class spell_the_lich_king_vile_spirit_move_target_search : public SpellScriptLoa              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_the_lich_king_vile_spirit_move_target_search_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_vile_spirit_move_target_search_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);                  OnEffectHitTarget += SpellEffectFn(spell_the_lich_king_vile_spirit_move_target_search_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);              } -            Unit* _target; +            WorldObject* _target;          };          SpellScript* GetSpellScript() const @@ -2805,7 +2827,7 @@ class spell_the_lich_king_vile_spirit_damage_target_search : public SpellScriptL                  return GetCaster()->GetTypeId() == TYPEID_UNIT;              } -            void CheckTargetCount(std::list<Unit*>& targets) +            void CheckTargetCount(std::list<WorldObject*>& targets)              {                  if (targets.empty())                      return; @@ -2822,7 +2844,7 @@ class spell_the_lich_king_vile_spirit_damage_target_search : public SpellScriptL              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_the_lich_king_vile_spirit_damage_target_search_SpellScript::CheckTargetCount, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_vile_spirit_damage_target_search_SpellScript::CheckTargetCount, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);              }              Unit* _target; @@ -2954,6 +2976,15 @@ class spell_the_lich_king_restore_soul : public SpellScriptLoader                      lichKing->AI()->DoAction(ACTION_TELEPORT_BACK);                  if (Creature* spawner = GetCaster()->FindNearestCreature(NPC_WORLD_TRIGGER_INFINITE_AOI, 50.0f))                      spawner->RemoveAllAuras(); + +                std::list<Creature*> spirits; +                GetCaster()->GetCreatureListWithEntryInGrid(spirits, NPC_WICKED_SPIRIT, 200.0f); +                for (std::list<Creature*>::iterator itr = spirits.begin(); itr != spirits.end(); ++itr) +                { +                    (*itr)->m_Events.KillAllEvents(true); +                    (*itr)->SetReactState(REACT_PASSIVE); +                    (*itr)->AI()->EnterEvadeMode(); +                }              }              void RemoveAura() @@ -3046,23 +3077,18 @@ class spell_the_lich_king_trigger_vile_spirit : public SpellScriptLoader          {              PrepareSpellScript(spell_the_lich_king_trigger_vile_spirit_SpellScript); -            void TeleportOutside() +            void ActivateSpirit()              {                  Creature* target = GetHitCreature();                  if (!target)                      return; -                Position dest; -                Position offset; -                TerenasSpawnHeroic.GetPositionOffsetTo(*target, offset); -                GetCaster()->GetPosition(&dest); -                dest.RelocateOffset(offset); -                target->NearTeleportTo(dest.GetPositionX(), dest.GetPositionY(), dest.GetPositionZ(), dest.GetOrientation()); +                VileSpiritActivateEvent(target).Execute(0, 0);              }              void Register()              { -                OnHit += SpellHitFn(spell_the_lich_king_trigger_vile_spirit_SpellScript::TeleportOutside); +                OnHit += SpellHitFn(spell_the_lich_king_trigger_vile_spirit_SpellScript::ActivateSpirit);              }          }; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp index c40a521c794..826c62a4390 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp @@ -1013,11 +1013,8 @@ class npc_dream_portal : public CreatureScript              {              } -            void DoAction(int32 const action) +            void OnSpellClick(Unit* /*clicker*/)              { -                if (action != EVENT_SPELLCLICK) -                    return; -                  _used = true;                  me->DespawnOrUnsummon();              } @@ -1190,13 +1187,13 @@ class spell_dreamwalker_summoner : public SpellScriptLoader                  return true;              } -            void FilterTargets(std::list<Unit*>& targets) +            void FilterTargets(std::list<WorldObject*>& targets)              { -                targets.remove_if (Trinity::UnitAuraCheck(true, SPELL_RECENTLY_SPAWNED)); +                targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_RECENTLY_SPAWNED));                  if (targets.empty())                      return; -                Unit* target = Trinity::Containers::SelectRandomContainerElement(targets); +                WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets);                  targets.clear();                  targets.push_back(target);              } @@ -1212,7 +1209,7 @@ class spell_dreamwalker_summoner : public SpellScriptLoader              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_dreamwalker_summoner_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_dreamwalker_summoner_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);                  OnEffectHitTarget += SpellEffectFn(spell_dreamwalker_summoner_SpellScript::HandleForceCast, EFFECT_0, SPELL_EFFECT_FORCE_CAST);              }          }; @@ -1241,7 +1238,7 @@ class spell_dreamwalker_summon_suppresser : public SpellScriptLoader                  std::list<Creature*> summoners;                  GetCreatureListWithEntryInGrid(summoners, caster, NPC_WORLD_TRIGGER, 100.0f); -                summoners.remove_if (Trinity::UnitAuraCheck(true, SPELL_RECENTLY_SPAWNED)); +                summoners.remove_if(Trinity::UnitAuraCheck(true, SPELL_RECENTLY_SPAWNED));                  Trinity::Containers::RandomResizeList(summoners, 2);                  if (summoners.empty())                      return; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp index fab9a5f0740..17e33912a86 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp @@ -19,6 +19,7 @@  #include "ScriptMgr.h"  #include "ScriptedCreature.h"  #include "ScriptedEscortAI.h" +#include "PassiveAI.h"  #include "Cell.h"  #include "CellImpl.h"  #include "GridNotifiers.h" @@ -158,6 +159,9 @@ enum Spells      SPELL_FEL_IRON_BOMB_UNDEAD      = 71787,      SPELL_MACHINE_GUN_UNDEAD        = 71788,      SPELL_ROCKET_LAUNCH_UNDEAD      = 71786, + +    // Invisible Stalker (Float, Uninteractible, LargeAOI) +    SPELL_SOUL_MISSILE              = 72585,  };  // Helper defines @@ -248,6 +252,9 @@ enum EventTypes      EVENT_RUPERT_FEL_IRON_BOMB          = 52,      EVENT_RUPERT_MACHINE_GUN            = 53,      EVENT_RUPERT_ROCKET_LAUNCH          = 54, + +    // Invisible Stalker (Float, Uninteractible, LargeAOI) +    EVENT_SOUL_MISSILE                  = 55,  };  enum DataTypesICC @@ -1668,6 +1675,56 @@ class npc_impaling_spear : public CreatureScript          }  }; +class npc_arthas_teleport_visual : public CreatureScript +{ +    public: +        npc_arthas_teleport_visual() : CreatureScript("npc_arthas_teleport_visual") { } + +        struct npc_arthas_teleport_visualAI : public NullCreatureAI +        { +            npc_arthas_teleport_visualAI(Creature* creature) : NullCreatureAI(creature), _instance(creature->GetInstanceScript()) +            { +            } + +            void Reset() +            { +                _events.Reset(); +                if (_instance->GetBossState(DATA_PROFESSOR_PUTRICIDE) == DONE && +                    _instance->GetBossState(DATA_BLOOD_QUEEN_LANA_THEL) == DONE && +                    _instance->GetBossState(DATA_SINDRAGOSA) == DONE) +                    _events.ScheduleEvent(EVENT_SOUL_MISSILE, urand(1000, 6000)); +            } + +            void UpdateAI(uint32 const diff) +            { +                if (_events.Empty()) +                    return; + +                _events.Update(diff); + +                if (_events.ExecuteEvent() == EVENT_SOUL_MISSILE) +                { +                    DoCastAOE(SPELL_SOUL_MISSILE); +                    _events.ScheduleEvent(EVENT_SOUL_MISSILE, urand(5000, 7000)); +                } +            } + +        private: +            InstanceScript* _instance; +            EventMap _events; +        }; + +        CreatureAI* GetAI(Creature* creature) const +        { +            // Distance from the center of the spire +            if (creature->GetExactDist2d(4357.052f, 2769.421f) < 100.0f && creature->GetHomePosition().GetPositionZ() < 315.0f) +                return GetIcecrownCitadelAI<npc_arthas_teleport_visualAI>(creature); + +            // Default to no script +            return NULL; +        } +}; +  class spell_icc_stoneform : public SpellScriptLoader  {      public: @@ -1777,15 +1834,15 @@ class DeathPlagueTargetSelector      public:          explicit DeathPlagueTargetSelector(Unit* caster) : _caster(caster) {} -        bool operator()(Unit* unit) +        bool operator()(WorldObject* object) const          { -            if (unit == _caster) +            if (object == _caster)                  return true; -            if (unit->GetTypeId() != TYPEID_PLAYER) +            if (object->GetTypeId() != TYPEID_PLAYER)                  return true; -            if (unit->HasAura(SPELL_RECENTLY_INFECTED) || unit->HasAura(SPELL_DEATH_PLAGUE_AURA)) +            if (object->ToUnit()->HasAura(SPELL_RECENTLY_INFECTED) || object->ToUnit()->HasAura(SPELL_DEATH_PLAGUE_AURA))                  return true;              return false; @@ -1811,25 +1868,25 @@ class spell_frost_giant_death_plague : public SpellScriptLoader              }              // First effect -            void CountTargets(std::list<Unit*>& unitList) +            void CountTargets(std::list<WorldObject*>& targets)              { -                unitList.remove(GetCaster()); -                _failed = unitList.empty(); +                targets.remove(GetCaster()); +                _failed = targets.empty();              }              // Second effect -            void FilterTargets(std::list<Unit*>& unitList) +            void FilterTargets(std::list<WorldObject*>& targets)              {                  // Select valid targets for jump -                unitList.remove_if (DeathPlagueTargetSelector(GetCaster())); -                if (!unitList.empty()) +                targets.remove_if(DeathPlagueTargetSelector(GetCaster())); +                if (!targets.empty())                  { -                    Unit* target = Trinity::Containers::SelectRandomContainerElement(unitList); -                    unitList.clear(); -                    unitList.push_back(target); +                    WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets); +                    targets.clear(); +                    targets.push_back(target);                  } -                unitList.push_back(GetCaster()); +                targets.push_back(GetCaster());              }              void HandleScript(SpellEffIndex effIndex) @@ -1843,8 +1900,8 @@ class spell_frost_giant_death_plague : public SpellScriptLoader              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_frost_giant_death_plague_SpellScript::CountTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY); -                OnUnitTargetSelect += SpellUnitTargetFn(spell_frost_giant_death_plague_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ALLY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_frost_giant_death_plague_SpellScript::CountTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_frost_giant_death_plague_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ALLY);                  OnEffectHitTarget += SpellEffectFn(spell_frost_giant_death_plague_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);              } @@ -1893,9 +1950,11 @@ class spell_icc_harvest_blight_specimen : public SpellScriptLoader  class AliveCheck  {      public: -        bool operator()(Unit* unit) +        bool operator()(WorldObject* object) const          { -            return unit->isAlive(); +            if (Unit* unit = object->ToUnit()) +                return unit->isAlive(); +            return true;          }  }; @@ -1908,10 +1967,10 @@ class spell_svalna_revive_champion : public SpellScriptLoader          {              PrepareSpellScript(spell_svalna_revive_champion_SpellScript); -            void RemoveAliveTarget(std::list<Unit*>& unitList) +            void RemoveAliveTarget(std::list<WorldObject*>& targets)              { -                unitList.remove_if(AliveCheck()); -                Trinity::Containers::RandomResizeList(unitList, 2); +                targets.remove_if(AliveCheck()); +                Trinity::Containers::RandomResizeList(targets, 2);              }              void Land(SpellEffIndex /*effIndex*/) @@ -1926,12 +1985,12 @@ class spell_svalna_revive_champion : public SpellScriptLoader                  //pos.m_positionZ = caster->GetBaseMap()->GetHeight(caster->GetPhaseMask(), pos.GetPositionX(), pos.GetPositionY(), caster->GetPositionZ(), true, 50.0f);                  //pos.m_positionZ += 0.05f;                  caster->SetHomePosition(pos); -                caster->GetMotionMaster()->MoveLand(POINT_LAND, pos, caster->GetSpeed(MOVE_FLIGHT)); +                caster->GetMotionMaster()->MoveLand(POINT_LAND, pos);              }              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_svalna_revive_champion_SpellScript::RemoveAliveTarget, EFFECT_0, TARGET_UNIT_DEST_AREA_ENTRY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_svalna_revive_champion_SpellScript::RemoveAliveTarget, EFFECT_0, TARGET_UNIT_DEST_AREA_ENTRY);                  OnEffectHit += SpellEffectFn(spell_svalna_revive_champion_SpellScript::Land, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);              }          }; @@ -1974,6 +2033,33 @@ class spell_svalna_remove_spear : public SpellScriptLoader          }  }; +class spell_icc_soul_missile : public SpellScriptLoader +{ +    public: +        spell_icc_soul_missile() : SpellScriptLoader("spell_icc_soul_missile") { } + +        class spell_icc_soul_missile_SpellScript : public SpellScript +        { +            PrepareSpellScript(spell_icc_soul_missile_SpellScript); + +            void RelocateDest() +            { +                static Position const offset = {0.0f, 0.0f, 200.0f, 0.0f}; +                const_cast<WorldLocation*>(GetExplTargetDest())->RelocateOffset(offset); +            } + +            void Register() +            { +                OnCast += SpellCastFn(spell_icc_soul_missile_SpellScript::RelocateDest); +            } +        }; + +        SpellScript* GetSpellScript() const +        { +            return new spell_icc_soul_missile_SpellScript(); +        } +}; +  class at_icc_saurfang_portal : public AreaTriggerScript  {      public: @@ -2063,6 +2149,7 @@ void AddSC_icecrown_citadel()      new npc_captain_rupert();      new npc_frostwing_vrykul();      new npc_impaling_spear(); +    new npc_arthas_teleport_visual();      new spell_icc_stoneform();      new spell_icc_sprit_alarm();      new spell_frost_giant_death_plague(); @@ -2070,6 +2157,7 @@ void AddSC_icecrown_citadel()      new spell_trigger_spell_from_caster("spell_svalna_caress_of_death", SPELL_IMPALING_SPEAR_KILL);      new spell_svalna_revive_champion();      new spell_svalna_remove_spear(); +    new spell_icc_soul_missile();      new at_icc_saurfang_portal();      new at_icc_shutdown_traps();      new at_icc_start_blood_quickening(); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h index 224777c3db7..31639a698ef 100755 --- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h +++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h @@ -51,6 +51,7 @@ enum SharedSpells      SPELL_GREEN_BLIGHT_RESIDUE          = 72145,      // The Lich King +    SPELL_ARTHAS_TELEPORTER_CEREMONY    = 72915,      SPELL_FROSTMOURNE_TELEPORT_VISUAL   = 73078,  }; @@ -275,6 +276,9 @@ enum CreaturesIds      NPC_WORLD_TRIGGER_INFINITE_AOI              = 36171,      NPC_SPIRIT_BOMB                             = 39189,      NPC_FROSTMOURNE_TRIGGER                     = 38584, + +    // Generic +    NPC_INVISIBLE_STALKER                       = 30298,  };  enum GameObjectsIds @@ -345,6 +349,7 @@ enum GameObjectsIds      GO_SIGIL_OF_THE_FROSTWING               = 202181,      // The Lich King +    GO_SCOURGE_TRANSPORTER_LK               = 202223,      GO_ARTHAS_PLATFORM                      = 202161,      GO_ARTHAS_PRECIPICE                     = 202078,      GO_DOODAD_ICECROWN_THRONEFROSTYWIND01   = 202188, diff --git a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp index cb83efc748f..650f426d29c 100755 --- a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp @@ -130,6 +130,7 @@ class instance_icecrown_citadel : public InstanceMapScript                  SindragosaGUID = 0;                  SpinestalkerGUID = 0;                  RimefangGUID = 0; +                TheLichKingTeleportGUID = 0;                  TheLichKingGUID = 0;                  HighlordTirionFordringGUID = 0;                  TerenasMenethilGUID = 0; @@ -138,9 +139,6 @@ class instance_icecrown_citadel : public InstanceMapScript                  FrozenThroneEdgeGUID = 0;                  FrozenThroneWindGUID = 0;                  FrozenThroneWarningGUID = 0; -                FrostwyrmCount = 0; -                SpinestalkerTrashCount = 0; -                RimefangTrashCount = 0;                  IsBonedEligible = true;                  IsOozeDanceEligible = true;                  IsNauseaEligible = true; @@ -283,6 +281,11 @@ class instance_icecrown_citadel : public InstanceMapScript                      case NPC_RIMEFANG:                          RimefangGUID = creature->GetGUID();                          break; +                    case NPC_INVISIBLE_STALKER: +                        // Teleporter visual at center +                        if (creature->GetExactDist2d(4357.052f, 2769.421f) < 10.0f) +                            creature->CastSpell(creature, SPELL_ARTHAS_TELEPORTER_CEREMONY, false); +                        break;                      case NPC_THE_LICH_KING:                          TheLichKingGUID = creature->GetGUID();                          break; @@ -293,11 +296,22 @@ class instance_icecrown_citadel : public InstanceMapScript                      case NPC_TERENAS_MENETHIL_FROSTMOURNE_H:                          TerenasMenethilGUID = creature->GetGUID();                          break; +                    case NPC_WICKED_SPIRIT: +                        // Remove corpse as soon as it dies (and respawn 10 seconds later) +                        creature->SetCorpseDelay(0); +                        creature->SetReactState(REACT_PASSIVE); +                        break;                      default:                          break;                  }              } +            void OnCreatureRemove(Creature* creature) +            { +                if (creature->GetEntry() == NPC_SINDRAGOSA) +                    SindragosaGUID = 0; +            } +              // Weekly quest spawn prevention              uint32 GetCreatureEntry(uint32 /*guidLow*/, CreatureData const* data)              { @@ -347,6 +361,43 @@ class instance_icecrown_citadel : public InstanceMapScript                          if (Creature* crok = instance->GetCreature(CrokScourgebaneGUID))                              crok->AI()->SetGUID(creature->GetGUID(), ACTION_VRYKUL_DEATH);                          break; +                    case NPC_FROSTWING_WHELP: +                        if (FrostwyrmGUIDs.empty()) +                            return; + +                        if (creature->AI()->GetData(1/*DATA_FROSTWYRM_OWNER*/) == DATA_SPINESTALKER) +                        { +                            SpinestalkerTrash.erase(creature->GetDBTableGUIDLow()); +                            if (SpinestalkerTrash.empty()) +                                if (Creature* spinestalk = instance->GetCreature(SpinestalkerGUID)) +                                    spinestalk->AI()->DoAction(ACTION_START_FROSTWYRM); +                        } +                        else +                        { +                            RimefangTrash.erase(creature->GetDBTableGUIDLow()); +                            if (RimefangTrash.empty()) +                                if (Creature* spinestalk = instance->GetCreature(RimefangGUID)) +                                    spinestalk->AI()->DoAction(ACTION_START_FROSTWYRM); +                        } +                        break; +                    case NPC_RIMEFANG: +                    case NPC_SPINESTALKER: +                    { +                        if (instance->IsHeroic() && !HeroicAttempts) +                            return; + +                        if (GetBossState(DATA_SINDRAGOSA) == DONE) +                            return; + +                        FrostwyrmGUIDs.erase(creature->GetDBTableGUIDLow()); +                        if (FrostwyrmGUIDs.empty()) +                        { +                            instance->LoadGrid(SindragosaSpawnPos.GetPositionX(), SindragosaSpawnPos.GetPositionY()); +                            if (Creature* boss = instance->SummonCreature(NPC_SINDRAGOSA, SindragosaSpawnPos)) +                                boss->AI()->DoAction(ACTION_START_FROSTWYRM); +                        } +                        break; +                    }                      default:                          break;                  } @@ -460,6 +511,11 @@ class instance_icecrown_citadel : public InstanceMapScript                              go->SetLootRecipient(valithria->GetLootRecipient());                          go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED | GO_FLAG_NOT_SELECTABLE | GO_FLAG_NODESPAWN);                          break; +                    case GO_SCOURGE_TRANSPORTER_LK: +                        TheLichKingTeleportGUID = go->GetGUID(); +                        if (GetBossState(DATA_PROFESSOR_PUTRICIDE) == DONE && GetBossState(DATA_BLOOD_QUEEN_LANA_THEL) == DONE && GetBossState(DATA_SINDRAGOSA) == DONE) +                            go->SetGoState(GO_STATE_ACTIVE); +                        break;                      case GO_ARTHAS_PLATFORM:                          // this enables movement at The Frozen Throne, when printed this value is 0.000000f                          // however, when represented as integer client will accept only this value @@ -538,11 +594,11 @@ class instance_icecrown_citadel : public InstanceMapScript                  switch (type)                  {                      case DATA_SINDRAGOSA_FROSTWYRMS: -                        return FrostwyrmCount; +                        return FrostwyrmGUIDs.size();                      case DATA_SPINESTALKER: -                        return SpinestalkerTrashCount; +                        return SpinestalkerTrash.size();                      case DATA_RIMEFANG: -                        return RimefangTrashCount; +                        return RimefangTrash.size();                      case DATA_COLDFLAME_JETS:                          return ColdflameJetsState;                      case DATA_TEAM_IN_INSTANCE: @@ -698,6 +754,8 @@ class instance_icecrown_citadel : public InstanceMapScript                          break;                      case DATA_PROFESSOR_PUTRICIDE:                          HandleGameObject(PlagueSigilGUID, state != DONE); +                        if (state == DONE) +                            CheckLichKingAvailability();                          if (instance->IsHeroic())                          {                              if (state == FAIL && HeroicAttempts) @@ -712,6 +770,8 @@ class instance_icecrown_citadel : public InstanceMapScript                          break;                      case DATA_BLOOD_QUEEN_LANA_THEL:                          HandleGameObject(BloodwingSigilGUID, state != DONE); +                        if (state == DONE) +                            CheckLichKingAvailability();                          if (instance->IsHeroic())                          {                              if (state == FAIL && HeroicAttempts) @@ -730,6 +790,8 @@ class instance_icecrown_citadel : public InstanceMapScript                          break;                      case DATA_SINDRAGOSA:                          HandleGameObject(FrostwingSigilGUID, state != DONE); +                        if (state == DONE) +                            CheckLichKingAvailability();                          if (instance->IsHeroic())                          {                              if (state == FAIL && HeroicAttempts) @@ -798,89 +860,14 @@ class instance_icecrown_citadel : public InstanceMapScript                          IsOrbWhispererEligible = data ? true : false;                          break;                      case DATA_SINDRAGOSA_FROSTWYRMS: -                    { -                        if (FrostwyrmCount == 255) -                            return; - -                        if (instance->IsHeroic() && !HeroicAttempts) -                            return; - -                        if (GetBossState(DATA_SINDRAGOSA) == DONE) -                            return; - -                        switch (data) -                        { -                            case 0: -                                if (FrostwyrmCount) -                                { -                                    --FrostwyrmCount; -                                    if (!FrostwyrmCount) -                                    { -                                        instance->LoadGrid(SindragosaSpawnPos.GetPositionX(), SindragosaSpawnPos.GetPositionY()); -                                        if (Creature* boss = instance->SummonCreature(NPC_SINDRAGOSA, SindragosaSpawnPos)) -                                            boss->AI()->DoAction(ACTION_START_FROSTWYRM); -                                    } -                                } -                                break; -                            case 1: -                                ++FrostwyrmCount; -                                break; -                            default: -                                FrostwyrmCount = data; -                                break; -                        } +                        FrostwyrmGUIDs.insert(data);                          break; -                    }                      case DATA_SPINESTALKER: -                    { -                        if (SpinestalkerTrashCount == 255) -                            return; - -                        switch (data) -                        { -                            case 0: -                                if (SpinestalkerTrashCount) -                                { -                                    --SpinestalkerTrashCount; -                                    if (!SpinestalkerTrashCount) -                                        if (Creature* spinestalk = instance->GetCreature(SpinestalkerGUID)) -                                            spinestalk->AI()->DoAction(ACTION_START_FROSTWYRM); -                                } -                                break; -                            case 1: -                                ++SpinestalkerTrashCount; -                                break; -                            default: -                                SpinestalkerTrashCount = data; -                                break; -                        } +                        SpinestalkerTrash.insert(data);                          break; -                    }                      case DATA_RIMEFANG: -                    { -                        if (RimefangTrashCount == 255) -                            return; - -                        switch (data) -                        { -                            case 0: -                                if (RimefangTrashCount) -                                { -                                    --RimefangTrashCount; -                                    if (!RimefangTrashCount) -                                        if (Creature* rime = instance->GetCreature(RimefangGUID)) -                                            rime->AI()->DoAction(ACTION_START_FROSTWYRM); -                                } -                                break; -                            case 1: -                                ++RimefangTrashCount; -                                break; -                            default: -                                RimefangTrashCount = data; -                                break; -                        } +                        RimefangTrash.insert(data);                          break; -                    }                      case DATA_COLDFLAME_JETS:                          ColdflameJetsState = data;                          if (ColdflameJetsState == DONE) @@ -1095,6 +1082,28 @@ class instance_icecrown_citadel : public InstanceMapScript                  return true;              } +            void CheckLichKingAvailability() +            { +                if (GetBossState(DATA_PROFESSOR_PUTRICIDE) == DONE && GetBossState(DATA_BLOOD_QUEEN_LANA_THEL) == DONE && GetBossState(DATA_SINDRAGOSA) == DONE) +                { +                    if (GameObject* teleporter = instance->GetGameObject(TheLichKingTeleportGUID)) +                    { +                        teleporter->SetGoState(GO_STATE_ACTIVE); + +                        std::list<Creature*> stalkers; +                        GetCreatureListWithEntryInGrid(stalkers, teleporter, NPC_INVISIBLE_STALKER, 100.0f); +                        if (stalkers.empty()) +                            return; + +                        stalkers.sort(Trinity::ObjectDistanceOrderPred(teleporter)); +                        stalkers.front()->CastSpell((Unit*)NULL, SPELL_ARTHAS_TELEPORTER_CEREMONY, false); +                        stalkers.pop_front(); +                        for (std::list<Creature*>::iterator itr = stalkers.begin(); itr != stalkers.end(); ++itr) +                            (*itr)->AI()->Reset(); +                    } +                } +            } +              std::string GetSaveData()              {                  OUT_SAVE_INST_DATA; @@ -1276,6 +1285,7 @@ class instance_icecrown_citadel : public InstanceMapScript              uint64 SindragosaGUID;              uint64 SpinestalkerGUID;              uint64 RimefangGUID; +            uint64 TheLichKingTeleportGUID;              uint64 TheLichKingGUID;              uint64 HighlordTirionFordringGUID;              uint64 TerenasMenethilGUID; @@ -1289,9 +1299,9 @@ class instance_icecrown_citadel : public InstanceMapScript              uint64 PillarsUnchainedGUID;              uint32 TeamInInstance;              uint32 ColdflameJetsState; -            uint32 FrostwyrmCount; -            uint32 SpinestalkerTrashCount; -            uint32 RimefangTrashCount; +            std::set<uint32> FrostwyrmGUIDs; +            std::set<uint32> SpinestalkerTrash; +            std::set<uint32> RimefangTrash;              uint32 BloodQuickeningState;              uint32 HeroicAttempts;              uint16 BloodQuickeningMinutes; diff --git a/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp b/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp index 17ed6a79c76..f81ddbf6bf8 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp @@ -15,7 +15,10 @@   * with this program. If not, see <http://www.gnu.org/licenses/>.   */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "SpellScript.h" +#include "SpellAuraEffects.h"  #include "naxxramas.h"  enum Horsemen @@ -26,6 +29,11 @@ enum Horsemen      HORSEMEN_SIR,  }; +enum Spells +{ +    SPELL_MARK_DAMAGE   = 28836 +}; +  enum Events  {      EVENT_NONE, @@ -395,7 +403,63 @@ public:  }; +class spell_four_horsemen_mark : public SpellScriptLoader +{ +    public: +        spell_four_horsemen_mark() : SpellScriptLoader("spell_four_horsemen_mark") { } + +        class spell_four_horsemen_mark_AuraScript : public AuraScript +        { +            PrepareAuraScript(spell_four_horsemen_mark_AuraScript); + +            void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) +            { +                if (Unit* caster = GetCaster()) +                { +                    int32 damage; +                    switch (GetStackAmount()) +                    { +                        case 1: +                            damage = 0; +                            break; +                        case 2: +                            damage = 500; +                            break; +                        case 3: +                            damage = 1000; +                            break; +                        case 4: +                            damage = 1500; +                            break; +                        case 5: +                            damage = 4000; +                            break; +                        case 6: +                            damage = 12000; +                            break; +                        default: +                            damage = 20000 + 1000 * (GetStackAmount() - 7); +                            break; +                    } +                    if (damage) +                        caster->CastCustomSpell(SPELL_MARK_DAMAGE, SPELLVALUE_BASE_POINT0, damage, GetTarget()); +                } +            } + +            void Register() +            { +                AfterEffectApply += AuraEffectApplyFn(spell_four_horsemen_mark_AuraScript::OnApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); +            } +        }; + +        AuraScript* GetAuraScript() const +        { +            return new spell_four_horsemen_mark_AuraScript(); +        } +}; +  void AddSC_boss_four_horsemen()  {      new boss_four_horsemen(); +    new spell_four_horsemen_mark();  } diff --git a/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp b/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp index 8d23de5427c..faaea9c4cae 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp @@ -15,7 +15,11 @@   * with this program. If not, see <http://www.gnu.org/licenses/>.   */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "SpellScript.h" +#include "GridNotifiers.h" +#include "CombatAI.h"  #include "naxxramas.h"  enum Yells @@ -25,6 +29,7 @@ enum Yells      SAY_DEATH                   = -1533042,      SAY_TELEPORT                = -1533043  }; +  //Gothik  enum Spells  { @@ -36,8 +41,11 @@ enum Spells      SPELL_INFORM_LIVE_RIDER     = 27935,      SPELL_INFORM_DEAD_TRAINEE   = 27915,      SPELL_INFORM_DEAD_KNIGHT    = 27931, -    SPELL_INFORM_DEAD_RIDER     = 27937 +    SPELL_INFORM_DEAD_RIDER     = 27937, + +    SPELL_SHADOW_MARK           = 27825  }; +  enum Creatures  {      MOB_LIVE_TRAINEE    = 16124, @@ -585,8 +593,35 @@ class mob_gothik_minion : public CreatureScript          }  }; +class spell_gothik_shadow_bolt_volley : public SpellScriptLoader +{ +    public: +        spell_gothik_shadow_bolt_volley() : SpellScriptLoader("spell_gothik_shadow_bolt_volley") { } + +        class spell_gothik_shadow_bolt_volley_SpellScript : public SpellScript +        { +            PrepareSpellScript(spell_gothik_shadow_bolt_volley_SpellScript); + +            void FilterTargets(std::list<WorldObject*>& targets) +            { +                targets.remove_if(Trinity::UnitAuraCheck(false, SPELL_SHADOW_MARK)); +            } + +            void Register() +            { +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_gothik_shadow_bolt_volley_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); +            } +        }; + +        SpellScript* GetSpellScript() const +        { +            return new spell_gothik_shadow_bolt_volley_SpellScript(); +        } +}; +  void AddSC_boss_gothik()  {      new boss_gothik();      new mob_gothik_minion(); +    new spell_gothik_shadow_bolt_volley();  } diff --git a/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp b/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp index 0a4fdec7222..38c22a93ac4 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp @@ -86,6 +86,7 @@ enum Spells      SPELL_SHADOW_FISURE                                    = 27810,      SPELL_VOID_BLAST                                       = 27812,      SPELL_MANA_DETONATION                                  = 27819, +    SPELL_MANA_DETONATION_DAMAGE                           = 27820,      SPELL_FROST_BLAST                                      = 27808,      SPELL_CHAINS_OF_KELTHUZAD                              = 28410, //28408 script effect      SPELL_KELTHUZAD_CHANNEL                                = 29423, @@ -773,6 +774,46 @@ class npc_kelthuzad_abomination : public CreatureScript          }  }; +class spell_kelthuzad_detonate_mana : public SpellScriptLoader +{ +    public: +        spell_kelthuzad_detonate_mana() : SpellScriptLoader("spell_kelthuzad_detonate_mana") { } + +        class spell_kelthuzad_detonate_mana_AuraScript : public AuraScript +        { +            PrepareAuraScript(spell_kelthuzad_detonate_mana_AuraScript); + +            bool Validate(SpellInfo const* /*spell*/) +            { +                if (!sSpellMgr->GetSpellInfo(SPELL_MANA_DETONATION_DAMAGE)) +                    return false; +                return true; +            } + +            void HandleScript(AuraEffect const* aurEff) +            { +                PreventDefaultAction(); + +                Unit* target = GetTarget(); +                if (int32 mana = int32(target->GetMaxPower(POWER_MANA) / 10)) +                { +                    mana = target->ModifyPower(POWER_MANA, -mana); +                    target->CastCustomSpell(SPELL_MANA_DETONATION_DAMAGE, SPELLVALUE_BASE_POINT0, -mana * 10, target, true, NULL, aurEff); +                } +            } + +            void Register() +            { +                OnEffectPeriodic += AuraEffectPeriodicFn(spell_kelthuzad_detonate_mana_AuraScript::HandleScript, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); +            } +        }; + +        AuraScript* GetAuraScript() const +        { +            return new spell_kelthuzad_detonate_mana_AuraScript(); +        } +}; +  class achievement_just_cant_get_enough : public AchievementCriteriaScript  {     public: @@ -796,5 +837,6 @@ void AddSC_boss_kelthuzad()      new boss_kelthuzad();      new at_kelthuzad_center();      new npc_kelthuzad_abomination(); +    new spell_kelthuzad_detonate_mana();      new achievement_just_cant_get_enough();  } diff --git a/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp b/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp index ccc8e9a5663..e45700ebd72 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp @@ -456,10 +456,10 @@ class spell_thaddius_pos_neg_charge : public SpellScriptLoader                  return GetCaster()->GetTypeId() == TYPEID_UNIT;              } -            void HandleTargets(std::list<Unit*>& targetList) +            void HandleTargets(std::list<WorldObject*>& targets)              {                  uint8 count = 0; -                for (std::list<Unit*>::iterator ihit = targetList.begin(); ihit != targetList.end(); ++ihit) +                for (std::list<WorldObject*>::iterator ihit = targets.begin(); ihit != targets.end(); ++ihit)                      if ((*ihit)->GetGUID() != GetCaster()->GetGUID())                          if (Player* target = (*ihit)->ToPlayer())                              if (target->HasAura(GetTriggeringSpell()->Id)) @@ -498,7 +498,7 @@ class spell_thaddius_pos_neg_charge : public SpellScriptLoader              void Register()              {                  OnEffectHitTarget += SpellEffectFn(spell_thaddius_pos_neg_charge_SpellScript::HandleDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); -                OnUnitTargetSelect += SpellUnitTargetFn(spell_thaddius_pos_neg_charge_SpellScript::HandleTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_thaddius_pos_neg_charge_SpellScript::HandleTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);              }          }; diff --git a/src/server/scripts/Northrend/Nexus/Oculus/boss_varos.cpp b/src/server/scripts/Northrend/Nexus/Oculus/boss_varos.cpp index 19a84fdae84..d200e8bf4bf 100644 --- a/src/server/scripts/Northrend/Nexus/Oculus/boss_varos.cpp +++ b/src/server/scripts/Northrend/Nexus/Oculus/boss_varos.cpp @@ -297,7 +297,7 @@ class spell_varos_energize_core_area_enemy : public SpellScriptLoader          {              PrepareSpellScript(spell_varos_energize_core_area_enemySpellScript) -            void FilterTargets(std::list<Unit*>& targetList) +            void FilterTargets(std::list<WorldObject*>& targets)              {                  Creature* varos = GetCaster()->ToCreature();                  if (!varos) @@ -308,7 +308,7 @@ class spell_varos_energize_core_area_enemy : public SpellScriptLoader                  float orientation = CAST_AI(boss_varos::boss_varosAI, varos->AI())->GetCoreEnergizeOrientation(); -                for (std::list<Unit*>::iterator itr = targetList.begin(); itr != targetList.end();) +                for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end();)                  {                      Position pos;                      (*itr)->GetPosition(&pos); @@ -317,7 +317,7 @@ class spell_varos_energize_core_area_enemy : public SpellScriptLoader                      float diff = fabs(orientation - angle);                      if (diff > 1.0f) -                        itr = targetList.erase(itr); +                        itr = targets.erase(itr);                      else                          ++itr;                  } @@ -325,7 +325,7 @@ class spell_varos_energize_core_area_enemy : public SpellScriptLoader              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_varos_energize_core_area_enemySpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_varos_energize_core_area_enemySpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);              }          }; @@ -344,7 +344,7 @@ class spell_varos_energize_core_area_entry : public SpellScriptLoader          {              PrepareSpellScript(spell_varos_energize_core_area_entrySpellScript) -            void FilterTargets(std::list<Unit*>& targetList) +            void FilterTargets(std::list<WorldObject*>& targets)              {                  Creature* varos = GetCaster()->ToCreature();                  if (!varos) @@ -355,7 +355,7 @@ class spell_varos_energize_core_area_entry : public SpellScriptLoader                  float orientation = CAST_AI(boss_varos::boss_varosAI, varos->AI())->GetCoreEnergizeOrientation(); -                for (std::list<Unit*>::iterator itr = targetList.begin(); itr != targetList.end();) +                for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end();)                  {                      Position pos;                      (*itr)->GetPosition(&pos); @@ -364,7 +364,7 @@ class spell_varos_energize_core_area_entry : public SpellScriptLoader                      float diff = fabs(orientation - angle);                      if (diff > 1.0f) -                        itr = targetList.erase(itr); +                        itr = targets.erase(itr);                      else                          ++itr;                  } @@ -372,7 +372,7 @@ class spell_varos_energize_core_area_entry : public SpellScriptLoader              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_varos_energize_core_area_entrySpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_varos_energize_core_area_entrySpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);              }          }; diff --git a/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp b/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp index 23f55a3033b..0eafd7a7fea 100644 --- a/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp +++ b/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp @@ -47,7 +47,9 @@ enum Drakes      NPC_VERDISA                                   = 27657,      NPC_BELGARISTRASZ                             = 27658, -    NPC_ETERNOS                                   = 27659 +    NPC_ETERNOS                                   = 27659, + +    SPELL_SHOCK_CHARGE                            = 49836,  };  enum Says @@ -210,8 +212,40 @@ public:      }  }; +class spell_gen_stop_time : public SpellScriptLoader +{ +public: +    spell_gen_stop_time() : SpellScriptLoader("spell_gen_stop_time") { } + +    class spell_gen_stop_time_AuraScript : public AuraScript +    { +        PrepareAuraScript(spell_gen_stop_time_AuraScript); + +        void Apply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) +        { +            Unit* caster = GetCaster(); +            if (!caster) +                return; +            Unit* target = GetTarget(); +            for (uint32 i = 0; i < 5; ++i) +                caster->CastSpell(target, SPELL_SHOCK_CHARGE, false); +        } + +        void Register() +        { +            AfterEffectApply += AuraEffectApplyFn(spell_gen_stop_time_AuraScript::Apply, EFFECT_0, SPELL_AURA_MOD_STUN, AURA_EFFECT_HANDLE_REAL); +        } +    }; + +    AuraScript* GetAuraScript() const +    { +        return new spell_gen_stop_time_AuraScript(); +    } +}; +  void AddSC_oculus()  {      new npc_oculus_drake();      new npc_image_belgaristrasz(); +    new spell_gen_stop_time();  } diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_loken.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_loken.cpp index 2e2744baa3c..f42fd87c643 100644 --- a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_loken.cpp +++ b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_loken.cpp @@ -19,11 +19,13 @@  /* ScriptData  SDName: Boss Loken  SD%Complete: 60% -SDComment: Missing intro. Remove hack of Pulsing Shockwave when core supports. Aura is not working (59414) +SDComment: Missing intro.  SDCategory: Halls of Lightning  EndScriptData */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "SpellScript.h"  #include "halls_of_lightning.h"  enum eEnums @@ -73,23 +75,17 @@ public:          InstanceScript* instance; -        bool m_bIsAura; -          uint32 m_uiArcLightning_Timer;          uint32 m_uiLightningNova_Timer; -        uint32 m_uiPulsingShockwave_Timer;          uint32 m_uiResumePulsingShockwave_Timer;          uint32 m_uiHealthAmountModifier;          void Reset()          { -            m_bIsAura = false; -              m_uiArcLightning_Timer = 15000;              m_uiLightningNova_Timer = 20000; -            m_uiPulsingShockwave_Timer = 2000; -            m_uiResumePulsingShockwave_Timer = 15000; +            m_uiResumePulsingShockwave_Timer = 1000;              m_uiHealthAmountModifier = 1; @@ -116,7 +112,10 @@ public:              Talk(SAY_DEATH);              if (instance) +            {                  instance->SetData(TYPE_LOKEN, DONE); +                instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_PULSING_SHOCKWAVE_AURA); +            }          }          void KilledUnit(Unit* /*victim*/) @@ -130,44 +129,13 @@ public:              if (!UpdateVictim())                  return; -            if (m_bIsAura) -            { -                // workaround for PULSING_SHOCKWAVE -                if (m_uiPulsingShockwave_Timer <= uiDiff) -                { -                    Map* map = me->GetMap(); -                    if (map->IsDungeon()) -                    { -                        Map::PlayerList const &PlayerList = map->GetPlayers(); - -                        if (PlayerList.isEmpty()) -                            return; - -                        for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) -                            if (i->getSource() && i->getSource()->isAlive() && i->getSource()->isTargetableForAttack()) -                            { -                                int32 dmg; -                                float m_fDist = me->GetExactDist(i->getSource()->GetPositionX(), i->getSource()->GetPositionY(), i->getSource()->GetPositionZ()); - -                                dmg = DUNGEON_MODE(100, 150); // need to correct damage -                                if (m_fDist > 1.0f) // Further from 1 yard -                                    dmg = int32(dmg*m_fDist); - -                                me->CastCustomSpell(i->getSource(), DUNGEON_MODE(52942, 59837), &dmg, 0, 0, false); -                            } -                    } -                    m_uiPulsingShockwave_Timer = 2000; -                } else m_uiPulsingShockwave_Timer -= uiDiff; -            } -            else +            if (m_uiResumePulsingShockwave_Timer)              {                  if (m_uiResumePulsingShockwave_Timer <= uiDiff)                  { -                    //breaks at movement, can we assume when it's time, this spell is casted and also must stop movement?                      DoCast(me, SPELL_PULSING_SHOCKWAVE_AURA, true); -                    DoCast(me, SPELL_PULSING_SHOCKWAVE_N); // need core support -                    m_bIsAura = true; +                    DoCast(me, SPELL_PULSING_SHOCKWAVE_N, true);                      m_uiResumePulsingShockwave_Timer = 0;                  }                  else @@ -190,7 +158,7 @@ public:                  Talk(EMOTE_NOVA);                  DoCast(me, SPELL_LIGHTNING_NOVA_N); -                m_bIsAura = false; +                me->RemoveAurasDueToSpell(DUNGEON_MODE<uint32>(SPELL_PULSING_SHOCKWAVE_N, SPELL_PULSING_SHOCKWAVE_H));                  m_uiResumePulsingShockwave_Timer = DUNGEON_MODE(5000, 4000); // Pause Pulsing Shockwave aura                  m_uiLightningNova_Timer = urand(20000, 21000);              } @@ -216,7 +184,39 @@ public:  }; +class spell_loken_pulsing_shockwave : public SpellScriptLoader +{ +    public: +        spell_loken_pulsing_shockwave() : SpellScriptLoader("spell_loken_pulsing_shockwave") { } + +        class spell_loken_pulsing_shockwave_SpellScript : public SpellScript +        { +            PrepareSpellScript(spell_loken_pulsing_shockwave_SpellScript); + +            void CalculateDamage(SpellEffIndex /*effIndex*/) +            { +                if (!GetHitUnit()) +                    return; + +                float distance = GetCaster()->GetDistance2d(GetHitUnit()); +                if (distance > 1.0f) +                    SetHitDamage(int32(GetHitDamage() * distance)); +            } + +            void Register() +            { +                OnEffectHitTarget += SpellEffectFn(spell_loken_pulsing_shockwave_SpellScript::CalculateDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); +            } +        }; + +        SpellScript* GetSpellScript() const +        { +            return new spell_loken_pulsing_shockwave_SpellScript(); +        } +}; +  void AddSC_boss_loken()  {      new boss_loken(); +    new spell_loken_pulsing_shockwave();  } diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_krystallus.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_krystallus.cpp index bc57ce21a4d..93bea92503c 100644 --- a/src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_krystallus.cpp +++ b/src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_krystallus.cpp @@ -23,7 +23,9 @@ SDComment:  SDCategory:  Script Data End */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "SpellScript.h"  #include "halls_of_stone.h"  enum Spells @@ -157,17 +159,12 @@ public:              DoScriptText(SAY_KILL, me);          } -        void SpellHitTarget(Unit* target, const SpellInfo* pSpell) +        void SpellHitTarget(Unit* /*target*/, const SpellInfo* pSpell)          {              //this part should be in the core              if (pSpell->Id == SPELL_SHATTER || pSpell->Id == H_SPELL_SHATTER)              { -                //this spell must have custom handling in the core, dealing damage based on distance -                target->CastSpell(target, DUNGEON_MODE(SPELL_SHATTER_EFFECT, H_SPELL_SHATTER_EFFECT), true); - -                if (target->HasAura(SPELL_STONED)) -                    target->RemoveAurasDueToSpell(SPELL_STONED); - +                // todo: we need eventmap to kill this stuff                  //clear this, if we are still performing                  if (bIsSlam)                  { @@ -186,7 +183,74 @@ public:  }; +class spell_krystallus_shatter : public SpellScriptLoader +{ +    public: +        spell_krystallus_shatter() : SpellScriptLoader("spell_krystallus_shatter") { } + +        class spell_krystallus_shatter_SpellScript : public SpellScript +        { +            PrepareSpellScript(spell_krystallus_shatter_SpellScript); + +            void HandleScript(SpellEffIndex /*effIndex*/) +            { +                if (Unit* target = GetHitUnit()) +                { +                    target->RemoveAurasDueToSpell(SPELL_STONED); +                    target->CastSpell((Unit*)NULL, SPELL_SHATTER_EFFECT, true); +                } +            } + +            void Register() +            { +                OnEffectHitTarget += SpellEffectFn(spell_krystallus_shatter_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); +            } +        }; + +        SpellScript* GetSpellScript() const +        { +            return new spell_krystallus_shatter_SpellScript(); +        } +}; + +class spell_krystallus_shatter_effect : public SpellScriptLoader +{ +    public: +        spell_krystallus_shatter_effect() : SpellScriptLoader("spell_krystallus_shatter_effect") { } + +        class spell_krystallus_shatter_effect_SpellScript : public SpellScript +        { +            PrepareSpellScript(spell_krystallus_shatter_effect_SpellScript); + +            void CalculateDamage() +            { +                if (!GetHitUnit()) +                    return; + +                float radius = GetSpellInfo()->Effects[EFFECT_0].CalcRadius(GetCaster()); +                if (!radius) +                    return; + +                float distance = GetCaster()->GetDistance2d(GetHitUnit()); +                if (distance > 1.0f) +                    SetHitDamage(int32(GetHitDamage() * ((radius - distance) / radius))); +            } + +            void Register() +            { +                OnHit += SpellHitFn(spell_krystallus_shatter_effect_SpellScript::CalculateDamage); +            } +        }; + +        SpellScript* GetSpellScript() const +        { +            return new spell_krystallus_shatter_effect_SpellScript(); +        } +}; +  void AddSC_boss_krystallus()  {      new boss_krystallus(); +    new spell_krystallus_shatter(); +    new spell_krystallus_shatter_effect();  } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp index 2af73389ecb..7ee67060f97 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp @@ -1080,7 +1080,7 @@ class NotVictimFilter          {          } -        bool operator()(Unit* target) +        bool operator()(WorldObject* target)          {              return target != _victim;          } @@ -1098,14 +1098,14 @@ class spell_algalon_arcane_barrage : public SpellScriptLoader          {              PrepareSpellScript(spell_algalon_arcane_barrage_SpellScript); -            void SelectTarget(std::list<Unit*>& targets) +            void SelectTarget(std::list<WorldObject*>& targets)              {                  targets.remove_if(NotVictimFilter(GetCaster()));              }              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_algalon_arcane_barrage_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_algalon_arcane_barrage_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);              }          }; @@ -1118,9 +1118,9 @@ class spell_algalon_arcane_barrage : public SpellScriptLoader  class ActiveConstellationFilter  {      public: -        bool operator()(Unit* target) const +        bool operator()(WorldObject* target) const          { -            return target->GetAI()->GetData(0); +            return target->ToUnit() && target->ToUnit()->GetAI() && target->ToUnit()->GetAI()->GetData(0);          }  }; @@ -1133,7 +1133,7 @@ class spell_algalon_trigger_3_adds : public SpellScriptLoader          {              PrepareSpellScript(spell_algalon_trigger_3_adds_SpellScript); -            void SelectTarget(std::list<Unit*>& targets) +            void SelectTarget(std::list<WorldObject*>& targets)              {                  targets.remove_if(ActiveConstellationFilter());              } @@ -1150,7 +1150,7 @@ class spell_algalon_trigger_3_adds : public SpellScriptLoader              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_algalon_trigger_3_adds_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_algalon_trigger_3_adds_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);              }          }; @@ -1202,7 +1202,7 @@ class spell_algalon_big_bang : public SpellScriptLoader                  return true;              } -            void CountTargets(std::list<Unit*>& targets) +            void CountTargets(std::list<WorldObject*>& targets)              {                  _targetCount = targets.size();              } @@ -1215,7 +1215,7 @@ class spell_algalon_big_bang : public SpellScriptLoader              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_algalon_big_bang_SpellScript::CountTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_algalon_big_bang_SpellScript::CountTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);                  AfterCast += SpellCastFn(spell_algalon_big_bang_SpellScript::CheckTargets);              } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp index 472ff153d73..ec3125f7c0a 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp @@ -472,9 +472,9 @@ class npc_feral_defender : public CreatureScript  class SanctumSentryCheck  {      public: -        bool operator() (Unit* unit) +        bool operator()(WorldObject* object) const          { -            if (unit->GetEntry() == NPC_SANCTUM_SENTRY) +            if (object->GetEntry() == NPC_SANCTUM_SENTRY)                  return false;              return true; @@ -490,14 +490,14 @@ class spell_auriaya_strenght_of_the_pack : public SpellScriptLoader          {              PrepareSpellScript(spell_auriaya_strenght_of_the_pack_SpellScript); -            void FilterTargets(std::list<Unit*>& unitList) +            void FilterTargets(std::list<WorldObject*>& unitList)              { -                unitList.remove_if (SanctumSentryCheck()); +                unitList.remove_if(SanctumSentryCheck());              }              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_auriaya_strenght_of_the_pack_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_auriaya_strenght_of_the_pack_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);              }          }; @@ -516,15 +516,15 @@ class spell_auriaya_sentinel_blast : public SpellScriptLoader          {              PrepareSpellScript(spell_auriaya_sentinel_blast_SpellScript); -            void FilterTargets(std::list<Unit*>& unitList) +            void FilterTargets(std::list<WorldObject*>& unitList)              { -                unitList.remove_if (PlayerOrPetCheck()); +                unitList.remove_if(PlayerOrPetCheck());              }              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_auriaya_sentinel_blast_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); -                OnUnitTargetSelect += SpellUnitTargetFn(spell_auriaya_sentinel_blast_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_auriaya_sentinel_blast_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_auriaya_sentinel_blast_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);              }          }; diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp index 0e453eceaa1..9d5adf39817 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp @@ -720,20 +720,18 @@ class boss_flame_leviathan_overload_device : public CreatureScript              {              } -            void DoAction(const int32 param) +            void OnSpellClick(Unit* /*clicker*/)              { -                if (param == EVENT_SPELLCLICK) +                if (me->GetVehicle())                  { -                    if (me->GetVehicle()) +                    me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); +                    me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + +                    if (Unit* player = me->GetVehicle()->GetPassenger(SEAT_PLAYER))                      { -                        me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); -                        me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); -                        if (Unit* player = me->GetVehicle()->GetPassenger(SEAT_PLAYER)) -                        { -                            me->GetVehicleBase()->CastSpell(player, SPELL_SMOKE_TRAIL, true); -                            player->GetMotionMaster()->MoveKnockbackFrom(me->GetVehicleBase()->GetPositionX(), me->GetVehicleBase()->GetPositionY(), 30, 30); -                            player->ExitVehicle(); -                        } +                        me->GetVehicleBase()->CastSpell(player, SPELL_SMOKE_TRAIL, true); +                        player->GetMotionMaster()->MoveKnockbackFrom(me->GetVehicleBase()->GetPositionX(), me->GetVehicleBase()->GetPositionY(), 30, 30); +                        player->ExitVehicle();                      }                  }              } @@ -1232,7 +1230,7 @@ public:      //bool OnGossipSelect(Player* player, Creature* creature, uint32 sender, uint32 action)      //{      //    player->PlayerTalkClass->ClearMenus(); -    //    switch(action) +    //    switch (action)      //    {      //        case GOSSIP_ACTION_INFO_DEF+1:      //            if (player) @@ -1619,7 +1617,7 @@ class FlameLeviathanPursuedTargetSelector      public:          explicit FlameLeviathanPursuedTargetSelector(Unit* unit) : _me(unit) {}; -        bool operator()(Unit* target) const +        bool operator()(WorldObject* target) const          {              //! No players, only vehicles (todo: check if blizzlike)              Creature* creatureTarget = target->ToCreature(); @@ -1667,7 +1665,7 @@ class spell_pursue : public SpellScriptLoader                  return true;              } -            void FilterTargets(std::list<Unit*>& targets) +            void FilterTargets(std::list<WorldObject*>& targets)              {                  targets.remove_if(FlameLeviathanPursuedTargetSelector(GetCaster()));                  if (targets.empty()) @@ -1683,7 +1681,7 @@ class spell_pursue : public SpellScriptLoader                  }              } -            void FilterTargetsSubsequently(std::list<Unit*>& targets) +            void FilterTargetsSubsequently(std::list<WorldObject*>& targets)              {                  targets.clear();                  if (_target) @@ -1710,12 +1708,12 @@ class spell_pursue : public SpellScriptLoader              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_pursue_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); -                OnUnitTargetSelect += SpellUnitTargetFn(spell_pursue_SpellScript::FilterTargetsSubsequently, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_pursue_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_pursue_SpellScript::FilterTargetsSubsequently, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);                  OnEffectHitTarget += SpellEffectFn(spell_pursue_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_APPLY_AURA);              } -            Unit* _target; +            WorldObject* _target;          };          SpellScript* GetSpellScript() const diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_general_vezax.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_general_vezax.cpp index 3556bf188de..8090b9e8a3e 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_general_vezax.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_general_vezax.cpp @@ -51,6 +51,8 @@ enum VezaxSpells      SPELL_SHADOW_CRASH_HIT                       = 62659,      SPELL_SURGE_OF_DARKNESS                      = 62662,      SPELL_SARONITE_VAPORS                        = 63323, +    SPELL_SARONITE_VAPORS_ENERGIZE               = 63337, +    SPELL_SARONITE_VAPORS_DAMAGE                 = 63338,      SPELL_SUMMON_SARONITE_VAPORS                 = 63081,      SPELL_BERSERK                                = 26662, @@ -463,6 +465,45 @@ class spell_mark_of_the_faceless : public SpellScriptLoader          }  }; +class spell_general_vezax_saronite_vapors : public SpellScriptLoader +{ +    public: +        spell_general_vezax_saronite_vapors() : SpellScriptLoader("spell_general_vezax_saronite_vapors") { } + +        class spell_general_vezax_saronite_vapors_AuraScript : public AuraScript +        { +            PrepareAuraScript(spell_general_vezax_saronite_vapors_AuraScript); + +            bool Validate(SpellInfo const* /*spell*/) +            { +                if (!sSpellMgr->GetSpellInfo(SPELL_SARONITE_VAPORS_ENERGIZE) || !sSpellMgr->GetSpellInfo(SPELL_SARONITE_VAPORS_DAMAGE)) +                    return false; +                return true; +            } + +            void HandleEffectApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) +            { +                if (Unit* caster = GetCaster()) +                { +                    int32 mana = int32(aurEff->GetAmount() * pow(2.0f, GetStackAmount())); // mana restore - bp * 2^stackamount +                    int32 damage = mana * 2; +                    caster->CastCustomSpell(GetTarget(), SPELL_SARONITE_VAPORS_ENERGIZE, &mana, NULL, NULL, true); +                    caster->CastCustomSpell(GetTarget(), SPELL_SARONITE_VAPORS_DAMAGE, &damage, NULL, NULL, true); +                } +            } + +            void Register() +            { +                AfterEffectApply += AuraEffectApplyFn(spell_general_vezax_saronite_vapors_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); +            } +        }; + +        AuraScript* GetAuraScript() const +        { +            return new spell_general_vezax_saronite_vapors_AuraScript(); +        } +}; +  class achievement_shadowdodger : public AchievementCriteriaScript  {      public: @@ -509,6 +550,7 @@ void AddSC_boss_general_vezax()      new boss_saronite_animus();      new npc_saronite_vapors();      new spell_mark_of_the_faceless(); +    new spell_general_vezax_saronite_vapors();      new achievement_shadowdodger();      new achievement_smell_saronite();  } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp index d89d640b083..24a9171e29f 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp @@ -354,7 +354,7 @@ class StoneGripTargetSelector : public std::unary_function<Unit*, bool>      public:          StoneGripTargetSelector(Creature* me, Unit const* victim) : _me(me), _victim(victim) {} -        bool operator() (Unit* target) +        bool operator()(WorldObject* target)          {              if (target == _victim && _me->getThreatManager().getThreatList().size() > 1)                  return true; @@ -385,10 +385,10 @@ class spell_ulduar_stone_grip_cast_target : public SpellScriptLoader                  return true;              } -            void FilterTargetsInitial(std::list<Unit*>& unitList) +            void FilterTargetsInitial(std::list<WorldObject*>& unitList)              {                  // Remove "main tank" and non-player targets -                unitList.remove_if (StoneGripTargetSelector(GetCaster()->ToCreature(), GetCaster()->getVictim())); +                unitList.remove_if(StoneGripTargetSelector(GetCaster()->ToCreature(), GetCaster()->getVictim()));                  // Maximum affected targets per difficulty mode                  uint32 maxTargets = 1;                  if (GetSpellInfo()->Id == 63981) @@ -397,7 +397,7 @@ class spell_ulduar_stone_grip_cast_target : public SpellScriptLoader                  // Return a random amount of targets based on maxTargets                  while (maxTargets < unitList.size())                  { -                    std::list<Unit*>::iterator itr = unitList.begin(); +                    std::list<WorldObject*>::iterator itr = unitList.begin();                      advance(itr, urand(0, unitList.size()-1));                      unitList.erase(itr);                  } @@ -406,20 +406,20 @@ class spell_ulduar_stone_grip_cast_target : public SpellScriptLoader                  m_unitList = unitList;              } -            void FillTargetsSubsequential(std::list<Unit*>& unitList) +            void FillTargetsSubsequential(std::list<WorldObject*>& unitList)              {                  unitList = m_unitList;              }              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_ulduar_stone_grip_cast_target_SpellScript::FilterTargetsInitial, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); -                OnUnitTargetSelect += SpellUnitTargetFn(spell_ulduar_stone_grip_cast_target_SpellScript::FillTargetsSubsequential, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY); -                OnUnitTargetSelect += SpellUnitTargetFn(spell_ulduar_stone_grip_cast_target_SpellScript::FillTargetsSubsequential, EFFECT_2, TARGET_UNIT_SRC_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_ulduar_stone_grip_cast_target_SpellScript::FilterTargetsInitial, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_ulduar_stone_grip_cast_target_SpellScript::FillTargetsSubsequential, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_ulduar_stone_grip_cast_target_SpellScript::FillTargetsSubsequential, EFFECT_2, TARGET_UNIT_SRC_AREA_ENEMY);              }              // Shared between effects -            std::list<Unit*> m_unitList; +            std::list<WorldObject*> m_unitList;          };          SpellScript* GetSpellScript() const @@ -598,14 +598,14 @@ class spell_kologarn_stone_shout : public SpellScriptLoader          {              PrepareSpellScript(spell_kologarn_stone_shout_SpellScript); -            void FilterTargets(std::list<Unit*>& unitList) +            void FilterTargets(std::list<WorldObject*>& unitList)              { -                unitList.remove_if (PlayerOrPetCheck()); +                unitList.remove_if(PlayerOrPetCheck());              }              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_kologarn_stone_shout_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_kologarn_stone_shout_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);              }          }; diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp index c7091b42c5a..79e4684f3a6 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp @@ -170,7 +170,11 @@ enum AchievementCredits      ACHIEV_MUST_DECONSTRUCT_FASTER              = 21027,  }; -#define HEART_VEHICLE_SEAT 0 +enum VehicleSeats +{ +    HEART_VEHICLE_SEAT_NORMAL   = 0, +    HEART_VEHICLE_SEAT_EXPOSED  = 1, +};  /*-------------------------------------------------------   * @@ -198,6 +202,8 @@ class boss_xt002 : public CreatureScript                  _Reset();                  me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); +                me->SetReactState(REACT_AGGRESSIVE); +                DoCast(me, SPELL_STAND);                  _healthRecovered = false;                  _gravityBombCasualty = false; @@ -356,15 +362,16 @@ class boss_xt002 : public CreatureScript                  me->AttackStop();                  me->SetReactState(REACT_PASSIVE); -                Unit* heart = me->GetVehicleKit() ? me->GetVehicleKit()->GetPassenger(HEART_VEHICLE_SEAT) : NULL; +                Unit* heart = me->GetVehicleKit() ? me->GetVehicleKit()->GetPassenger(HEART_VEHICLE_SEAT_NORMAL) : NULL;                  if (heart)                  {                      heart->CastSpell(heart, SPELL_HEART_OVERLOAD, false);                      heart->CastSpell(me, SPELL_HEART_LIGHTNING_TETHER, false);                      heart->CastSpell(heart, SPELL_HEART_HEAL_TO_FULL, true);                      heart->CastSpell(heart, SPELL_EXPOSED_HEART, false);    // Channeled - -                    heart->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); +                    heart->ChangeSeat(HEART_VEHICLE_SEAT_EXPOSED, true); +                    heart->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); +                    heart->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_29);                 }                  events.CancelEvent(EVENT_SEARING_LIGHT); @@ -392,11 +399,13 @@ class boss_xt002 : public CreatureScript                  events.RescheduleEvent(EVENT_GRAVITY_BOMB, TIMER_GRAVITY_BOMB);                  events.RescheduleEvent(EVENT_TYMPANIC_TANTRUM, urand(TIMER_TYMPANIC_TANTRUM_MIN, TIMER_TYMPANIC_TANTRUM_MAX)); -                Unit* heart = me->GetVehicleKit() ? me->GetVehicleKit()->GetPassenger(HEART_VEHICLE_SEAT) : NULL; +                Unit* heart = me->GetVehicleKit() ? me->GetVehicleKit()->GetPassenger(HEART_VEHICLE_SEAT_EXPOSED) : NULL;                  if (!heart)                      return; -                heart->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); +                heart->ChangeSeat(HEART_VEHICLE_SEAT_NORMAL, false); +                heart->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); +                heart->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_29);                  heart->RemoveAurasDueToSpell(SPELL_EXPOSED_HEART);                  if (!_hardMode) @@ -425,43 +434,39 @@ class boss_xt002 : public CreatureScript   *        XT-002 HEART   *   *///---------------------------------------------------- +  class mob_xt002_heart : public CreatureScript  {      public:          mob_xt002_heart() : CreatureScript("mob_xt002_heart") { } -        CreatureAI* GetAI(Creature* creature) const +        struct mob_xt002_heartAI : public Scripted_NoMovementAI          { -            return new mob_xt002_heartAI(creature); -        } - -        struct mob_xt002_heartAI : public ScriptedAI -        { -            mob_xt002_heartAI(Creature* creature) : ScriptedAI(creature) +            mob_xt002_heartAI(Creature* creature) : Scripted_NoMovementAI(creature), +                _instance(creature->GetInstanceScript())              { -                _instance = creature->GetInstanceScript(); -                me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_STUNNED | UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); -                me->SetReactState(REACT_PASSIVE);              } -            void DamageTaken(Unit* /*pDone*/, uint32 &damage) +            void UpdateAI(uint32 const /*diff*/) { } + +            void JustDied(Unit* /*killer*/)              { -                Creature* xt002 = me->GetCreature(*me, _instance->GetData64(BOSS_XT002)); +                Creature* xt002 = _instance ? me->GetCreature(*me, _instance->GetData64(BOSS_XT002)) : NULL;                  if (!xt002 || !xt002->AI())                      return; -                if (damage >= me->GetHealth()) -                { -                    xt002->AI()->SetData(DATA_TRANSFERED_HEALTH, me->GetMaxHealth()); -                    xt002->AI()->DoAction(ACTION_ENTER_HARD_MODE); -                    damage = 0; -                } +                xt002->AI()->SetData(DATA_TRANSFERED_HEALTH, me->GetHealth()); +                xt002->AI()->DoAction(ACTION_ENTER_HARD_MODE);              } -            private: -                InstanceScript* _instance; -                uint32 _damageTaken; +        private: +            InstanceScript* _instance;          }; + +        CreatureAI* GetAI(Creature* creature) const +        { +            return new mob_xt002_heartAI(creature); +        }  };  /*------------------------------------------------------- @@ -915,7 +920,7 @@ class spell_xt002_heart_overload_periodic : public SpellScriptLoader                              {                                  uint8 a = urand(0, 4);                                  uint32 spellId = spells[a]; -                                toyPile->CastSpell(toyPile, spellId, true); +                                toyPile->CastSpell(toyPile, spellId, true, NULL, NULL, instance->GetData64(BOSS_XT002));                              }                          }                      } @@ -945,9 +950,9 @@ class spell_xt002_tympanic_tantrum : public SpellScriptLoader          {              PrepareSpellScript(spell_xt002_tympanic_tantrum_SpellScript); -            void FilterTargets(std::list<Unit*>& unitList) +            void FilterTargets(std::list<WorldObject*>& targets)              { -                unitList.remove_if(PlayerOrPetCheck()); +                targets.remove_if(PlayerOrPetCheck());              }              void RecalculateDamage() @@ -957,8 +962,9 @@ class spell_xt002_tympanic_tantrum : public SpellScriptLoader              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_xt002_tympanic_tantrum_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); -                OnUnitTargetSelect += SpellUnitTargetFn(spell_xt002_tympanic_tantrum_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_xt002_tympanic_tantrum_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_xt002_tympanic_tantrum_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY); +                OnHit += SpellHitFn(spell_xt002_tympanic_tantrum_SpellScript::RecalculateDamage);                  OnHit += SpellHitFn(spell_xt002_tympanic_tantrum_SpellScript::RecalculateDamage);              }          }; diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h index d35f0559080..858a82bbe57 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h @@ -268,10 +268,10 @@ GameObjectAI* GetUlduarAI(GameObject* go)  class PlayerOrPetCheck  {      public: -        bool operator() (Unit* unit) +        bool operator()(WorldObject* object) const          { -            if (unit->GetTypeId() != TYPEID_PLAYER) -                if (!unit->ToCreature()->isPet()) +            if (object->GetTypeId() != TYPEID_PLAYER) +                if (!object->ToCreature()->isPet())                      return true;              return false; diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp index 29b8f2e7f48..41a25ce5f76 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp @@ -276,7 +276,7 @@ public:                              arthas->CastSpell(me, SPELL_TRANSFORMING_CHANNEL, false);                              pos.Relocate(me);                              pos.m_positionZ += 8.0f; -                            me->GetMotionMaster()->MoveTakeoff(0, pos, 3.30078125f); +                            me->GetMotionMaster()->MoveTakeoff(0, pos);                              // spectators flee event                              if (instance)                              { @@ -333,7 +333,9 @@ public:                              pos.m_positionX = me->GetHomePosition().GetPositionX();                              pos.m_positionY = me->GetHomePosition().GetPositionY();                              pos.m_positionZ = 90.6065f; -                            me->GetMotionMaster()->MoveLand(0, pos, 6.247422f); +                            me->GetMotionMaster()->MoveLand(0, pos); +                            me->SetDisableGravity(false, true); +                            me->SetHover(true);                              me->SetDisableGravity(false, true);                              me->SetHover(true);                              ++introPhase; @@ -522,12 +524,12 @@ public:      };  }; -class checkRitualTarget +class RitualTargetCheck  {      public: -        explicit checkRitualTarget(Unit* _caster) : caster(_caster) { } +        explicit RitualTargetCheck(Unit* _caster) : caster(_caster) { } -        bool operator() (Unit* unit) +        bool operator() (WorldObject* unit) const          {              if (InstanceScript* instance = caster->GetInstanceScript())                  if (instance->GetData64(DATA_SACRIFICED_PLAYER) == unit->GetGUID()) @@ -549,14 +551,14 @@ class spell_paralyze_pinnacle : public SpellScriptLoader          {              PrepareSpellScript(spell_paralyze_pinnacle_SpellScript); -            void FilterTargets(std::list<Unit*>& unitList) +            void FilterTargets(std::list<WorldObject*>& unitList)              { -                unitList.remove_if(checkRitualTarget(GetCaster())); +                unitList.remove_if(RitualTargetCheck(GetCaster()));              }              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_paralyze_pinnacle_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_paralyze_pinnacle_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);              }          }; diff --git a/src/server/scripts/Northrend/dragonblight.cpp b/src/server/scripts/Northrend/dragonblight.cpp index 4cbe280a9f2..1b339b24549 100644 --- a/src/server/scripts/Northrend/dragonblight.cpp +++ b/src/server/scripts/Northrend/dragonblight.cpp @@ -69,7 +69,106 @@ public:      }  }; +/*###### +## Quest Strengthen the Ancients (12096|12092) +######*/ + +enum StrengthenAncientsMisc +{ +    SAY_WALKER_FRIENDLY = 0, +    SAY_WALKER_ENEMY = 1, +    SAY_LOTHALOR = 0, + +    SPELL_CREATE_ITEM_BARK = 47550, +    SPELL_CONFUSED = 47044, + +    NPC_LOTHALOR = 26321, + +    FACTION_WALKER_ENEMY = 14, +}; + +class spell_q12096_q12092_dummy : public SpellScriptLoader // Strengthen the Ancients: On Interact Dummy to Woodlands Walker +{ +public: +    spell_q12096_q12092_dummy() : SpellScriptLoader("spell_q12096_q12092_dummy") { } + +    class spell_q12096_q12092_dummy_SpellScript : public SpellScript +    { +        PrepareSpellScript(spell_q12096_q12092_dummy_SpellScript); + +        void HandleDummy(SpellEffIndex /*effIndex*/) +        { +            uint32 roll = rand() % 2; + +            Creature* tree = GetHitCreature(); +            Player* player = GetCaster()->ToPlayer(); + +            if (!tree || !player) +                return; + +            tree->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); + +            if (roll == 1) // friendly version +            { +                tree->CastSpell(player, SPELL_CREATE_ITEM_BARK); +                tree->AI()->Talk(SAY_WALKER_FRIENDLY, player->GetGUID()); +                tree->DespawnOrUnsummon(1000); +            } +            else if (roll == 0) // enemy version +            { +                tree->AI()->Talk(SAY_WALKER_ENEMY, player->GetGUID()); +                tree->setFaction(FACTION_WALKER_ENEMY); +                tree->Attack(player, true); +            } +        } + +        void Register() +        { +            OnEffectHitTarget += SpellEffectFn(spell_q12096_q12092_dummy_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); +        } +    }; + +    SpellScript* GetSpellScript() const +    { +        return new spell_q12096_q12092_dummy_SpellScript(); +    } +}; + +class spell_q12096_q12092_bark : public SpellScriptLoader // Bark of the Walkers +{ +public: +    spell_q12096_q12092_bark() : SpellScriptLoader("spell_q12096_q12092_bark") { } + +    class spell_q12096_q12092_bark_SpellScript : public SpellScript +    { +        PrepareSpellScript(spell_q12096_q12092_bark_SpellScript); + +        void HandleDummy(SpellEffIndex /*effIndex*/) +        { +            Creature* lothalor = GetHitCreature(); +            if (!lothalor || lothalor->GetEntry() != NPC_LOTHALOR) +                return; + +            lothalor->AI()->Talk(SAY_LOTHALOR); +            lothalor->RemoveAura(SPELL_CONFUSED); +            lothalor->DespawnOrUnsummon(4000); +        } + +        void Register() +        { +            OnEffectHitTarget += SpellEffectFn(spell_q12096_q12092_bark_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); +        } +    }; + +    SpellScript* GetSpellScript() const +    { +        return new spell_q12096_q12092_bark_SpellScript(); +    } +}; +  void AddSC_dragonblight()  {      new npc_alexstrasza_wr_gate; +    new spell_q12096_q12092_dummy; +    new spell_q12096_q12092_bark;  } diff --git a/src/server/scripts/Northrend/sholazar_basin.cpp b/src/server/scripts/Northrend/sholazar_basin.cpp index 93d0182ea08..afab9b90a4a 100644 --- a/src/server/scripts/Northrend/sholazar_basin.cpp +++ b/src/server/scripts/Northrend/sholazar_basin.cpp @@ -746,6 +746,130 @@ public:      }  }; +/*###### +## Quest Kick, What Kick? (12589) +######*/ + +enum KickWhatKick +{ +    NPC_LUCKY_WILHELM = 28054, +    NPC_APPLE = 28053, +    NPC_DROSTAN = 28328, +    NPC_CRUNCHY = 28346, +    NPC_THICKBIRD = 28093, + +    SPELL_HIT_APPLE = 51331, +    SPELL_MISS_APPLE = 51332, +    SPELL_MISS_BIRD_APPLE = 51366, +    SPELL_APPLE_FALL = 51371, +    SPELL_BIRD_FALL = 51369, + +    EVENT_MISS = 0, +    EVENT_HIT = 1, +    EVENT_MISS_BIRD = 2, + +    SAY_WILHELM_MISS = 0, +    SAY_WILHELM_HIT = 1, +    SAY_DROSTAN_REPLY_MISS = 0, +}; + +class spell_q12589_shoot_rjr : public SpellScriptLoader +{ +public: +    spell_q12589_shoot_rjr() : SpellScriptLoader("spell_q12589_shoot_rjr") { } + +    class spell_q12589_shoot_rjr_SpellScript : public SpellScript +    { +        PrepareSpellScript(spell_q12589_shoot_rjr_SpellScript); + +        SpellCastResult CheckCast() +        { +            if (Unit* target = GetExplTargetUnit()) +                if (target->GetEntry() == NPC_LUCKY_WILHELM) +                    return SPELL_CAST_OK; + +            SetCustomCastResultMessage(SPELL_CUSTOM_ERROR_MUST_TARGET_WILHELM); +            return SPELL_FAILED_CUSTOM_ERROR; +        } + +        void HandleDummy(SpellEffIndex /*effIndex*/) +        { +            uint32 roll = urand(1, 100); + +            uint8 ev; +            if (roll <= 50) +                ev = EVENT_MISS; +            else if (roll <= 83) +                ev = EVENT_HIT; +            else +                ev = EVENT_MISS_BIRD; + +            Unit* shooter = GetCaster(); +            Creature* wilhelm = GetHitUnit()->ToCreature(); +            Creature* apple = shooter->FindNearestCreature(NPC_APPLE, 30); +            Creature* drostan = shooter->FindNearestCreature(NPC_DROSTAN, 30); + +            if (!wilhelm || !apple || !drostan) +                return; + +            switch (ev) +            { +                case EVENT_MISS_BIRD: +                { +                    Creature* crunchy = shooter->FindNearestCreature(NPC_CRUNCHY, 30); +                    Creature* bird = shooter->FindNearestCreature(NPC_THICKBIRD, 30); + +                    if (!bird || !crunchy) +                        ; // fall to EVENT_MISS +                    else +                    { +                        shooter->CastSpell(bird, SPELL_MISS_BIRD_APPLE); +                        bird->CastSpell(bird, SPELL_BIRD_FALL); +                        wilhelm->AI()->Talk(SAY_WILHELM_MISS); +                        drostan->AI()->Talk(SAY_DROSTAN_REPLY_MISS); + +                        bird->Kill(bird); +                        crunchy->GetMotionMaster()->MovePoint(0, bird->GetPositionX(), bird->GetPositionY(), +                            bird->GetMap()->GetWaterOrGroundLevel(bird->GetPositionX(), bird->GetPositionY(), bird->GetPositionZ())); +                        // TODO: Make crunchy perform emote eat when he reaches the bird + +                        break; +                    } +                } +                case EVENT_MISS: +                { +                    shooter->CastSpell(wilhelm, SPELL_MISS_APPLE); +                    wilhelm->AI()->Talk(SAY_WILHELM_MISS); +                    drostan->AI()->Talk(SAY_DROSTAN_REPLY_MISS); +                    break; +                } +                case EVENT_HIT: +                { +                    shooter->CastSpell(apple, SPELL_HIT_APPLE); +                    apple->CastSpell(apple, SPELL_APPLE_FALL); +                    wilhelm->AI()->Talk(SAY_WILHELM_HIT); +                    if (Player* player = shooter->ToPlayer()) +                        player->KilledMonsterCredit(NPC_APPLE, 0); +                    apple->DespawnOrUnsummon(); + +                    break; +                } +            } +        } + +        void Register() +        { +            OnCheckCast += SpellCheckCastFn(spell_q12589_shoot_rjr_SpellScript::CheckCast); +            OnEffectHitTarget += SpellEffectFn(spell_q12589_shoot_rjr_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); +        } +    }; + +    SpellScript* GetSpellScript() const +    { +        return new spell_q12589_shoot_rjr_SpellScript(); +    } +}; +  void AddSC_sholazar_basin()  {      new npc_injured_rainspeaker_oracle(); @@ -756,4 +880,5 @@ void AddSC_sholazar_basin()      new npc_adventurous_dwarf();      new npc_jungle_punch_target();      new spell_q12620_the_lifewarden_wrath(); +    new spell_q12589_shoot_rjr();  } diff --git a/src/server/scripts/Outland/GruulsLair/boss_gruul.cpp b/src/server/scripts/Outland/GruulsLair/boss_gruul.cpp index 0e654ade995..3443103fa70 100644 --- a/src/server/scripts/Outland/GruulsLair/boss_gruul.cpp +++ b/src/server/scripts/Outland/GruulsLair/boss_gruul.cpp @@ -19,11 +19,13 @@  /* ScriptData  SDName: Boss_Gruul  SD%Complete: 60 -SDComment: Ground Slam need further development (knock back effect and shatter effect must be added to the core) +SDComment: Ground Slam need further development (knock back effect must be added to the core)  SDCategory: Gruul's Lair  EndScriptData */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "SpellScript.h"  #include "gruuls_lair.h"  enum eEnums @@ -144,12 +146,7 @@ public:              //this part should be in the core              if (pSpell->Id == SPELL_SHATTER)              { -                //this spell must have custom handling in the core, dealing damage based on distance -                target->CastSpell(target, SPELL_SHATTER_EFFECT, true); - -                if (target->HasAura(SPELL_STONED)) -                    target->RemoveAurasDueToSpell(SPELL_STONED); - +                // todo: use eventmap to kill this stuff                  //clear this, if we are still performing                  if (m_bPerformingGroundSlam)                  { @@ -258,7 +255,83 @@ public:  }; +class spell_gruul_shatter : public SpellScriptLoader +{ +    public: +        spell_gruul_shatter() : SpellScriptLoader("spell_gruul_shatter") { } + +        class spell_gruul_shatter_SpellScript : public SpellScript +        { +            PrepareSpellScript(spell_gruul_shatter_SpellScript); + +            bool Validate(SpellInfo const* /*spell*/) +            { +                if (!sSpellMgr->GetSpellInfo(SPELL_STONED)) +                    return false; +                if (!sSpellMgr->GetSpellInfo(SPELL_SHATTER_EFFECT)) +                    return false; +                return true; +            } + +            void HandleScript(SpellEffIndex /*effIndex*/) +            { +                if (Unit* target = GetHitUnit()) +                { +                    target->RemoveAurasDueToSpell(SPELL_STONED); +                    target->CastSpell((Unit*)NULL, SPELL_SHATTER_EFFECT, true); +                } +            } + +            void Register() +            { +                OnEffectHitTarget += SpellEffectFn(spell_gruul_shatter_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); +            } +        }; + +        SpellScript* GetSpellScript() const +        { +            return new spell_gruul_shatter_SpellScript(); +        } +}; + +class spell_gruul_shatter_effect : public SpellScriptLoader +{ +    public: +        spell_gruul_shatter_effect() : SpellScriptLoader("spell_gruul_shatter_effect") { } + +        class spell_gruul_shatter_effect_SpellScript : public SpellScript +        { +            PrepareSpellScript(spell_gruul_shatter_effect_SpellScript); + +            void CalculateDamage() +            { +                if (!GetHitUnit()) +                    return; + +                float radius = GetSpellInfo()->Effects[EFFECT_0].CalcRadius(GetCaster()); +                if (!radius) +                    return; + +                float distance = GetCaster()->GetDistance2d(GetHitUnit()); +                if (distance > 1.0f) +                    SetHitDamage(int32(GetHitDamage() * ((radius - distance) / radius))); +            } + +            void Register() +            { +                OnHit += SpellHitFn(spell_gruul_shatter_effect_SpellScript::CalculateDamage); +            } +        }; + +        SpellScript* GetSpellScript() const +        { +            return new spell_gruul_shatter_effect_SpellScript(); +        } +}; +  void AddSC_boss_gruul()  {      new boss_gruul(); +    new spell_gruul_shatter(); +    new spell_gruul_shatter_effect();  } diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp index d202fdd2f44..0454274401c 100644 --- a/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp +++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp @@ -518,7 +518,7 @@ class spell_astromancer_wrath_of_the_astromancer : public SpellScriptLoader                  return true;              } -            void CountTargets(std::list<Unit*>& targetList) +            void CountTargets(std::list<WorldObject*>& targetList)              {                  _targetCount = targetList.size();              } @@ -549,7 +549,7 @@ class spell_astromancer_wrath_of_the_astromancer : public SpellScriptLoader              void Register()              {                  OnEffectHitTarget += SpellEffectFn(spell_astromancer_wrath_of_the_astromancer_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); -                OnUnitTargetSelect += SpellUnitTargetFn(spell_astromancer_wrath_of_the_astromancer_SpellScript::CountTargets, EFFECT_0, TARGET_DEST_CASTER_RADIUS); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_astromancer_wrath_of_the_astromancer_SpellScript::CountTargets, EFFECT_0, TARGET_DEST_CASTER_RADIUS);              }          }; diff --git a/src/server/scripts/Outland/TempestKeep/Mechanar/boss_mechano_lord_capacitus.cpp b/src/server/scripts/Outland/TempestKeep/Mechanar/boss_mechano_lord_capacitus.cpp index 3579a7d697b..1cd67065af1 100644 --- a/src/server/scripts/Outland/TempestKeep/Mechanar/boss_mechano_lord_capacitus.cpp +++ b/src/server/scripts/Outland/TempestKeep/Mechanar/boss_mechano_lord_capacitus.cpp @@ -52,10 +52,10 @@ class spell_capacitus_polarity_charge : public SpellScriptLoader                  return true;              } -            void HandleTargets(std::list<Unit*>& targetList) +            void HandleTargets(std::list<WorldObject*>& targetList)              {                  uint8 count = 0; -                for (std::list<Unit*>::iterator ihit = targetList.begin(); ihit != targetList.end(); ++ihit) +                for (std::list<WorldObject*>::iterator ihit = targetList.begin(); ihit != targetList.end(); ++ihit)                      if ((*ihit)->GetGUID() != GetCaster()->GetGUID())                          if (Player* target = (*ihit)->ToPlayer())                              if (target->HasAura(GetTriggeringSpell()->Id)) @@ -88,7 +88,7 @@ class spell_capacitus_polarity_charge : public SpellScriptLoader              void Register()              {                  OnEffectHitTarget += SpellEffectFn(spell_capacitus_polarity_charge_SpellScript::HandleDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); -                OnUnitTargetSelect += SpellUnitTargetFn(spell_capacitus_polarity_charge_SpellScript::HandleTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_capacitus_polarity_charge_SpellScript::HandleTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);              }          }; diff --git a/src/server/scripts/Outland/blades_edge_mountains.cpp b/src/server/scripts/Outland/blades_edge_mountains.cpp index 4ec1d04b6ad..c46757a3956 100644 --- a/src/server/scripts/Outland/blades_edge_mountains.cpp +++ b/src/server/scripts/Outland/blades_edge_mountains.cpp @@ -651,7 +651,7 @@ class npc_simon_bunny : public CreatureScript              {                  _events.Update(diff); -                switch(_events.ExecuteEvent()) +                switch (_events.ExecuteEvent())                  {                      case EVENT_SIMON_PERIODIC_PLAYER_CHECK:                          if (!CheckPlayer()) diff --git a/src/server/scripts/Outland/boss_doomlord_kazzak.cpp b/src/server/scripts/Outland/boss_doomlord_kazzak.cpp index a213713ae1a..96897ae3033 100644 --- a/src/server/scripts/Outland/boss_doomlord_kazzak.cpp +++ b/src/server/scripts/Outland/boss_doomlord_kazzak.cpp @@ -16,7 +16,10 @@   * with this program. If not, see <http://www.gnu.org/licenses/>.   */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "SpellAuraEffects.h" +#include "SpellScript.h"  enum Texts  { @@ -36,6 +39,7 @@ enum Spells      SPELL_THUNDERCLAP           = 36706,      SPELL_VOID_BOLT             = 39329,      SPELL_MARK_OF_KAZZAK        = 32960, +    SPELL_MARK_OF_KAZZAK_DAMAGE = 32961,      SPELL_ENRAGE                = 32964,      SPELL_CAPTURE_SOUL          = 32966,      SPELL_TWISTED_REFLECTION    = 21063, @@ -171,7 +175,55 @@ class boss_doomlord_kazzak : public CreatureScript          }  }; +class spell_mark_of_kazzak : public SpellScriptLoader +{ +    public: +        spell_mark_of_kazzak() : SpellScriptLoader("spell_mark_of_kazzak") { } + +        class spell_mark_of_kazzak_AuraScript : public AuraScript +        { +            PrepareAuraScript(spell_mark_of_kazzak_AuraScript); + +            bool Validate(SpellInfo const* /*spell*/) +            { +                if (!sSpellMgr->GetSpellInfo(SPELL_MARK_OF_KAZZAK_DAMAGE)) +                    return false; +                return true; +            } + +            void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/) +            { +                if (Unit* owner = GetUnitOwner()) +                    amount = CalculatePctU(owner->GetPower(POWER_MANA), 5); +            } + +            void OnPeriodic(AuraEffect const* aurEff) +            { +                Unit* target = GetTarget(); + +                if (target->GetPower(POWER_MANA) == 0) +                { +                    target->CastSpell(target, SPELL_MARK_OF_KAZZAK_DAMAGE, true, NULL, aurEff); +                    // Remove aura +                    SetDuration(0); +                } +            } + +            void Register() +            { +                DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_mark_of_kazzak_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_PERIODIC_MANA_LEECH); +                OnEffectPeriodic += AuraEffectPeriodicFn(spell_mark_of_kazzak_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_MANA_LEECH); +            } +        }; + +        AuraScript* GetAuraScript() const +        { +            return new spell_mark_of_kazzak_AuraScript(); +        } +}; +  void AddSC_boss_doomlordkazzak()  {      new boss_doomlord_kazzak(); +    new spell_mark_of_kazzak();  } diff --git a/src/server/scripts/Outland/netherstorm.cpp b/src/server/scripts/Outland/netherstorm.cpp index afc18c71b92..16dac13d1a9 100644 --- a/src/server/scripts/Outland/netherstorm.cpp +++ b/src/server/scripts/Outland/netherstorm.cpp @@ -777,10 +777,10 @@ public:                  PlayerGUID = who->GetGUID();          } -        void SpellHit(Unit* /*caster*/, const SpellInfo* /*spell*/) -        { -            DoCast(me, SPELL_DE_MATERIALIZE); -        } +        //void SpellHit(Unit* /*caster*/, const SpellInfo* /*spell*/) +        //{ +        //    DoCast(me, SPELL_DE_MATERIALIZE); +        //}          void UpdateAI(const uint32 diff)          { diff --git a/src/server/scripts/Spells/CMakeLists.txt b/src/server/scripts/Spells/CMakeLists.txt index 04dcee9287c..2bb695bd8a9 100644 --- a/src/server/scripts/Spells/CMakeLists.txt +++ b/src/server/scripts/Spells/CMakeLists.txt @@ -24,6 +24,7 @@ set(scripts_STAT_SRCS    Spells/spell_paladin.cpp    Spells/spell_item.cpp    Spells/spell_holiday.cpp +  Spells/spell_pet.cpp  )  message("  -> Prepared: Spells") diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp index 36dcb53ad00..5095092927e 100644 --- a/src/server/scripts/Spells/spell_dk.cpp +++ b/src/server/scripts/Spells/spell_dk.cpp @@ -40,6 +40,8 @@ enum DeathKnightSpells      DK_SPELL_IMPROVED_BLOOD_PRESENCE_TRIGGERED  = 63611,      DK_SPELL_UNHOLY_PRESENCE                    = 48265,      DK_SPELL_IMPROVED_UNHOLY_PRESENCE_TRIGGERED = 63622, +    SPELL_DK_ITEM_T8_MALEE_4P_BONUS             = 64736, +    DK_SPELL_BLACK_ICE_R1                       = 49140,  };  // 50462 - Anti-Magic Shell (on raid member) @@ -111,8 +113,7 @@ class spell_dk_anti_magic_shell_self : public SpellScriptLoader              void CalculateAmount(AuraEffect const* /*aurEff*/, int32 & amount, bool & /*canBeRecalculated*/)              { -                // Set absorbtion amount to unlimited -                amount = -1; +                amount = GetCaster()->CountPctFromMaxHealth(hpPct);              }              void Absorb(AuraEffect* /*aurEff*/, DamageInfo & dmgInfo, uint32 & absorbAmount) @@ -334,16 +335,30 @@ class spell_dk_death_pact : public SpellScriptLoader          {              PrepareSpellScript(spell_dk_death_pact_SpellScript); -            void FilterTargets(std::list<Unit*>& unitList) +            SpellCastResult CheckCast() +            { +                // Check if we have valid targets, otherwise skip spell casting here +                if (Player* player = GetCaster()->ToPlayer()) +                    for (Unit::ControlList::const_iterator itr = player->m_Controlled.begin(); itr != player->m_Controlled.end(); ++itr) +                        if (Creature* undeadPet = (*itr)->ToCreature()) +                            if (undeadPet->isAlive() && +                                undeadPet->GetOwnerGUID() == player->GetGUID() && +                                undeadPet->GetCreatureType() == CREATURE_TYPE_UNDEAD && +                                undeadPet->IsWithinDist(player, 100.0f, false)) +                                return SPELL_CAST_OK; + +                return SPELL_FAILED_NO_PET; +            } + +            void FilterTargets(std::list<WorldObject*>& unitList)              {                  Unit* unit_to_add = NULL; -                for (std::list<Unit*>::iterator itr = unitList.begin(); itr != unitList.end(); ++itr) +                for (std::list<WorldObject*>::iterator itr = unitList.begin(); itr != unitList.end(); ++itr)                  { -                    if ((*itr)->GetTypeId() == TYPEID_UNIT -                        && (*itr)->GetOwnerGUID() == GetCaster()->GetGUID() -                        && (*itr)->ToCreature()->GetCreatureTemplate()->type == CREATURE_TYPE_UNDEAD) +                    if (Unit* unit = (*itr)->ToUnit()) +                    if (unit->GetOwnerGUID() == GetCaster()->GetGUID() && unit->GetCreatureType() == CREATURE_TYPE_UNDEAD)                      { -                        unit_to_add = (*itr); +                        unit_to_add = unit;                          break;                      }                  } @@ -351,18 +366,12 @@ class spell_dk_death_pact : public SpellScriptLoader                  unitList.clear();                  if (unit_to_add)                      unitList.push_back(unit_to_add); -                else -                { -                    // Pet not found - remove cooldown -                    if (Player* modOwner = GetCaster()->GetSpellModOwner()) -                        modOwner->RemoveSpellCooldown(GetSpellInfo()->Id, true); -                    FinishCast(SPELL_FAILED_NO_PET); -                }              }              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_dk_death_pact_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_DEST_AREA_ALLY); +                OnCheckCast += SpellCheckCastFn(spell_dk_death_pact_SpellScript::CheckCast); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_dk_death_pact_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_DEST_AREA_ALLY);              }          }; @@ -381,6 +390,13 @@ class spell_dk_scourge_strike : public SpellScriptLoader          class spell_dk_scourge_strike_SpellScript : public SpellScript          {              PrepareSpellScript(spell_dk_scourge_strike_SpellScript); +            float multiplier; + +            bool Load() +            { +                multiplier = 1.0f; +                return true; +            }              bool Validate(SpellInfo const* /*spellEntry*/)              { @@ -394,7 +410,23 @@ class spell_dk_scourge_strike : public SpellScriptLoader                  Unit* caster = GetCaster();                  if (Unit* unitTarget = GetHitUnit())                  { -                    int32 bp = CalculatePctN(GetHitDamage(), GetEffectValue() * unitTarget->GetDiseasesByCaster(caster->GetGUID())); +                    multiplier = (GetEffectValue() * unitTarget->GetDiseasesByCaster(caster->GetGUID()) / 100.f); +                    // Death Knight T8 Melee 4P Bonus +                    if (AuraEffect const* aurEff = caster->GetAuraEffect(SPELL_DK_ITEM_T8_MALEE_4P_BONUS, EFFECT_0)) +                        AddPctF(multiplier, aurEff->GetAmount()); +                } +            } + +            void HandleAfterHit() +            { +                Unit* caster = GetCaster(); +                if (Unit* unitTarget = GetHitUnit()) +                { +                    int32 bp = GetHitDamage() * multiplier; + +                    if (AuraEffect* aurEff = caster->GetAuraEffectOfRankedSpell(DK_SPELL_BLACK_ICE_R1, EFFECT_0)) +                        AddPctN(bp, aurEff->GetAmount()); +                      caster->CastCustomSpell(unitTarget, DK_SPELL_SCOURGE_STRIKE_TRIGGERED, &bp, NULL, NULL, true);                  }              } @@ -402,6 +434,7 @@ class spell_dk_scourge_strike : public SpellScriptLoader              void Register()              {                  OnEffectHitTarget += SpellEffectFn(spell_dk_scourge_strike_SpellScript::HandleDummy, EFFECT_2, SPELL_EFFECT_DUMMY); +                AfterHit += SpellHitFn(spell_dk_scourge_strike_SpellScript::HandleAfterHit);              }          }; @@ -588,7 +621,7 @@ public:              if (!target->HasAura(DK_SPELL_BLOOD_PRESENCE) && !target->HasAura(DK_SPELL_IMPROVED_BLOOD_PRESENCE_TRIGGERED))              {                  int32 basePoints1 = aurEff->GetAmount(); -                target->CastCustomSpell(target, 63611, NULL, &basePoints1, NULL, true, 0, aurEff); +                target->CastCustomSpell(target, DK_SPELL_IMPROVED_BLOOD_PRESENCE_TRIGGERED, NULL, &basePoints1, NULL, true, 0, aurEff);              }          } @@ -723,14 +756,14 @@ class spell_dk_death_coil : public SpellScriptLoader          {              PrepareSpellScript(spell_dk_death_coil_SpellScript); -            bool Validate(SpellInfo const* /*SpellEntry*/) +            bool Validate(SpellInfo const* /*spell*/)              {                  if (!sSpellMgr->GetSpellInfo(SPELL_DEATH_COIL_DAMAGE) || !sSpellMgr->GetSpellInfo(SPELL_DEATH_COIL_HEAL))                      return false;                  return true;              } -            void HandleDummy(SpellEffIndex /* effIndex */) +            void HandleDummy(SpellEffIndex /*effIndex*/)              {                  int32 damage = GetEffectValue();                  Unit* caster = GetCaster(); diff --git a/src/server/scripts/Spells/spell_druid.cpp b/src/server/scripts/Spells/spell_druid.cpp index 286bec6abab..f34e9e772f3 100644 --- a/src/server/scripts/Spells/spell_druid.cpp +++ b/src/server/scripts/Spells/spell_druid.cpp @@ -28,7 +28,11 @@  enum DruidSpells  {      DRUID_INCREASED_MOONFIRE_DURATION   = 38414, -    DRUID_NATURES_SPLENDOR              = 57865 +    DRUID_NATURES_SPLENDOR              = 57865, +    DRUID_LIFEBLOOM_FINAL_HEAL          = 33778, +    DRUID_LIFEBLOOM_ENERGIZE            = 64372, +    DRUID_SURVIVAL_INSTINCTS            = 50322, +    DRUID_SAVAGE_ROAR                   = 62071  };  // 54846 Glyph of Starfire @@ -154,7 +158,7 @@ class spell_dru_primal_tenacity : public SpellScriptLoader              void Absorb(AuraEffect* /*aurEff*/, DamageInfo & dmgInfo, uint32 & absorbAmount)              {                  // reduces all damage taken while Stunned in Cat Form -                if (GetTarget()->GetShapeshiftForm() == FORM_CAT && GetTarget()->GetUInt32Value(UNIT_FIELD_FLAGS) & (UNIT_FLAG_STUNNED) && GetTarget()->HasAuraWithMechanic(1<<MECHANIC_STUN)) +                if (GetTarget()->GetShapeshiftForm() == FORM_CAT && GetTarget()->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED) && GetTarget()->HasAuraWithMechanic(1<<MECHANIC_STUN))                      absorbAmount = CalculatePctN(dmgInfo.GetDamage(), absorbPct);              } @@ -228,37 +232,37 @@ class spell_dru_t10_restoration_4p_bonus : public SpellScriptLoader                  return GetCaster()->GetTypeId() == TYPEID_PLAYER;              } -            void FilterTargets(std::list<Unit*>& unitList) +            void FilterTargets(std::list<WorldObject*>& targets)              {                  if (!GetCaster()->ToPlayer()->GetGroup())                  { -                    unitList.clear(); -                    unitList.push_back(GetCaster()); +                    targets.clear(); +                    targets.push_back(GetCaster());                  }                  else                  { -                    unitList.remove(GetExplTargetUnit()); +                    targets.remove(GetExplTargetUnit());                      std::list<Unit*> tempTargets; -                    for (std::list<Unit*>::const_iterator itr = unitList.begin(); itr != unitList.end(); ++itr) -                        if ((*itr)->GetTypeId() == TYPEID_PLAYER && GetCaster()->IsInRaidWith(*itr)) -                            tempTargets.push_back(*itr); +                    for (std::list<WorldObject*>::const_iterator itr = targets.begin(); itr != targets.end(); ++itr) +                        if ((*itr)->GetTypeId() == TYPEID_PLAYER && GetCaster()->IsInRaidWith((*itr)->ToUnit())) +                            tempTargets.push_back((*itr)->ToUnit());                      if (tempTargets.empty())                      { -                        unitList.clear(); +                        targets.clear();                          FinishCast(SPELL_FAILED_DONT_REPORT);                          return;                      }                      Unit* target = Trinity::Containers::SelectRandomContainerElement(tempTargets); -                    unitList.clear(); -                    unitList.push_back(target); +                    targets.clear(); +                    targets.push_back(target);                  }              }              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_dru_t10_restoration_4p_bonus_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ALLY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_dru_t10_restoration_4p_bonus_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ALLY);              }          }; @@ -277,14 +281,14 @@ class spell_dru_starfall_aoe : public SpellScriptLoader          {              PrepareSpellScript(spell_dru_starfall_aoe_SpellScript); -            void FilterTargets(std::list<Unit*>& unitList) +            void FilterTargets(std::list<WorldObject*>& targets)              { -                unitList.remove(GetExplTargetUnit()); +                targets.remove(GetExplTargetUnit());              }              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_dru_starfall_aoe_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_dru_starfall_aoe_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);              }          }; @@ -337,7 +341,12 @@ class spell_dru_starfall_dummy : public SpellScriptLoader          {              PrepareSpellScript(spell_dru_starfall_dummy_SpellScript); -            void HandleDummy(SpellEffIndex /* effIndex */) +            void FilterTargets(std::list<WorldObject*>& targets) +            { +                Trinity::Containers::RandomResizeList(targets, 2); +            } + +            void HandleDummy(SpellEffIndex /*effIndex*/)              {                  Unit* caster = GetCaster();                  // Shapeshifting into an animal form or mounting cancels the effect @@ -348,15 +357,16 @@ class spell_dru_starfall_dummy : public SpellScriptLoader                      return;                  } -                //Any effect which causes you to lose control of your character will supress the starfall effect. +                // Any effect which causes you to lose control of your character will supress the starfall effect.                  if (caster->HasUnitState(UNIT_STATE_CONTROLLED))                      return; -                caster->CastSpell(GetHitUnit(), GetEffectValue(), true); +                caster->CastSpell(GetHitUnit(), uint32(GetEffectValue()), true);              }              void Register()              { +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_dru_starfall_dummy_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);                  OnEffectHitTarget += SpellEffectFn(spell_dru_starfall_dummy_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);              }          }; @@ -367,6 +377,244 @@ class spell_dru_starfall_dummy : public SpellScriptLoader          }  }; +class spell_dru_lifebloom : public SpellScriptLoader +{ +    public: +        spell_dru_lifebloom() : SpellScriptLoader("spell_dru_lifebloom") { } + +        class spell_dru_lifebloom_AuraScript : public AuraScript +        { +            PrepareAuraScript(spell_dru_lifebloom_AuraScript); + +            bool Validate(SpellInfo const* /*spell*/) +            { +                if (!sSpellMgr->GetSpellInfo(DRUID_LIFEBLOOM_FINAL_HEAL)) +                    return false; +                if (!sSpellMgr->GetSpellInfo(DRUID_LIFEBLOOM_ENERGIZE)) +                    return false; +                return true; +            } + +            void AfterRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) +            { +                // Final heal only on duration end +                if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE) +                    return; + +                // final heal +                int32 stack = GetStackAmount(); +                int32 healAmount = aurEff->GetAmount(); +                if (Unit* caster = GetCaster()) +                { +                    healAmount = caster->SpellHealingBonusDone(GetTarget(), GetSpellInfo(), healAmount, HEAL, stack); +                    healAmount = GetTarget()->SpellHealingBonusTaken(caster, GetSpellInfo(), healAmount, HEAL, stack); + +                    GetTarget()->CastCustomSpell(GetTarget(), DRUID_LIFEBLOOM_FINAL_HEAL, &healAmount, NULL, NULL, true, NULL, aurEff, GetCasterGUID()); + +                    // restore mana +                    int32 returnMana = CalculatePctU(caster->GetCreateMana(), GetSpellInfo()->ManaCostPercentage) * stack / 2; +                    caster->CastCustomSpell(caster, DRUID_LIFEBLOOM_ENERGIZE, &returnMana, NULL, NULL, true, NULL, aurEff, GetCasterGUID()); +                    return; +                } + +                GetTarget()->CastCustomSpell(GetTarget(), DRUID_LIFEBLOOM_FINAL_HEAL, &healAmount, NULL, NULL, true, NULL, aurEff, GetCasterGUID()); +            } + +            void HandleDispel(DispelInfo* dispelInfo) +            { +                if (Unit* target = GetUnitOwner()) +                { +                    if (AuraEffect const* aurEff = GetEffect(EFFECT_1)) +                    { +                        // final heal +                        int32 healAmount = aurEff->GetAmount(); +                        if (Unit* caster = GetCaster()) +                        { +                            healAmount = caster->SpellHealingBonusDone(target, GetSpellInfo(), healAmount, HEAL, dispelInfo->GetRemovedCharges()); +                            healAmount = target->SpellHealingBonusTaken(caster, GetSpellInfo(), healAmount, HEAL, dispelInfo->GetRemovedCharges()); +                            target->CastCustomSpell(target, DRUID_LIFEBLOOM_FINAL_HEAL, &healAmount, NULL, NULL, true, NULL, NULL, GetCasterGUID()); + +                            // restore mana +                            int32 returnMana = CalculatePctU(caster->GetCreateMana(), GetSpellInfo()->ManaCostPercentage) * dispelInfo->GetRemovedCharges() / 2; +                            caster->CastCustomSpell(caster, DRUID_LIFEBLOOM_ENERGIZE, &returnMana, NULL, NULL, true, NULL, NULL, GetCasterGUID()); +                            return; +                        } + +                        target->CastCustomSpell(target, DRUID_LIFEBLOOM_FINAL_HEAL, &healAmount, NULL, NULL, true, NULL, NULL, GetCasterGUID()); +                    } +                } +            } + +            void Register() +            { +                AfterEffectRemove += AuraEffectRemoveFn(spell_dru_lifebloom_AuraScript::AfterRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); +                AfterDispel += AuraDispelFn(spell_dru_lifebloom_AuraScript::HandleDispel); +            } +        }; + +        AuraScript* GetAuraScript() const +        { +            return new spell_dru_lifebloom_AuraScript(); +        } +}; + +class spell_dru_predatory_strikes : public SpellScriptLoader +{ +    public: +        spell_dru_predatory_strikes() : SpellScriptLoader("spell_dru_predatory_strikes") { } + +        class spell_dru_predatory_strikes_AuraScript : public AuraScript +        { +            PrepareAuraScript(spell_dru_predatory_strikes_AuraScript); + +            void UpdateAmount(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) +            { +                if (Player* target = GetTarget()->ToPlayer()) +                    target->UpdateAttackPowerAndDamage(); +            } + +            void Register() +            { +                AfterEffectApply += AuraEffectApplyFn(spell_dru_predatory_strikes_AuraScript::UpdateAmount, EFFECT_ALL, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK); +                AfterEffectRemove += AuraEffectRemoveFn(spell_dru_predatory_strikes_AuraScript::UpdateAmount, EFFECT_ALL, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK); +            } +        }; + +        AuraScript* GetAuraScript() const +        { +            return new spell_dru_predatory_strikes_AuraScript(); +        } +}; + +class spell_dru_savage_roar : public SpellScriptLoader +{ +    public: +        spell_dru_savage_roar() : SpellScriptLoader("spell_dru_savage_roar") { } + +        class spell_dru_savage_roar_SpellScript : public SpellScript +        { +            PrepareSpellScript(spell_dru_savage_roar_SpellScript); + +            SpellCastResult CheckCast() +            { +                Unit* caster = GetCaster(); +                if (caster->GetShapeshiftForm() != FORM_CAT) +                    return SPELL_FAILED_ONLY_SHAPESHIFT; + +                return SPELL_CAST_OK; +            } + +            void Register() +            { +                OnCheckCast += SpellCheckCastFn(spell_dru_savage_roar_SpellScript::CheckCast); +            } +        }; + +        class spell_dru_savage_roar_AuraScript : public AuraScript +        { +            PrepareAuraScript(spell_dru_savage_roar_AuraScript); + +            bool Validate(SpellInfo const* /*spell*/) +            { +                if (!sSpellMgr->GetSpellInfo(DRUID_SAVAGE_ROAR)) +                    return false; +                return true; +            } + +            void AfterApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) +            { +                Unit* target = GetTarget(); +                target->CastSpell(target, DRUID_SAVAGE_ROAR, true, NULL, aurEff, GetCasterGUID()); +            } + +            void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) +            { +                GetTarget()->RemoveAurasDueToSpell(DRUID_SAVAGE_ROAR); +            } + +            void Register() +            { +                AfterEffectApply += AuraEffectApplyFn(spell_dru_savage_roar_AuraScript::AfterApply, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); +                AfterEffectRemove += AuraEffectRemoveFn(spell_dru_savage_roar_AuraScript::AfterRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); +            } +        }; + +        SpellScript* GetSpellScript() const +        { +            return new spell_dru_savage_roar_SpellScript(); +        } + +        AuraScript* GetAuraScript() const +        { +            return new spell_dru_savage_roar_AuraScript(); +        } +}; + +class spell_dru_survival_instincts : public SpellScriptLoader +{ +    public: +        spell_dru_survival_instincts() : SpellScriptLoader("spell_dru_survival_instincts") { } + +        class spell_dru_survival_instincts_SpellScript : public SpellScript +        { +            PrepareSpellScript(spell_dru_survival_instincts_SpellScript); + +            SpellCastResult CheckCast() +            { +                Unit* caster = GetCaster(); +                if (!caster->IsInFeralForm()) +                    return SPELL_FAILED_ONLY_SHAPESHIFT; + +                return SPELL_CAST_OK; +            } + +            void Register() +            { +                OnCheckCast += SpellCheckCastFn(spell_dru_survival_instincts_SpellScript::CheckCast); +            } +        }; + +        class spell_dru_survival_instincts_AuraScript : public AuraScript +        { +            PrepareAuraScript(spell_dru_survival_instincts_AuraScript); + +            bool Validate(SpellInfo const* /*spell*/) +            { +                if (!sSpellMgr->GetSpellInfo(DRUID_SURVIVAL_INSTINCTS)) +                    return false; +                return true; +            } + +            void AfterApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) +            { +                Unit* target = GetTarget(); +                int32 bp0 = target->CountPctFromMaxHealth(aurEff->GetAmount()); +                target->CastCustomSpell(target, DRUID_SURVIVAL_INSTINCTS, &bp0, NULL, NULL, true); +            } + +            void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) +            { +                GetTarget()->RemoveAurasDueToSpell(DRUID_SURVIVAL_INSTINCTS); +            } + +            void Register() +            { +                AfterEffectApply += AuraEffectApplyFn(spell_dru_survival_instincts_AuraScript::AfterApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK); +                AfterEffectRemove += AuraEffectRemoveFn(spell_dru_survival_instincts_AuraScript::AfterRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK); +            } +        }; + +        SpellScript* GetSpellScript() const +        { +            return new spell_dru_survival_instincts_SpellScript(); +        } + +        AuraScript* GetAuraScript() const +        { +            return new spell_dru_survival_instincts_AuraScript(); +        } +}; +  void AddSC_druid_spell_scripts()  {      new spell_dru_glyph_of_starfire(); @@ -377,4 +625,8 @@ void AddSC_druid_spell_scripts()      new spell_dru_starfall_aoe();      new spell_dru_swift_flight_passive();      new spell_dru_starfall_dummy(); +    new spell_dru_lifebloom(); +    new spell_dru_predatory_strikes(); +    new spell_dru_savage_roar(); +    new spell_dru_survival_instincts();  } diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index 0c879cfb029..a35d243593e 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -239,7 +239,7 @@ class spell_gen_parachute : public SpellScriptLoader          {              PrepareAuraScript(spell_gen_parachute_AuraScript); -            bool Validate(SpellInfo const* /*spellEntry*/) +            bool Validate(SpellInfo const* /*spell*/)              {                  if (!sSpellMgr->GetSpellInfo(SPELL_PARACHUTE) || !sSpellMgr->GetSpellInfo(SPELL_PARACHUTE_BUFF))                      return false; @@ -660,22 +660,16 @@ class spell_pvp_trinket_wotf_shared_cd : public SpellScriptLoader                  return true;              } -            void HandleScript(SpellEffIndex /*effIndex*/) +            void HandleScript()              { -                Player* caster = GetCaster()->ToPlayer(); -                SpellInfo const* spellInfo = GetSpellInfo(); -                caster->AddSpellCooldown(spellInfo->Id, 0, time(NULL) + sSpellMgr->GetSpellInfo(SPELL_WILL_OF_THE_FORSAKEN_COOLDOWN_TRIGGER)->GetRecoveryTime() / IN_MILLISECONDS); -                WorldPacket data(SMSG_SPELL_COOLDOWN, 8+1+4); -                data << uint64(caster->GetGUID()); -                data << uint8(0); -                data << uint32(spellInfo->Id); -                data << uint32(0); -                caster->GetSession()->SendPacket(&data); +                // This is only needed because spells cast from spell_linked_spell are triggered by default +                // Spell::SendSpellCooldown() skips all spells with TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD +                GetCaster()->ToPlayer()->AddSpellAndCategoryCooldowns(GetSpellInfo(), GetCastItem() ? GetCastItem()->GetEntry() : 0, GetSpell());              }              void Register()              { -                OnEffectHit += SpellEffectFn(spell_pvp_trinket_wotf_shared_cd_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); +                AfterCast += SpellCastFn(spell_pvp_trinket_wotf_shared_cd_SpellScript::HandleScript);              }          }; @@ -2052,9 +2046,9 @@ class spell_gen_defend : public SpellScriptLoader      public:          spell_gen_defend() : SpellScriptLoader("spell_gen_defend") { } -        class spell_gen_defendAuraScript : public AuraScript +        class spell_gen_defend_AuraScript : public AuraScript          { -            PrepareAuraScript(spell_gen_defendAuraScript); +            PrepareAuraScript(spell_gen_defend_AuraScript);              bool Validate(SpellInfo const* /*spellEntry*/)              { @@ -2103,26 +2097,26 @@ class spell_gen_defend : public SpellScriptLoader                  // Defend spells casted by NPCs (add visuals)                  if (spell->Effects[EFFECT_0].ApplyAuraName == SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN)                  { -                    AfterEffectApply += AuraEffectApplyFn(spell_gen_defendAuraScript::RefreshVisualShields, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); -                    OnEffectRemove += AuraEffectRemoveFn(spell_gen_defendAuraScript::RemoveVisualShields, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK); +                    AfterEffectApply += AuraEffectApplyFn(spell_gen_defend_AuraScript::RefreshVisualShields, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); +                    OnEffectRemove += AuraEffectRemoveFn(spell_gen_defend_AuraScript::RemoveVisualShields, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK);                  }                  // Remove Defend spell from player when he dismounts                  if (spell->Effects[EFFECT_2].ApplyAuraName == SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN) -                    OnEffectRemove += AuraEffectRemoveFn(spell_gen_defendAuraScript::RemoveDummyFromDriver, EFFECT_2, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL); +                    OnEffectRemove += AuraEffectRemoveFn(spell_gen_defend_AuraScript::RemoveDummyFromDriver, EFFECT_2, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL);                  // Defend spells casted by players (add/remove visuals)                  if (spell->Effects[EFFECT_1].ApplyAuraName == SPELL_AURA_DUMMY)                  { -                    AfterEffectApply += AuraEffectApplyFn(spell_gen_defendAuraScript::RefreshVisualShields, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); -                    OnEffectRemove += AuraEffectRemoveFn(spell_gen_defendAuraScript::RemoveVisualShields, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK); +                    AfterEffectApply += AuraEffectApplyFn(spell_gen_defend_AuraScript::RefreshVisualShields, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); +                    OnEffectRemove += AuraEffectRemoveFn(spell_gen_defend_AuraScript::RemoveVisualShields, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK);                  }              }          };          AuraScript* GetAuraScript() const          { -            return new spell_gen_defendAuraScript(); +            return new spell_gen_defend_AuraScript();          }  }; @@ -2326,9 +2320,9 @@ class spell_gen_on_tournament_mount : public SpellScriptLoader      public:          spell_gen_on_tournament_mount() : SpellScriptLoader("spell_gen_on_tournament_mount") { } -        class spell_gen_on_tournament_mountAuraScript : public AuraScript +        class spell_gen_on_tournament_mount_AuraScript : public AuraScript          { -            PrepareAuraScript(spell_gen_on_tournament_mountAuraScript); +            PrepareAuraScript(spell_gen_on_tournament_mount_AuraScript);              uint32 _pennantSpellId; @@ -2468,14 +2462,14 @@ class spell_gen_on_tournament_mount : public SpellScriptLoader              void Register()              { -                AfterEffectApply += AuraEffectApplyFn(spell_gen_on_tournament_mountAuraScript::HandleApplyEffect, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); -                OnEffectRemove += AuraEffectRemoveFn(spell_gen_on_tournament_mountAuraScript::HandleRemoveEffect, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); +                AfterEffectApply += AuraEffectApplyFn(spell_gen_on_tournament_mount_AuraScript::HandleApplyEffect, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); +                OnEffectRemove += AuraEffectRemoveFn(spell_gen_on_tournament_mount_AuraScript::HandleRemoveEffect, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);              }          };          AuraScript* GetAuraScript() const          { -            return new spell_gen_on_tournament_mountAuraScript(); +            return new spell_gen_on_tournament_mount_AuraScript();          }  }; @@ -2484,9 +2478,9 @@ class spell_gen_tournament_pennant : public SpellScriptLoader      public:          spell_gen_tournament_pennant() : SpellScriptLoader("spell_gen_tournament_pennant") { } -        class spell_gen_tournament_pennantAuraScript : public AuraScript +        class spell_gen_tournament_pennant_AuraScript : public AuraScript          { -            PrepareAuraScript(spell_gen_tournament_pennantAuraScript); +            PrepareAuraScript(spell_gen_tournament_pennant_AuraScript);              bool Load()              { @@ -2502,13 +2496,13 @@ class spell_gen_tournament_pennant : public SpellScriptLoader              void Register()              { -                OnEffectApply += AuraEffectApplyFn(spell_gen_tournament_pennantAuraScript::HandleApplyEffect, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); +                OnEffectApply += AuraEffectApplyFn(spell_gen_tournament_pennant_AuraScript::HandleApplyEffect, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);              }          };          AuraScript* GetAuraScript() const          { -            return new spell_gen_tournament_pennantAuraScript(); +            return new spell_gen_tournament_pennant_AuraScript();          }  }; @@ -2688,6 +2682,401 @@ public:      }  }; +class spell_gen_touch_the_nightmare : public SpellScriptLoader +{ +public: +    spell_gen_touch_the_nightmare() : SpellScriptLoader("spell_gen_touch_the_nightmare") { } + +    class spell_gen_touch_the_nightmare_SpellScript : public SpellScript +    { +        PrepareSpellScript(spell_gen_touch_the_nightmare_SpellScript); + +        void HandleDamageCalc(SpellEffIndex /*effIndex*/) +        { +            uint32 bp = GetCaster()->GetMaxHealth() * 0.3f; +            SetHitDamage(bp); +        } + +        void Register() +        { +            OnEffectHitTarget += SpellEffectFn(spell_gen_touch_the_nightmare_SpellScript::HandleDamageCalc, EFFECT_2, SPELL_EFFECT_SCHOOL_DAMAGE); +        } +    }; + +    SpellScript* GetSpellScript() const +    { +        return new spell_gen_touch_the_nightmare_SpellScript(); +    } +}; + +class spell_gen_dream_funnel: public SpellScriptLoader +{ +public: +    spell_gen_dream_funnel() : SpellScriptLoader("spell_gen_dream_funnel") { } + +    class spell_gen_dream_funnel_AuraScript : public AuraScript +    { +        PrepareAuraScript(spell_gen_dream_funnel_AuraScript); + +        void HandleEffectCalcAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& canBeRecalculated) +        { +            if (GetCaster()) +                amount = GetCaster()->GetMaxHealth() * 0.05f; + +            canBeRecalculated = false; +        } + +        void Register() +        { +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_dream_funnel_AuraScript::HandleEffectCalcAmount, EFFECT_0, SPELL_AURA_PERIODIC_HEAL); +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_dream_funnel_AuraScript::HandleEffectCalcAmount, EFFECT_2, SPELL_AURA_PERIODIC_DAMAGE); +        } +    }; + +    AuraScript* GetAuraScript() const +    { +        return new spell_gen_dream_funnel_AuraScript(); +    } +}; + +enum GenericBandage +{ +    SPELL_RECENTLY_BANDAGED = 11196, +}; + +class spell_gen_bandage : public SpellScriptLoader +{ +    public: +        spell_gen_bandage() : SpellScriptLoader("spell_gen_bandage") { } + +        class spell_gen_bandage_SpellScript : public SpellScript +        { +            PrepareSpellScript(spell_gen_bandage_SpellScript); + +            bool Validate(SpellInfo const* /*spell*/) +            { +                if (!sSpellMgr->GetSpellInfo(SPELL_RECENTLY_BANDAGED)) +                    return false; +                return true; +            } + +            SpellCastResult CheckCast() +            { +                if (Unit* target = GetExplTargetUnit()) +                { +                    if (target->HasAura(SPELL_RECENTLY_BANDAGED)) +                        return SPELL_FAILED_TARGET_AURASTATE; +                } +                return SPELL_CAST_OK; +            } + +            void HandleScript() +            { +                if (Unit* target = GetHitUnit()) +                    GetCaster()->CastSpell(target, SPELL_RECENTLY_BANDAGED, true); +            } + +            void Register() +            { +                OnCheckCast += SpellCheckCastFn(spell_gen_bandage_SpellScript::CheckCast); +                AfterHit += SpellHitFn(spell_gen_bandage_SpellScript::HandleScript); +            } +        }; + +        SpellScript* GetSpellScript() const +        { +            return new spell_gen_bandage_SpellScript(); +        } +}; + +enum GenericLifebloom +{ +    SPELL_HEXLORD_MALACRASS_LIFEBLOOM_FINAL_HEAL        = 43422, +    SPELL_TUR_RAGEPAW_LIFEBLOOM_FINAL_HEAL              = 52552, +    SPELL_CENARION_SCOUT_LIFEBLOOM_FINAL_HEAL           = 53692, +    SPELL_TWISTED_VISAGE_LIFEBLOOM_FINAL_HEAL           = 57763, +    SPELL_FACTION_CHAMPIONS_DRU_LIFEBLOOM_FINAL_HEAL    = 66094, +}; + +class spell_gen_lifebloom : public SpellScriptLoader +{ +    public: +        spell_gen_lifebloom(const char* name, uint32 spellId) : SpellScriptLoader(name), _spellId(spellId) { } + +        class spell_gen_lifebloom_AuraScript : public AuraScript +        { +            PrepareAuraScript(spell_gen_lifebloom_AuraScript); + +        public: +            spell_gen_lifebloom_AuraScript(uint32 spellId) : AuraScript(), _spellId(spellId) { } + +            bool Validate(SpellInfo const* /*spell*/) +            { +                if (!sSpellMgr->GetSpellInfo(_spellId)) +                    return false; +                return true; +            } + +            void AfterRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) +            { +                // Final heal only on duration end +                if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE && GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_ENEMY_SPELL) +                    return; + +                // final heal +                GetTarget()->CastSpell(GetTarget(), _spellId, true, NULL, aurEff, GetCasterGUID()); +            } + +            void Register() +            { +                AfterEffectRemove += AuraEffectRemoveFn(spell_gen_lifebloom_AuraScript::AfterRemove, EFFECT_0, SPELL_AURA_PERIODIC_HEAL, AURA_EFFECT_HANDLE_REAL); +            } + +        private: +            uint32 _spellId; +        }; + +        AuraScript* GetAuraScript() const +        { +            return new spell_gen_lifebloom_AuraScript(_spellId); +        } + +    private: +        uint32 _spellId; +}; + +enum SummonElemental +{ +    SPELL_SUMMON_FIRE_ELEMENTAL  = 8985, +    SPELL_SUMMON_EARTH_ELEMENTAL = 19704 +}; + +class spell_gen_summon_elemental : public SpellScriptLoader +{ +    public: +        spell_gen_summon_elemental(const char* name, uint32 spellId) : SpellScriptLoader(name), _spellId(spellId) { } + +        class spell_gen_summon_elemental_AuraScript : public AuraScript +        { +            PrepareAuraScript(spell_gen_summon_elemental_AuraScript); + +        public: +            spell_gen_summon_elemental_AuraScript(uint32 spellId) : AuraScript(), _spellId(spellId) { } + +            bool Validate(SpellInfo const* /*spell*/) +            { +                if (!sSpellMgr->GetSpellInfo(_spellId)) +                    return false; +                return true; +            } + +            void AfterApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) +            { +                if (GetCaster()) +                    if (Unit* owner = GetCaster()->GetOwner()) +                        owner->CastSpell(owner, _spellId, true); +            } + +            void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) +            { +                if (GetCaster()) +                    if (Unit* owner = GetCaster()->GetOwner()) +                        if (owner->GetTypeId() == TYPEID_PLAYER) // todo: this check is maybe wrong +                            owner->ToPlayer()->RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true); +            } + +            void Register() +            { +                 AfterEffectApply += AuraEffectApplyFn(spell_gen_summon_elemental_AuraScript::AfterApply, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); +                 AfterEffectRemove += AuraEffectRemoveFn(spell_gen_summon_elemental_AuraScript::AfterRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); +            } + +        private: +            uint32 _spellId; +        }; + +        AuraScript* GetAuraScript() const +        { +            return new spell_gen_summon_elemental_AuraScript(_spellId); +        } + +    private: +        uint32 _spellId; +}; + +enum Mounts +{ +    SPELL_COLD_WEATHER_FLYING           = 54197, + +    // Magic Broom +    SPELL_MAGIC_BROOM_60                = 42680, +    SPELL_MAGIC_BROOM_100               = 42683, +    SPELL_MAGIC_BROOM_150               = 42667, +    SPELL_MAGIC_BROOM_280               = 42668, + +    // Headless Horseman's Mount +    SPELL_HEADLESS_HORSEMAN_MOUNT_60    = 51621, +    SPELL_HEADLESS_HORSEMAN_MOUNT_100   = 48024, +    SPELL_HEADLESS_HORSEMAN_MOUNT_150   = 51617, +    SPELL_HEADLESS_HORSEMAN_MOUNT_280   = 48023, + +    // Winged Steed of the Ebon Blade +    SPELL_WINGED_STEED_150              = 54726, +    SPELL_WINGED_STEED_280              = 54727, + +    // Big Love Rocket +    SPELL_BIG_LOVE_ROCKET_0             = 71343, +    SPELL_BIG_LOVE_ROCKET_60            = 71344, +    SPELL_BIG_LOVE_ROCKET_100           = 71345, +    SPELL_BIG_LOVE_ROCKET_150           = 71346, +    SPELL_BIG_LOVE_ROCKET_310           = 71347, + +    // Invincible +    SPELL_INVINCIBLE_60                 = 72281, +    SPELL_INVINCIBLE_100                = 72282, +    SPELL_INVINCIBLE_150                = 72283, +    SPELL_INVINCIBLE_310                = 72284, + +    // Blazing Hippogryph +    SPELL_BLAZING_HIPPOGRYPH_150        = 74854, +    SPELL_BLAZING_HIPPOGRYPH_280        = 74855, + +    // Celestial Steed +    SPELL_CELESTIAL_STEED_60            = 75619, +    SPELL_CELESTIAL_STEED_100           = 75620, +    SPELL_CELESTIAL_STEED_150           = 75617, +    SPELL_CELESTIAL_STEED_280           = 75618, +    SPELL_CELESTIAL_STEED_310           = 76153, + +    // X-53 Touring Rocket +    SPELL_X53_TOURING_ROCKET_150        = 75957, +    SPELL_X53_TOURING_ROCKET_280        = 75972, +    SPELL_X53_TOURING_ROCKET_310        = 76154, +}; + +class spell_gen_mount : public SpellScriptLoader +{ +    public: +        spell_gen_mount(const char* name, uint32 mount0 = 0, uint32 mount60 = 0, uint32 mount100 = 0, uint32 mount150 = 0, uint32 mount280 = 0, uint32 mount310 = 0) : SpellScriptLoader(name), +            _mount0(mount0), _mount60(mount60), _mount100(mount100), _mount150(mount150), _mount280(mount280), _mount310(mount310) { } + +        class spell_gen_mount_SpellScript : public SpellScript +        { +            PrepareSpellScript(spell_gen_mount_SpellScript); + +        public: +            spell_gen_mount_SpellScript(uint32 mount0, uint32 mount60, uint32 mount100, uint32 mount150, uint32 mount280, uint32 mount310) : SpellScript(), +                _mount0(mount0), _mount60(mount60), _mount100(mount100), _mount150(mount150), _mount280(mount280), _mount310(mount310) { } + +            bool Validate(SpellInfo const* /*spell*/) +            { +                if (_mount0 && !sSpellMgr->GetSpellInfo(_mount0)) +                    return false; +                if (_mount60 && !sSpellMgr->GetSpellInfo(_mount60)) +                    return false; +                if (_mount100 && !sSpellMgr->GetSpellInfo(_mount100)) +                    return false; +                if (_mount150 && !sSpellMgr->GetSpellInfo(_mount150)) +                    return false; +                if (_mount280 && !sSpellMgr->GetSpellInfo(_mount280)) +                    return false; +                if (_mount310 && !sSpellMgr->GetSpellInfo(_mount310)) +                    return false; +                return true; +            } + +            void HandleMount(SpellEffIndex effIndex) +            { +                PreventHitDefaultEffect(effIndex); + +                if (Player* target = GetHitPlayer()) +                { +                    // Prevent stacking of mounts and client crashes upon dismounting +                    target->RemoveAurasByType(SPELL_AURA_MOUNTED, 0, GetHitAura()); + +                    // Triggered spell id dependent on riding skill and zone +                    bool canFly = false; +                    uint32 map = GetVirtualMapForMapAndZone(target->GetMapId(), target->GetZoneId()); +                    if (map == 530 || (map == 571 && target->HasSpell(SPELL_COLD_WEATHER_FLYING))) +                        canFly = true; + +                    float x, y, z; +                    target->GetPosition(x, y, z); +                    uint32 areaFlag = target->GetBaseMap()->GetAreaFlag(x, y, z); +                    AreaTableEntry const* area = sAreaStore.LookupEntry(areaFlag); +                    if (!area || (canFly && (area->flags & AREA_FLAG_NO_FLY_ZONE))) +                        canFly = false; + +                    uint32 mount = 0; +                    switch (target->GetBaseSkillValue(SKILL_RIDING)) +                    { +                        case 0: +                            mount = _mount0; +                            break; +                        case 75: +                            mount = _mount60; +                            break; +                        case 150: +                            mount = _mount100; +                            break; +                        case 225: +                            if (canFly) +                                mount = _mount150; +                            else +                                mount = _mount100; +                            break; +                        case 300: +                            if (canFly) +                                mount = _mount280; +                            else +                                mount = _mount100; +                            break; +                        case 375: +                            if (canFly) +                                mount = _mount310; +                            else +                                mount = _mount100; +                            break; +                        default: +                            break; +                    } + +                    if (mount) +                    { +                        PreventHitAura(); +                        target->CastSpell(target, mount, true); +                    } +                } +            } + +            void Register() +            { +                 OnEffectHitTarget += SpellEffectFn(spell_gen_mount_SpellScript::HandleMount, EFFECT_2, SPELL_EFFECT_SCRIPT_EFFECT); +            } + +        private: +            uint32 _mount0; +            uint32 _mount60; +            uint32 _mount100; +            uint32 _mount150; +            uint32 _mount280; +            uint32 _mount310; +        }; + +        SpellScript* GetSpellScript() const +        { +            return new spell_gen_mount_SpellScript(_mount0, _mount60, _mount100, _mount150, _mount280, _mount310); +        } + +    private: +        uint32 _mount0; +        uint32 _mount60; +        uint32 _mount100; +        uint32 _mount150; +        uint32 _mount280; +        uint32 _mount310; +}; +  void AddSC_generic_spell_scripts()  {      new spell_gen_absorb0_hitlimit1(); @@ -2742,4 +3131,22 @@ void AddSC_generic_spell_scripts()      new spell_gen_count_pct_from_max_hp("spell_gen_default_count_pct_from_max_hp");      new spell_gen_count_pct_from_max_hp("spell_gen_50pct_count_pct_from_max_hp", 50);      new spell_gen_despawn_self(); +    new spell_gen_touch_the_nightmare(); +    new spell_gen_dream_funnel(); +    new spell_gen_bandage(); +    new spell_gen_lifebloom("spell_hexlord_lifebloom", SPELL_HEXLORD_MALACRASS_LIFEBLOOM_FINAL_HEAL); +    new spell_gen_lifebloom("spell_tur_ragepaw_lifebloom", SPELL_TUR_RAGEPAW_LIFEBLOOM_FINAL_HEAL); +    new spell_gen_lifebloom("spell_cenarion_scout_lifebloom", SPELL_CENARION_SCOUT_LIFEBLOOM_FINAL_HEAL); +    new spell_gen_lifebloom("spell_twisted_visage_lifebloom", SPELL_TWISTED_VISAGE_LIFEBLOOM_FINAL_HEAL); +    new spell_gen_lifebloom("spell_faction_champion_dru_lifebloom", SPELL_FACTION_CHAMPIONS_DRU_LIFEBLOOM_FINAL_HEAL); +    new spell_gen_summon_elemental("spell_gen_summon_fire_elemental", SPELL_SUMMON_FIRE_ELEMENTAL); +    new spell_gen_summon_elemental("spell_gen_summon_earth_elemental", SPELL_SUMMON_EARTH_ELEMENTAL); +    new spell_gen_mount("spell_magic_broom", 0, SPELL_MAGIC_BROOM_60, SPELL_MAGIC_BROOM_100, SPELL_MAGIC_BROOM_150, SPELL_MAGIC_BROOM_280); +    new spell_gen_mount("spell_headless_horseman_mount", 0, SPELL_HEADLESS_HORSEMAN_MOUNT_60, SPELL_HEADLESS_HORSEMAN_MOUNT_100, SPELL_HEADLESS_HORSEMAN_MOUNT_150, SPELL_HEADLESS_HORSEMAN_MOUNT_280); +    new spell_gen_mount("spell_winged_steed_of_the_ebon_blade", 0, 0, 0, SPELL_WINGED_STEED_150, SPELL_WINGED_STEED_280); +    new spell_gen_mount("spell_big_love_rocket", SPELL_BIG_LOVE_ROCKET_0, SPELL_BIG_LOVE_ROCKET_60, SPELL_BIG_LOVE_ROCKET_100, SPELL_BIG_LOVE_ROCKET_150, SPELL_BIG_LOVE_ROCKET_310); +    new spell_gen_mount("spell_invincible", 0, SPELL_INVINCIBLE_60, SPELL_INVINCIBLE_100, SPELL_INVINCIBLE_150, SPELL_INVINCIBLE_310); +    new spell_gen_mount("spell_blazing_hippogryph", 0, 0, 0, SPELL_BLAZING_HIPPOGRYPH_150, SPELL_BLAZING_HIPPOGRYPH_280); +    new spell_gen_mount("spell_celestial_steed", 0, SPELL_CELESTIAL_STEED_60, SPELL_CELESTIAL_STEED_100, SPELL_CELESTIAL_STEED_150, SPELL_CELESTIAL_STEED_280, SPELL_CELESTIAL_STEED_310); +    new spell_gen_mount("spell_x53_touring_rocket", 0, 0, 0, SPELL_X53_TOURING_ROCKET_150, SPELL_X53_TOURING_ROCKET_280, SPELL_X53_TOURING_ROCKET_310);  } diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp index 896ed331bde..a2ee6c1c3a3 100644 --- a/src/server/scripts/Spells/spell_hunter.cpp +++ b/src/server/scripts/Spells/spell_hunter.cpp @@ -618,6 +618,86 @@ class spell_hun_misdirection_proc : public SpellScriptLoader          }  }; +class spell_hun_disengage : public SpellScriptLoader +{ +    public: +        spell_hun_disengage() : SpellScriptLoader("spell_hun_disengage") { } + +        class spell_hun_disengage_SpellScript : public SpellScript +        { +            PrepareSpellScript(spell_hun_disengage_SpellScript); + +            SpellCastResult CheckCast() +            { +                Unit* caster = GetCaster(); +                if (caster->GetTypeId() == TYPEID_PLAYER && !caster->isInCombat()) +                    return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW; + +                return SPELL_CAST_OK; +            } + +            void Register() +            { +                OnCheckCast += SpellCheckCastFn(spell_hun_disengage_SpellScript::CheckCast); +            } +        }; + +        SpellScript* GetSpellScript() const +        { +            return new spell_hun_disengage_SpellScript(); +        } +}; + +class spell_hun_tame_beast : public SpellScriptLoader +{ +    public: +        spell_hun_tame_beast() : SpellScriptLoader("spell_hun_tame_beast") { } + +        class spell_hun_tame_beast_SpellScript : public SpellScript +        { +            PrepareSpellScript(spell_hun_tame_beast_SpellScript); + +            SpellCastResult CheckCast() +            { +                Unit* caster = GetCaster(); +                if (caster->GetTypeId() != TYPEID_PLAYER) +                    return SPELL_FAILED_DONT_REPORT; + +                if (!GetExplTargetUnit()) +                    return SPELL_FAILED_BAD_IMPLICIT_TARGETS; + +                if (Creature* target = GetExplTargetUnit()->ToCreature()) +                { +                    if (target->getLevel() > caster->getLevel()) +                        return SPELL_FAILED_HIGHLEVEL; + +                    // use SMSG_PET_TAME_FAILURE? +                    if (!target->GetCreatureTemplate()->isTameable(caster->ToPlayer()->CanTameExoticPets())) +                        return SPELL_FAILED_BAD_TARGETS; + +                    if (caster->GetPetGUID()) +                        return SPELL_FAILED_ALREADY_HAVE_SUMMON; + +                    if (caster->GetCharmGUID()) +                        return SPELL_FAILED_ALREADY_HAVE_CHARM; +                } +                else +                    return SPELL_FAILED_BAD_IMPLICIT_TARGETS; + +                return SPELL_CAST_OK; +            } + +            void Register() +            { +                OnCheckCast += SpellCheckCastFn(spell_hun_tame_beast_SpellScript::CheckCast); +            } +        }; + +        SpellScript* GetSpellScript() const +        { +            return new spell_hun_tame_beast_SpellScript(); +        } +};  void AddSC_hunter_spell_scripts()  { @@ -633,4 +713,6 @@ void AddSC_hunter_spell_scripts()      new spell_hun_pet_carrion_feeder();      new spell_hun_misdirection();      new spell_hun_misdirection_proc(); +    new spell_hun_disengage(); +    new spell_hun_tame_beast();  } diff --git a/src/server/scripts/Spells/spell_item.cpp b/src/server/scripts/Spells/spell_item.cpp index 4e2eb633662..3c89cb7005a 100644 --- a/src/server/scripts/Spells/spell_item.cpp +++ b/src/server/scripts/Spells/spell_item.cpp @@ -1848,60 +1848,6 @@ class spell_item_unusual_compass : public SpellScriptLoader          }  }; -enum UDED -{ -    NPC_IRONWOOL_MAMMOTH        = 53806, -    SPELL_MAMMOTH_CARCASS       = 57444, -    SPELL_MAMMOTH_MEAT          = 54625, -}; - -class spell_item_uded : public SpellScriptLoader -{ -    public: -        spell_item_uded() : SpellScriptLoader("spell_item_uded") { } - -        class spell_item_uded_SpellScript : public SpellScript -        { -            PrepareSpellScript(spell_item_uded_SpellScript); - -            bool Load() -            { -                if (GetHitCreature() && GetHitCreature()->GetEntry() == NPC_IRONWOOL_MAMMOTH) -                    return true; -                return false; -            } - -            bool Validate(SpellInfo const* /*spell*/) -            { -                if (!sSpellMgr->GetSpellInfo(SPELL_MAMMOTH_CARCASS) || !sSpellMgr->GetSpellInfo(SPELL_MAMMOTH_MEAT)) -                    return false; -                return true; -            } - -            void HandleDummy(SpellEffIndex /* effIndex */) -            { -                Unit* caster = GetCaster(); -                Creature* creature = GetHitCreature(); -                caster->CastSpell(caster,SPELL_MAMMOTH_CARCASS,true); - -                for (uint8 i = 0; i < 4; ++i) -                    caster->CastSpell(caster,SPELL_MAMMOTH_MEAT,true); - -                creature->Kill(creature); -            } - -            void Register() -            { -                OnEffectHitTarget += SpellEffectFn(spell_item_uded_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); -            } -        }; - -        SpellScript* GetSpellScript() const -        { -            return new spell_item_uded_SpellScript(); -        } -}; -  enum ChickenCover  {      SPELL_CHICKEN_NET               = 51959, @@ -2109,7 +2055,6 @@ void AddSC_item_spell_scripts()      new spell_item_rocket_boots();      new spell_item_pygmy_oil();      new spell_item_unusual_compass(); -    new spell_item_uded();      new spell_item_chicken_cover();      new spell_item_muisek_vessel();      new spell_item_greatmothers_soulcatcher(); diff --git a/src/server/scripts/Spells/spell_mage.cpp b/src/server/scripts/Spells/spell_mage.cpp index 050741ffaba..0edfbaee437 100644 --- a/src/server/scripts/Spells/spell_mage.cpp +++ b/src/server/scripts/Spells/spell_mage.cpp @@ -342,13 +342,52 @@ public:      }  }; +class spell_mage_living_bomb : public SpellScriptLoader +{ +    public: +        spell_mage_living_bomb() : SpellScriptLoader("spell_mage_living_bomb") { } + +        class spell_mage_living_bomb_AuraScript : public AuraScript +        { +            PrepareAuraScript(spell_mage_living_bomb_AuraScript); + +            bool Validate(SpellInfo const* spell) +            { +                if (!sSpellMgr->GetSpellInfo(uint32(spell->Effects[EFFECT_1].CalcValue()))) +                    return false; +                return true; +            } + +            void AfterRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) +            { +                AuraRemoveMode removeMode = GetTargetApplication()->GetRemoveMode(); +                if (removeMode != AURA_REMOVE_BY_ENEMY_SPELL && removeMode != AURA_REMOVE_BY_EXPIRE) +                    return; + +                if (Unit* caster = GetCaster()) +                    caster->CastSpell(GetTarget(), uint32(aurEff->GetAmount()), true, NULL, aurEff); +            } + +            void Register() +            { +                AfterEffectRemove += AuraEffectRemoveFn(spell_mage_living_bomb_AuraScript::AfterRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); +            } +        }; + +        AuraScript* GetAuraScript() const +        { +            return new spell_mage_living_bomb_AuraScript(); +        } +}; +  void AddSC_mage_spell_scripts()  { -    new spell_mage_blast_wave; -    new spell_mage_cold_snap; +    new spell_mage_blast_wave(); +    new spell_mage_cold_snap();      new spell_mage_frost_warding_trigger();      new spell_mage_incanters_absorbtion_absorb();      new spell_mage_incanters_absorbtion_manashield(); -    new spell_mage_polymorph_cast_visual; -    new spell_mage_summon_water_elemental; +    new spell_mage_polymorph_cast_visual(); +    new spell_mage_summon_water_elemental(); +    new spell_mage_living_bomb();  } diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp index 4baa1eb3735..7d248b35853 100644 --- a/src/server/scripts/Spells/spell_paladin.cpp +++ b/src/server/scripts/Spells/spell_paladin.cpp @@ -43,6 +43,10 @@ enum PaladinSpells      SPELL_DIVINE_STORM                           = 53385,      SPELL_DIVINE_STORM_DUMMY                     = 54171,      SPELL_DIVINE_STORM_HEAL                      = 54172, + +    SPELL_FORBEARANCE                            = 25771, +    SPELL_AVENGING_WRATH_MARKER                  = 61987, +    SPELL_IMMUNE_SHIELD_MARKER                   = 61988,  };  // 31850 - Ardent Defender @@ -255,17 +259,18 @@ class spell_pal_holy_shock : public SpellScriptLoader          class spell_pal_holy_shock_SpellScript : public SpellScript          { -            PrepareSpellScript(spell_pal_holy_shock_SpellScript) -            bool Validate(SpellInfo const* spellEntry) +            PrepareSpellScript(spell_pal_holy_shock_SpellScript); + +            bool Validate(SpellInfo const* spell)              {                  if (!sSpellMgr->GetSpellInfo(PALADIN_SPELL_HOLY_SHOCK_R1))                      return false;                  // can't use other spell than holy shock due to spell_ranks dependency -                if (sSpellMgr->GetFirstSpellInChain(PALADIN_SPELL_HOLY_SHOCK_R1) != sSpellMgr->GetFirstSpellInChain(spellEntry->Id)) +                if (sSpellMgr->GetFirstSpellInChain(PALADIN_SPELL_HOLY_SHOCK_R1) != sSpellMgr->GetFirstSpellInChain(spell->Id))                      return false; -                uint8 rank = sSpellMgr->GetSpellRank(spellEntry->Id); +                uint8 rank = sSpellMgr->GetSpellRank(spell->Id);                  if (!sSpellMgr->GetSpellWithRank(PALADIN_SPELL_HOLY_SHOCK_R1_DAMAGE, rank, true) || !sSpellMgr->GetSpellWithRank(PALADIN_SPELL_HOLY_SHOCK_R1_HEALING, rank, true))                      return false; @@ -287,7 +292,7 @@ class spell_pal_holy_shock : public SpellScriptLoader              SpellCastResult CheckCast()              { -                Player* caster = GetCaster()->ToPlayer(); +                Unit* caster = GetCaster();                  if (Unit* target = GetExplTargetUnit())                  {                      if (!caster->IsFriendlyTo(target)) @@ -404,7 +409,7 @@ class spell_pal_divine_storm_dummy : public SpellScriptLoader                  return true;              } -            void CountTargets(std::list<Unit*>& targetList) +            void CountTargets(std::list<WorldObject*>& targetList)              {                  _targetCount = targetList.size();              } @@ -423,7 +428,7 @@ class spell_pal_divine_storm_dummy : public SpellScriptLoader              void Register()              {                  OnEffectHitTarget += SpellEffectFn(spell_pal_divine_storm_dummy_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); -                OnUnitTargetSelect += SpellUnitTargetFn(spell_pal_divine_storm_dummy_SpellScript::CountTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_RAID); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_pal_divine_storm_dummy_SpellScript::CountTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_RAID);              }          }; @@ -433,6 +438,99 @@ class spell_pal_divine_storm_dummy : public SpellScriptLoader          }  }; +class spell_pal_lay_on_hands : public SpellScriptLoader +{ +    public: +        spell_pal_lay_on_hands() : SpellScriptLoader("spell_pal_lay_on_hands") { } + +        class spell_pal_lay_on_hands_SpellScript : public SpellScript +        { +            PrepareSpellScript(spell_pal_lay_on_hands_SpellScript); + +            bool Validate(SpellInfo const* /*spell*/) +            { +                if (!sSpellMgr->GetSpellInfo(SPELL_FORBEARANCE)) +                    return false; +                if (!sSpellMgr->GetSpellInfo(SPELL_AVENGING_WRATH_MARKER)) +                    return false; +                if (!sSpellMgr->GetSpellInfo(SPELL_IMMUNE_SHIELD_MARKER)) +                    return false; +                return true; +            } + +            SpellCastResult CheckCast() +            { +                Unit* caster = GetCaster(); +                if (Unit* target = GetExplTargetUnit()) +                    if (caster == target) +                        if (target->HasAura(SPELL_FORBEARANCE) || target->HasAura(SPELL_AVENGING_WRATH_MARKER) || target->HasAura(SPELL_IMMUNE_SHIELD_MARKER)) +                            return SPELL_FAILED_TARGET_AURASTATE; + +                return SPELL_CAST_OK; +            } + +            void HandleScript() +            { +                Unit* caster = GetCaster(); +                if (caster == GetHitUnit()) +                { +                    caster->CastSpell(caster, SPELL_FORBEARANCE, true); +                    caster->CastSpell(caster, SPELL_AVENGING_WRATH_MARKER, true); +                    caster->CastSpell(caster, SPELL_IMMUNE_SHIELD_MARKER, true); +                } +            } + +            void Register() +            { +                OnCheckCast += SpellCheckCastFn(spell_pal_lay_on_hands_SpellScript::CheckCast); +                AfterHit += SpellHitFn(spell_pal_lay_on_hands_SpellScript::HandleScript); +            } +        }; + +        SpellScript* GetSpellScript() const +        { +            return new spell_pal_lay_on_hands_SpellScript(); +        } +}; + +class spell_pal_righteous_defense : public SpellScriptLoader +{ +    public: +        spell_pal_righteous_defense() : SpellScriptLoader("spell_pal_righteous_defense") { } + +        class spell_pal_righteous_defense_SpellScript : public SpellScript +        { +            PrepareSpellScript(spell_pal_righteous_defense_SpellScript); + +            SpellCastResult CheckCast() +            { +                Unit* caster = GetCaster(); +                if (caster->GetTypeId() != TYPEID_PLAYER) +                    return SPELL_FAILED_DONT_REPORT; + +                if (Unit* target = GetExplTargetUnit()) +                { +                    if (!target->IsFriendlyTo(caster) || target->getAttackers().empty()) +                        return SPELL_FAILED_BAD_TARGETS; +                } +                else +                    return SPELL_FAILED_BAD_TARGETS; + +                return SPELL_CAST_OK; +            } + +            void Register() +            { +                OnCheckCast += SpellCheckCastFn(spell_pal_righteous_defense_SpellScript::CheckCast); +            } +        }; + +        SpellScript* GetSpellScript() const +        { +            return new spell_pal_righteous_defense_SpellScript(); +        } +}; +  void AddSC_paladin_spell_scripts()  {      new spell_pal_ardent_defender(); @@ -443,4 +541,6 @@ void AddSC_paladin_spell_scripts()      new spell_pal_judgement_of_command();      new spell_pal_divine_storm();      new spell_pal_divine_storm_dummy(); +    new spell_pal_lay_on_hands(); +    new spell_pal_righteous_defense();  } diff --git a/src/server/scripts/Spells/spell_pet.cpp b/src/server/scripts/Spells/spell_pet.cpp new file mode 100644 index 00000000000..4928ec40abd --- /dev/null +++ b/src/server/scripts/Spells/spell_pet.cpp @@ -0,0 +1,1726 @@ +/* + * Copyright (C) 2008-2012 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/>. + */ + +/* + * Scripts for spells with SPELLFAMILY_DEATHKNIGHT and SPELLFAMILY_GENERIC spells used by deathknight players. + * Ordered alphabetically using scriptname. + * Scriptnames of files in this file should be prefixed with "spell_dk_". + */ + +#include "ScriptMgr.h" +#include "SpellScript.h" +#include "SpellAuraEffects.h" +#include "Unit.h" +#include "Player.h" +#include "Pet.h" + +enum HunterPetCalculate +{ +     SPELL_TAMED_PET_PASSIVE_06         = 19591, +     SPELL_TAMED_PET_PASSIVE_07         = 20784, +     SPELL_TAMED_PET_PASSIVE_08         = 34666, +     SPELL_TAMED_PET_PASSIVE_09         = 34667, +     SPELL_TAMED_PET_PASSIVE_10         = 34675, +     SPELL_HUNTER_PET_SCALING_01        = 34902, +     SPELL_HUNTER_PET_SCALING_02        = 34903, +     SPELL_HUNTER_PET_SCALING_03        = 34904, +     SPELL_HUNTER_PET_SCALING_04        = 61017, +     SPELL_HUNTER_ANIMAL_HANDLER        = 34453, +}; + +enum WarlockPetCalculate +{ +     SPELL_PET_PASSIVE_CRIT             = 35695, +     SPELL_PET_PASSIVE_DAMAGE_TAKEN     = 35697, +     SPELL_WARLOCK_PET_SCALING_01       = 34947, +     SPELL_WARLOCK_PET_SCALING_02       = 34956, +     SPELL_WARLOCK_PET_SCALING_03       = 34957, +     SPELL_WARLOCK_PET_SCALING_04       = 34958, +     SPELL_WARLOCK_PET_SCALING_05       = 61013, +     ENTRY_FELGUARD                     = 17252, +     ENTRY_VOIDWALKER                   = 1860, +     ENTRY_FELHUNTER                    = 417, +     ENTRY_SUCCUBUS                     = 1863, +     ENTRY_IMP                          = 416, +     SPELL_WARLOCK_GLYPH_OF_VOIDWALKER  = 56247, +}; + +enum DKPetCalculate +{ +    SPELL_DEATH_KNIGHT_RUNE_WEAPON_02   = 51906, +    SPELL_DEATH_KNIGHT_PET_SCALING_01   = 54566, +    SPELL_DEATH_KNIGHT_PET_SCALING_02   = 51996, +    SPELL_DEATH_KNIGHT_PET_SCALING_03   = 61697, +    SPELL_NIGHT_OF_THE_DEAD             = 55620, +    ENTRY_ARMY_OF_THE_DEAD_GHOUL        = 24207, +    SPELL_DEATH_KNIGHT_GLYPH_OF_GHOUL   = 58686, +}; + +enum ShamanPetCalculate +{ +    SPELL_FERAL_SPIRIT_PET_UNK_01      = 35674, +    SPELL_FERAL_SPIRIT_PET_UNK_02      = 35675, +    SPELL_FERAL_SPIRIT_PET_UNK_03      = 35676, +    SPELL_FERAL_SPIRIT_PET_SCALING_04  = 61783, +}; + +enum MiscPetCalculate +{ +     SPELL_MAGE_PET_PASSIVE_ELEMENTAL   = 44559, +     SPELL_PET_HEALTH_SCALING           = 61679, +     SPELL_PET_UNK_01                   = 67561, +     SPELL_PET_UNK_02                   = 67557, +}; + +class spell_gen_pet_calculate : public SpellScriptLoader +{ +    public: +        spell_gen_pet_calculate() : SpellScriptLoader("spell_gen_pet_calculate") { } + +        class spell_gen_pet_calculate_AuraScript : public AuraScript +        { +            PrepareAuraScript(spell_gen_pet_calculate_AuraScript); + +            bool Load() +            { +                if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER) +                    return false; +                return true; +            } + +            void CalculateAmountCritSpell(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +            { +                if (Player* owner = GetCaster()->GetOwner()->ToPlayer()) +                { +                    // For others recalculate it from: +                    float CritSpell = 0.0f; +                    // Crit from Intellect +                    CritSpell += owner->GetSpellCritFromIntellect(); +                    // Increase crit from SPELL_AURA_MOD_SPELL_CRIT_CHANCE +                    CritSpell += owner->GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_CRIT_CHANCE); +                    // Increase crit from SPELL_AURA_MOD_CRIT_PCT +                    CritSpell += owner->GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_PCT); +                    // Increase crit spell from spell crit ratings +                    CritSpell += owner->GetRatingBonusValue(CR_CRIT_SPELL); + +                    amount += int32(CritSpell); +                } +            } + +            void CalculateAmountCritMelee(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +            { +                if (Player* owner = GetCaster()->GetOwner()->ToPlayer()) +                { +                    // For others recalculate it from: +                    float CritMelee = 0.0f; +                    // Crit from Agility +                    CritMelee += owner->GetMeleeCritFromAgility(); +                    // Increase crit from SPELL_AURA_MOD_WEAPON_CRIT_PERCENT +                    CritMelee += owner->GetTotalAuraModifier(SPELL_AURA_MOD_WEAPON_CRIT_PERCENT); +                    // Increase crit from SPELL_AURA_MOD_CRIT_PCT +                    CritMelee += owner->GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_PCT); +                    // Increase crit melee from melee crit ratings +                    CritMelee += owner->GetRatingBonusValue(CR_CRIT_MELEE); + +                    amount += int32(CritMelee); +                } +            } + +            void CalculateAmountMeleeHit(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +            { +                if (Player* owner = GetCaster()->GetOwner()->ToPlayer()) +                { +                    // For others recalculate it from: +                    float HitMelee = 0.0f; +                    // Increase hit from SPELL_AURA_MOD_HIT_CHANCE +                    HitMelee += owner->GetTotalAuraModifier(SPELL_AURA_MOD_HIT_CHANCE); +                    // Increase hit melee from meele hit ratings +                    HitMelee += owner->GetRatingBonusValue(CR_HIT_MELEE); + +                    amount += int32(HitMelee); +                } +            } + +            void CalculateAmountSpellHit(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +            { +                if (Player* owner = GetCaster()->GetOwner()->ToPlayer()) +                { +                    // For others recalculate it from: +                    float HitSpell = 0.0f; +                    // Increase hit from SPELL_AURA_MOD_SPELL_HIT_CHANCE +                    HitSpell += owner->GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_HIT_CHANCE); +                    // Increase hit spell from spell hit ratings +                    HitSpell += owner->GetRatingBonusValue(CR_HIT_SPELL); + +                    amount += int32(HitSpell); +                } +            } + +            void CalculateAmountExpertise(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +            { +                if (Player* owner = GetCaster()->GetOwner()->ToPlayer()) +                { +                    // For others recalculate it from: +                    float Expertise = 0.0f; +                    // Increase hit from SPELL_AURA_MOD_EXPERTISE +                    Expertise += owner->GetTotalAuraModifier(SPELL_AURA_MOD_EXPERTISE); +                    // Increase Expertise from Expertise ratings +                    Expertise += owner->GetRatingBonusValue(CR_EXPERTISE); + +                    amount += int32(Expertise); +                } +            } + +            void Register() +            { +                switch (m_scriptSpellId) +                { +                    case SPELL_TAMED_PET_PASSIVE_06: +                        DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_pet_calculate_AuraScript::CalculateAmountCritMelee, EFFECT_0, SPELL_AURA_MOD_WEAPON_CRIT_PERCENT); +                        DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_pet_calculate_AuraScript::CalculateAmountCritSpell, EFFECT_1, SPELL_AURA_MOD_SPELL_CRIT_CHANCE); +                        break; +                    case SPELL_PET_PASSIVE_CRIT: +                        DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_pet_calculate_AuraScript::CalculateAmountCritSpell, EFFECT_0, SPELL_AURA_MOD_SPELL_CRIT_CHANCE); +                        DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_pet_calculate_AuraScript::CalculateAmountCritMelee, EFFECT_1, SPELL_AURA_MOD_WEAPON_CRIT_PERCENT); +                        break; +                    case SPELL_WARLOCK_PET_SCALING_05: +                    case SPELL_HUNTER_PET_SCALING_04: +                        DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_pet_calculate_AuraScript::CalculateAmountMeleeHit, EFFECT_0, SPELL_AURA_MOD_HIT_CHANCE); +                        DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_pet_calculate_AuraScript::CalculateAmountSpellHit, EFFECT_1, SPELL_AURA_MOD_SPELL_HIT_CHANCE); +                        DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_pet_calculate_AuraScript::CalculateAmountExpertise, EFFECT_2, SPELL_AURA_MOD_EXPERTISE); +                        break; +                    case SPELL_DEATH_KNIGHT_PET_SCALING_03: +//                    case SPELL_SHAMAN_PET_HIT: +                        DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_pet_calculate_AuraScript::CalculateAmountMeleeHit, EFFECT_0, SPELL_AURA_MOD_HIT_CHANCE); +                        DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_pet_calculate_AuraScript::CalculateAmountSpellHit, EFFECT_1, SPELL_AURA_MOD_SPELL_HIT_CHANCE); +                        break; +                    default: +                        break; +                } +            } +        }; + +        AuraScript* GetAuraScript() const +        { +            return new spell_gen_pet_calculate_AuraScript(); +        } +}; + +class spell_warl_pet_scaling_01 : public SpellScriptLoader +{ +public: +    spell_warl_pet_scaling_01() : SpellScriptLoader("spell_warl_pet_scaling_01") { } + +    class spell_warl_pet_scaling_01_AuraScript : public AuraScript +    { +        PrepareAuraScript(spell_warl_pet_scaling_01_AuraScript); + +        bool Load() +        { +            if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER) +                return false; +            _tempBonus = 0; +            return true; +        } + +        void CalculateStaminaAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +        { +            if (Unit* pet = GetUnitOwner()) +                if (pet->isPet()) +                    if (Unit* owner = pet->ToPet()->GetOwner()) +                    { +                        float ownerBonus = CalculatePctN(owner->GetStat(STAT_STAMINA), 75); + +                        amount += ownerBonus; +                    } +        } + +        void ApplyEffect(AuraEffect const* /* aurEff */, AuraEffectHandleModes /*mode*/) +        { +            if (Unit* pet = GetUnitOwner()) +                if (_tempBonus) +                { +                    PetLevelInfo const* pInfo = sObjectMgr->GetPetLevelInfo(pet->GetEntry(), pet->getLevel()); +                    uint32 healthMod = 0; +                    uint32 baseHealth = pInfo->health; +                    switch (pet->GetEntry()) +                    { +                        case ENTRY_IMP: +                            healthMod = uint32(_tempBonus * 8.4f); +                            break; +                        case ENTRY_FELGUARD: +                        case ENTRY_VOIDWALKER: +                            healthMod = _tempBonus * 11; +                            break; +                        case ENTRY_SUCCUBUS: +                            healthMod = uint32(_tempBonus * 9.1f); +                            break; +                        case ENTRY_FELHUNTER: +                            healthMod = uint32(_tempBonus * 9.5f); +                            break; +                        default: +                            healthMod = 0; +                            break; +                    } +                    if (healthMod) +                        pet->ToPet()->SetCreateHealth(baseHealth + healthMod); +                } +        } + +        void RemoveEffect(AuraEffect const* /* aurEff */, AuraEffectHandleModes /*mode*/) +        { +            if (Unit* pet = GetUnitOwner()) +                if (pet->isPet()) +                { +                    PetLevelInfo const* pInfo = sObjectMgr->GetPetLevelInfo(pet->GetEntry(), pet->getLevel()); +                    pet->ToPet()->SetCreateHealth(pInfo->health); +                } +        } + +        void CalculateAttackPowerAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +        { +            if (Unit* pet = GetUnitOwner()) +                if (pet->isPet()) + +                if (Unit* owner = pet->ToPet()->GetOwner()) +                { +                    int32 fire  = int32(owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_FIRE)) - owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + SPELL_SCHOOL_FIRE); +                    int32 shadow = int32(owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_SHADOW)) - owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + SPELL_SCHOOL_SHADOW); +                    int32 maximum  = (fire > shadow) ? fire : shadow; +                    if (maximum < 0) +                        maximum = 0; +                    float bonusAP = maximum * 0.57f; + +                    amount += bonusAP; + +                    // Glyph of felguard +                    if (pet->GetEntry() == ENTRY_FELGUARD) +                    { +                        if (AuraEffect* /* aurEff */ect = owner->GetAuraEffect(56246, EFFECT_0)) +                        { +                            float base_attPower = pet->GetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE) * pet->GetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_PCT); +                            amount += CalculatePctN(amount+base_attPower, /* aurEff */ect->GetAmount()); +                        } +                    } +                } +        } + +        void CalculateDamageDoneAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +        { +            if (Unit* pet = GetUnitOwner()) +                if (pet->isPet()) +                    if (Unit* owner = pet->ToPet()->GetOwner()) +                    { +                        //the damage bonus used for pets is either fire or shadow damage, whatever is higher +                        int32 fire  = int32(owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_FIRE)) - owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + SPELL_SCHOOL_FIRE); +                        int32 shadow = int32(owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_SHADOW)) - owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + SPELL_SCHOOL_SHADOW); +                        int32 maximum  = (fire > shadow) ? fire : shadow; +                        float bonusDamage = 0.0f; + +                        if (maximum > 0) +                            bonusDamage = maximum * 0.15f; + +                        amount += bonusDamage; +                    } +        } + +        void Register() +        { +            OnEffectRemove += AuraEffectRemoveFn(spell_warl_pet_scaling_01_AuraScript::RemoveEffect, EFFECT_0, SPELL_AURA_MOD_STAT, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK); +            AfterEffectApply += AuraEffectApplyFn(spell_warl_pet_scaling_01_AuraScript::ApplyEffect, EFFECT_0, SPELL_AURA_MOD_STAT, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK); +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_01_AuraScript::CalculateStaminaAmount, EFFECT_0, SPELL_AURA_MOD_STAT); +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_01_AuraScript::CalculateAttackPowerAmount, EFFECT_1, SPELL_AURA_MOD_ATTACK_POWER); +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_01_AuraScript::CalculateDamageDoneAmount, EFFECT_2, SPELL_AURA_MOD_DAMAGE_DONE); +        } + +    private: +        uint32 _tempBonus; +    }; + +    AuraScript* GetAuraScript() const +    { +        return new spell_warl_pet_scaling_01_AuraScript(); +    } +}; + +class spell_warl_pet_scaling_02 : public SpellScriptLoader +{ +public: +    spell_warl_pet_scaling_02() : SpellScriptLoader("spell_warl_pet_scaling_02") { } + +    class spell_warl_pet_scaling_02_AuraScript : public AuraScript +    { +        PrepareAuraScript(spell_warl_pet_scaling_02_AuraScript); + +        bool Load() +        { +            if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER) +                return false; +            _tempBonus = 0; +            return true; +        } + +        void CalculateIntellectAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +        { +            if (Unit* pet = GetUnitOwner()) +                if (pet->isPet()) +                    if (Unit* owner = pet->ToPet()->GetOwner()) +                    { +                        float ownerBonus = 0.0f; + +                        ownerBonus = CalculatePctN(owner->GetStat(STAT_INTELLECT), 30); + +                        amount += ownerBonus; +                        _tempBonus = ownerBonus; +                    } +        } + +        void ApplyEffect(AuraEffect const* /* aurEff */, AuraEffectHandleModes /*mode*/) +        { +            if (Unit* pet = GetUnitOwner()) +                if (_tempBonus) +                { +                    PetLevelInfo const* pInfo = sObjectMgr->GetPetLevelInfo(pet->GetEntry(), pet->getLevel()); +                    uint32 manaMod = 0; +                    uint32 baseMana = pInfo->mana; +                    switch (pet->GetEntry()) +                    { +                    case ENTRY_IMP: +                        manaMod = uint32(_tempBonus * 4.9f); +                        break; +                    case ENTRY_VOIDWALKER: +                    case ENTRY_SUCCUBUS: +                    case ENTRY_FELHUNTER: +                    case ENTRY_FELGUARD: +                        manaMod = uint32(_tempBonus * 11.5f); +                        break; +                    default: +                        manaMod = 0; +                        break; +                    } +                    if (manaMod) +                        pet->ToPet()->SetCreateMana(baseMana + manaMod); +                } +        } + +        void RemoveEffect(AuraEffect const* /* aurEff */, AuraEffectHandleModes /*mode*/) +        { +            if (Unit* pet = GetUnitOwner()) +                if (pet->isPet()) +                { +                    PetLevelInfo const* pInfo = sObjectMgr->GetPetLevelInfo(pet->GetEntry(), pet->getLevel()); +                    pet->ToPet()->SetCreateMana(pInfo->mana); +                } +        } + +        void CalculateArmorAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +        { +            if (Unit* pet = GetUnitOwner()) +                if (pet->isPet()) +                    if (Unit* owner = pet->ToPet()->GetOwner()) +                    { +                        float ownerBonus = 0.0f; +                        ownerBonus = CalculatePctN(owner->GetArmor(), 35); +                        amount += ownerBonus; +                    } +        } + +        void CalculateFireResistanceAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +        { +            if (Unit* pet = GetUnitOwner()) +                if (pet->isPet()) +                    if (Unit* owner = pet->ToPet()->GetOwner()) +                    { +                        float ownerBonus = 0.0f; +                        ownerBonus = CalculatePctN(owner->GetResistance(SPELL_SCHOOL_FIRE), 40); +                        amount += ownerBonus; +                    } +        } + +        void Register() +        { +            OnEffectRemove += AuraEffectRemoveFn(spell_warl_pet_scaling_02_AuraScript::RemoveEffect, EFFECT_0, SPELL_AURA_MOD_STAT, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK); +            AfterEffectApply += AuraEffectApplyFn(spell_warl_pet_scaling_02_AuraScript::ApplyEffect, EFFECT_0, SPELL_AURA_MOD_STAT, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK); +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_02_AuraScript::CalculateIntellectAmount, EFFECT_0, SPELL_AURA_MOD_STAT); +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_02_AuraScript::CalculateArmorAmount, EFFECT_1, SPELL_AURA_MOD_RESISTANCE); +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_02_AuraScript::CalculateFireResistanceAmount, EFFECT_2, SPELL_AURA_MOD_RESISTANCE); +        } + +    private: +        uint32 _tempBonus; +    }; + +    AuraScript* GetAuraScript() const +    { +        return new spell_warl_pet_scaling_02_AuraScript(); +    } +}; + +class spell_warl_pet_scaling_03 : public SpellScriptLoader +{ +public: +    spell_warl_pet_scaling_03() : SpellScriptLoader("spell_warl_pet_scaling_03") { } + +    class spell_warl_pet_scaling_03_AuraScript : public AuraScript +    { +        PrepareAuraScript(spell_warl_pet_scaling_03_AuraScript); + +        bool Load() +        { +            if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER) +                return false; +            return true; +        } + +        void CalculateFrostResistanceAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +        { +            if (Unit* pet = GetUnitOwner()) +                if (pet->isPet()) +                    if (Unit* owner = pet->ToPet()->GetOwner()) +                    { +                        float ownerBonus = 0.0f; +                        ownerBonus = CalculatePctN(owner->GetResistance(SPELL_SCHOOL_FROST), 40); +                        amount += ownerBonus; +                    } +        } + +        void CalculateArcaneResistanceAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +        { +            if (Unit* pet = GetUnitOwner()) +                if (pet->isPet()) +                    if (Unit* owner = pet->ToPet()->GetOwner()) +                    { +                        float ownerBonus = 0.0f; +                        ownerBonus = CalculatePctN(owner->GetResistance(SPELL_SCHOOL_ARCANE), 40); +                        amount += ownerBonus; +                    } +        } + +        void CalculateNatureResistanceAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +        { +            if (Unit* pet = GetUnitOwner()) +                if (pet->isPet()) +                    if (Unit* owner = pet->ToPet()->GetOwner()) +                    { +                        float ownerBonus = 0.0f; +                        ownerBonus = CalculatePctN(owner->GetResistance(SPELL_SCHOOL_NATURE), 40); +                        amount += ownerBonus; +                    } +        } + +        void Register() +        { +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_03_AuraScript::CalculateFrostResistanceAmount, EFFECT_0, SPELL_AURA_MOD_RESISTANCE); +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_03_AuraScript::CalculateArcaneResistanceAmount, EFFECT_1, SPELL_AURA_MOD_RESISTANCE); +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_03_AuraScript::CalculateNatureResistanceAmount, EFFECT_2, SPELL_AURA_MOD_RESISTANCE); +        } +    }; + +    AuraScript* GetAuraScript() const +    { +        return new spell_warl_pet_scaling_03_AuraScript(); +    } +}; + + +class spell_warl_pet_scaling_04 : public SpellScriptLoader +{ +public: +    spell_warl_pet_scaling_04() : SpellScriptLoader("spell_warl_pet_scaling_04") { } + +    class spell_warl_pet_scaling_04_AuraScript : public AuraScript +    { +        PrepareAuraScript(spell_warl_pet_scaling_04_AuraScript); + +        bool Load() +        { +            if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER) +                return false; +            return true; +        } + +        void CalculateShadowResistanceAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +        { +            if (Unit* pet = GetUnitOwner()) +                if (pet->isPet()) +                    if (Unit* owner = pet->ToPet()->GetOwner()) +                    { +                        float ownerBonus = 0.0f; +                        ownerBonus = CalculatePctN(owner->GetResistance(SPELL_SCHOOL_SHADOW), 40); +                        amount += ownerBonus; +                    } +        } + +        void Register() +        { +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_04_AuraScript::CalculateShadowResistanceAmount, EFFECT_0, SPELL_AURA_MOD_RESISTANCE); +        } +    }; + +    AuraScript* GetAuraScript() const +    { +        return new spell_warl_pet_scaling_04_AuraScript(); +    } +}; + +class spell_warl_pet_scaling_05 : public SpellScriptLoader +{ +public: +    spell_warl_pet_scaling_05() : SpellScriptLoader("spell_warl_pet_scaling_05") { } + +    class spell_warl_pet_scaling_05_AuraScript : public AuraScript +    { +        PrepareAuraScript(spell_warl_pet_scaling_05_AuraScript); + +        bool Load() +        { +            if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER) +                return false; +            return true; +        } + +        void CalculateAmountMeleeHit(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +        { +            if (Player* owner = GetCaster()->GetOwner()->ToPlayer()) +            { +                // For others recalculate it from: +                float HitMelee = 0.0f; +                // Increase hit from SPELL_AURA_MOD_SPELL_HIT_CHANCE +                HitMelee += owner->GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_HIT_CHANCE); +                // Increase hit spell from spell hit ratings +                HitMelee += owner->GetRatingBonusValue(CR_HIT_SPELL); + +                amount += int32(HitMelee); +            } +        } + +        void CalculateAmountSpellHit(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +        { +            if (Player* owner = GetCaster()->GetOwner()->ToPlayer()) +            { +                // For others recalculate it from: +                float HitSpell = 0.0f; +                // Increase hit from SPELL_AURA_MOD_SPELL_HIT_CHANCE +                HitSpell += owner->GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_HIT_CHANCE); +                // Increase hit spell from spell hit ratings +                HitSpell += owner->GetRatingBonusValue(CR_HIT_SPELL); + +                amount += int32(HitSpell); +            } +        } + +        void CalculateAmountExpertise(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +        { +            if (Player* owner = GetCaster()->GetOwner()->ToPlayer()) +            { +                // For others recalculate it from: +                float Expertise = 0.0f; +                // Increase hit from SPELL_AURA_MOD_SPELL_HIT_CHANCE +                Expertise += owner->GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_HIT_CHANCE); +                // Increase hit spell from spell hit ratings +                Expertise += owner->GetRatingBonusValue(CR_HIT_SPELL); + +                amount += int32(Expertise); +            } +        } + +        void Register() +        { +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_05_AuraScript::CalculateAmountMeleeHit, EFFECT_0, SPELL_AURA_MOD_HIT_CHANCE); +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_05_AuraScript::CalculateAmountSpellHit, EFFECT_1, SPELL_AURA_MOD_SPELL_HIT_CHANCE); +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_05_AuraScript::CalculateAmountExpertise, EFFECT_2, SPELL_AURA_MOD_EXPERTISE); +        } +    }; + +    AuraScript* GetAuraScript() const +    { +        return new spell_warl_pet_scaling_05_AuraScript(); +    } +}; + +class spell_warl_pet_passive : public SpellScriptLoader +{ +public: +    spell_warl_pet_passive() : SpellScriptLoader("spell_warl_pet_passive") { } + +    class spell_warl_pet_passive_AuraScript : public AuraScript +    { +        PrepareAuraScript(spell_warl_pet_passive_AuraScript); + +        bool Load() +        { +            if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER) +                return false; +            return true; +        } + +        void CalculateAmountCritSpell(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +        { +            if (Player* owner = GetCaster()->GetOwner()->ToPlayer()) +            { +                // For others recalculate it from: +                float CritSpell = 0.0f; +                // Crit from Intellect +                CritSpell += owner->GetSpellCritFromIntellect(); +                // Increase crit from SPELL_AURA_MOD_SPELL_CRIT_CHANCE +                CritSpell += owner->GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_CRIT_CHANCE); +                // Increase crit from SPELL_AURA_MOD_CRIT_PCT +                CritSpell += owner->GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_PCT); +                // Increase crit spell from spell crit ratings +                CritSpell += owner->GetRatingBonusValue(CR_CRIT_SPELL); + +                if (AuraApplication* improvedDemonicTacticsApp = owner->GetAuraApplicationOfRankedSpell(54347)) +                    if (Aura* improvedDemonicTactics = improvedDemonicTacticsApp->GetBase()) +                        if (AuraEffect* improvedDemonicTacticsEffect = improvedDemonicTactics->GetEffect(EFFECT_0)) +                            amount += CalculatePctN(CritSpell, improvedDemonicTacticsEffect->GetAmount()); +            } +        } + +        void CalculateAmountCritMelee(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +        { +            if (Player* owner = GetCaster()->GetOwner()->ToPlayer()) +            { +                // For others recalculate it from: +                float CritMelee = 0.0f; +                // Crit from Agility +                CritMelee += owner->GetMeleeCritFromAgility(); +                // Increase crit from SPELL_AURA_MOD_WEAPON_CRIT_PERCENT +                CritMelee += owner->GetTotalAuraModifier(SPELL_AURA_MOD_WEAPON_CRIT_PERCENT); +                // Increase crit from SPELL_AURA_MOD_CRIT_PCT +                CritMelee += owner->GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_PCT); +                // Increase crit melee from melee crit ratings +                CritMelee += owner->GetRatingBonusValue(CR_CRIT_MELEE); + +                if (AuraApplication* improvedDemonicTacticsApp = owner->GetAuraApplicationOfRankedSpell(54347)) +                    if (Aura* improvedDemonicTactics = improvedDemonicTacticsApp->GetBase()) +                        if (AuraEffect* improvedDemonicTacticsEffect = improvedDemonicTactics->GetEffect(EFFECT_0)) +                            amount += CalculatePctN(CritMelee, improvedDemonicTacticsEffect->GetAmount()); +            } +        } + +        void Register() +        { +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_passive_AuraScript::CalculateAmountCritSpell, EFFECT_0, SPELL_AURA_MOD_SPELL_CRIT_CHANCE); +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_passive_AuraScript::CalculateAmountCritMelee, EFFECT_1, SPELL_AURA_MOD_WEAPON_CRIT_PERCENT); +        } +    }; + +    AuraScript* GetAuraScript() const +    { +        return new spell_warl_pet_passive_AuraScript(); +    } +}; +// this doesnt actually fit in here +class spell_warl_pet_passive_damage_done : public SpellScriptLoader +{ +public: +    spell_warl_pet_passive_damage_done() : SpellScriptLoader("spell_warl_pet_passive_damage_done") { } + +    class spell_warl_pet_passive_damage_done_AuraScript : public AuraScript +    { +        PrepareAuraScript(spell_warl_pet_passive_damage_done_AuraScript); + +        bool Load() +        { +            if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER) +                return false; +            return true; +        } + +        void CalculateAmountDamageDone(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +        { +            if (!GetCaster() || !GetCaster()->GetOwner()) +                return; +            if (GetCaster()->GetOwner()->ToPlayer()) +            { +                switch (GetCaster()->GetEntry()) +                { +                case ENTRY_VOIDWALKER: +                    amount += -16; +                    break; +                case ENTRY_FELHUNTER: +                    amount += -20; +                    break; +                case ENTRY_SUCCUBUS: +                case ENTRY_FELGUARD: +                    amount += 5; +                    break; +                } +            } +        } + +        void Register() +        { +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_passive_damage_done_AuraScript::CalculateAmountDamageDone, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_passive_damage_done_AuraScript::CalculateAmountDamageDone, EFFECT_1, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); +        } +    }; + +    AuraScript* GetAuraScript() const +    { +        return new spell_warl_pet_passive_damage_done_AuraScript(); +    } +}; + +class spell_warl_pet_passive_voidwalker : public SpellScriptLoader +{ +public: +    spell_warl_pet_passive_voidwalker() : SpellScriptLoader("spell_warl_pet_passive_voidwalker") { } + +    class spell_warl_pet_passive_voidwalker_AuraScript : public AuraScript +    { +        PrepareAuraScript(spell_warl_pet_passive_voidwalker_AuraScript); + +        bool Load() +        { +            if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER) +                return false; +            return true; +        } + +        void CalculateAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +        { +            if (Unit* pet = GetUnitOwner()) +                if (pet->isPet()) +                    if (Unit* owner = pet->ToPet()->GetOwner()) +                        if (AuraEffect* /* aurEff */ect = owner->GetAuraEffect(SPELL_WARLOCK_GLYPH_OF_VOIDWALKER, EFFECT_0)) +                            amount += /* aurEff */ect->GetAmount(); +        } + +        void Register() +        { +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_passive_voidwalker_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE); +        } +    }; + +    AuraScript* GetAuraScript() const +    { +        return new spell_warl_pet_passive_voidwalker_AuraScript(); +    } +}; + + +class spell_sha_pet_scaling_04 : public SpellScriptLoader +{ +public: +    spell_sha_pet_scaling_04() : SpellScriptLoader("spell_sha_pet_scaling_04") { } + +    class spell_sha_pet_scaling_04_AuraScript : public AuraScript +    { +        PrepareAuraScript(spell_sha_pet_scaling_04_AuraScript); + +        bool Load() +        { +            if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER) +                return false; +            return true; +        } + +        void CalculateAmountMeleeHit(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +        { +            if (Player* owner = GetCaster()->GetOwner()->ToPlayer()) +            { +                // For others recalculate it from: +                float HitMelee = 0.0f; +                // Increase hit from SPELL_AURA_MOD_HIT_CHANCE +                HitMelee += owner->GetTotalAuraModifier(SPELL_AURA_MOD_HIT_CHANCE); +                // Increase hit melee from meele hit ratings +                HitMelee += owner->GetRatingBonusValue(CR_HIT_MELEE); + +                amount += int32(HitMelee); +            } +        } + +        void CalculateAmountSpellHit(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +        { +            if (Player* owner = GetCaster()->GetOwner()->ToPlayer()) +            { +                // For others recalculate it from: +                float HitSpell = 0.0f; +                // Increase hit from SPELL_AURA_MOD_SPELL_HIT_CHANCE +                HitSpell += owner->GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_HIT_CHANCE); +                // Increase hit spell from spell hit ratings +                HitSpell += owner->GetRatingBonusValue(CR_HIT_SPELL); + +                amount += int32(HitSpell); +            } +        } + +        void Register() +        { +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_sha_pet_scaling_04_AuraScript::CalculateAmountMeleeHit, EFFECT_0, SPELL_AURA_MOD_HIT_CHANCE); +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_sha_pet_scaling_04_AuraScript::CalculateAmountSpellHit, EFFECT_1, SPELL_AURA_MOD_SPELL_HIT_CHANCE); +        } +    }; + +    AuraScript* GetAuraScript() const +    { +        return new spell_sha_pet_scaling_04_AuraScript(); +    } +}; + +class spell_hun_pet_scaling_01 : public SpellScriptLoader +{ +public: +    spell_hun_pet_scaling_01() : SpellScriptLoader("spell_hun_pet_scaling_01") { } + +    class spell_hun_pet_scaling_01_AuraScript : public AuraScript +    { +        PrepareAuraScript(spell_hun_pet_scaling_01_AuraScript); + +        void CalculateStaminaAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +        { +            if (Unit* pet = GetUnitOwner()) +                if (pet->isPet()) +                    if (Unit* owner = pet->ToPet()->GetOwner()) +                    { +                        float mod = 0.45f; +                        float ownerBonus = 0.0f; + +                        PetSpellMap::const_iterator itr = (pet->ToPet()->m_spells.find(62758)); // Wild Hunt rank 1 +                        if (itr == pet->ToPet()->m_spells.end()) +                            itr = pet->ToPet()->m_spells.find(62762); // Wild Hunt rank 2 + +                        if (itr != pet->ToPet()->m_spells.end()) // If pet has Wild Hunt +                        { +                            SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value +                            AddPctN(mod, spellInfo->Effects[EFFECT_0].CalcValue()); +                        } + +                        ownerBonus = owner->GetStat(STAT_STAMINA)*mod; + +                        amount += ownerBonus; +                    } +        } + +        void ApplyEffect(AuraEffect const* /* aurEff */, AuraEffectHandleModes /*mode*/) +        { +            if (Unit* pet = GetUnitOwner()) +                if (_tempHealth) +                    pet->SetHealth(_tempHealth); +        } + +        void RemoveEffect(AuraEffect const* /* aurEff */, AuraEffectHandleModes /*mode*/) +        { +            if (Unit* pet = GetUnitOwner()) +                _tempHealth = pet->GetHealth(); +        } + +        void CalculateAttackPowerAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +        { +            if (Unit* pet = GetUnitOwner()) +            { +                if (!pet->isPet()) +                    return; + +                Unit* owner = pet->ToPet()->GetOwner(); +                if (!owner) +                    return; + +                float mod = 1.0f;                                                 //Hunter contribution modifier +                float bonusAP = 0.0f; + +                PetSpellMap::const_iterator itr = (pet->ToPet()->m_spells.find(62758)); // Wild Hunt rank 1 +                if (itr == pet->ToPet()->m_spells.end()) +                    itr = pet->ToPet()->m_spells.find(62762); // Wild Hunt rank 2 + +                if (itr != pet->ToPet()->m_spells.end()) // If pet has Wild Hunt +                { +                    SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value +                    mod += CalculatePctN(1.0f, spellInfo->Effects[EFFECT_1].CalcValue()); +                } + +                bonusAP = owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.22f * mod; + +                amount += bonusAP; +            } +        } + +        void CalculateDamageDoneAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +        { +            if (Unit* pet = GetUnitOwner()) +            { +                if (!pet->isPet()) +                    return; + +                Unit* owner = pet->ToPet()->GetOwner(); +                if (!owner) +                    return; + +                float mod = 1.0f;                                                 //Hunter contribution modifier +                float bonusDamage = 0.0f; + +                PetSpellMap::const_iterator itr = (pet->ToPet()->m_spells.find(62758)); // Wild Hunt rank 1 +                if (itr == pet->ToPet()->m_spells.end()) +                    itr = pet->ToPet()->m_spells.find(62762); // Wild Hunt rank 2 + +                if (itr != pet->ToPet()->m_spells.end()) // If pet has Wild Hunt +                { +                    SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value +                    mod += CalculatePctN(1.0f, spellInfo->Effects[EFFECT_1].CalcValue()); +                } + +                bonusDamage = owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.1287f * mod; + +                amount += bonusDamage; +            } +        } + +        void Register() +        { +            OnEffectRemove += AuraEffectRemoveFn(spell_hun_pet_scaling_01_AuraScript::RemoveEffect, EFFECT_0, SPELL_AURA_MOD_STAT, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK); +            AfterEffectApply += AuraEffectApplyFn(spell_hun_pet_scaling_01_AuraScript::ApplyEffect, EFFECT_0, SPELL_AURA_MOD_STAT, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK); +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_01_AuraScript::CalculateStaminaAmount, EFFECT_0, SPELL_AURA_MOD_STAT); +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_01_AuraScript::CalculateAttackPowerAmount, EFFECT_1, SPELL_AURA_MOD_ATTACK_POWER); +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_01_AuraScript::CalculateDamageDoneAmount, EFFECT_2, SPELL_AURA_MOD_DAMAGE_DONE); +        } + +    private: +        uint32 _tempHealth; +    }; + +    AuraScript* GetAuraScript() const +    { +        return new spell_hun_pet_scaling_01_AuraScript(); +    } +}; + +class spell_hun_pet_scaling_02 : public SpellScriptLoader +{ +public: +    spell_hun_pet_scaling_02() : SpellScriptLoader("spell_hun_pet_scaling_02") { } + +    class spell_hun_pet_scaling_02_AuraScript : public AuraScript +    { +        PrepareAuraScript(spell_hun_pet_scaling_02_AuraScript); + +        bool Load() +        { +            if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER) +                return false; +            return true; +        } + +        void CalculateFrostResistanceAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +        { +            if (Unit* pet = GetUnitOwner()) +            { +                if (!pet->isPet()) +                    return; + +                Unit* owner = pet->ToPet()->GetOwner(); +                if (!owner) +                    return; + +                float ownerBonus = 0.0f; + +                ownerBonus = CalculatePctN(owner->GetResistance(SPELL_SCHOOL_FROST), 40); + +                amount += ownerBonus; +            } +        } + +        void CalculateFireResistanceAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +        { +            if (Unit* pet = GetUnitOwner()) +            { +                if (!pet->isPet()) +                    return; + +                Unit* owner = pet->ToPet()->GetOwner(); +                if (!owner) +                    return; + +                float ownerBonus = 0.0f; + +                ownerBonus = CalculatePctN(owner->GetResistance(SPELL_SCHOOL_FIRE), 40); + +                amount += ownerBonus; +            } +        } + +        void CalculateNatureResistanceAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +        { +            if (Unit* pet = GetUnitOwner()) +            { +                if (!pet->isPet()) +                    return; + +                Unit* owner = pet->ToPet()->GetOwner(); +                if (!owner) +                    return; + +                float ownerBonus = 0.0f; + +                ownerBonus = CalculatePctN(owner->GetResistance(SPELL_SCHOOL_NATURE), 40); + +                amount += ownerBonus; +            } +        } + +        void Register() +        { +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_02_AuraScript::CalculateFrostResistanceAmount, EFFECT_1, SPELL_AURA_MOD_RESISTANCE); +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_02_AuraScript::CalculateFireResistanceAmount, EFFECT_0, SPELL_AURA_MOD_RESISTANCE); +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_02_AuraScript::CalculateNatureResistanceAmount, EFFECT_2, SPELL_AURA_MOD_RESISTANCE); +        } +    }; + +    AuraScript* GetAuraScript() const +    { +        return new spell_hun_pet_scaling_02_AuraScript(); +    } +}; + +class spell_hun_pet_scaling_03 : public SpellScriptLoader +{ +public: +    spell_hun_pet_scaling_03() : SpellScriptLoader("spell_hun_pet_scaling_03") { } + +    class spell_hun_pet_scaling_03_AuraScript : public AuraScript +    { +        PrepareAuraScript(spell_hun_pet_scaling_03_AuraScript); + +        bool Load() +        { +            if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER) +                return false; +            return true; +        } + +        void CalculateShadowResistanceAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +        { +            if (Unit* pet = GetUnitOwner()) +            { +                if (!pet->isPet()) +                    return; + +                Unit* owner = pet->ToPet()->GetOwner(); +                if (!owner) +                    return; + +                float ownerBonus = 0.0f; + +                ownerBonus = CalculatePctN(owner->GetResistance(SPELL_SCHOOL_SHADOW), 40); + +                amount += ownerBonus; +            } +        } + +        void CalculateArcaneResistanceAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +        { +            if (Unit* pet = GetUnitOwner()) +            { +                if (!pet->isPet()) +                    return; + +                Unit* owner = pet->ToPet()->GetOwner(); +                if (!owner) +                    return; + +                float ownerBonus = 0.0f; + +                ownerBonus = CalculatePctN(owner->GetResistance(SPELL_SCHOOL_ARCANE), 40); + +                amount += ownerBonus; +            } +        } + +        void CalculateArmorAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +        { +            if (Unit* pet = GetUnitOwner()) +            { +                if (!pet->isPet()) +                    return; + +                Unit* owner = pet->ToPet()->GetOwner(); +                if (!owner) +                    return; + +                float ownerBonus = 0.0f; + +                ownerBonus = CalculatePctN(owner->GetArmor(), 35); + +                amount += ownerBonus; +            } +        } + +        void Register() +        { +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_03_AuraScript::CalculateShadowResistanceAmount, EFFECT_0, SPELL_AURA_MOD_RESISTANCE); +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_03_AuraScript::CalculateArcaneResistanceAmount, EFFECT_1, SPELL_AURA_MOD_RESISTANCE); +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_03_AuraScript::CalculateArmorAmount, EFFECT_2, SPELL_AURA_MOD_RESISTANCE); +        } +    }; + +    AuraScript* GetAuraScript() const +    { +        return new spell_hun_pet_scaling_03_AuraScript(); +    } +}; + +class spell_hun_pet_scaling_04 : public SpellScriptLoader +{ +public: +    spell_hun_pet_scaling_04() : SpellScriptLoader("spell_hun_pet_scaling_04") { } + +    class spell_hun_pet_scaling_04_AuraScript : public AuraScript +    { +        PrepareAuraScript(spell_hun_pet_scaling_04_AuraScript); + +        bool Load() +        { +            if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER) +                return false; +            return true; +        } + +        void CalculateAmountMeleeHit(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +        { +            if (!GetCaster() || !GetCaster()->GetOwner()) +                return; +            if (Player* owner = GetCaster()->GetOwner()->ToPlayer()) +            { +                // For others recalculate it from: +                float HitMelee = 0.0f; +                // Increase hit from SPELL_AURA_MOD_HIT_CHANCE +                HitMelee += owner->GetTotalAuraModifier(SPELL_AURA_MOD_HIT_CHANCE); +                // Increase hit melee from meele hit ratings +                HitMelee += owner->GetRatingBonusValue(CR_HIT_MELEE); + +                amount += int32(HitMelee); +            } +        } + +        void CalculateAmountSpellHit(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +        { +            if (!GetCaster() || !GetCaster()->GetOwner()) +                return; +            if (Player* owner = GetCaster()->GetOwner()->ToPlayer()) +            { +                // For others recalculate it from: +                float HitSpell = 0.0f; +                // Increase hit from SPELL_AURA_MOD_SPELL_HIT_CHANCE +                HitSpell += owner->GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_HIT_CHANCE); +                // Increase hit spell from spell hit ratings +                HitSpell += owner->GetRatingBonusValue(CR_HIT_SPELL); + +                amount += int32(HitSpell); +            } +        } + +        void CalculateAmountExpertise(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +        { +            if (!GetCaster() || !GetCaster()->GetOwner()) +                return; +            if (Player* owner = GetCaster()->GetOwner()->ToPlayer()) +            { +                // For others recalculate it from: +                float Expertise = 0.0f; +                // Increase hit from SPELL_AURA_MOD_EXPERTISE +                Expertise += owner->GetTotalAuraModifier(SPELL_AURA_MOD_EXPERTISE); +                // Increase Expertise from Expertise ratings +                Expertise += owner->GetRatingBonusValue(CR_EXPERTISE); + +                amount += int32(Expertise); +            } +        } + +        void Register() +        { +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_04_AuraScript::CalculateAmountMeleeHit, EFFECT_0, SPELL_AURA_MOD_HIT_CHANCE); +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_04_AuraScript::CalculateAmountSpellHit, EFFECT_1, SPELL_AURA_MOD_SPELL_HIT_CHANCE); +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_04_AuraScript::CalculateAmountExpertise, EFFECT_2, SPELL_AURA_MOD_EXPERTISE); +        } +    }; + +    AuraScript* GetAuraScript() const +    { +        return new spell_hun_pet_scaling_04_AuraScript(); +    } +}; + +class spell_hun_pet_passive_crit : public SpellScriptLoader +{ +public: +    spell_hun_pet_passive_crit() : SpellScriptLoader("spell_hun_pet_passive_crit") { } + +    class spell_hun_pet_passive_crit_AuraScript : public AuraScript +    { +        PrepareAuraScript(spell_hun_pet_passive_crit_AuraScript); + +        bool Load() +        { +            if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER) +                return false; +            return true; +        } + +        void CalculateAmountCritSpell(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +        { +            if (!GetCaster() || !GetCaster()->GetOwner()) +                return; +            if (GetCaster()->GetOwner()->ToPlayer()) +            { +                // For others recalculate it from: +                float CritSpell = 0.0f; +                // Crit from Intellect +                // CritSpell += owner->GetSpellCritFromIntellect(); +                // Increase crit from SPELL_AURA_MOD_SPELL_CRIT_CHANCE +                // CritSpell += owner->GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_CRIT_CHANCE); +                // Increase crit from SPELL_AURA_MOD_CRIT_PCT +                // CritSpell += owner->GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_PCT); +                // Increase crit spell from spell crit ratings +                // CritSpell += owner->GetRatingBonusValue(CR_CRIT_SPELL); + +                amount += (CritSpell*0.8f); +            } +        } + +        void CalculateAmountCritMelee(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +        { +            if (!GetCaster() || !GetCaster()->GetOwner()) +                return; +            if (GetCaster()->GetOwner()->ToPlayer()) +            { +                // For others recalculate it from: +                float CritMelee = 0.0f; +                // Crit from Agility +                // CritMelee += owner->GetMeleeCritFromAgility(); +                // Increase crit from SPELL_AURA_MOD_WEAPON_CRIT_PERCENT +                // CritMelee += owner->GetTotalAuraModifier(SPELL_AURA_MOD_WEAPON_CRIT_PERCENT); +                // Increase crit from SPELL_AURA_MOD_CRIT_PCT +                // CritMelee += owner->GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_PCT); +                // Increase crit melee from melee crit ratings +                // CritMelee += owner->GetRatingBonusValue(CR_CRIT_MELEE); + +                amount += (CritMelee*0.8f); +            } +        } + +        void Register() +        { +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_passive_crit_AuraScript::CalculateAmountCritSpell, EFFECT_1, SPELL_AURA_MOD_SPELL_CRIT_CHANCE); +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_passive_crit_AuraScript::CalculateAmountCritMelee, EFFECT_0, SPELL_AURA_MOD_WEAPON_CRIT_PERCENT); +        } +    }; + +    AuraScript* GetAuraScript() const +    { +        return new spell_hun_pet_passive_crit_AuraScript(); +    } +}; + +class spell_hun_pet_passive_damage_done : public SpellScriptLoader +{ +public: +    spell_hun_pet_passive_damage_done() : SpellScriptLoader("spell_hun_pet_passive_damage_done") { } + +    class spell_hun_pet_passive_damage_done_AuraScript : public AuraScript +    { +        PrepareAuraScript(spell_hun_pet_passive_damage_done_AuraScript); + +        bool Load() +        { +            if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER) +                return false; +            return true; +        } + +        void CalculateAmountDamageDone(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +        { +            if (!GetCaster() || !GetCaster()->GetOwner()) +                return; +            if (GetCaster()->GetOwner()->ToPlayer()) +            { +                // Cobra Reflexes +                if (AuraEffect* cobraReflexes = GetCaster()->GetAuraEffectOfRankedSpell(61682, EFFECT_0)) +                    amount -= cobraReflexes->GetAmount(); +            } +        } + +        void Register() +        { +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_passive_damage_done_AuraScript::CalculateAmountDamageDone, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); +        } +    }; + +    AuraScript* GetAuraScript() const +    { +        return new spell_hun_pet_passive_damage_done_AuraScript(); +    } +}; + +class spell_hun_animal_handler : public SpellScriptLoader +{ +public: +    spell_hun_animal_handler() : SpellScriptLoader("spell_hun_animal_handler") { } + +    class spell_hun_animal_handler_AuraScript : public AuraScript +    { +        PrepareAuraScript(spell_hun_animal_handler_AuraScript); + +        bool Load() +        { +            if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER) +                return false; +            return true; +        } + +        void CalculateAmountDamageDone(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +        { +            if (!GetCaster() || !GetCaster()->GetOwner()) +                return; +            if (Player* owner = GetCaster()->GetOwner()->ToPlayer()) +            { +                if (AuraEffect* /* aurEff */ect = owner->GetAuraEffectOfRankedSpell(SPELL_HUNTER_ANIMAL_HANDLER, EFFECT_1)) +                    amount = /* aurEff */ect->GetAmount(); +                else +                    amount = 0; +            } +        } + +        void Register() +        { +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_animal_handler_AuraScript::CalculateAmountDamageDone, EFFECT_0, SPELL_AURA_MOD_ATTACK_POWER_PCT); +        } +    }; + +    AuraScript* GetAuraScript() const +    { +        return new spell_hun_animal_handler_AuraScript(); +    } +}; + + +class spell_dk_avoidance_passive : public SpellScriptLoader +{ +public: +    spell_dk_avoidance_passive() : SpellScriptLoader("spell_dk_avoidance_passive") { } + +    class spell_dk_avoidance_passive_AuraScript : public AuraScript +    { +        PrepareAuraScript(spell_dk_avoidance_passive_AuraScript); + +        bool Load() +        { +            if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER) +                return false; +            return true; +        } + +        void CalculateAvoidanceAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +        { +            if (Unit* pet = GetUnitOwner()) +            { +                if (Unit* owner = pet->GetOwner()) +                { +                    // Army of the dead ghoul +                    if (pet->GetEntry() == ENTRY_ARMY_OF_THE_DEAD_GHOUL) +                        amount = -90; +                    // Night of the dead +                    else if ( Aura * aur = owner->GetAuraOfRankedSpell(SPELL_NIGHT_OF_THE_DEAD)) +                        amount = aur->GetSpellInfo()->Effects[EFFECT_2].CalcValue(); +                } +            } +        } + +        void Register() +        { +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_avoidance_passive_AuraScript::CalculateAvoidanceAmount, EFFECT_0, SPELL_AURA_MOD_CREATURE_AOE_DAMAGE_AVOIDANCE); +        } +    }; + +    AuraScript* GetAuraScript() const +    { +        return new spell_dk_avoidance_passive_AuraScript(); +    } +}; + +class spell_dk_pet_scaling_01 : public SpellScriptLoader +{ +public: +    spell_dk_pet_scaling_01() : SpellScriptLoader("spell_dk_pet_scaling_01") { } + +    class spell_dk_pet_scaling_01_AuraScript : public AuraScript +    { +        PrepareAuraScript(spell_dk_pet_scaling_01_AuraScript); + +        bool Load() +        { +            if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER) +                return false; +            _tempHealth = 0; +            return true; +        } + +        void CalculateStaminaAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +        { +            if (Unit* pet = GetUnitOwner()) +            { +                if (pet->isGuardian()) +                { +                    if (Unit* owner = pet->GetOwner()) +                    { +                        float mod = 0.3f; + +                        // Ravenous Dead. Check just if owner has Ravenous Dead since it's effect is not an aura +                        if (AuraEffect const* aurEff = owner->GetAuraEffect(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE, SPELLFAMILY_DEATHKNIGHT, 3010, 0)) +                        { +                            mod += aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue()/100;                   // Ravenous Dead edits the original scale +                        } +                        // Glyph of the Ghoul +                        if (AuraEffect const* aurEff = owner->GetAuraEffect(SPELL_DEATH_KNIGHT_GLYPH_OF_GHOUL, 0)) +                            mod += aurEff->GetAmount()/100; + +                        float ownerBonus = float(owner->GetStat(STAT_STAMINA)) * mod; +                        amount += ownerBonus; +                    } +                } +            } +        } + +        void ApplyEffect(AuraEffect const* /* aurEff */, AuraEffectHandleModes /*mode*/) +        { +            if (Unit* pet = GetUnitOwner()) +                if (_tempHealth) +                    pet->SetHealth(_tempHealth); +        } + +        void RemoveEffect(AuraEffect const* /* aurEff */, AuraEffectHandleModes /*mode*/) +        { +            if (Unit* pet = GetUnitOwner()) +                _tempHealth = pet->GetHealth(); +        } + +        void CalculateStrengthAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +        { +            if (Unit* pet = GetUnitOwner()) +            { +                if (!pet->isGuardian()) +                    return; + +                Unit* owner = pet->GetOwner(); +                if (!owner) +                    return; + +                float mod = 0.7f; + +                // Ravenous Dead +                AuraEffect const* aurEff = NULL; +                // Check just if owner has Ravenous Dead since it's effect is not an aura +                aurEff = owner->GetAuraEffect(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE, SPELLFAMILY_DEATHKNIGHT, 3010, 0); +                if (aurEff) +                { +                    mod += CalculatePctN(mod, aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue());                   // Ravenous Dead edits the original scale +                } +                // Glyph of the Ghoul +                aurEff = owner->GetAuraEffect(58686, 0); +                if (aurEff) +                    mod += CalculatePctN(1.0f, aurEff->GetAmount());                                                    // Glyph of the Ghoul adds a flat value to the scale mod +                float ownerBonus = float(owner->GetStat(STAT_STRENGTH)) * mod; +                amount += ownerBonus; +            } +        } + +        void Register() +        { +            OnEffectRemove += AuraEffectRemoveFn(spell_dk_pet_scaling_01_AuraScript::RemoveEffect, EFFECT_0, SPELL_AURA_MOD_STAT, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK); +            AfterEffectApply += AuraEffectApplyFn(spell_dk_pet_scaling_01_AuraScript::ApplyEffect, EFFECT_0, SPELL_AURA_MOD_STAT, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK); +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_pet_scaling_01_AuraScript::CalculateStaminaAmount, EFFECT_0, SPELL_AURA_MOD_STAT); +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_pet_scaling_01_AuraScript::CalculateStrengthAmount, EFFECT_1, SPELL_AURA_MOD_STAT); +        } + +    private: +        uint32 _tempHealth; +    }; + +    AuraScript* GetAuraScript() const +    { +        return new spell_dk_pet_scaling_01_AuraScript(); +    } +}; + +class spell_dk_pet_scaling_02 : public SpellScriptLoader +{ +public: +    spell_dk_pet_scaling_02() : SpellScriptLoader("spell_dk_pet_scaling_02") { } + +    class spell_dk_pet_scaling_02_AuraScript : public AuraScript +    { +        PrepareAuraScript(spell_dk_pet_scaling_02_AuraScript); + +        bool Load() +        { +            if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER) +                return false; +            return true; +        } + +        void CalculateAmountMeleeHaste(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +        { +            if (!GetCaster() || !GetCaster()->GetOwner()) +                return; +            if (Player* owner = GetCaster()->GetOwner()->ToPlayer()) +            { +                // For others recalculate it from: +                float HasteMelee = 0.0f; +                // Increase hit from SPELL_AURA_MOD_HIT_CHANCE +                HasteMelee += (1-owner->m_modAttackSpeedPct[BASE_ATTACK])*100; + +                amount += int32(HasteMelee); +            } +        } + +        void Register() +        { +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_pet_scaling_02_AuraScript::CalculateAmountMeleeHaste, EFFECT_1, SPELL_AURA_MELEE_SLOW); +        } +    }; + +    AuraScript* GetAuraScript() const +    { +        return new spell_dk_pet_scaling_02_AuraScript(); +    } +}; + +class spell_dk_pet_scaling_03 : public SpellScriptLoader +{ +public: +    spell_dk_pet_scaling_03() : SpellScriptLoader("spell_dk_pet_scaling_03") { } + +    class spell_dk_pet_scaling_03_AuraScript : public AuraScript +    { +        PrepareAuraScript(spell_dk_pet_scaling_03_AuraScript); + +        bool Load() +        { +            if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER) +                return false; +            return true; +        } + +        void CalculateAmountMeleeHit(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +        { +            if (!GetCaster() || !GetCaster()->GetOwner()) +                return; +            if (Player* owner = GetCaster()->GetOwner()->ToPlayer()) +            { +                // For others recalculate it from: +                float HitMelee = 0.0f; +                // Increase hit from SPELL_AURA_MOD_HIT_CHANCE +                HitMelee += owner->GetTotalAuraModifier(SPELL_AURA_MOD_HIT_CHANCE); +                // Increase hit melee from meele hit ratings +                HitMelee += owner->GetRatingBonusValue(CR_HIT_MELEE); + +                amount += int32(HitMelee); +            } +        } + +        void CalculateAmountSpellHit(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +        { +            if (!GetCaster() || !GetCaster()->GetOwner()) +                return; +            if (Player* owner = GetCaster()->GetOwner()->ToPlayer()) +            { +                // For others recalculate it from: +                float HitSpell = 0.0f; +                // Increase hit from SPELL_AURA_MOD_SPELL_HIT_CHANCE +                HitSpell += owner->GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_HIT_CHANCE); +                // Increase hit spell from spell hit ratings +                HitSpell += owner->GetRatingBonusValue(CR_HIT_SPELL); + +                amount += int32(HitSpell); +            } +        } + +        void Register() +        { +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_pet_scaling_03_AuraScript::CalculateAmountMeleeHit, EFFECT_0, SPELL_AURA_MOD_HIT_CHANCE); +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_pet_scaling_03_AuraScript::CalculateAmountSpellHit, EFFECT_1, SPELL_AURA_MOD_SPELL_HIT_CHANCE); +        } +    }; + +    AuraScript* GetAuraScript() const +    { +        return new spell_dk_pet_scaling_03_AuraScript(); +    } +}; + +class spell_dk_rune_weapon_scaling_02 : public SpellScriptLoader +{ +public: +    spell_dk_rune_weapon_scaling_02() : SpellScriptLoader("spell_dk_rune_weapon_scaling_02") { } + +    class spell_dk_rune_weapon_scaling_02_AuraScript : public AuraScript +    { +        PrepareAuraScript(spell_dk_rune_weapon_scaling_02_AuraScript); + +        bool Load() +        { +            if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER) +                return false; +            return true; +        } + +        void CalculateDamageDoneAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +        { +            if (Unit* pet = GetUnitOwner()) +            { +                Unit* owner = pet->GetOwner(); +                if (!owner) +                    return; + +                if (pet->isGuardian()) +                    ((Guardian*)pet)->SetBonusDamage(owner->GetTotalAttackPowerValue(BASE_ATTACK)); + +                amount += owner->CalculateDamage(BASE_ATTACK, true, true);; +            } +        } + +        void CalculateAmountMeleeHaste(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) +        { +            if (!GetCaster() || !GetCaster()->GetOwner()) +                return; +            if (Player* owner = GetCaster()->GetOwner()->ToPlayer()) +            { +                // For others recalculate it from: +                float HasteMelee = 0.0f; +                // Increase hit from SPELL_AURA_MOD_HIT_CHANCE +                HasteMelee += (1-owner->m_modAttackSpeedPct[BASE_ATTACK])*100; + +                amount += int32(HasteMelee); +            } +        } + +        void Register() +        { +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_rune_weapon_scaling_02_AuraScript::CalculateDamageDoneAmount, EFFECT_0, SPELL_AURA_MOD_DAMAGE_DONE); +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_rune_weapon_scaling_02_AuraScript::CalculateAmountMeleeHaste, EFFECT_1, SPELL_AURA_MELEE_SLOW); +        } +    }; + +    AuraScript* GetAuraScript() const +    { +        return new spell_dk_rune_weapon_scaling_02_AuraScript(); +    } +}; + +void AddSC_pet_spell_scripts() +{ +    new spell_gen_pet_calculate(); +} diff --git a/src/server/scripts/Spells/spell_priest.cpp b/src/server/scripts/Spells/spell_priest.cpp index 8088004c9d1..aab1e974e53 100644 --- a/src/server/scripts/Spells/spell_priest.cpp +++ b/src/server/scripts/Spells/spell_priest.cpp @@ -34,6 +34,9 @@ enum PriestSpells      PRIEST_SPELL_PENANCE_R1_HEAL                = 47757,      PRIEST_SPELL_REFLECTIVE_SHIELD_TRIGGERED    = 33619,      PRIEST_SPELL_REFLECTIVE_SHIELD_R1           = 33201, +    PRIEST_SPELL_VAMPIRIC_TOUCH_DISPEL          = 64085, +    PRIEST_SPELL_EMPOWERED_RENEW                = 63544, +    PRIEST_ICON_ID_EMPOWERED_RENEW_TALENT       = 3021,  };  // Guardian Spirit @@ -129,14 +132,14 @@ class spell_pri_mind_sear : public SpellScriptLoader          {              PrepareSpellScript(spell_pri_mind_sear_SpellScript); -            void FilterTargets(std::list<Unit*>& unitList) +            void FilterTargets(std::list<WorldObject*>& unitList)              { -                unitList.remove_if (Trinity::ObjectGUIDCheck(GetCaster()->GetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT))); +                unitList.remove_if(Trinity::ObjectGUIDCheck(GetCaster()->GetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT)));              }              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_pri_mind_sear_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_pri_mind_sear_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);              }          }; @@ -330,6 +333,88 @@ public:      }  }; +class spell_pri_vampiric_touch : public SpellScriptLoader +{ +    public: +        spell_pri_vampiric_touch() : SpellScriptLoader("spell_pri_vampiric_touch") { } + +        class spell_pri_vampiric_touch_AuraScript : public AuraScript +        { +            PrepareAuraScript(spell_pri_vampiric_touch_AuraScript); + +            bool Validate(SpellInfo const* /*spell*/) +            { +                if (!sSpellMgr->GetSpellInfo(PRIEST_SPELL_VAMPIRIC_TOUCH_DISPEL)) +                    return false; +                return true; +            } + +            void HandleDispel(DispelInfo* /*dispelInfo*/) +            { +                if (Unit* caster = GetCaster()) +                    if (Unit* target = GetUnitOwner()) +                        if (AuraEffect const* aurEff = GetEffect(EFFECT_1)) +                        { +                            int32 damage = aurEff->GetAmount() * 8; +                            // backfire damage +                            caster->CastCustomSpell(target, PRIEST_SPELL_VAMPIRIC_TOUCH_DISPEL, &damage, NULL, NULL, true, NULL, aurEff); +                        } +            } + +            void Register() +            { +                AfterDispel += AuraDispelFn(spell_pri_vampiric_touch_AuraScript::HandleDispel); +            } +        }; + +        AuraScript* GetAuraScript() const +        { +            return new spell_pri_vampiric_touch_AuraScript(); +        } +}; + +class spell_priest_renew : public SpellScriptLoader +{ +    public: +        spell_priest_renew() : SpellScriptLoader("spell_priest_renew") { } + +        class spell_priest_renew_AuraScript : public AuraScript +        { +            PrepareAuraScript(spell_priest_renew_AuraScript); + +            bool Load() +            { +                return GetCaster() && GetCaster()->GetTypeId() == TYPEID_PLAYER; +            } + +            void HandleApplyEffect(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) +            { +                if (Unit* caster = GetCaster()) +                { +                    // Empowered Renew +                    if (AuraEffect const* empoweredRenewAurEff = caster->GetDummyAuraEffect(SPELLFAMILY_PRIEST, PRIEST_ICON_ID_EMPOWERED_RENEW_TALENT, EFFECT_1)) +                    { +                        uint32 heal = caster->SpellHealingBonusDone(GetTarget(), GetSpellInfo(), GetEffect(EFFECT_0)->GetAmount(), DOT); +                        heal = GetTarget()->SpellHealingBonusTaken(caster, GetSpellInfo(), heal, DOT); + +                        int32 basepoints0 = empoweredRenewAurEff->GetAmount() * GetEffect(EFFECT_0)->GetTotalTicks() * int32(heal) / 100; +                        caster->CastCustomSpell(GetTarget(), PRIEST_SPELL_EMPOWERED_RENEW, &basepoints0, NULL, NULL, true, NULL, aurEff); +                    } +                } +            } + +            void Register() +            { +                OnEffectApply += AuraEffectApplyFn(spell_priest_renew_AuraScript::HandleApplyEffect, EFFECT_0, SPELL_AURA_PERIODIC_HEAL, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); +            } +        }; + +        AuraScript* GetAuraScript() const +        { +            return new spell_priest_renew_AuraScript(); +        } +}; +  void AddSC_priest_spell_scripts()  {      new spell_pri_guardian_spirit(); @@ -339,4 +424,6 @@ void AddSC_priest_spell_scripts()      new spell_pri_reflective_shield_trigger();      new spell_pri_mind_sear();      new spell_pri_prayer_of_mending_heal(); +    new spell_pri_vampiric_touch(); +    new spell_priest_renew();  } diff --git a/src/server/scripts/Spells/spell_quest.cpp b/src/server/scripts/Spells/spell_quest.cpp index 810cc20e04b..e3714a22304 100644 --- a/src/server/scripts/Spells/spell_quest.cpp +++ b/src/server/scripts/Spells/spell_quest.cpp @@ -639,7 +639,7 @@ class spell_q12851_going_bearback : public SpellScriptLoader                      // Already in fire                      if (target->HasAura(SPELL_ABLAZE))                          return; -                         +                      if (Player* player = caster->GetCharmerOrOwnerPlayerOrPlayerItself())                      {                          switch (target->GetEntry()) @@ -1162,6 +1162,84 @@ class spell_q12277_wintergarde_mine_explosion : public SpellScriptLoader          }  }; +enum FocusOnTheBeach +{ +    SPELL_BUNNY_CREDIT_BEAM = 47390, +}; + +class spell_q12066_bunny_kill_credit : public SpellScriptLoader +{ +public: +    spell_q12066_bunny_kill_credit() : SpellScriptLoader("spell_q12066_bunny_kill_credit") { } + +    class spell_q12066_bunny_kill_credit_SpellScript : public SpellScript +    { +        PrepareSpellScript(spell_q12066_bunny_kill_credit_SpellScript); + +        void HandleDummy(SpellEffIndex /*effIndex*/) +        { +            if (Creature* target = GetHitCreature()) +                target->CastSpell(GetCaster(), SPELL_BUNNY_CREDIT_BEAM, false); +        } + +        void Register() +        { +            OnEffectHitTarget += SpellEffectFn(spell_q12066_bunny_kill_credit_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); +        } +    }; + +    SpellScript* GetSpellScript() const +    { +        return new spell_q12066_bunny_kill_credit_SpellScript(); +    } +}; + +enum ACleansingSong +{ +    SPELL_SUMMON_SPIRIT_ATAH        = 52954, +    SPELL_SUMMON_SPIRIT_HAKHALAN    = 52958, +    SPELL_SUMMON_SPIRIT_KOOSU       = 52959, + +    AREA_BITTERTIDELAKE             = 4385, +    AREA_RIVERSHEART                = 4290, +    AREA_WINTERGRASPRIVER           = 4388, +}; + +class spell_q12735_song_of_cleansing : public SpellScriptLoader +{ +    public: +        spell_q12735_song_of_cleansing() : SpellScriptLoader("spell_q12735_song_of_cleansing") { } + +        class spell_q12735_song_of_cleansing_SpellScript : public SpellScript +        { +            PrepareSpellScript(spell_q12735_song_of_cleansing_SpellScript); + +            void HandleScript(SpellEffIndex /*effIndex*/) +            { +                Unit* caster = GetCaster(); + +                if (caster && caster->GetAreaId() == AREA_BITTERTIDELAKE) +                    caster->CastSpell(caster, SPELL_SUMMON_SPIRIT_ATAH); + +                else if (caster && caster->GetAreaId() == AREA_RIVERSHEART) +                    caster->CastSpell(caster, SPELL_SUMMON_SPIRIT_HAKHALAN); + +                else if (caster && caster->GetAreaId() == AREA_WINTERGRASPRIVER) +                    caster->CastSpell(caster, SPELL_SUMMON_SPIRIT_KOOSU); +            } + +            void Register() +            { +                OnEffectHitTarget += SpellEffectFn(spell_q12735_song_of_cleansing_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); +            } +        }; + +        SpellScript* GetSpellScript() const +        { +            return new spell_q12735_song_of_cleansing_SpellScript(); +        } +}; +  void AddSC_quest_spell_scripts()  {      new spell_q55_sacred_cleansing(); @@ -1189,4 +1267,6 @@ void AddSC_quest_spell_scripts()      new spell_q9452_cast_net();      new spell_q12987_read_pronouncement();      new spell_q12277_wintergarde_mine_explosion(); +    new spell_q12066_bunny_kill_credit(); +    new spell_q12735_song_of_cleansing();  } diff --git a/src/server/scripts/Spells/spell_shaman.cpp b/src/server/scripts/Spells/spell_shaman.cpp index c9c036d5329..c863c2363af 100644 --- a/src/server/scripts/Spells/spell_shaman.cpp +++ b/src/server/scripts/Spells/spell_shaman.cpp @@ -35,13 +35,19 @@ enum ShamanSpells      SHAMAN_SPELL_FIRE_NOVA_TRIGGERED_R1    = 8349,      SHAMAN_SPELL_SATED                     = 57724,      SHAMAN_SPELL_EXHAUSTION                = 57723, -     +      SHAMAN_SPELL_STORM_EARTH_AND_FIRE      = 51483,      EARTHBIND_TOTEM_SPELL_EARTHGRAB        = 64695,      // For Earthen Power      SHAMAN_TOTEM_SPELL_EARTHBIND_TOTEM     = 6474,      SHAMAN_TOTEM_SPELL_EARTHEN_POWER       = 59566, + +    SHAMAN_BIND_SIGHT                      = 6277, + +    ICON_ID_SHAMAN_LAVA_FLOW               = 3087, +    SHAMAN_LAVA_FLOWS_R1                   = 51480, +    SHAMAN_LAVA_FLOWS_TRIGGERED_R1         = 64694,  };  // 51474 - Astral shift @@ -255,10 +261,13 @@ class EarthenPowerTargetSelector  {      public:          EarthenPowerTargetSelector() { } -  -        bool operator() (Unit* target) + +        bool operator() (WorldObject* target)          { -            if (!target->HasAuraWithMechanic(1 << MECHANIC_SNARE)) +            if (!target->ToUnit()) +                return true; + +            if (!target->ToUnit()->HasAuraWithMechanic(1 << MECHANIC_SNARE))                  return true;              return false; @@ -274,14 +283,14 @@ class spell_sha_earthen_power : public SpellScriptLoader          {              PrepareSpellScript(spell_sha_earthen_power_SpellScript); -            void FilterTargets(std::list<Unit*>& unitList) +            void FilterTargets(std::list<WorldObject*>& unitList)              {                  unitList.remove_if(EarthenPowerTargetSelector());              }              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_sha_earthen_power_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sha_earthen_power_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);              }          }; @@ -307,7 +316,7 @@ class spell_sha_bloodlust : public SpellScriptLoader                  return true;              } -            void RemoveInvalidTargets(std::list<Unit*>& targets) +            void RemoveInvalidTargets(std::list<WorldObject*>& targets)              {                  targets.remove_if(Trinity::UnitAuraCheck(true, SHAMAN_SPELL_SATED));              } @@ -320,9 +329,9 @@ class spell_sha_bloodlust : public SpellScriptLoader              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_sha_bloodlust_SpellScript::RemoveInvalidTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_RAID); -                OnUnitTargetSelect += SpellUnitTargetFn(spell_sha_bloodlust_SpellScript::RemoveInvalidTargets, EFFECT_1, TARGET_UNIT_CASTER_AREA_RAID); -                OnUnitTargetSelect += SpellUnitTargetFn(spell_sha_bloodlust_SpellScript::RemoveInvalidTargets, EFFECT_2, TARGET_UNIT_CASTER_AREA_RAID); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sha_bloodlust_SpellScript::RemoveInvalidTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_RAID); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sha_bloodlust_SpellScript::RemoveInvalidTargets, EFFECT_1, TARGET_UNIT_CASTER_AREA_RAID); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sha_bloodlust_SpellScript::RemoveInvalidTargets, EFFECT_2, TARGET_UNIT_CASTER_AREA_RAID);                  AfterHit += SpellHitFn(spell_sha_bloodlust_SpellScript::ApplyDebuff);              }          }; @@ -349,9 +358,9 @@ class spell_sha_heroism : public SpellScriptLoader                  return true;              } -            void RemoveInvalidTargets(std::list<Unit*>& targets) +            void RemoveInvalidTargets(std::list<WorldObject*>& targets)              { -                targets.remove_if (Trinity::UnitAuraCheck(true, SHAMAN_SPELL_EXHAUSTION)); +                targets.remove_if(Trinity::UnitAuraCheck(true, SHAMAN_SPELL_EXHAUSTION));              }              void ApplyDebuff() @@ -362,9 +371,9 @@ class spell_sha_heroism : public SpellScriptLoader              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_sha_heroism_SpellScript::RemoveInvalidTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_RAID); -                OnUnitTargetSelect += SpellUnitTargetFn(spell_sha_heroism_SpellScript::RemoveInvalidTargets, EFFECT_1, TARGET_UNIT_CASTER_AREA_RAID); -                OnUnitTargetSelect += SpellUnitTargetFn(spell_sha_heroism_SpellScript::RemoveInvalidTargets, EFFECT_2, TARGET_UNIT_CASTER_AREA_RAID); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sha_heroism_SpellScript::RemoveInvalidTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_RAID); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sha_heroism_SpellScript::RemoveInvalidTargets, EFFECT_1, TARGET_UNIT_CASTER_AREA_RAID); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sha_heroism_SpellScript::RemoveInvalidTargets, EFFECT_2, TARGET_UNIT_CASTER_AREA_RAID);                  AfterHit += SpellHitFn(spell_sha_heroism_SpellScript::ApplyDebuff);              }          }; @@ -652,6 +661,94 @@ class spell_sha_chain_heal : public SpellScriptLoader          }  }; +class spell_sha_flame_shock : public SpellScriptLoader +{ +    public: +        spell_sha_flame_shock() : SpellScriptLoader("spell_sha_flame_shock") { } + +        class spell_sha_flame_shock_AuraScript : public AuraScript +        { +            PrepareAuraScript(spell_sha_flame_shock_AuraScript); + +            bool Validate(SpellInfo const* /*spell*/) +            { +                if (!sSpellMgr->GetSpellInfo(SHAMAN_LAVA_FLOWS_R1)) +                    return false; +                if (!sSpellMgr->GetSpellInfo(SHAMAN_LAVA_FLOWS_TRIGGERED_R1)) +                    return false; +                return true; +            } + +            void HandleDispel(DispelInfo* /*dispelInfo*/) +            { +                if (Unit* caster = GetCaster()) +                    // Lava Flows +                    if (AuraEffect const* aurEff = caster->GetDummyAuraEffect(SPELLFAMILY_SHAMAN, ICON_ID_SHAMAN_LAVA_FLOW, EFFECT_0)) +                    { +                        if (sSpellMgr->GetFirstSpellInChain(SHAMAN_LAVA_FLOWS_R1) != sSpellMgr->GetFirstSpellInChain(aurEff->GetId())) +                            return; + +                        uint8 rank = sSpellMgr->GetSpellRank(aurEff->GetId()); +                        caster->CastSpell(caster, sSpellMgr->GetSpellWithRank(SHAMAN_LAVA_FLOWS_TRIGGERED_R1, rank), true); +                    } +            } + +            void Register() +            { +                AfterDispel += AuraDispelFn(spell_sha_flame_shock_AuraScript::HandleDispel); +            } +        }; + +        AuraScript* GetAuraScript() const +        { +            return new spell_sha_flame_shock_AuraScript(); +        } +}; + +class spell_sha_sentry_totem : public SpellScriptLoader +{ +    public: +        spell_sha_sentry_totem() : SpellScriptLoader("spell_sha_sentry_totem") { } + +        class spell_sha_sentry_totem_AuraScript : public AuraScript +        { +            PrepareAuraScript(spell_sha_sentry_totem_AuraScript); + +            bool Validate(SpellInfo const* /*spell*/) +            { +                if (!sSpellMgr->GetSpellInfo(SHAMAN_BIND_SIGHT)) +                    return false; +                return true; +            } + +            void AfterApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) +            { +                if (Unit* caster = GetCaster()) +                    if (Creature* totem = caster->GetMap()->GetCreature(caster->m_SummonSlot[4])) +                        if (totem->isTotem()) +                            caster->CastSpell(totem, SHAMAN_BIND_SIGHT, true); +            } + +            void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) +            { +                if (Unit* caster = GetCaster()) +                    if (caster->GetTypeId() == TYPEID_PLAYER) +                        caster->ToPlayer()->StopCastingBindSight(); +            } + +            void Register() +            { +                 AfterEffectApply += AuraEffectApplyFn(spell_sha_sentry_totem_AuraScript::AfterApply, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); +                 AfterEffectRemove += AuraEffectRemoveFn(spell_sha_sentry_totem_AuraScript::AfterRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); +            } +        }; + +        AuraScript* GetAuraScript() const +        { +            return new spell_sha_sentry_totem_AuraScript(); +        } +}; +  void AddSC_shaman_spell_scripts()  {      new spell_sha_astral_shift(); @@ -667,4 +764,6 @@ void AddSC_shaman_spell_scripts()      new spell_sha_mana_spring_totem();      new spell_sha_lava_lash();      new spell_sha_chain_heal(); +    new spell_sha_flame_shock(); +    new spell_sha_sentry_totem();  } diff --git a/src/server/scripts/Spells/spell_warlock.cpp b/src/server/scripts/Spells/spell_warlock.cpp index 838b9e4f932..74118599b9f 100644 --- a/src/server/scripts/Spells/spell_warlock.cpp +++ b/src/server/scripts/Spells/spell_warlock.cpp @@ -37,6 +37,9 @@ enum WarlockSpells      WARLOCK_DEMONIC_CIRCLE_SUMMON           = 48018,      WARLOCK_DEMONIC_CIRCLE_TELEPORT         = 48020,      WARLOCK_DEMONIC_CIRCLE_ALLOW_CAST       = 62388, +    WARLOCK_HAUNT                           = 48181, +    WARLOCK_HAUNT_HEAL                      = 48210, +    WARLOCK_UNSTABLE_AFFLICTION_DISPEL      = 31117,  };  class spell_warl_banish : public SpellScriptLoader @@ -299,15 +302,15 @@ class spell_warl_seed_of_corruption : public SpellScriptLoader          {              PrepareSpellScript(spell_warl_seed_of_corruption_SpellScript); -            void FilterTargets(std::list<Unit*>& unitList) +            void FilterTargets(std::list<WorldObject*>& targets)              {                  if (GetExplTargetUnit()) -                    unitList.remove(GetExplTargetUnit()); +                    targets.remove(GetExplTargetUnit());              }              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_warl_seed_of_corruption_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_warl_seed_of_corruption_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);              }          }; @@ -523,6 +526,107 @@ class spell_warl_demonic_circle_teleport : public SpellScriptLoader          }  }; +class spell_warl_haunt : public SpellScriptLoader +{ +    public: +        spell_warl_haunt() : SpellScriptLoader("spell_warl_haunt") { } + +        class spell_warl_haunt_SpellScript : public SpellScript +        { +            PrepareSpellScript(spell_warl_haunt_SpellScript); + +            void HandleOnHit() +            { +                if (Aura* aura = GetHitAura()) +                    if (AuraEffect* aurEff = aura->GetEffect(EFFECT_1)) +                        aurEff->SetAmount(CalculatePctN(aurEff->GetAmount(), GetHitDamage())); +            } + +            void Register() +            { +                OnHit += SpellHitFn(spell_warl_haunt_SpellScript::HandleOnHit); +            } +        }; + +        class spell_warl_haunt_AuraScript : public AuraScript +        { +            PrepareAuraScript(spell_warl_haunt_AuraScript); + +            bool Validate(SpellInfo const* /*spell*/) +            { +                if (!sSpellMgr->GetSpellInfo(WARLOCK_HAUNT_HEAL)) +                    return false; +                return true; +            } + +            void HandleRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) +            { +                if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_ENEMY_SPELL && GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE) +                    return; + +                if (Unit* caster = GetCaster()) +                { +                    int32 amount = aurEff->GetAmount(); +                    GetTarget()->CastCustomSpell(caster, WARLOCK_HAUNT_HEAL, &amount, NULL, NULL, true, NULL, aurEff, GetCasterGUID()); +                } +            } + +            void Register() +            { +                OnEffectRemove += AuraEffectApplyFn(spell_warl_haunt_AuraScript::HandleRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); +            } +        }; + +        SpellScript* GetSpellScript() const +        { +            return new spell_warl_haunt_SpellScript(); +        } + +        AuraScript* GetAuraScript() const +        { +            return new spell_warl_haunt_AuraScript(); +        } +}; + +class spell_warl_unstable_affliction : public SpellScriptLoader +{ +    public: +        spell_warl_unstable_affliction() : SpellScriptLoader("spell_warl_unstable_affliction") { } + +        class spell_warl_unstable_affliction_AuraScript : public AuraScript +        { +            PrepareAuraScript(spell_warl_unstable_affliction_AuraScript); + +            bool Validate(SpellInfo const* /*spell*/) +            { +                if (!sSpellMgr->GetSpellInfo(WARLOCK_UNSTABLE_AFFLICTION_DISPEL)) +                    return false; +                return true; +            } + +            void HandleDispel(DispelInfo* dispelInfo) +            { +                if (Unit* caster = GetCaster()) +                    if (AuraEffect const* aurEff = GetEffect(EFFECT_0)) +                    { +                        int32 damage = aurEff->GetAmount() * 9; +                        // backfire damage and silence +                        caster->CastCustomSpell(dispelInfo->GetDispeller(), WARLOCK_UNSTABLE_AFFLICTION_DISPEL, &damage, NULL, NULL, true, NULL, aurEff); +                    } +            } + +            void Register() +            { +                AfterDispel += AuraDispelFn(spell_warl_unstable_affliction_AuraScript::HandleDispel); +            } +        }; + +        AuraScript* GetAuraScript() const +        { +            return new spell_warl_unstable_affliction_AuraScript(); +        } +}; +  void AddSC_warlock_spell_scripts()  {      new spell_warl_banish(); @@ -535,4 +639,6 @@ void AddSC_warlock_spell_scripts()      new spell_warl_life_tap();      new spell_warl_demonic_circle_summon();      new spell_warl_demonic_circle_teleport(); +    new spell_warl_haunt(); +    new spell_warl_unstable_affliction();  } diff --git a/src/server/scripts/Spells/spell_warrior.cpp b/src/server/scripts/Spells/spell_warrior.cpp index 0ba5c866d63..c64101e11ea 100644 --- a/src/server/scripts/Spells/spell_warrior.cpp +++ b/src/server/scripts/Spells/spell_warrior.cpp @@ -77,7 +77,7 @@ class spell_warr_improved_spell_reflection : public SpellScriptLoader          {              PrepareSpellScript(spell_warr_improved_spell_reflection_SpellScript); -            void FilterTargets(std::list<Unit*>& unitList) +            void FilterTargets(std::list<WorldObject*>& unitList)              {                  if (GetCaster())                      unitList.remove(GetCaster()); @@ -85,7 +85,7 @@ class spell_warr_improved_spell_reflection : public SpellScriptLoader              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_warr_improved_spell_reflection_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_PARTY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_warr_improved_spell_reflection_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_PARTY);              }          }; @@ -184,9 +184,9 @@ class spell_warr_deep_wounds : public SpellScriptLoader                      damage = caster->SpellDamageBonusDone(target, GetSpellInfo(), damage, SPELL_DIRECT_DAMAGE);                      ApplyPctN(damage, 16 * sSpellMgr->GetSpellRank(GetSpellInfo()->Id)); -                     +                      damage = target->SpellDamageBonusTaken(caster, GetSpellInfo(), damage, SPELL_DIRECT_DAMAGE); -                     +                      SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(SPELL_DEEP_WOUNDS_RANK_PERIODIC);                      uint32 ticks = spellInfo->GetDuration() / spellInfo->Effects[EFFECT_0].Amplitude; @@ -397,7 +397,20 @@ class spell_warr_bloodthirst : public SpellScriptLoader          {              PrepareSpellScript(spell_warr_bloodthirst_SpellScript); -            void HandleDummy(SpellEffIndex /* effIndex */) +            void HandleDamage(SpellEffIndex /*effIndex*/) +            { +                int32 damage = GetEffectValue(); +                ApplyPctF(damage, GetCaster()->GetTotalAttackPowerValue(BASE_ATTACK)); + +                if (Unit* target = GetHitUnit()) +                { +                    damage = GetCaster()->SpellDamageBonusDone(target, GetSpellInfo(), uint32(damage), SPELL_DIRECT_DAMAGE); +                    damage = target->SpellDamageBonusTaken(GetCaster(), GetSpellInfo(), uint32(damage), SPELL_DIRECT_DAMAGE); +                } +                SetHitDamage(damage); +            } + +            void HandleDummy(SpellEffIndex /*effIndex*/)              {                  int32 damage = GetEffectValue();                  GetCaster()->CastCustomSpell(GetCaster(), SPELL_BLOODTHIRST, &damage, NULL, NULL, true, NULL); @@ -405,7 +418,8 @@ class spell_warr_bloodthirst : public SpellScriptLoader              void Register()              { -                OnEffectHitTarget += SpellEffectFn(spell_warr_bloodthirst_SpellScript::HandleDummy, EFFECT_1, SPELL_EFFECT_DUMMY); +                OnEffectHitTarget += SpellEffectFn(spell_warr_bloodthirst_SpellScript::HandleDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); +                OnEffectHit += SpellEffectFn(spell_warr_bloodthirst_SpellScript::HandleDummy, EFFECT_1, SPELL_EFFECT_DUMMY);              }          }; @@ -415,6 +429,38 @@ class spell_warr_bloodthirst : public SpellScriptLoader          }  }; +enum BloodthirstHeal +{ +    SPELL_BLOODTHIRST_DAMAGE = 23881, +}; + +class spell_warr_bloodthirst_heal : public SpellScriptLoader +{ +    public: +        spell_warr_bloodthirst_heal() : SpellScriptLoader("spell_warr_bloodthirst_heal") { } + +        class spell_warr_bloodthirst_heal_SpellScript : public SpellScript +        { +            PrepareSpellScript(spell_warr_bloodthirst_heal_SpellScript); + +            void HandleHeal(SpellEffIndex /*effIndex*/) +            { +                if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(SPELL_BLOODTHIRST_DAMAGE)) +                    SetHitHeal(GetCaster()->CountPctFromMaxHealth(spellInfo->Effects[EFFECT_1].CalcValue(GetCaster()))); +            } + +            void Register() +            { +                OnEffectHitTarget += SpellEffectFn(spell_warr_bloodthirst_heal_SpellScript::HandleHeal, EFFECT_0, SPELL_EFFECT_HEAL); +            } +        }; + +        SpellScript* GetSpellScript() const +        { +            return new spell_warr_bloodthirst_heal_SpellScript(); +        } +}; +  enum Overpower  {      SPELL_UNRELENTING_ASSAULT_RANK_1        = 46859, @@ -471,5 +517,6 @@ void AddSC_warrior_spell_scripts()      new spell_warr_execute();      new spell_warr_concussion_blow();      new spell_warr_bloodthirst(); +    new spell_warr_bloodthirst_heal();      new spell_warr_overpower();  } diff --git a/src/server/scripts/World/achievement_scripts.cpp b/src/server/scripts/World/achievement_scripts.cpp index 9bcf450b3aa..3dc737f0c95 100755 --- a/src/server/scripts/World/achievement_scripts.cpp +++ b/src/server/scripts/World/achievement_scripts.cpp @@ -313,6 +313,27 @@ class achievement_tilted : public AchievementCriteriaScript          }  }; +class achievement_not_even_a_scratch : public AchievementCriteriaScript +{ +    public: +        achievement_not_even_a_scratch() : AchievementCriteriaScript("achievement_not_even_a_scratch") { } + +        bool OnCheck(Player* source, Unit* /*target*/) +        { +            if (!source) +                return false; + +            Battleground* battleground = source->GetBattleground(); +            if (!battleground) +                return false; + +            if (static_cast<BattlegroundSA*>(battleground)->notEvenAScratch(source->GetTeam())) +                return true; + +            return false; +        } +}; +  void AddSC_achievement_scripts()  {      new achievement_resilient_victory(); @@ -331,4 +352,5 @@ void AddSC_achievement_scripts()      new achievement_arena_kills("achievement_arena_5v5_kills", ARENA_TYPE_5v5);      new achievement_bg_sa_defense_of_ancients();      new achievement_tilted(); +    new achievement_not_even_a_scratch();  } diff --git a/src/server/scripts/World/boss_emerald_dragons.cpp b/src/server/scripts/World/boss_emerald_dragons.cpp index 045dea9c9a9..abb20130ef8 100644 --- a/src/server/scripts/World/boss_emerald_dragons.cpp +++ b/src/server/scripts/World/boss_emerald_dragons.cpp @@ -224,9 +224,9 @@ class DreamFogTargetSelector      public:          DreamFogTargetSelector() { } -        bool operator()(Unit* unit) +        bool operator()(WorldObject* object) const          { -            return unit->HasAura(SPELL_SLEEP); +            return object->ToUnit() && object->ToUnit()->HasAura(SPELL_SLEEP);          }  }; @@ -239,14 +239,14 @@ class spell_dream_fog_sleep : public SpellScriptLoader          {              PrepareSpellScript(spell_dream_fog_sleep_SpellScript); -            void FilterTargets(std::list<Unit*>& unitList) +            void FilterTargets(std::list<WorldObject*>& unitList)              { -                unitList.remove_if (DreamFogTargetSelector()); +                unitList.remove_if(DreamFogTargetSelector());              }              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_dream_fog_sleep_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_dream_fog_sleep_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);              }          }; @@ -265,10 +265,12 @@ class MarkOfNatureTargetSelector      public:          MarkOfNatureTargetSelector() { } -        bool operator()(Unit* unit) +        bool operator()(WorldObject* object) const          { -            // return anyone that isn't tagged or already under the influence of Aura of Nature -            return !(unit->HasAura(SPELL_MARK_OF_NATURE) && !unit->HasAura(SPELL_AURA_OF_NATURE)); +            if (Unit* unit = object->ToUnit()) +                // return anyone that isn't tagged or already under the influence of Aura of Nature +                return !(unit->HasAura(SPELL_MARK_OF_NATURE) && !unit->HasAura(SPELL_AURA_OF_NATURE)); +            return true;          }  }; @@ -290,9 +292,9 @@ class spell_mark_of_nature : public SpellScriptLoader                  return true;              } -            void FilterTargets(std::list<Unit*>& unitList) +            void FilterTargets(std::list<WorldObject*>& targets)              { -                unitList.remove_if (MarkOfNatureTargetSelector()); +                targets.remove_if(MarkOfNatureTargetSelector());              }              void HandleEffect(SpellEffIndex effIndex) @@ -305,7 +307,7 @@ class spell_mark_of_nature : public SpellScriptLoader              void Register()              { -                OnUnitTargetSelect += SpellUnitTargetFn(spell_mark_of_nature_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mark_of_nature_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);                  OnEffectHitTarget += SpellEffectFn(spell_mark_of_nature_SpellScript::HandleEffect, EFFECT_0, SPELL_EFFECT_APPLY_AURA);              }          }; diff --git a/src/server/scripts/World/go_scripts.cpp b/src/server/scripts/World/go_scripts.cpp index 790a9d0f814..21a852ae9ed 100644 --- a/src/server/scripts/World/go_scripts.cpp +++ b/src/server/scripts/World/go_scripts.cpp @@ -1245,6 +1245,58 @@ class go_veil_skith_cage : public GameObjectScript         }  }; +/*###### +## go_frostblade_shrine +######*/ + +enum TheCleansing +{ +   QUEST_THE_CLEANSING_HORDE      = 11317, +   QUEST_THE_CLEANSING_ALLIANCE   = 11322, +   SPELL_CLEANSING_SOUL           = 43351, +   SPELL_RECENT_MEDITATION        = 61720, +}; + +class go_frostblade_shrine : public GameObjectScript +{ +public: +    go_frostblade_shrine() : GameObjectScript("go_frostblade_shrine") { } + +    bool OnGossipHello(Player* player, GameObject* go) +    { +        if (!player->HasAura(SPELL_RECENT_MEDITATION)) +            if (player->GetQuestStatus(QUEST_THE_CLEANSING_HORDE) == QUEST_STATUS_INCOMPLETE || player->GetQuestStatus(QUEST_THE_CLEANSING_ALLIANCE) == QUEST_STATUS_INCOMPLETE) +            { +                go->UseDoorOrButton(10); +                player->CastSpell(player, SPELL_CLEANSING_SOUL); +                player->SetStandState(UNIT_STAND_STATE_SIT); +            } +            return true; +    } +}; + +/*###### +## go_midsummer_bonfire +######*/ + +enum eMidsummerBonfire +{ +    STAMP_OUT_BONFIRE_QUEST_COMPLETE    = 45458, +}; + +class go_midsummer_bonfire : public GameObjectScript +{ +public: +    go_midsummer_bonfire() : GameObjectScript("go_midsummer_bonfire") { } + +    bool OnGossipSelect(Player* player, GameObject* /*go*/, uint32 /*sender*/, uint32 /*action*/) +    { +        player->CastSpell(player, STAMP_OUT_BONFIRE_QUEST_COMPLETE, true); +        player->CLOSE_GOSSIP_MENU(); +        return false; +    } +}; +  void AddSC_go_scripts()  {      new go_cat_figurine; @@ -1285,4 +1337,6 @@ void AddSC_go_scripts()      new go_gjalerbron_cage;      new go_large_gjalerbron_cage;      new go_veil_skith_cage; +    new go_frostblade_shrine; +    new go_midsummer_bonfire;  } diff --git a/src/server/scripts/World/npcs_special.cpp b/src/server/scripts/World/npcs_special.cpp index ecd1a439a58..57a65423b6f 100644 --- a/src/server/scripts/World/npcs_special.cpp +++ b/src/server/scripts/World/npcs_special.cpp @@ -47,6 +47,7 @@ EndContentData */  #include "ObjectMgr.h"  #include "ScriptMgr.h"  #include "World.h" +#include "PetAI.h"  /*########  # npc_air_force_bots @@ -2100,16 +2101,18 @@ class npc_shadowfiend : public CreatureScript      public:          npc_shadowfiend() : CreatureScript("npc_shadowfiend") { } -        struct npc_shadowfiendAI : public ScriptedAI +        struct npc_shadowfiendAI : public PetAI          { -            npc_shadowfiendAI(Creature* creature) : ScriptedAI(creature) {} +            npc_shadowfiendAI(Creature* creature) : PetAI(creature) {} -            void DamageTaken(Unit* /*killer*/, uint32& damage) +            void JustDied(Unit* killer)              {                  if (me->isSummon())                      if (Unit* owner = me->ToTempSummon()->GetSummoner()) -                        if (owner->HasAura(GLYPH_OF_SHADOWFIEND) && damage >= me->GetHealth()) +                        if (owner->HasAura(GLYPH_OF_SHADOWFIEND))                              owner->CastSpell(owner, GLYPH_OF_SHADOWFIEND_MANA, true); + +                PetAI::JustDied(killer);              }          }; @@ -2988,6 +2991,31 @@ public:      };  }; +/*###### +## npc_generic_harpoon_cannon +######*/ + +class npc_generic_harpoon_cannon : public CreatureScript +{ +public: +    npc_generic_harpoon_cannon() : CreatureScript("npc_generic_harpoon_cannon") { } + +    struct npc_generic_harpoon_cannonAI : public ScriptedAI +    { +        npc_generic_harpoon_cannonAI(Creature* creature) : ScriptedAI(creature) {} + +        void Reset() +        { +            me->SetUnitMovementFlags(MOVEMENTFLAG_ROOT); +        } +    }; + +    CreatureAI* GetAI(Creature* creature) const +    { +        return new npc_generic_harpoon_cannonAI(creature); +    } +}; +  void AddSC_npcs_special()  {      new npc_air_force_bots(); @@ -3020,4 +3048,5 @@ void AddSC_npcs_special()      new npc_earth_elemental();      new npc_firework();      new npc_spring_rabbit(); +    new npc_generic_harpoon_cannon();  } diff --git a/src/server/shared/Cryptography/WardenKeyGeneration.h b/src/server/shared/Cryptography/WardenKeyGeneration.h index 9b44ab1832e..f0a9905b6fe 100644 --- a/src/server/shared/Cryptography/WardenKeyGeneration.h +++ b/src/server/shared/Cryptography/WardenKeyGeneration.h @@ -21,50 +21,56 @@  #ifndef _WARDEN_KEY_GENERATION_H  #define _WARDEN_KEY_GENERATION_H -class SHA1Randx { +class SHA1Randx +{  public: -    SHA1Randx(uint8 *buff, uint32 size) { +    SHA1Randx(uint8* buff, uint32 size) +    {          uint32 taken = size/2;          sh.Initialize(); -        sh.UpdateData(buff,taken); +        sh.UpdateData(buff, taken);          sh.Finalize(); -        memcpy(o1,sh.GetDigest(),20); +        memcpy(o1, sh.GetDigest(), 20);          sh.Initialize(); -        sh.UpdateData(buff+taken,size-taken); +        sh.UpdateData(buff + taken, size - taken);          sh.Finalize(); -        memcpy(o2,sh.GetDigest(),20); +        memcpy(o2, sh.GetDigest(), 20); -        memset(o0,0x00,20); +        memset(o0, 0x00, 20); -        fillUp(); +        FillUp();      } -    void generate(uint8 *buf, uint32 sz) { -        for(uint32 i=0;i<sz;i++) { -            if(taken == 20) { -                fillUp(); -            } +    void Generate(uint8* buf, uint32 sz) +    { +        for (uint32 i = 0; i < sz; ++i) +        { +            if (taken == 20) +                FillUp();              buf[i] = o0[taken];              taken++;          }      } +  private: -    void fillUp() { +    void FillUp() +    {          sh.Initialize(); -        sh.UpdateData(o1,20); -        sh.UpdateData(o0,20); -        sh.UpdateData(o2,20); +        sh.UpdateData(o1, 20); +        sh.UpdateData(o0, 20); +        sh.UpdateData(o2, 20);          sh.Finalize(); -        memcpy(o0,sh.GetDigest(),20); +        memcpy(o0, sh.GetDigest(), 20);          taken = 0;      } +      SHA1Hash sh;      uint32 taken;      uint8 o0[20],o1[20],o2[20]; diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp index ea9165f86ec..27bf92ad846 100755 --- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp @@ -317,18 +317,17 @@ void CharacterDatabaseConnection::DoPrepareStatements()      PREPARE_STATEMENT(CHAR_DEL_OLD_CORPSES, "DELETE FROM corpse WHERE corpseType = 0 OR time < (UNIX_TIMESTAMP(NOW()) - ?)", CONNECTION_ASYNC)      // Creature respawn -    PREPARE_STATEMENT(CHAR_SEL_CREATURE_RESPAWNS, "SELECT guid, respawnTime, instanceId FROM creature_respawn", CONNECTION_SYNCH) -    PREPARE_STATEMENT(CHAR_REP_CREATURE_RESPAWN, "REPLACE INTO creature_respawn (guid, respawnTime, instanceId) VALUES (?, ?, ?)", CONNECTION_ASYNC) -    PREPARE_STATEMENT(CHAR_DEL_CREATURE_RESPAWN, "DELETE FROM creature_respawn WHERE guid = ? AND instanceId = ?", CONNECTION_ASYNC) -    PREPARE_STATEMENT(CHAR_DEL_CREATURE_RESPAWN_BY_GUID, "DELETE FROM creature_respawn WHERE guid = ?", CONNECTION_ASYNC) -    PREPARE_STATEMENT(CHAR_DEL_CREATURE_RESPAWN_BY_INSTANCE, "DELETE FROM creature_respawn WHERE instanceId = ?", CONNECTION_ASYNC) +    PREPARE_STATEMENT(CHAR_SEL_CREATURE_RESPAWNS, "SELECT guid, respawnTime FROM creature_respawn WHERE mapId = ? AND instanceId = ?", CONNECTION_SYNCH) +    PREPARE_STATEMENT(CHAR_REP_CREATURE_RESPAWN, "REPLACE INTO creature_respawn (guid, respawnTime, mapId, instanceId) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC) +    PREPARE_STATEMENT(CHAR_DEL_CREATURE_RESPAWN, "DELETE FROM creature_respawn WHERE guid = ? AND mapId = ? AND instanceId = ?", CONNECTION_ASYNC) +    PREPARE_STATEMENT(CHAR_DEL_CREATURE_RESPAWN_BY_INSTANCE, "DELETE FROM creature_respawn WHERE mapId = ? AND instanceId = ?", CONNECTION_ASYNC)      PREPARE_STATEMENT(CHAR_SEL_MAX_CREATURE_RESPAWNS, "SELECT MAX(respawnTime), instanceId FROM creature_respawn WHERE instanceId > 0 GROUP BY instanceId", CONNECTION_SYNCH)      // Gameobject respawn -    PREPARE_STATEMENT(CHAR_SEL_GO_RESPAWNS, "SELECT guid, respawnTime, instanceId FROM gameobject_respawn", CONNECTION_SYNCH) -    PREPARE_STATEMENT(CHAR_REP_GO_RESPAWN, "REPLACE INTO gameobject_respawn (guid, respawnTime, instanceId) VALUES (?, ?, ?)", CONNECTION_ASYNC) -    PREPARE_STATEMENT(CHAR_DEL_GO_RESPAWN, "DELETE FROM gameobject_respawn WHERE guid = ? AND instanceId = ?", CONNECTION_ASYNC) -    PREPARE_STATEMENT(CHAR_DEL_GO_RESPAWN_BY_INSTANCE, "DELETE FROM gameobject_respawn WHERE instanceId = ?", CONNECTION_ASYNC) +    PREPARE_STATEMENT(CHAR_SEL_GO_RESPAWNS, "SELECT guid, respawnTime FROM gameobject_respawn WHERE mapId = ? AND instanceId = ?", CONNECTION_SYNCH) +    PREPARE_STATEMENT(CHAR_REP_GO_RESPAWN, "REPLACE INTO gameobject_respawn (guid, respawnTime, mapId, instanceId) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC) +    PREPARE_STATEMENT(CHAR_DEL_GO_RESPAWN, "DELETE FROM gameobject_respawn WHERE guid = ? AND mapId = ? AND instanceId = ?", CONNECTION_ASYNC) +    PREPARE_STATEMENT(CHAR_DEL_GO_RESPAWN_BY_INSTANCE, "DELETE FROM gameobject_respawn WHERE mapId = ? AND instanceId = ?", CONNECTION_ASYNC)      // GM Tickets      PREPARE_STATEMENT(CHAR_SEL_GM_TICKETS, "SELECT ticketId, guid, name, message, createTime, mapId, posX, posY, posZ, lastModifiedTime, closedBy, assignedTo, comment, completed, escalated, viewed FROM gm_tickets", CONNECTION_SYNCH) diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.h b/src/server/shared/Database/Implementation/CharacterDatabase.h index 51ab97fe021..08265c455d6 100755 --- a/src/server/shared/Database/Implementation/CharacterDatabase.h +++ b/src/server/shared/Database/Implementation/CharacterDatabase.h @@ -298,7 +298,6 @@ enum CharacterDatabaseStatements      CHAR_SEL_CREATURE_RESPAWNS,      CHAR_REP_CREATURE_RESPAWN,      CHAR_DEL_CREATURE_RESPAWN, -    CHAR_DEL_CREATURE_RESPAWN_BY_GUID,      CHAR_DEL_CREATURE_RESPAWN_BY_INSTANCE,      CHAR_SEL_MAX_CREATURE_RESPAWNS, diff --git a/src/server/shared/Database/PreparedStatement.cpp b/src/server/shared/Database/PreparedStatement.cpp index db26dabaee7..58aa2bd3aa0 100755 --- a/src/server/shared/Database/PreparedStatement.cpp +++ b/src/server/shared/Database/PreparedStatement.cpp @@ -209,7 +209,7 @@ m_bind(NULL)  MySQLPreparedStatement::~MySQLPreparedStatement()  {      ClearParameters(); -    if(m_Mstmt->bind_result_done) +    if (m_Mstmt->bind_result_done)      {          delete[] m_Mstmt->bind->length;          delete[] m_Mstmt->bind->is_null; diff --git a/src/server/shared/Packets/ByteBuffer.h b/src/server/shared/Packets/ByteBuffer.h index bc87950da16..27d5e78bac5 100755 --- a/src/server/shared/Packets/ByteBuffer.h +++ b/src/server/shared/Packets/ByteBuffer.h @@ -326,8 +326,7 @@ class ByteBuffer          ByteBuffer &operator<<(const char *str)          { -            size_t len = 0; -            if (str && (len = strlen(str))) +            if (size_t len = (str ? strlen(str) : 0))                  append((uint8 const*)str, len);              append((uint8)0);              return *this; diff --git a/src/server/worldserver/CommandLine/CliRunnable.cpp b/src/server/worldserver/CommandLine/CliRunnable.cpp index e85a3e1870d..699e7cad97c 100755 --- a/src/server/worldserver/CommandLine/CliRunnable.cpp +++ b/src/server/worldserver/CommandLine/CliRunnable.cpp @@ -116,458 +116,6 @@ void commandFinished(void*, bool /*success*/)      fflush(stdout);  } -/** - * Collects all GUIDs (and related info) from deleted characters which are still in the database. - * - * @param foundList    a reference to an std::list which will be filled with info data - * @param searchString the search string which either contains a player GUID or a part fo the character-name - * @return             returns false if there was a problem while selecting the characters (e.g. player name not normalizeable) - */ -bool ChatHandler::GetDeletedCharacterInfoList(DeletedInfoList& foundList, std::string searchString) -{ -    PreparedQueryResult result; -    PreparedStatement* stmt; -    if (!searchString.empty()) -    { -        // search by GUID -        if (isNumeric(searchString.c_str())) -        { -            stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_DEL_INFO_BY_GUID); - -            stmt->setUInt32(0, uint32(atoi(searchString.c_str()))); - -            result = CharacterDatabase.Query(stmt); -        } -        // search by name -        else -        { -            if (!normalizePlayerName(searchString)) -                return false; - -            stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_DEL_INFO_BY_NAME); - -            stmt->setString(0, searchString); - -            result = CharacterDatabase.Query(stmt); -        } -    } -    else -    { -        stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_DEL_INFO); - -        result = CharacterDatabase.Query(stmt); -    } - -    if (result) -    { -        do -        { -            Field* fields = result->Fetch(); - -            DeletedInfo info; - -            info.lowguid    = fields[0].GetUInt32(); -            info.name       = fields[1].GetString(); -            info.accountId  = fields[2].GetUInt32(); - -            // account name will be empty for not existed account -            AccountMgr::GetName(info.accountId, info.accountName); - -            info.deleteDate = time_t(fields[3].GetUInt32()); - -            foundList.push_back(info); -        } while (result->NextRow()); -    } - -    return true; -} - -/** - * Generate WHERE guids list by deleted info in way preventing return too long where list for existed query string length limit. - * - * @param itr          a reference to an deleted info list iterator, it updated in function for possible next function call if list to long - * @param itr_end      a reference to an deleted info list iterator end() - * @return             returns generated where list string in form: 'guid IN (gui1, guid2, ...)' - */ -std::string ChatHandler::GenerateDeletedCharacterGUIDsWhereStr(DeletedInfoList::const_iterator& itr, DeletedInfoList::const_iterator const& itr_end) -{ -    std::ostringstream wherestr; -    wherestr << "guid IN ('"; -    for (; itr != itr_end; ++itr) -    { -        wherestr << itr->lowguid; - -        if (wherestr.str().size() > MAX_QUERY_LEN - 50)     // near to max query -        { -            ++itr; -            break; -        } - -        DeletedInfoList::const_iterator itr2 = itr; -        if (++itr2 != itr_end) -            wherestr << "', '"; -    } -    wherestr << "')"; -    return wherestr.str(); -} - -/** - * Shows all deleted characters which matches the given search string, expected non empty list - * - * @see ChatHandler::HandleCharacterDeletedListCommand - * @see ChatHandler::HandleCharacterDeletedRestoreCommand - * @see ChatHandler::HandleCharacterDeletedDeleteCommand - * @see ChatHandler::DeletedInfoList - * - * @param foundList contains a list with all found deleted characters - */ -void ChatHandler::HandleCharacterDeletedListHelper(DeletedInfoList const& foundList) -{ -    if (!m_session) -    { -        SendSysMessage(LANG_CHARACTER_DELETED_LIST_BAR); -        SendSysMessage(LANG_CHARACTER_DELETED_LIST_HEADER); -        SendSysMessage(LANG_CHARACTER_DELETED_LIST_BAR); -    } - -    for (DeletedInfoList::const_iterator itr = foundList.begin(); itr != foundList.end(); ++itr) -    { -        std::string dateStr = TimeToTimestampStr(itr->deleteDate); - -        if (!m_session) -            PSendSysMessage(LANG_CHARACTER_DELETED_LIST_LINE_CONSOLE, -                itr->lowguid, itr->name.c_str(), itr->accountName.empty() ? "<Not existed>" : itr->accountName.c_str(), -                itr->accountId, dateStr.c_str()); -        else -            PSendSysMessage(LANG_CHARACTER_DELETED_LIST_LINE_CHAT, -                itr->lowguid, itr->name.c_str(), itr->accountName.empty() ? "<Not existed>" : itr->accountName.c_str(), -                itr->accountId, dateStr.c_str()); -    } - -    if (!m_session) -        SendSysMessage(LANG_CHARACTER_DELETED_LIST_BAR); -} - -/** - * Handles the '.character deleted list' command, which shows all deleted characters which matches the given search string - * - * @see ChatHandler::HandleCharacterDeletedListHelper - * @see ChatHandler::HandleCharacterDeletedRestoreCommand - * @see ChatHandler::HandleCharacterDeletedDeleteCommand - * @see ChatHandler::DeletedInfoList - * - * @param args the search string which either contains a player GUID or a part fo the character-name - */ -bool ChatHandler::HandleCharacterDeletedListCommand(const char* args) -{ -    DeletedInfoList foundList; -    if (!GetDeletedCharacterInfoList(foundList, args)) -        return false; - -    // if no characters have been found, output a warning -    if (foundList.empty()) -    { -        SendSysMessage(LANG_CHARACTER_DELETED_LIST_EMPTY); -        return false; -    } - -    HandleCharacterDeletedListHelper(foundList); -    return true; -} - -/** - * Restore a previously deleted character - * - * @see ChatHandler::HandleCharacterDeletedListHelper - * @see ChatHandler::HandleCharacterDeletedRestoreCommand - * @see ChatHandler::HandleCharacterDeletedDeleteCommand - * @see ChatHandler::DeletedInfoList - * - * @param delInfo the informations about the character which will be restored - */ -void ChatHandler::HandleCharacterDeletedRestoreHelper(DeletedInfo const& delInfo) -{ -    if (delInfo.accountName.empty())                    // account not exist -    { -        PSendSysMessage(LANG_CHARACTER_DELETED_SKIP_ACCOUNT, delInfo.name.c_str(), delInfo.lowguid, delInfo.accountId); -        return; -    } - -    // check character count -    uint32 charcount = AccountMgr::GetCharactersCount(delInfo.accountId); -    if (charcount >= 10) -    { -        PSendSysMessage(LANG_CHARACTER_DELETED_SKIP_FULL, delInfo.name.c_str(), delInfo.lowguid, delInfo.accountId); -        return; -    } - -    if (sObjectMgr->GetPlayerGUIDByName(delInfo.name)) -    { -        PSendSysMessage(LANG_CHARACTER_DELETED_SKIP_NAME, delInfo.name.c_str(), delInfo.lowguid, delInfo.accountId); -        return; -    } - -    PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UDP_RESTORE_DELETE_INFO); - -    stmt->setString(0, delInfo.name); -    stmt->setUInt32(1, delInfo.accountId); -    stmt->setUInt32(2, delInfo.lowguid); - -    CharacterDatabase.Execute(stmt); - -    stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_NAME_DATA); -    stmt->setUInt32(0, delInfo.lowguid); -    if (PreparedQueryResult result = CharacterDatabase.Query(stmt)) -        sWorld->AddCharacterNameData(delInfo.lowguid, delInfo.name, (*result)[2].GetUInt8(), (*result)[0].GetUInt8(), (*result)[1].GetUInt8()); -} - -/** - * Handles the '.character deleted restore' command, which restores all deleted characters which matches the given search string - * - * The command automatically calls '.character deleted list' command with the search string to show all restored characters. - * - * @see ChatHandler::HandleCharacterDeletedRestoreHelper - * @see ChatHandler::HandleCharacterDeletedListCommand - * @see ChatHandler::HandleCharacterDeletedDeleteCommand - * - * @param args the search string which either contains a player GUID or a part of the character-name - */ -bool ChatHandler::HandleCharacterDeletedRestoreCommand(const char* args) -{ -    // It is required to submit at least one argument -    if (!*args) -        return false; - -    std::string searchString; -    std::string newCharName; -    uint32 newAccount = 0; - -    // GCC by some strange reason fail build code without temporary variable -    std::istringstream params(args); -    params >> searchString >> newCharName >> newAccount; - -    DeletedInfoList foundList; -    if (!GetDeletedCharacterInfoList(foundList, searchString)) -        return false; - -    if (foundList.empty()) -    { -        SendSysMessage(LANG_CHARACTER_DELETED_LIST_EMPTY); -        return false; -    } - -    SendSysMessage(LANG_CHARACTER_DELETED_RESTORE); -    HandleCharacterDeletedListHelper(foundList); - -    if (newCharName.empty()) -    { -        // Drop not existed account cases -        for (DeletedInfoList::iterator itr = foundList.begin(); itr != foundList.end(); ++itr) -            HandleCharacterDeletedRestoreHelper(*itr); -    } -    else if (foundList.size() == 1 && normalizePlayerName(newCharName)) -    { -        DeletedInfo delInfo = foundList.front(); - -        // update name -        delInfo.name = newCharName; - -        // if new account provided update deleted info -        if (newAccount && newAccount != delInfo.accountId) -        { -            delInfo.accountId = newAccount; -            AccountMgr::GetName(newAccount, delInfo.accountName); -        } - -        HandleCharacterDeletedRestoreHelper(delInfo); -    } -    else -        SendSysMessage(LANG_CHARACTER_DELETED_ERR_RENAME); - -    return true; -} - -/** - * Handles the '.character deleted delete' command, which completely deletes all deleted characters which matches the given search string - * - * @see Player::GetDeletedCharacterGUIDs - * @see Player::DeleteFromDB - * @see ChatHandler::HandleCharacterDeletedListCommand - * @see ChatHandler::HandleCharacterDeletedRestoreCommand - * - * @param args the search string which either contains a player GUID or a part fo the character-name - */ -bool ChatHandler::HandleCharacterDeletedDeleteCommand(const char* args) -{ -    // It is required to submit at least one argument -    if (!*args) -        return false; - -    DeletedInfoList foundList; -    if (!GetDeletedCharacterInfoList(foundList, args)) -        return false; - -    if (foundList.empty()) -    { -        SendSysMessage(LANG_CHARACTER_DELETED_LIST_EMPTY); -        return false; -    } - -    SendSysMessage(LANG_CHARACTER_DELETED_DELETE); -    HandleCharacterDeletedListHelper(foundList); - -    // Call the appropriate function to delete them (current account for deleted characters is 0) -    for (DeletedInfoList::const_iterator itr = foundList.begin(); itr != foundList.end(); ++itr) -        Player::DeleteFromDB(itr->lowguid, 0, false, true); - -    return true; -} - -/** - * Handles the '.character deleted old' command, which completely deletes all deleted characters deleted with some days ago - * - * @see Player::DeleteOldCharacters - * @see Player::DeleteFromDB - * @see ChatHandler::HandleCharacterDeletedDeleteCommand - * @see ChatHandler::HandleCharacterDeletedListCommand - * @see ChatHandler::HandleCharacterDeletedRestoreCommand - * - * @param args the search string which either contains a player GUID or a part fo the character-name - */ -bool ChatHandler::HandleCharacterDeletedOldCommand(const char* args) -{ -    int32 keepDays = sWorld->getIntConfig(CONFIG_CHARDELETE_KEEP_DAYS); - -    char* px = strtok((char*)args, " "); -    if (px) -    { -        if (!isNumeric(px)) -            return false; - -        keepDays = atoi(px); -        if (keepDays < 0) -            return false; -    } -    // config option value 0 -> disabled and can't be used -    else if (keepDays <= 0) -        return false; - -    Player::DeleteOldCharacters((uint32)keepDays); -    return true; -} - -bool ChatHandler::HandleCharacterEraseCommand(const char* args){ -    if (!*args) -        return false; - -    char *character_name_str = strtok((char*)args, " "); -    if (!character_name_str) -        return false; - -    std::string character_name = character_name_str; -    if (!normalizePlayerName(character_name)) -        return false; - -    uint64 character_guid; -    uint32 account_id; - -    Player* player = sObjectAccessor->FindPlayerByName(character_name.c_str()); -    if (player) -    { -        character_guid = player->GetGUID(); -        account_id = player->GetSession()->GetAccountId(); -        player->GetSession()->KickPlayer(); -    } -    else -    { -        character_guid = sObjectMgr->GetPlayerGUIDByName(character_name); -        if (!character_guid) -        { -            PSendSysMessage(LANG_NO_PLAYER, character_name.c_str()); -            SetSentErrorMessage(true); -            return false; -        } - -        account_id = sObjectMgr->GetPlayerAccountIdByGUID(character_guid); -    } - -    std::string account_name; -    AccountMgr::GetName (account_id, account_name); - -    Player::DeleteFromDB(character_guid, account_id, true, true); -    PSendSysMessage(LANG_CHARACTER_DELETED, character_name.c_str(), GUID_LOPART(character_guid), account_name.c_str(), account_id); -    return true; -} - -/// Exit the realm -bool ChatHandler::HandleServerExitCommand(const char* /*args*/) -{ -    SendSysMessage(LANG_COMMAND_EXIT); -    World::StopNow(SHUTDOWN_EXIT_CODE); -    return true; -} - -/// Set the level of logging -bool ChatHandler::HandleServerSetLogFileLevelCommand(const char *args) -{ -    if (!*args) -        return false; - -    char *NewLevel = strtok((char*)args, " "); -    if (!NewLevel) -        return false; - -    sLog->SetLogFileLevel(NewLevel); -    return true; -} - -/// Set the level of logging -bool ChatHandler::HandleServerSetLogLevelCommand(const char *args) -{ -    if (!*args) -        return false; - -    char *NewLevel = strtok((char*)args, " "); -    if (!NewLevel) -        return false; - -    sLog->SetLogLevel(NewLevel); -    return true; -} - -/// set diff time record interval -bool ChatHandler::HandleServerSetDiffTimeCommand(const char *args) -{ -    if (!*args) -        return false; - -    char *NewTimeStr = strtok((char*)args, " "); -    if (!NewTimeStr) -        return false; - -    int32 NewTime =atoi(NewTimeStr); -    if (NewTime < 0) -        return false; - -    sWorld->SetRecordDiffInterval(NewTime); -    printf( "Record diff every %u ms\n", NewTime); -    return true; -} - -/// toggle sql driver query logging -bool ChatHandler::HandleServerToggleQueryLogging(const char* /* args */) -{ -    sLog->SetSQLDriverQueryLogging(!sLog->GetSQLDriverQueryLogging()); -    if (sLog->GetSQLDriverQueryLogging()) -        PSendSysMessage(LANG_SQLDRIVER_QUERY_LOGGING_ENABLED); -    else -        PSendSysMessage(LANG_SQLDRIVER_QUERY_LOGGING_DISABLED); - -    return true; -} - -/// @} -  #ifdef linux  // Non-blocking keypress detector, when return pressed, return 1, else always return 0  int kb_hit_return() diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index 6c598667a1f..110b7744b94 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -484,12 +484,13 @@ LogFileLevel = 0  DebugLogMask = 0  # -#    WorldLogFile -#        Description: Packet logging file for the world server. -#        Example:     "World.log" - (Enabled) +#    PacketLogFile +#        Description: Binary packet logging file for the world server. +#                     Filename extension must be .bin to be parsable with WowPacketParser. +#        Example:     "World.bin" - (Enabled)  #        Default:     ""          - (Disabled) -WorldLogFile = "" +PacketLogFile = ""  #  #    DBErrorLogFile @@ -2025,17 +2026,17 @@ Visibility.GroupMode = 1  #    Visibility.Distance.Instances  #    Visibility.Distance.BGArenas  #        Description: Visibility distance to see other players or gameobjects. -#                     Visibility on continents on retail ~90 yards. In BG/Arenas ~180. -#                     For instances default ~120. -#                     Max limited by active player zone: ~ 333 +#                     Visibility on continents on retail ~90 yards. In BG/Arenas ~533. +#                     For instances default ~170. +#                     Max limited by grid size: 533.33333  #                     Min limit is max aggro radius (45) * Rate.Creature.Aggro  #        Default:     90  - (Visibility.Distance.Continents) -#                     120 - (Visibility.Distance.Instances) -#                     180 - (Visibility.Distance.BGArenas) +#                     170 - (Visibility.Distance.Instances) +#                     533 - (Visibility.Distance.BGArenas)  Visibility.Distance.Continents = 90 -Visibility.Distance.Instances = 120 -Visibility.Distance.BGArenas = 180 +Visibility.Distance.Instances = 170 +Visibility.Distance.BGArenas = 533  #  #    Visibility.Notify.Period.OnContinents @@ -2515,6 +2516,13 @@ Arena.MaxRatingDifference = 150  Arena.RatingDiscardTimer = 600000  # +#    Arena.RatedUpdateTimer +#        Description: Time (in milliseconds) between checks for matchups in rated arena +#        Default:     5000 - (5 seconds) + +Arena.RatedUpdateTimer = 5000 + +#  #    Arena.AutoDistributePoints  #        Description: Automatically distribute arena points.  #        Default:     0 - (Disabled)  | 
