diff options
51 files changed, 1010 insertions, 677 deletions
diff --git a/sql/TBC-WLK converter/TBC-WLK_world.sql b/sql/TBC-WLK converter/TBC-WLK_world.sql index 21b3ed5ab0a..53bf9dce9bc 100644 --- a/sql/TBC-WLK converter/TBC-WLK_world.sql +++ b/sql/TBC-WLK converter/TBC-WLK_world.sql @@ -100,6 +100,10 @@ CREATE TABLE `spell_affect` (    PRIMARY KEY  (`entry`,`effectId`)  ) ENGINE=MyISAM DEFAULT CHARSET=utf8; +ALTER TABLE skill_discovery_template +   DROP PRIMARY KEY, +   ADD PRIMARY KEY (`spellId`,`reqSpell`), +   ADD COLUMN reqClass tinyint(2) unsigned NOT NULL default '0' COMMENT 'class requirement' AFTER reqSpell;  -- command  DELETE FROM `command` WHERE `name` = 'modify runicpower'; diff --git a/sql/characters.sql b/sql/characters.sql index c3d8cffdd26..92cda40fdf6 100644 --- a/sql/characters.sql +++ b/sql/characters.sql @@ -21,7 +21,7 @@  DROP TABLE IF EXISTS `character_db_version`;  CREATE TABLE `character_db_version` ( -  `required_7100_01_characters_character_spell` bit(1) default NULL +  `required_7113_01_characters_character_achievement_progress` bit(1) default NULL  ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Last applied sql update to DB';  -- diff --git a/sql/mangos.sql b/sql/mangos.sql index 8d4088f95d7..b2198d4f765 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -22,7 +22,7 @@  DROP TABLE IF EXISTS `db_version`;  CREATE TABLE `db_version` (    `version` varchar(120) default NULL, -  `required_7107_01_mangos_string` bit(1) default NULL +  `required_7118_01_mangos_skill_discovery_template` bit(1) default NULL  ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';  -- @@ -12999,8 +12999,9 @@ DROP TABLE IF EXISTS `skill_discovery_template`;  CREATE TABLE `skill_discovery_template` (    `spellId` mediumint(8) unsigned NOT NULL default '0' COMMENT 'SpellId of the discoverable spell',    `reqSpell` mediumint(8) unsigned NOT NULL default '0' COMMENT 'spell requirement', +  `reqClass` tinyint(2) unsigned NOT NULL default '0' COMMENT 'class requirement',    `chance` float NOT NULL default '0' COMMENT 'chance to discover', -  PRIMARY KEY  (`spellId`) +  PRIMARY KEY (`spellId`,`reqSpell`)  ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Skill Discovery System';  -- diff --git a/sql/updates/7113_01_characters_character_achievement_progress.sql b/sql/updates/7113_01_characters_character_achievement_progress.sql new file mode 100644 index 00000000000..6e38cd9981f --- /dev/null +++ b/sql/updates/7113_01_characters_character_achievement_progress.sql @@ -0,0 +1,3 @@ +ALTER TABLE character_db_version CHANGE COLUMN required_7100_01_characters_character_spell required_7113_01_characters_character_achievement_progress bit; + +DELETE FROM character_achievement_progress WHERE counter=0; diff --git a/sql/updates/7118_01_mangos_skill_discovery_template.sql b/sql/updates/7118_01_mangos_skill_discovery_template.sql new file mode 100644 index 00000000000..f854855e64d --- /dev/null +++ b/sql/updates/7118_01_mangos_skill_discovery_template.sql @@ -0,0 +1,6 @@ +ALTER TABLE db_version CHANGE COLUMN required_7107_01_mangos_string required_7118_01_mangos_skill_discovery_template bit; + +ALTER TABLE skill_discovery_template +   DROP PRIMARY KEY, +   ADD PRIMARY KEY (`spellId`,`reqSpell`), +   ADD COLUMN reqClass tinyint(2) unsigned NOT NULL default '0' COMMENT 'class requirement' AFTER reqSpell; diff --git a/src/framework/GameSystem/NGrid.h b/src/framework/GameSystem/NGrid.h index 77d82d1e60b..b6a59361bcf 100644 --- a/src/framework/GameSystem/NGrid.h +++ b/src/framework/GameSystem/NGrid.h @@ -76,12 +76,12 @@ class TRINITY_DLL_DECL NGrid          const GridType& operator()(unsigned short x, unsigned short y) const { return i_cells[x][y]; }          GridType& operator()(unsigned short x, unsigned short y) { return i_cells[x][y]; } -        inline const uint32& GetGridId(void) const { return i_gridId; } -        inline void SetGridId(const uint32 id) const { i_gridId = id; } -        inline grid_state_t GetGridState(void) const { return i_cellstate; } -        inline void SetGridState(grid_state_t s) { i_cellstate = s; } -        inline int32 getX() const { return i_x; } -        inline int32 getY() const { return i_y; } +        const uint32& GetGridId(void) const { return i_gridId; } +        void SetGridId(const uint32 id) const { i_gridId = id; } +        grid_state_t GetGridState(void) const { return i_cellstate; } +        void SetGridState(grid_state_t s) { i_cellstate = s; } +        int32 getX() const { return i_x; } +        int32 getY() const { return i_y; }          void link(GridRefManager<NGrid<N, ACTIVE_OBJECT, WORLD_OBJECT_TYPES, GRID_OBJECT_TYPES, ThreadModel> >* pTo)          { diff --git a/src/framework/Policies/ObjectLifeTime.h b/src/framework/Policies/ObjectLifeTime.h index fac827b3803..b518be2b621 100644 --- a/src/framework/Policies/ObjectLifeTime.h +++ b/src/framework/Policies/ObjectLifeTime.h @@ -34,7 +34,7 @@ namespace Trinity          class TRINITY_DLL_DECL ObjectLifeTime      {          public: -            inline static void ScheduleCall(void (*destroyer)() ) +            static void ScheduleCall(void (*destroyer)() )              {                  at_exit( destroyer );              } @@ -44,7 +44,7 @@ namespace Trinity      };      template <class T> -        inline void ObjectLifeTime<T>::OnDeadReference(void)// We don't handle Dead Reference for now +        void ObjectLifeTime<T>::OnDeadReference(void)       // We don't handle Dead Reference for now      {          throw std::runtime_error("Dead Reference");      } diff --git a/src/framework/Utilities/LinkedReference/Reference.h b/src/framework/Utilities/LinkedReference/Reference.h index bce0e0f387c..6e2bba658b8 100644 --- a/src/framework/Utilities/LinkedReference/Reference.h +++ b/src/framework/Utilities/LinkedReference/Reference.h @@ -44,7 +44,7 @@ template <class TO, class FROM> class Reference : public LinkedListElement          virtual ~Reference() {}          // Create new link -        inline void link(TO* toObj, FROM* fromObj) +        void link(TO* toObj, FROM* fromObj)          {              assert(fromObj);                                // fromObj MUST not be NULL              if(isValid()) @@ -59,16 +59,16 @@ template <class TO, class FROM> class Reference : public LinkedListElement          // We don't need the reference anymore. Call comes from the refFrom object          // Tell our refTo object, that the link is cut -        inline void unlink() { targetObjectDestroyLink(); delink(); iRefTo = NULL; iRefFrom = NULL; } +        void unlink() { targetObjectDestroyLink(); delink(); iRefTo = NULL; iRefFrom = NULL; }          // Link is invalid due to destruction of referenced target object. Call comes from the refTo object          // Tell our refFrom object, that the link is cut -        inline void invalidate()                            // the iRefFrom MUST remain!! +        void invalidate()                                   // the iRefFrom MUST remain!!          {              sourceObjectDestroyLink(); delink(); iRefTo = NULL;          } -        inline bool isValid() const                         // Only check the iRefTo +        bool isValid() const                                // Only check the iRefTo          {              return iRefTo != NULL;          } @@ -83,10 +83,10 @@ template <class TO, class FROM> class Reference : public LinkedListElement          Reference<TO,FROM>       * nocheck_prev()       { return((Reference<TO,FROM>       *) LinkedListElement::nocheck_prev()); }          Reference<TO,FROM> const * nocheck_prev() const { return((Reference<TO,FROM> const *) LinkedListElement::nocheck_prev()); } -        inline TO* operator ->() const { return iRefTo; } -        inline TO* getTarget() const { return iRefTo; } +        TO* operator ->() const { return iRefTo; } +        TO* getTarget() const { return iRefTo; } -        inline FROM* getSource() const { return iRefFrom; } +        FROM* getSource() const { return iRefFrom; }  };  //===================================================== diff --git a/src/game/AchievementMgr.cpp b/src/game/AchievementMgr.cpp index c4a634c15c0..598bca0087f 100644 --- a/src/game/AchievementMgr.cpp +++ b/src/game/AchievementMgr.cpp @@ -141,7 +141,8 @@ void AchievementMgr::SaveToDB()      if(!m_criteriaProgress.empty())      {          /// prepare deleting and insert -        bool need_execute = false; +        bool need_execute_del = false; +        bool need_execute_ins = false;          std::ostringstream ssdel;          std::ostringstream ssins;          for(CriteriaProgressMap::iterator iter = m_criteriaProgress.begin(); iter!=m_criteriaProgress.end(); ++iter) @@ -149,36 +150,53 @@ void AchievementMgr::SaveToDB()              if(!iter->second.changed)                  continue; -            /// first new/changed record prefix -            if(!need_execute) +            // deleted data (including 0 progress state)              { -                ssdel << "DELETE FROM character_achievement_progress WHERE guid = " << GetPlayer()->GetGUIDLow() << " AND criteria IN ("; -                ssins << "INSERT INTO character_achievement_progress (guid, criteria, counter, date) VALUES "; -                need_execute = true; +                /// first new/changed record prefix (for any counter value) +                if(!need_execute_del) +                { +                    ssdel << "DELETE FROM character_achievement_progress WHERE guid = " << GetPlayer()->GetGUIDLow() << " AND criteria IN ("; +                    need_execute_del = true; +                } +                /// next new/changed record prefix +                else +                    ssdel << ", "; + +                // new/changed record data +                ssdel << iter->first;              } -            /// next new/changed record prefix -            else + +            // store data only for real progress +            if(iter->second.counter != 0)              { -                ssdel << ", "; -                ssins << ", "; -            } +                /// first new/changed record prefix +                if(!need_execute_ins) +                { +                    ssins << "INSERT INTO character_achievement_progress (guid, criteria, counter, date) VALUES "; +                    need_execute_ins = true; +                } +                /// next new/changed record prefix +                else +                    ssins << ", "; -            // new/changed record data -            ssdel << iter->first; -            ssins << "(" << GetPlayer()->GetGUIDLow() << ", " << iter->first << ", " << iter->second.counter << ", " << iter->second.date << ")"; +                // new/changed record data +                ssins << "(" << GetPlayer()->GetGUIDLow() << ", " << iter->first << ", " << iter->second.counter << ", " << iter->second.date << ")"; +            } -            /// mark as saved in db +            /// mark as updated in db              iter->second.changed = false;          } -        if(need_execute) +        if(need_execute_del)                                // DELETE ... IN (.... _)_              ssdel << ")"; -        if(need_execute) +        if(need_execute_del || need_execute_ins)          {              CharacterDatabase.BeginTransaction (); -            CharacterDatabase.Execute( ssdel.str().c_str() ); -            CharacterDatabase.Execute( ssins.str().c_str() ); +            if(need_execute_del) +                CharacterDatabase.Execute( ssdel.str().c_str() ); +            if(need_execute_ins) +                CharacterDatabase.Execute( ssins.str().c_str() );              CharacterDatabase.CommitTransaction ();          }      } @@ -386,6 +404,10 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui                  if(GetPlayer()->HasSpell(achievementCriteria->learn_spell.spellID))                      SetCriteriaProgress(achievementCriteria, 1);                  break; +            case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT: +                if(m_completedAchievements.find(achievementCriteria->complete_achievement.linkedAchievement) != m_completedAchievements.end()) +                    SetCriteriaProgress(achievementCriteria, 1); +                break;              case ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP:                  // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case                  if(!miscvalue1) @@ -628,7 +650,7 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve          case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE:              return progress->counter >= achievementCriteria->kill_creature.creatureCount;          case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT: -            return m_completedAchievements.find(achievementCriteria->complete_achievement.linkedAchievement) != m_completedAchievements.end(); +            return progress->counter >= 1;          case ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL:              return progress->counter >= achievementCriteria->reach_skill_level.skillLevel;          case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT: @@ -729,6 +751,10 @@ void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry,      if(iter == m_criteriaProgress.end())      { +        // not create record for 0 counter +        if(newValue == 0) +            return; +          progress = &m_criteriaProgress[entry->ID];          progress->counter = newValue;          progress->date = time(NULL); @@ -738,8 +764,11 @@ void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry,          progress = &iter->second;          if(relative)              newValue += progress->counter; + +        // not update (not mark as changed) if counter will have same value          if(progress->counter == newValue)              return; +          progress->counter = newValue;      } diff --git a/src/game/AuctionHouseObject.h b/src/game/AuctionHouseObject.h index cccba8413da..d7edfd5869b 100644 --- a/src/game/AuctionHouseObject.h +++ b/src/game/AuctionHouseObject.h @@ -84,20 +84,12 @@ class AuctionHouseObject          AuctionEntry* GetAuction(uint32 id) const          {              AuctionEntryMap::const_iterator itr = AuctionsMap.find( id ); -            if( itr != AuctionsMap.end() ) -                return itr->second; -            return NULL; +            return itr != AuctionsMap.end() ? itr->second : NULL;          }          bool RemoveAuction(uint32 id)          { -            AuctionEntryMap::iterator i = AuctionsMap.find(id); -            if (i == AuctionsMap.end()) -            { -                return false; -            } -            AuctionsMap.erase(i); -            return true; +            return AuctionsMap.erase(id) ? true : false;          }      private: diff --git a/src/game/BattleGroundMgr.h b/src/game/BattleGroundMgr.h index 4e193284522..6a973f4f732 100644 --- a/src/game/BattleGroundMgr.h +++ b/src/game/BattleGroundMgr.h @@ -207,8 +207,8 @@ class BattleGroundMgr          uint32 CreateBattleGround(uint32 bgTypeId, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam, uint32 LevelMin, uint32 LevelMax, char* BattleGroundName, uint32 MapID, float Team1StartLocX, float Team1StartLocY, float Team1StartLocZ, float Team1StartLocO, float Team2StartLocX, float Team2StartLocY, float Team2StartLocZ, float Team2StartLocO); -        inline void AddBattleGround(uint32 ID, BattleGround* BG) { m_BattleGrounds[ID] = BG; }; -        inline void RemoveBattleGround(uint32 instanceID) { m_BattleGrounds.erase(instanceID); } +        void AddBattleGround(uint32 ID, BattleGround* BG) { m_BattleGrounds[ID] = BG; }; +        void RemoveBattleGround(uint32 instanceID) { m_BattleGrounds.erase(instanceID); }          void CreateInitialBattleGrounds(); diff --git a/src/game/Cell.h b/src/game/Cell.h index 35bcdbeea8a..a7e40a29683 100644 --- a/src/game/Cell.h +++ b/src/game/Cell.h @@ -93,13 +93,13 @@ struct TRINITY_DLL_DECL Cell          y = data.Part.grid_y*MAX_NUMBER_OF_CELLS + data.Part.cell_y;      } -    inline bool DiffCell(const Cell &cell) const +    bool DiffCell(const Cell &cell) const      {          return( data.Part.cell_x != cell.data.Part.cell_x ||              data.Part.cell_y != cell.data.Part.cell_y );      } -    inline bool DiffGrid(const Cell &cell) const +    bool DiffGrid(const Cell &cell) const      {          return( data.Part.grid_x != cell.data.Part.grid_x ||              data.Part.grid_y != cell.data.Part.grid_y ); diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp index 14c78201999..d30136993f3 100644 --- a/src/game/CharacterHandler.cpp +++ b/src/game/CharacterHandler.cpp @@ -1222,7 +1222,7 @@ void WorldSession::HandleRemoveGlyph( WorldPacket & recv_data )      uint32 slot;      recv_data >> slot; -    if(slot > 5) +    if(slot > MAX_GLYPH_SLOT_INDEX)      {          sLog.outDebug("Client sent wrong glyph slot number in opcode CMSG_REMOVE_GLYPH %u", slot);          return; diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index ecb16ce9521..7ce5de97297 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -910,13 +910,11 @@ void Creature::sendPreparedGossip(Player* player)      if(!player)          return; -    GossipMenu& gossipmenu = player->PlayerTalkClass->GetGossipMenu(); -      if(GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_WORLDEVENT) // if world event npc then          gameeventmgr.HandleWorldEventGossip(player, this);      // update world state with progress      // in case empty gossip menu open quest menu if any -    if (gossipmenu.Empty() && GetNpcTextId() == 0) +    if (player->PlayerTalkClass->GetGossipMenu().Empty() && !player->PlayerTalkClass->GetQuestMenu().Empty())      {          player->SendPreparedQuest(GetGUID());          return; diff --git a/src/game/GossipDef.cpp b/src/game/GossipDef.cpp index 90aa7304c90..7feeb195607 100644 --- a/src/game/GossipDef.cpp +++ b/src/game/GossipDef.cpp @@ -127,7 +127,7 @@ bool PlayerMenu::GossipOptionCoded( unsigned int Selection )  void PlayerMenu::SendGossipMenu( uint32 TitleTextId, uint64 npcGUID )  {      WorldPacket data( SMSG_GOSSIP_MESSAGE, (100) );         // guess size -    data << npcGUID; +    data << uint64(npcGUID);      data << uint32(0);                                      // new 2.4.0      data << uint32( TitleTextId );      data << uint32( mGossipMenu.MenuItemCount() );          // max count 0x0F diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index c68865a2794..b0cf4695afe 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -4488,8 +4488,10 @@ bool ChatHandler::HandleResetLevelCommand(const char * args)      // reset level to summoned pet      Pet* pet = player->GetPet();      if(pet && pet->getPetType()==SUMMON_PET) +    {          pet->InitStatsForLevel(1); - +        pet->InitTalentForLevel(); +    }      return true;  } @@ -4601,13 +4603,6 @@ bool ChatHandler::HandleResetTalentsCommand(const char * args)      else          player = getSelectedPlayer(); -    if(!player && !playerGUID) -    { -        SendSysMessage(LANG_NO_CHAR_SELECTED); -        SetSentErrorMessage(true); -        return false; -    } -      if(player)      {          player->resetTalents(true); @@ -4616,14 +4611,33 @@ bool ChatHandler::HandleResetTalentsCommand(const char * args)          if(m_session->GetPlayer()!=player)              PSendSysMessage(LANG_RESET_TALENTS_ONLINE,player->GetName()); +        return true;      } -    else +    else if (playerGUID)      {          CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",uint32(AT_LOGIN_RESET_TALENTS), GUID_LOPART(playerGUID) );          PSendSysMessage(LANG_RESET_TALENTS_OFFLINE,pName); +        return true; +    } +    // Try reset talenents as Hunter Pet +    Creature* creature = getSelectedCreature(); +    if (creature && creature->isPet() && ((Pet *)creature)->getPetType() == HUNTER_PET) +    { +        ((Pet *)creature)->resetTalents(true); +        Unit *owner = creature->GetOwner(); +        if (owner && owner->GetTypeId() == TYPEID_PLAYER) +        { +            player = (Player *)owner; +            ChatHandler(player).SendSysMessage(LANG_RESET_TALENTS); +            if(m_session->GetPlayer()!=player) +                PSendSysMessage(LANG_RESET_TALENTS_ONLINE,player->GetName()); +        } +        return true;      } -    return true; +    SendSysMessage(LANG_NO_CHAR_SELECTED); +    SetSentErrorMessage(true); +    return false;  }  bool ChatHandler::HandleResetAllCommand(const char * args) diff --git a/src/game/Map.cpp b/src/game/Map.cpp index c90effba476..0919db4ebe1 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -1657,14 +1657,6 @@ void Map::RemoveAllObjectsInRemoveList()      //sLog.outDebug("Object remover 2 check.");  } -bool Map::CanUnload(const uint32 &diff) -{ -    if(!m_unloadTimer) return false; -    if(m_unloadTimer < diff) return true; -    m_unloadTimer -= diff; -    return false; -} -  uint32 Map::GetPlayersCountExceptGMs() const  {      uint32 count = 0; diff --git a/src/game/Map.h b/src/game/Map.h index bae8889d3ee..bcdb4d9782c 100644 --- a/src/game/Map.h +++ b/src/game/Map.h @@ -133,7 +133,13 @@ class TRINITY_DLL_SPEC Map : public GridRefManager<NGridType>, public Trinity::O          virtual ~Map();          // currently unused for normal maps -        virtual bool CanUnload(const uint32& diff); +        bool CanUnload(uint32 diff) +        { +            if(!m_unloadTimer) return false; +            if(m_unloadTimer <= diff) return true; +            m_unloadTimer -= diff; +            return false; +        }          virtual bool Add(Player *);          virtual void Remove(Player *, bool); @@ -152,7 +158,7 @@ class TRINITY_DLL_SPEC Map : public GridRefManager<NGridType>, public Trinity::O          template<class LOCK_TYPE, class T, class CONTAINER> void Visit(const CellLock<LOCK_TYPE> &cell, TypeContainerVisitor<T, CONTAINER> &visitor); -        inline bool IsRemovalGrid(float x, float y) const +        bool IsRemovalGrid(float x, float y) const          {              GridPair p = Trinity::ComputeGridPair(x, y);              return( !getNGrid(p.x_coord, p.y_coord) || getNGrid(p.x_coord, p.y_coord)->GetGridState() == GRID_STATE_REMOVAL ); @@ -307,7 +313,7 @@ class TRINITY_DLL_SPEC Map : public GridRefManager<NGridType>, public Trinity::O          bool isGridObjectDataLoaded(uint32 x, uint32 y) const { return getNGrid(x,y)->isGridObjectDataLoaded(); }          void setGridObjectDataLoaded(bool pLoaded, uint32 x, uint32 y) { getNGrid(x,y)->setGridObjectDataLoaded(pLoaded); } -        inline void setNGrid(NGridType* grid, uint32 x, uint32 y); +        void setNGrid(NGridType* grid, uint32 x, uint32 y);          void UpdateActiveCells(const float &x, const float &y, const uint32 &t_diff);      protected: diff --git a/src/game/MapManager.h b/src/game/MapManager.h index e7ff17b0aa1..ec793b81a38 100644 --- a/src/game/MapManager.h +++ b/src/game/MapManager.h @@ -47,18 +47,18 @@ class TRINITY_DLL_DECL MapManager : public Trinity::Singleton<MapManager, Trinit          Map const* GetBaseMap(uint32 id) const { return const_cast<MapManager*>(this)->_GetBaseMap(id); }          void DeleteInstance(uint32 mapid, uint32 instanceId); -        inline uint16 GetAreaFlag(uint32 mapid, float x, float y, float z) const +        uint16 GetAreaFlag(uint32 mapid, float x, float y, float z) const          {              Map const* m = GetBaseMap(mapid);              return m->GetAreaFlag(x, y, z);          } -        inline uint32 GetAreaId(uint32 mapid, float x, float y, float z) { return Map::GetAreaId(GetAreaFlag(mapid, x, y, z),mapid); } -        inline uint32 GetZoneId(uint32 mapid, float x, float y, float z) { return Map::GetZoneId(GetAreaFlag(mapid, x, y, z),mapid); } +        uint32 GetAreaId(uint32 mapid, float x, float y, float z) const { return Map::GetAreaId(GetAreaFlag(mapid, x, y, z),mapid); } +        uint32 GetZoneId(uint32 mapid, float x, float y, float z) const { return Map::GetZoneId(GetAreaFlag(mapid, x, y, z),mapid); }          void Initialize(void);          void Update(time_t); -        inline void SetGridCleanUpDelay(uint32 t) +        void SetGridCleanUpDelay(uint32 t)          {              if( t < MIN_GRID_DELAY )                  i_gridCleanUpDelay = MIN_GRID_DELAY; @@ -66,7 +66,7 @@ class TRINITY_DLL_DECL MapManager : public Trinity::Singleton<MapManager, Trinit                  i_gridCleanUpDelay = t;          } -        inline void SetMapUpdateInterval(uint32 t) +        void SetMapUpdateInterval(uint32 t)          {              if( t > MIN_MAP_UPDATE_DELAY )                  t = MIN_MAP_UPDATE_DELAY; @@ -108,7 +108,7 @@ class TRINITY_DLL_DECL MapManager : public Trinity::Singleton<MapManager, Trinit          bool CanPlayerEnter(uint32 mapid, Player* player);          void RemoveBonesFromMap(uint32 mapid, uint64 guid, float x, float y); -        inline uint32 GenerateInstanceId() { return ++i_MaxInstanceId; } +        uint32 GenerateInstanceId() { return ++i_MaxInstanceId; }          void InitMaxInstanceId();          /* statistics */ diff --git a/src/game/ObjectAccessor.cpp b/src/game/ObjectAccessor.cpp index 872cf8280f5..dc451011110 100644 --- a/src/game/ObjectAccessor.cpp +++ b/src/game/ObjectAccessor.cpp @@ -277,22 +277,6 @@ ObjectAccessor::UpdateObject(Object* obj, Player* exceptPlayer)  }  void -ObjectAccessor::AddUpdateObject(Object *obj) -{ -    Guard guard(i_updateGuard); -    i_objects.insert(obj); -} - -void -ObjectAccessor::RemoveUpdateObject(Object *obj) -{ -    Guard guard(i_updateGuard); -    std::set<Object *>::iterator iter = i_objects.find(obj); -    if( iter != i_objects.end() ) -        i_objects.erase( iter ); -} - -void  ObjectAccessor::_buildUpdateObject(Object *obj, UpdateDataMapType &update_players)  {      bool build_for_all = true; diff --git a/src/game/ObjectAccessor.h b/src/game/ObjectAccessor.h index 3cb743be573..5d5568c536f 100644 --- a/src/game/ObjectAccessor.h +++ b/src/game/ObjectAccessor.h @@ -59,9 +59,7 @@ class HashMapHolder          static void Remove(T* o)          {              Guard guard(i_lock); -            typename MapType::iterator itr = m_objectMap.find(o->GetGUID()); -            if (itr != m_objectMap.end()) -                m_objectMap.erase(itr); +            m_objectMap.erase(o->GetGUID());          }          static T* Find(uint64 guid) @@ -176,16 +174,22 @@ class TRINITY_DLL_DECL ObjectAccessor : public Trinity::Singleton<ObjectAccessor              HashMapHolder<Player>::Remove(pl);              Guard guard(i_updateGuard); - -            std::set<Object *>::iterator iter2 = std::find(i_objects.begin(), i_objects.end(), (Object *)pl); -            if( iter2 != i_objects.end() ) -                i_objects.erase(iter2); +            i_objects.erase((Object *)pl);          }          void SaveAllPlayers(); -        void AddUpdateObject(Object *obj); -        void RemoveUpdateObject(Object *obj); +        void AddUpdateObject(Object *obj) +        { +            Guard guard(i_updateGuard); +            i_objects.insert(obj); +        } + +        void RemoveUpdateObject(Object *obj) +        { +            Guard guard(i_updateGuard); +            i_objects.erase( obj ); +        }          void Update(uint32 diff);          void UpdatePlayers(uint32 diff); diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp index 6c77138c38c..e5fd0d037e4 100644 --- a/src/game/Pet.cpp +++ b/src/game/Pet.cpp @@ -55,6 +55,7 @@ Pet::Pet(PetType type) : Creature()      m_resetTalentsCost = 0;      m_resetTalentsTime = 0; +    m_usedTalentCount = 0;      m_auraUpdateMask = 0; @@ -725,6 +726,7 @@ void Pet::GivePetLevel(uint32 level)          return;      InitStatsForLevel(level); +    InitTalentForLevel();  }  bool Pet::CreateBaseAtCreature(Creature* creature) @@ -1325,22 +1327,42 @@ bool Pet::addSpell(uint16 spell_id, uint16 active, PetSpellState state, PetSpell      else          newspell->active = active; -    uint32 chainstart = spellmgr.GetFirstSpellInChain(spell_id); - -    for (PetSpellMap::iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr) +    // talent: unlearn all other talent ranks (high and low) +    if(TalentSpellPos const* talentPos = GetTalentSpellPos(spell_id))      { -        if(itr->second->state == PETSPELL_REMOVED) continue; +        if(TalentEntry const *talentInfo = sTalentStore.LookupEntry( talentPos->talent_id )) +        { +            for(int i=0; i <5; ++i) +            { +                // skip learning spell and no rank spell case +                uint32 rankSpellId = talentInfo->RankID[i]; +                if(!rankSpellId || rankSpellId==spell_id) +                    continue; -        if(spellmgr.GetFirstSpellInChain(itr->first) == chainstart) +                // skip unknown ranks +                if(!HasSpell(rankSpellId)) +                    continue; +                removeSpell(rankSpellId); +            } +        } +    } +    else if(uint32 chainstart = spellmgr.GetFirstSpellInChain(spell_id)) +    { +        for (PetSpellMap::iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr)          { -            newspell->active = itr->second->active; +            if(itr->second->state == PETSPELL_REMOVED) continue; + +            if(spellmgr.GetFirstSpellInChain(itr->first) == chainstart) +            { +                newspell->active = itr->second->active; -            if(newspell->active == ACT_ENABLED) -                ToggleAutocast(itr->first, false); +                if(newspell->active == ACT_ENABLED) +                    ToggleAutocast(itr->first, false); -            oldspell_id = itr->first; -            unlearnSpell(itr->first); -            break; +                oldspell_id = itr->first; +                unlearnSpell(itr->first); +                break; +            }          }      } @@ -1354,6 +1376,15 @@ bool Pet::addSpell(uint16 spell_id, uint16 active, PetSpellState state, PetSpell      if(newspell->active == ACT_ENABLED)          ToggleAutocast(spell_id, true); +    uint32 talentCost = GetTalentSpellCost(spell_id); +    if (talentCost) +    { +        int32 free_points = GetMaxTalentPointsForLevel(getLevel()); +        m_usedTalentCount+=talentCost; +        // update free talent points +        free_points-=m_usedTalentCount; +        SetFreeTalentPoints(free_points > 0 ? free_points : 0); +    }      return true;  } @@ -1363,19 +1394,17 @@ bool Pet::learnSpell(uint16 spell_id)      if (!addSpell(spell_id))          return false; -    if(GetOwner()->GetTypeId() == TYPEID_PLAYER) +    Unit* owner = GetOwner(); +    if(owner && owner->GetTypeId() == TYPEID_PLAYER)      {          if(!m_loading)          {              WorldPacket data(SMSG_PET_LEARNED_SPELL, 2);              data << uint16(spell_id); -            ((Player*)GetOwner())->GetSession()->SendPacket(&data); +            ((Player*)owner)->GetSession()->SendPacket(&data);          } -    } - -    Unit* owner = GetOwner(); -    if(owner->GetTypeId() == TYPEID_PLAYER)          ((Player*)owner)->PetSpellInitialize(); +    }      return true;  } @@ -1433,6 +1462,18 @@ bool Pet::removeSpell(uint16 spell_id)      RemoveAurasDueToSpell(spell_id); +    uint32 talentCost = GetTalentSpellCost(spell_id); +    if (talentCost > 0) +    { +        if (m_usedTalentCount > talentCost) +            m_usedTalentCount-=talentCost; +        else +            m_usedTalentCount = 0; +        // update free talent points +        int32 free_points = GetMaxTalentPointsForLevel(getLevel()) - m_usedTalentCount; +        SetFreeTalentPoints(free_points > 0 ? free_points : 0); +    } +      return true;  } @@ -1512,6 +1553,110 @@ void Pet::CheckLearning(uint32 spellid)      }  } +bool Pet::resetTalents(bool no_cost) +{ +    Unit *owner = GetOwner(); +    if (!owner || owner->GetTypeId()!=TYPEID_PLAYER) +        return false; + +    CreatureInfo const * ci = GetCreatureInfo(); +    if(!ci) +        return false; +    // Check pet talent type +    CreatureFamilyEntry const *pet_family = sCreatureFamilyStore.LookupEntry(ci->family); +    if(!pet_family || pet_family->petTalentType < 0) +        return false; + +    Player *player = (Player *)owner; + +    uint32 level = getLevel(); +    uint32 talentPointsForLevel = GetMaxTalentPointsForLevel(level); + +    if (m_usedTalentCount == 0) +    { +        SetFreeTalentPoints(talentPointsForLevel); +        return false; +    } + +    uint32 cost = 0; + +    if(!no_cost) +    { +        cost = resetTalentsCost(); + +        if (player->GetMoney() < cost) +        { +            player->SendBuyError( BUY_ERR_NOT_ENOUGHT_MONEY, 0, 0, 0); +            return false; +        } +    } + +    for (unsigned int i = 0; i < sTalentStore.GetNumRows(); i++) +    { +        TalentEntry const *talentInfo = sTalentStore.LookupEntry(i); + +        if (!talentInfo) continue; + +        TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab ); + +        if(!talentTabInfo) +            continue; + +        // unlearn only talents for pets family talent type +        if(!((1 << pet_family->petTalentType) & talentTabInfo->petTalentMask)) +            continue; + +        for (int j = 0; j < 5; j++) +        { +            for(PetSpellMap::iterator itr = m_spells.begin(); itr != m_spells.end();) +            { +                if(itr->second->state == PETSPELL_REMOVED) +                { +                    ++itr; +                    continue; +                } +                // remove learned spells (all ranks) +                uint32 itrFirstId = spellmgr.GetFirstSpellInChain(itr->first); + +                // unlearn if first rank is talent or learned by talent +                if (itrFirstId == talentInfo->RankID[j] || spellmgr.IsSpellLearnToSpell(talentInfo->RankID[j],itrFirstId)) +                { +                    removeSpell(itr->first); +                    itr = m_spells.begin(); +                    continue; +                } +                else +                    ++itr; +            } +        } +    } + +    SetFreeTalentPoints(talentPointsForLevel); + +    if(!no_cost) +    { +        player->ModifyMoney(-(int32)cost); + +        m_resetTalentsCost = cost; +        m_resetTalentsTime = time(NULL); +    } +    player->PetSpellInitialize(); +    return true; +} + +void Pet::InitTalentForLevel() +{ +    uint32 level = getLevel(); +    uint32 talentPointsForLevel = GetMaxTalentPointsForLevel(level); +    // Reset talents in case low level (on level down) or wrong points for level (hunter can unlearn TP increase talent) +    if(talentPointsForLevel == 0 || m_usedTalentCount > talentPointsForLevel) +    { +        // Remove all talent points +        resetTalents(true); +    } +    SetFreeTalentPoints(talentPointsForLevel - m_usedTalentCount); +} +  uint32 Pet::resetTalentsCost() const  {      uint32 days = (sWorld.GetGameTime() - m_resetTalentsTime)/DAY; @@ -1530,6 +1675,15 @@ uint32 Pet::resetTalentsCost() const          return (m_resetTalentsCost + 1*GOLD > 10*GOLD ? 10*GOLD : m_resetTalentsCost + 1*GOLD);  } +uint8 Pet::GetMaxTalentPointsForLevel(uint32 level) +{ +    uint8 points = (level >= 20) ? ((level - 16) / 4) : 0; +    // Mod points from owner SPELL_AURA_MOD_PET_TALENT_POINTS +    if (Unit *owner = GetOwner()) +        points+=owner->GetTotalAuraModifier(SPELL_AURA_MOD_PET_TALENT_POINTS); +    return points; +} +  void Pet::ToggleAutocast(uint32 spellid, bool apply)  {      if(IsPassiveSpell(spellid)) @@ -1594,7 +1748,8 @@ bool Pet::Create(uint32 guidlow, Map *map, uint32 Entry, uint32 pet_number)  bool Pet::HasSpell(uint32 spell) const  { -    return (m_spells.find(spell) != m_spells.end()); +    PetSpellMap::const_iterator itr = m_spells.find((uint16)spell); +    return (itr != m_spells.end() && itr->second->state != PETSPELL_REMOVED );  }  // Get all passive spells in our skill line diff --git a/src/game/Pet.h b/src/game/Pet.h index d62418e8ee7..d89e14e1d74 100644 --- a/src/game/Pet.h +++ b/src/game/Pet.h @@ -203,13 +203,18 @@ class Pet : public Creature          void InitPetCreateSpells();          void CheckLearning(uint32 spellid); + +        bool resetTalents(bool no_cost = false);          uint32 resetTalentsCost() const; -        uint8 GetMaxTalentPointsForLevel(uint32 level) { return (level >= 20) ? ((level - 16) / 4) : 0; } +        void InitTalentForLevel(); + +        uint8 GetMaxTalentPointsForLevel(uint32 level);          uint8 GetFreeTalentPoints() { return GetByteValue(UNIT_FIELD_BYTES_1, 1); }          void SetFreeTalentPoints(uint8 points) { SetByteValue(UNIT_FIELD_BYTES_1, 1, points); }          uint32  m_resetTalentsCost;          time_t  m_resetTalentsTime; +        uint32  m_usedTalentCount;          uint64 GetAuraUpdateMask() { return m_auraUpdateMask; }          void SetAuraUpdateMask(uint8 slot) { m_auraUpdateMask |= (uint64(1) << slot); } diff --git a/src/game/PetHandler.cpp b/src/game/PetHandler.cpp index c9c9bfde6df..a08c3f1bff8 100644 --- a/src/game/PetHandler.cpp +++ b/src/game/PetHandler.cpp @@ -507,11 +507,11 @@ void WorldSession::HandlePetUnlearnOpcode(WorldPacket& recvPacket)      sLog.outDetail("CMSG_PET_UNLEARN");      uint64 guid; -    recvPacket >> guid; +    recvPacket >> guid;                 // Pet guid      Pet* pet = _player->GetPet(); -    if(!pet || pet->getPetType() != HUNTER_PET || pet->m_spells.size() <= 1) +    if(!pet || pet->getPetType() != HUNTER_PET || pet->m_usedTalentCount == 0)          return;      if(guid != pet->GetGUID()) @@ -526,37 +526,7 @@ void WorldSession::HandlePetUnlearnOpcode(WorldPacket& recvPacket)          sLog.outError("WorldSession::HandlePetUnlearnOpcode: object "I64FMTD" is considered pet-like but doesn't have a charminfo!", pet->GetGUID());          return;      } - -    uint32 cost = pet->resetTalentsCost(); - -    if (GetPlayer()->GetMoney() < cost) -    { -        GetPlayer()->SendBuyError( BUY_ERR_NOT_ENOUGHT_MONEY, 0, 0, 0); -        return; -    } - -    for(PetSpellMap::iterator itr = pet->m_spells.begin(); itr != pet->m_spells.end();) -    { -        uint32 spell_id = itr->first;                       // Pet::removeSpell can invalidate iterator at erase NEW spell -        ++itr; -        //pet->removeSpell(spell_id); -        pet->unlearnSpell(spell_id); -    } - -    for(uint8 i = 0; i < 10; i++) -    { -        if(charmInfo->GetActionBarEntry(i)->SpellOrAction && charmInfo->GetActionBarEntry(i)->Type == ACT_ENABLED || charmInfo->GetActionBarEntry(i)->Type == ACT_DISABLED) -            charmInfo->GetActionBarEntry(i)->SpellOrAction = 0; -    } - -    // relearn pet passives -    pet->LearnPetPassives(); - -    pet->m_resetTalentsTime = time(NULL); -    pet->m_resetTalentsCost = cost; -    GetPlayer()->ModifyMoney(-(int32)cost); - -    GetPlayer()->PetSpellInitialize(); +    pet->resetTalents();  }  void WorldSession::HandlePetSpellAutocastOpcode( WorldPacket& recvPacket ) @@ -839,7 +809,4 @@ void WorldSession::HandlePetLearnTalent( WorldPacket & recv_data )      // learn! (other talent ranks will unlearned at learning)      pet->learnSpell(spellid);      sLog.outDetail("TalentID: %u Rank: %u Spell: %u\n", talent_id, requested_rank, spellid); - -    // update free talent points -    pet->SetFreeTalentPoints(CurTalentPoints - 1);  } diff --git a/src/game/Player.cpp b/src/game/Player.cpp index d89b6d9fa39..c9da16cab17 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -4657,7 +4657,7 @@ void Player::ApplyRatingMod(CombatRating cr, int32 value, bool apply)      AuraList const& modRatingFromStat = GetAurasByType(SPELL_AURA_MOD_RATING_FROM_STAT);      for(AuraList::const_iterator i = modRatingFromStat.begin();i != modRatingFromStat.end(); ++i)          if ((*i)->GetMiscValue() & (1<<cr)) -            amount += GetStat(Stats((*i)->GetMiscBValue())) * (*i)->GetModifier()->m_amount / 100.0f; +            amount += int32(GetStat(Stats((*i)->GetMiscBValue())) * (*i)->GetModifier()->m_amount / 100.0f);      if (amount < 0)          amount = 0;      SetUInt32Value(PLAYER_FIELD_COMBAT_RATING_1 + cr, uint32(amount)); @@ -6683,7 +6683,7 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto, uint8 slot, bool appl                      uint32 level = ((getLevel() > ssd->MaxLevel) ? ssd->MaxLevel : getLevel());                      if(ScalingStatValuesEntry const *ssv = sScalingStatValuesStore.LookupEntry(level))                      { -                        int multiplier = ssv->Multiplier[proto->GetScalingStatValuesColumn()]; +                        uint32 multiplier = ssv->Multiplier[proto->GetScalingStatValuesColumn()];                          val = (multiplier * modifier) / 10000;                      }                  } @@ -6692,7 +6692,7 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto, uint8 slot, bool appl          else          {              statType = proto->ItemStat[i].ItemStatType; -            val = float(proto->ItemStat[i].ItemStatValue); +            val = proto->ItemStat[i].ItemStatValue;          }          if(val == 0) @@ -14667,12 +14667,12 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )      SetCharm(NULL);      SetMover(NULL);      SetPet(NULL); -    SetCharmerGUID(NULL); -    SetOwnerGUID(NULL); -    SetCreatorGUID(NULL); +    SetCharmerGUID(0); +    SetOwnerGUID(0); +    SetCreatorGUID(0);      // reset some aura modifiers before aura apply -    SetFarSight(NULL); +    SetFarSightGUID(0);      SetUInt32Value(PLAYER_TRACK_CREATURES, 0 );      SetUInt32Value(PLAYER_TRACK_RESOURCES, 0 ); @@ -14720,6 +14720,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )      //_LoadMail();      _LoadAuras(holder->GetResult(PLAYER_LOGIN_QUERY_LOADAURAS), time_diff); +    _LoadGlyphAuras();      // add ghost flag (must be after aura load: PLAYER_FLAGS_GHOST set in aura)      if( HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST) ) @@ -14988,6 +14989,36 @@ void Player::_LoadAuras(QueryResult *result, uint32 timediff)          CastSpell(this,SPELL_ID_PASSIVE_BATTLE_STANCE,true);  } +void Player::_LoadGlyphAuras() +{ +    for (uint8 i = 0; i <= MAX_GLYPH_SLOT_INDEX; ++i) +    { +        if (uint32 glyph = GetGlyph(i)) +        { +            if (GlyphPropertiesEntry const *gp = sGlyphPropertiesStore.LookupEntry(glyph)) +            { +                if (GlyphSlotEntry const *gs = sGlyphSlotStore.LookupEntry(GetGlyphSlot(i))) +                { +                    if(gp->TypeFlags == gs->TypeFlags) +                    { +                        CastSpell(this, gp->SpellId, true); +                        continue; +                    } +                    else +                        sLog.outError("Player %s has glyph with typeflags %u in slot with typeflags %u, removing.", m_name.c_str(), gp->TypeFlags, gs->TypeFlags); +                } +                else +                    sLog.outError("Player %s has not existing glyph slot entry %u on index %u", m_name.c_str(), GetGlyphSlot(i), i); +            } +            else +                sLog.outError("Player %s has not existing glyph entry %u on index %u", m_name.c_str(), glyph, i); + +            // On any error remove glyph +            SetGlyph(i, 0); +        } +    } +} +  void Player::LoadCorpse()  {      if( isAlive() ) @@ -19766,7 +19797,7 @@ void Player::ClearFarsight()  {      if(GetFarSight())      { -        SetFarSight(0); +        SetFarSightGUID(0);          WorldPacket data(SMSG_CLEAR_FAR_SIGHT_IMMEDIATE, 0);          GetSession()->SendPacket(&data);      } @@ -19780,7 +19811,7 @@ void Player::SetFarsightTarget(WorldObject* obj)      // Remove the current target if there is one      RemoveFarsightTarget(); -    SetFarSight(obj->GetGUID()); +    SetFarSightGUID(obj->GetGUID());  }  bool Player::isAllowUseBattleGroundObject() @@ -19870,7 +19901,7 @@ void Player::EnterVehicle(Vehicle *vehicle)      SetCharm(vehicle);                                      // charm      SetMover(vehicle); -    SetFarSight(vehicle->GetGUID());                        // set view +    SetFarSightGUID(vehicle->GetGUID());                        // set view      SetClientControl(vehicle, 1);                           // redirect controls to vehicle @@ -19922,7 +19953,7 @@ void Player::ExitVehicle(Vehicle *vehicle)      SetCharm(NULL);      SetMover(NULL); -    SetFarSight(NULL); +    SetFarSightGUID(0);      SetClientControl(vehicle, 0); diff --git a/src/game/Player.h b/src/game/Player.h index 0e98cc40825..1cbe373dcd1 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1454,10 +1454,7 @@ class TRINITY_DLL_SPEC Player : public Unit          Item* GetMItem(uint32 id)          {              ItemMap::const_iterator itr = mMitems.find(id); -            if (itr != mMitems.end()) -                return itr->second; - -            return NULL; +            return itr != mMitems.end() ? itr->second : NULL;          }          void AddMItem(Item* it) @@ -1469,12 +1466,7 @@ class TRINITY_DLL_SPEC Player : public Unit          bool RemoveMItem(uint32 id)          { -            ItemMap::iterator i = mMitems.find(id); -            if (i == mMitems.end()) -                return false; - -            mMitems.erase(i); -            return true; +            return mMitems.erase(id) ? true : false;          }          void PetSpellInitialize(); @@ -2083,7 +2075,7 @@ class TRINITY_DLL_SPEC Player : public Unit          }          uint64 GetFarSight() const { return GetUInt64Value(PLAYER_FARSIGHT); } -        void SetFarSight(uint64 guid) { SetUInt64Value(PLAYER_FARSIGHT, guid); } +        void SetFarSightGUID(uint64 guid) { SetUInt64Value(PLAYER_FARSIGHT, guid); }          void SetBindSight(Unit *target);          WorldObject* GetFarsightTarget() const;          void ClearFarsight(); @@ -2263,6 +2255,7 @@ class TRINITY_DLL_SPEC Player : public Unit          void _LoadActions(QueryResult *result);          void _LoadAuras(QueryResult *result, uint32 timediff); +        void _LoadGlyphAuras();          void _LoadBoundInstances(QueryResult *result);          void _LoadInventory(QueryResult *result, uint32 timediff);          void _LoadMailInit(QueryResult *resultUnread, QueryResult *resultDelivery); diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h index 7cc41ae075f..adfc6af32ef 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -448,6 +448,8 @@ enum SpellCategory  #define SPELL_ATTR_EX6_UNK30                      0x40000000            // 30 not set in 3.0.3  #define SPELL_ATTR_EX6_UNK31                      0x80000000            // 31 not set in 3.0.3 +#define MAX_GLYPH_SLOT_INDEX    5 +  enum SheathTypes  {      SHEATHETYPE_NONE                   = 0, @@ -681,7 +683,7 @@ enum SpellEffects      SPELL_EFFECT_154                       = 154,      SPELL_EFFECT_TITAN_GRIP                = 155,      SPELL_EFFECT_ADD_SOCKET                = 156, -    SPELL_EFFECT_157                       = 157, +    SPELL_EFFECT_CREATE_ITEM_2             = 157,      SPELL_EFFECT_MILLING                   = 158,      SPELL_EFFECT_ALLOW_RENAME_PET          = 159,      TOTAL_SPELL_EFFECTS                    = 160 diff --git a/src/game/SkillDiscovery.cpp b/src/game/SkillDiscovery.cpp index 2a1c6ec9d82..edded6302aa 100644 --- a/src/game/SkillDiscovery.cpp +++ b/src/game/SkillDiscovery.cpp @@ -31,14 +31,15 @@  struct SkillDiscoveryEntry  { -    uint32  spellId; -    float   chance; +    uint32  spellId;                                        // discavered spell +    uint32  reqClass;                                       // class limitation +    float   chance;                                         // chance      SkillDiscoveryEntry() -        : spellId(0), chance(0) {} +        : spellId(0), reqClass(0), chance(0) {} -    SkillDiscoveryEntry(uint16 _spellId, float _chance) -        : spellId(_spellId), chance(_chance) {} +    SkillDiscoveryEntry(uint16 _spellId, uint32 req_class, float _chance) +        : spellId(_spellId), reqClass(req_class), chance(_chance) {}  };  typedef std::list<SkillDiscoveryEntry> SkillDiscoveryList; @@ -53,8 +54,8 @@ void LoadSkillDiscoveryTable()      uint32 count = 0; -    //                                                 0        1         2 -    QueryResult *result = WorldDatabase.Query("SELECT spellId, reqSpell, chance FROM skill_discovery_template"); +    //                                                0        1         2         3 +    QueryResult *result = WorldDatabase.Query("SELECT spellId, reqSpell, reqClass, chance FROM skill_discovery_template");      if (result)      { @@ -69,11 +70,18 @@ void LoadSkillDiscoveryTable()              uint32 spellId         = fields[0].GetUInt32();              int32  reqSkillOrSpell = fields[1].GetInt32(); -            float  chance          = fields[2].GetFloat(); +            uint32 reqClass        = fields[2].GetInt32(); +            float  chance          = fields[3].GetFloat();              if( chance <= 0 )                               // chance              { -                ssNonDiscoverableEntries << "spellId = " << spellId << " reqSkillOrSpell = " << reqSkillOrSpell << " chance = " << chance << "\n"; +                ssNonDiscoverableEntries << "spellId = " << spellId << " reqSkillOrSpell = " << reqSkillOrSpell << " reqClass = " << reqClass << " chance = " << chance << "(chance problem)\n"; +                continue; +            } + +            if(reqClass && (reqClass >= MAX_CLASSES || ((1 << (reqClass-1)) & CLASSMASK_ALL_PLAYABLE)==0)) +            { +                ssNonDiscoverableEntries << "spellId = " << spellId << " reqSkillOrSpell = " << reqSkillOrSpell << " reqClass = " << reqClass << " chance = " << chance << "(class problem)\n";                  continue;              } @@ -86,13 +94,16 @@ void LoadSkillDiscoveryTable()                      continue;                  } -                if( spellEntry->Mechanic != MECHANIC_DISCOVERY ) +                // mechanic discovery +                if (spellEntry->Mechanic != MECHANIC_DISCOVERY && +                    // explicit discovery ability +                    !IsExplicitDiscoverySpell(spellEntry))                  { -                    sLog.outErrorDb("Spell (ID: %u) not have have MECHANIC_DISCOVERY (28) value in Mechanic field in spell.dbc but listed in `skill_discovery_template` table",spellId); +                    sLog.outErrorDb("Spell (ID: %u) not have have MECHANIC_DISCOVERY (28) value in Mechanic field in spell.dbc and not 100% chance random discovery ability but listed in `skill_discovery_template` table",spellId);                      continue;                  } -                SkillDiscoveryStore[reqSkillOrSpell].push_back( SkillDiscoveryEntry(spellId, chance) ); +                SkillDiscoveryStore[reqSkillOrSpell].push_back( SkillDiscoveryEntry(spellId, reqClass, chance) );              }              else if( reqSkillOrSpell == 0 )                 // skill case              { @@ -107,7 +118,7 @@ void LoadSkillDiscoveryTable()                  for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx)                  { -                    SkillDiscoveryStore[-int32(_spell_idx->second->skillId)].push_back( SkillDiscoveryEntry(spellId, chance) ); +                    SkillDiscoveryStore[-int32(_spell_idx->second->skillId)].push_back( SkillDiscoveryEntry(spellId, reqClass, chance) );                  }              }              else @@ -115,6 +126,7 @@ void LoadSkillDiscoveryTable()                  sLog.outErrorDb("Spell (ID: %u) have negative value in `reqSpell` field in `skill_discovery_template` table",spellId);                  continue;              } +              ++count;          } while (result->NextRow()); @@ -139,8 +151,45 @@ uint32 GetSkillDiscoverySpell(uint32 skillId, uint32 spellId, Player* player)      if(tab != SkillDiscoveryStore.end())      { +        SpellEntry const* spellInfo = sSpellStore.LookupEntry (spellId); +        if(!spellInfo) +            return 0; + +        // explicit discovery spell chances (alwasy success if case exist) +        if(IsExplicitDiscoverySpell(spellInfo)) +        { +            float full_chance = 0; +            for(SkillDiscoveryList::iterator item_iter = tab->second.begin(); item_iter != tab->second.end(); ++item_iter) +                if(!item_iter->reqClass || player->getClass ()==item_iter->reqClass) +                    if(!player->HasSpell(item_iter->spellId)) +                        full_chance += item_iter->chance; + +            float rate = full_chance / 100.0f; +            float roll = rand_chance() * rate;              // roll now in range 0..full_chance + +            for(SkillDiscoveryList::iterator item_iter = tab->second.begin(); item_iter != tab->second.end(); ++item_iter) +            { +                if(item_iter->reqClass && player->getClass ()!= item_iter->reqClass) +                    continue; + +                if(player->HasSpell(item_iter->spellId)) +                    continue; + +                if(item_iter->chance > roll) +                    return item_iter->spellId; + +                roll -= item_iter->chance; +            } + +            return 0; +        } + +          for(SkillDiscoveryList::iterator item_iter = tab->second.begin(); item_iter != tab->second.end(); ++item_iter)          { +            if(item_iter->reqClass && player->getClass ()!= item_iter->reqClass) +                continue; +              if( roll_chance_f(item_iter->chance * sWorld.getRate(RATE_SKILL_DISCOVERY))                  && !player->HasSpell(item_iter->spellId) )                  return item_iter->spellId; @@ -149,12 +198,18 @@ uint32 GetSkillDiscoverySpell(uint32 skillId, uint32 spellId, Player* player)          return 0;      } +    if(!skillId) +        return 0; +      // check skill line case      tab = SkillDiscoveryStore.find(-(int32)skillId);      if(tab != SkillDiscoveryStore.end())      {          for(SkillDiscoveryList::iterator item_iter = tab->second.begin(); item_iter != tab->second.end(); ++item_iter)          { +            if(item_iter->reqClass && player->getClass ()!= item_iter->reqClass) +                continue; +              if( roll_chance_f(item_iter->chance * sWorld.getRate(RATE_SKILL_DISCOVERY))                  && !player->HasSpell(item_iter->spellId) )                  return item_iter->spellId; diff --git a/src/game/SocialMgr.cpp b/src/game/SocialMgr.cpp index baabe9b043f..ce9d6cbd8df 100644 --- a/src/game/SocialMgr.cpp +++ b/src/game/SocialMgr.cpp @@ -182,13 +182,6 @@ SocialMgr::~SocialMgr()  } -void SocialMgr::RemovePlayerSocial(uint32 guid) -{ -    SocialMap::iterator itr = m_socialMap.find(guid); -    if(itr != m_socialMap.end()) -        m_socialMap.erase(itr); -} -  void SocialMgr::GetFriendInfo(Player *player, uint32 friendGUID, FriendInfo &friendInfo)  {      if(!player) diff --git a/src/game/SocialMgr.h b/src/game/SocialMgr.h index 1cc14589e51..27280992173 100644 --- a/src/game/SocialMgr.h +++ b/src/game/SocialMgr.h @@ -143,7 +143,8 @@ class SocialMgr          SocialMgr();          ~SocialMgr();          // Misc -        void RemovePlayerSocial(uint32 guid); +        void RemovePlayerSocial(uint32 guid) { m_socialMap.erase(guid); } +          void GetFriendInfo(Player *player, uint32 friendGUID, FriendInfo &friendInfo);          // Packet management          void MakeFriendStatusPacket(FriendsResult result, uint32 friend_guid, WorldPacket *data); diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 5d771c2c1ec..1530e0728fc 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -3044,7 +3044,7 @@ void Spell::SendLogExecute()                          data << uint8(0);                      break;                  case SPELL_EFFECT_CREATE_ITEM: -                case SPELL_EFFECT_157: +                case SPELL_EFFECT_CREATE_ITEM_2:                      data << uint32(m_spellInfo->EffectItemType[0]);                      break;                  case SPELL_EFFECT_SUMMON: diff --git a/src/game/Spell.h b/src/game/Spell.h index 39849eb6197..afe9776374d 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -384,11 +384,10 @@ class Spell          bool HaveTargetsForEffect(uint8 effect) const;          void Delayed();          void DelayedChannel(); -        inline uint32 getState() const { return m_spellState; } +        uint32 getState() const { return m_spellState; }          void setState(uint32 state) { m_spellState = state; }          void DoCreateItem(uint32 i, uint32 itemtype); -          void WriteSpellGoTargets( WorldPacket * data );          void WriteAmmoToPacket( WorldPacket * data );          void FillTargetMap(); diff --git a/src/game/SpellAuraDefines.h b/src/game/SpellAuraDefines.h index 1ea8d875132..98abee49b16 100644 --- a/src/game/SpellAuraDefines.h +++ b/src/game/SpellAuraDefines.h @@ -189,8 +189,8 @@ enum AuraType      SPELL_AURA_MOD_BASE_RESISTANCE_PCT = 142,      SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE = 143,      SPELL_AURA_SAFE_FALL = 144, -    SPELL_AURA_CHARISMA = 145, -    SPELL_AURA_PERSUADED = 146, +    SPELL_AURA_MOD_PET_TALENT_POINTS = 145, +    SPELL_AURA_ALLOW_TAME_PET_TYPE = 146,      SPELL_AURA_ADD_CREATURE_IMMUNITY = 147,      SPELL_AURA_RETAIN_COMBO_POINTS = 148,      SPELL_AURA_RESIST_PUSHBACK  = 149,                      //    Resist Pushback diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index b7225898810..72bf6d91a03 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -199,8 +199,8 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=      &Aura::HandleAuraModBaseResistancePCT,                  //142 SPELL_AURA_MOD_BASE_RESISTANCE_PCT      &Aura::HandleAuraModResistanceExclusive,                //143 SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE      &Aura::HandleNoImmediateEffect,                         //144 SPELL_AURA_SAFE_FALL                  implemented in WorldSession::HandleMovementOpcodes -    &Aura::HandleUnused,                                    //145 SPELL_AURA_CHARISMA obsolete? -    &Aura::HandleUnused,                                    //146 SPELL_AURA_PERSUADED obsolete? +    &Aura::HandleAuraModPetTalentsPoints,                   //145 SPELL_AURA_MOD_PET_TALENT_POINTS +    &Aura::HandleNoImmediateEffect,                         //146 SPELL_AURA_ALLOW_TAME_PET_TYPE      &Aura::HandleNULL,                                      //147 SPELL_AURA_ADD_CREATURE_IMMUNITY      &Aura::HandleAuraRetainComboPoints,                     //148 SPELL_AURA_RETAIN_COMBO_POINTS      &Aura::HandleNoImmediateEffect,                         //149 SPELL_AURA_RESIST_PUSHBACK @@ -2917,7 +2917,7 @@ void Aura::HandleFarSight(bool apply, bool Real)      if(!caster || caster->GetTypeId() != TYPEID_PLAYER)          return; -    ((Player*)caster)->SetFarSight(apply ? m_target->GetGUID() : NULL); +    ((Player*)caster)->SetFarSightGUID(apply ? m_target->GetGUID() : 0);  }  void Aura::HandleAuraTrackCreatures(bool apply, bool Real) @@ -3024,7 +3024,7 @@ void Aura::HandleAuraModScale(bool apply, bool Real)          }      }      if(caster->GetTypeId() == TYPEID_PLAYER) -        ((Player*)caster)->SetFarSight(apply ? m_target->GetGUID() : NULL); +        ((Player*)caster)->SetFarSightGUID(apply ? m_target->GetGUID() : 0);  }  void Aura::HandleModPossessPet(bool apply, bool Real) @@ -3045,7 +3045,7 @@ void Aura::HandleModPossessPet(bool apply, bool Real)      else          pet->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24); -    ((Player*)caster)->SetFarSight(apply ? pet->GetGUID() : NULL); +    ((Player*)caster)->SetFarSightGUID(apply ? pet->GetGUID() : NULL);      ((Player*)caster)->SetCharm(apply ? pet : NULL);      ((Player*)caster)->SetClientControl(pet, apply ? 1 : 0); @@ -3061,9 +3061,19 @@ void Aura::HandleModPossessPet(bool apply, bool Real)          pet->GetMotionMaster()->MoveFollow(caster, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);          pet->SetUnitMovementFlags(MOVEMENTFLAG_NONE);      } +}*/ + +void Aura::HandleAuraModPetTalentsPoints(bool Apply, bool Real) +{ +    if(!Real) +        return; + +    // Recalculate pet tlaent points +    if (Pet *pet=m_target->GetPet()) +        pet->InitTalentForLevel();  } -void Aura::HandleModCharm(bool apply, bool Real) +/*void Aura::HandleModCharm(bool apply, bool Real)  {      if(!Real)          return; diff --git a/src/game/SpellAuras.h b/src/game/SpellAuras.h index 2c490f5ae57..67bf2c439c0 100644 --- a/src/game/SpellAuras.h +++ b/src/game/SpellAuras.h @@ -114,6 +114,7 @@ class TRINITY_DLL_SPEC Aura          void HandlePeriodicTriggerSpell(bool Apply, bool Real);          void HandlePeriodicEnergize(bool Apply, bool Real);          void HandleAuraModResistanceExclusive(bool Apply, bool Real); +        void HandleAuraModPetTalentsPoints(bool Apply, bool Real);          void HandleModStealth(bool Apply, bool Real);          void HandleInvisibility(bool Apply, bool Real);          void HandleInvisibilityDetect(bool Apply, bool Real); diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 510d6e3501d..22aab9d7ebe 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -60,6 +60,7 @@  #include "CellImpl.h"  #include "GridNotifiers.h"  #include "GridNotifiersImpl.h" +#include "SkillDiscovery.h"  pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=  { @@ -220,7 +221,7 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=      &Spell::EffectNULL,                                     //154 unused      &Spell::EffectTitanGrip,                                //155 SPELL_EFFECT_TITAN_GRIP Allows you to equip two-handed axes, maces and swords in one hand, but you attack $49152s1% slower than normal.      &Spell::EffectNULL,                                     //156 Add Socket -    &Spell::EffectNULL,                                     //157 create/learn random item/spell for profession +    &Spell::EffectCreateItem,                               //157 SPELL_EFFECT_CREATE_ITEM_2 create/learn item/spell for profession      &Spell::EffectMilling,                                  //158 milling      &Spell::EffectNULL                                      //159 allow rename pet once again  }; @@ -530,7 +531,7 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)                          Aura *poison = 0;                          // Lookup for Deadly poison (only attacker applied)                          Unit::AuraList const& auras = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE); -                        for(Unit::AuraList::const_iterator itr = auras.begin(); itr!=auras.end() && combo;) +                        for(Unit::AuraList::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr)                              if( (*itr)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_ROGUE &&                                   (*itr)->GetSpellProto()->SpellFamilyFlags & 0x10000 &&                                  (*itr)->GetCasterGUID()==m_caster->GetGUID() ) @@ -4242,6 +4243,7 @@ void Spell::EffectSummonPet(uint32 i)      NewSummon->InitStatsForLevel(petlevel);      NewSummon->InitPetCreateSpells(); +    NewSummon->InitTalentForLevel();      if(NewSummon->getPetType()==SUMMON_PET)      { @@ -4738,460 +4740,534 @@ void Spell::EffectScriptEffect(uint32 effIndex)  {      // TODO: we must implement hunter pet summon at login there (spell 6962) -    // by spell id -    switch(m_spellInfo->Id) +    switch(m_spellInfo->SpellFamilyName)      { -        // PX-238 Winter Wondervolt TRAP -        case 26275: +        case SPELLFAMILY_GENERIC:          { -            if( unitTarget->HasAura(26272,0) -             || unitTarget->HasAura(26157,0) -             || unitTarget->HasAura(26273,0) -             || unitTarget->HasAura(26274,0)) -                return; +            switch(m_spellInfo->Id) +            { +                // PX-238 Winter Wondervolt TRAP +                case 26275: +                { +                    if (unitTarget->HasAura(26272,0) || +                        unitTarget->HasAura(26157,0) || +                        unitTarget->HasAura(26273,0) || +                        unitTarget->HasAura(26274,0)) +                        return; -            uint32 iTmpSpellId; +                    uint32 iTmpSpellId; +                    switch(urand(0,3)) +                    { +                        case 0: iTmpSpellId = 26272; break; +                        case 1: iTmpSpellId = 26157; break; +                        case 2: iTmpSpellId = 26273; break; +                        case 3: iTmpSpellId = 26274; break; +                    } -            switch(urand(0,3)) -            { -                case 0: -                    iTmpSpellId = 26272; -                    break; -                case 1: -                    iTmpSpellId = 26157; -                    break; -                case 2: -                    iTmpSpellId = 26273; -                    break; -                case 3: -                    iTmpSpellId = 26274; -                    break; -            } +                    unitTarget->CastSpell(unitTarget, iTmpSpellId, true); +                    return; +                } +                // Bending Shinbone +                case 8856: +                { +                    if(!itemTarget && m_caster->GetTypeId()!=TYPEID_PLAYER) +                        return; -            unitTarget->CastSpell(unitTarget, iTmpSpellId, true); +                    uint32 spell_id = 0; +                    switch(urand(1,5)) +                    { +                    case 1:  spell_id = 8854; break; +                    default: spell_id = 8855; break; +                    } -            return; -        } +                    m_caster->CastSpell(m_caster,spell_id,true,NULL); +                    return; +                } +                // Brittle Armor - need remove one 24575 Brittle Armor aura +                case 24590: +                    unitTarget->RemoveSingleSpellAurasFromStack(24575); +                    return; +                // Mercurial Shield - need remove one 26464 Mercurial Shield aura +                case 26465: +                    unitTarget->RemoveSingleSpellAurasFromStack(26464); +                    return; +                // Orb teleport spells +                case 25140: +                case 25143: +                case 25650: +                case 25652: +                case 29128: +                case 29129: +                case 35376: +                case 35727: +                { +                    if(!unitTarget) +                        return; -        // Bending Shinbone -        case 8856: -        { -            if(!itemTarget && m_caster->GetTypeId()!=TYPEID_PLAYER) -                return; +                    uint32 spellid; +                    switch(m_spellInfo->Id) +                    { +                    case 25140: spellid =  32571; break; +                    case 25143: spellid =  32572; break; +                    case 25650: spellid =  30140; break; +                    case 25652: spellid =  30141; break; +                    case 29128: spellid =  32568; break; +                    case 29129: spellid =  32569; break; +                    case 35376: spellid =  25649; break; +                    case 35727: spellid =  35730; break; +                    default: +                        return; +                    } -            uint32 spell_id = 0; -            switch(urand(1,5)) -            { -                case 1:  spell_id = 8854; break; -                default: spell_id = 8855; break; -            } +                    unitTarget->CastSpell(unitTarget,spellid,false); +                    return; +                } +                // Shadow Flame (All script effects, not just end ones to prevent player from dodging the last triggered spell) +                case 22539: +                case 22972: +                case 22975: +                case 22976: +                case 22977: +                case 22978: +                case 22979: +                case 22980: +                case 22981: +                case 22982: +                case 22983: +                case 22984: +                case 22985: +                { +                    if(!unitTarget || !unitTarget->isAlive()) +                        return; -            m_caster->CastSpell(m_caster,spell_id,true,NULL); -            return; -        } +                    // Onyxia Scale Cloak +                    if(unitTarget->GetDummyAura(22683)) +                        return; -        // Healthstone creating spells -        case  6201: -        case  6202: -        case  5699: -        case 11729: -        case 11730: -        case 27230: -        case 47871: -        case 47878: -        { -            uint32 itemtype; -            uint32 rank = 0; -            Unit::AuraList const& mDummyAuras = unitTarget->GetAurasByType(SPELL_AURA_DUMMY); -            for(Unit::AuraList::const_iterator i = mDummyAuras.begin();i != mDummyAuras.end(); ++i) -            { -                if((*i)->GetId() == 18692) +                    // Shadow Flame +                    m_caster->CastSpell(unitTarget, 22682, true); +                    return; +                } +                // Summon Black Qiraji Battle Tank +                case 26656:                  { -                    rank = 1; +                    if(!unitTarget) +                        return; + +                    // Prevent stacking of mounts +                    unitTarget->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED); + +                    // Two separate mounts depending on area id (allows use both in and out of specific instance) +                    if (unitTarget->GetAreaId() == 3428) +                        unitTarget->CastSpell(unitTarget, 25863, false); +                    else +                        unitTarget->CastSpell(unitTarget, 26655, false);                      break;                  } -                else if((*i)->GetId() == 18693) +                // Piccolo of the Flaming Fire +                case 17512:                  { -                    rank = 2; +                    if(!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) +                        return; +                    unitTarget->HandleEmoteCommand(EMOTE_STATE_DANCE);                      break;                  } -            } - -            static uint32 const itypes[8][3] = { -                { 5512,19004,19005},                        // Minor Healthstone -                { 5511,19006,19007},                        // Lesser Healthstone -                { 5509,19008,19009},                        // Healthstone -                { 5510,19010,19011},                        // Greater Healthstone -                { 9421,19012,19013},                        // Major Healthstone -                {22103,22104,22105},                        // Master Healthstone -                {36889,36890,36891},                        // Demonic Healthstone -                {36892,36893,36894}                         // Fel Healthstone -            }; +                // Mirren's Drinking Hat +                case 29830: +                { +                    uint32 item = 0; +                    switch ( urand(1,6) ) +                    { +                        case 1:case 2:case 3: +                            item = 23584;break;             // Loch Modan Lager +                        case 4:case 5: +                            item = 23585;break;             // Stouthammer Lite +                        case 6: +                            item = 23586;break;             // Aerie Peak Pale Ale +                    } +                    if (item) +                        DoCreateItem(effIndex,item); +                    break; +                } +                // Improved Sprint +                case 30918: +                { +                    // Removes snares and roots. +                    uint32 mechanic_mask = (1<<MECHANIC_ROOT) | (1<<MECHANIC_SNARE); +                    Unit::AuraMap& Auras = unitTarget->GetAuras(); +                    for(Unit::AuraMap::iterator iter = Auras.begin(), next; iter != Auras.end(); iter = next) +                    { +                        next = iter; +                        ++next; +                        Aura *aur = iter->second; +                        if (!aur->IsPositive())             //only remove negative spells +                        { +                            // check for mechanic mask +                            if(GetSpellMechanicMask(aur->GetSpellProto(), aur->GetEffIndex()) & mechanic_mask) +                            { +                                unitTarget->RemoveAurasDueToSpell(aur->GetId()); +                                if(Auras.empty()) +                                    break; +                                else +                                    next = Auras.begin(); +                            } +                        } +                    } +                    break; +                } +                /*// Flame Crash +                case 41126: +                { +                    if(!unitTarget) +                        return; -            switch(m_spellInfo->Id) -            { -                case  6201: itemtype=itypes[0][rank];break; // Minor Healthstone -                case  6202: itemtype=itypes[1][rank];break; // Lesser Healthstone -                case  5699: itemtype=itypes[2][rank];break; // Healthstone -                case 11729: itemtype=itypes[3][rank];break; // Greater Healthstone -                case 11730: itemtype=itypes[4][rank];break; // Major Healthstone -                case 27230: itemtype=itypes[5][rank];break; // Master Healthstone -                case 47871: itemtype=itypes[6][rank];break; // Demonic Healthstone -                case 47878: itemtype=itypes[7][rank];break; // Fel Healthstone -                default: -                    return; -            } -            DoCreateItem( effIndex, itemtype ); -            return; -        } -        // Brittle Armor - need remove one 24575 Brittle Armor aura -        case 24590: -            unitTarget->RemoveSingleSpellAurasFromStack(24575); -            return; -        // Mercurial Shield - need remove one 26464 Mercurial Shield aura -        case 26465: -            unitTarget->RemoveSingleSpellAurasFromStack(26464); -            return; -        // Orb teleport spells -        case 25140: -        case 25143: -        case 25650: -        case 25652: -        case 29128: -        case 29129: -        case 35376: -        case 35727: -        { -            if(!unitTarget) -                return; +                    unitTarget->CastSpell(unitTarget, 41131, true); +                    break; +                }*/ +                // Draw Soul +                case 40904: +                { +                    if(!unitTarget) +                        return; -            uint32 spellid; -            switch(m_spellInfo->Id) -            { -                case 25140: spellid =  32571; break; -                case 25143: spellid =  32572; break; -                case 25650: spellid =  30140; break; -                case 25652: spellid =  30141; break; -                case 29128: spellid =  32568; break; -                case 29129: spellid =  32569; break; -                case 35376: spellid =  25649; break; -                case 35727: spellid =  35730; break; -                default: -                    return; -            } +                    unitTarget->CastSpell(m_caster, 40903, true); +                    break; +                } +                case 41931: +                { +                    if(m_caster->GetTypeId() != TYPEID_PLAYER) +                        return; -            unitTarget->CastSpell(unitTarget,spellid,false); -            return; -        } +                    int bag=19; +                    int slot=0; +                    Item* item = NULL; +                     +                    while (bag < 256) +                    { +                        item = ((Player*)m_caster)->GetItemByPos(bag,slot); +                        if (item && item->GetEntry() == 38587) break; +                        slot++; +                        if (slot == 39) +                        { +                            slot = 0; +                            bag++; +                        } +                    } +                    if (bag < 256) +                    { +                        if (((Player*)m_caster)->GetItemByPos(bag,slot)->GetCount() == 1) ((Player*)m_caster)->RemoveItem(bag,slot,true); +                        else ((Player*)m_caster)->GetItemByPos(bag,slot)->SetCount(((Player*)m_caster)->GetItemByPos(bag,slot)->GetCount()-1); +                        // Spell 42518 (Braufest - Gratisprobe des Braufest herstellen) +                        m_caster->CastSpell(m_caster,42518,true); +                        return; +                    } +                    break; +                } +                // Force Cast - Portal Effect: Sunwell Isle +                case 44876: +                { +                    if(!unitTarget) +                        return; -        // Shadow Flame (All script effects, not just end ones to prevent player from dodging the last triggered spell) -        case 22539: -        case 22972: -        case 22975: -        case 22976: -        case 22977: -        case 22978: -        case 22979: -        case 22980: -        case 22981: -        case 22982: -        case 22983: -        case 22984: -        case 22985: -        { -            if(!unitTarget || !unitTarget->isAlive()) -                return; +                    unitTarget->CastSpell(unitTarget, 44870, true); +                    break; +                } +                // Goblin Weather Machine +                case 46203: +                { +                    if(!unitTarget) +                        return; -            // Onyxia Scale Cloak -            if(unitTarget->GetDummyAura(22683)) -                return; +                    uint32 spellId; +                    switch(rand()%4) +                    { +                    case 0: +                        spellId=46740; +                        break; +                    case 1: +                        spellId=46739; +                        break; +                    case 2: +                        spellId=46738; +                        break; +                    case 3: +                        spellId=46736; +                        break; +                    } +                    unitTarget->CastSpell(unitTarget, spellId, true); +                    break; +                } +                //5,000 Gold +                case 46642: +                { +                    if(!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) +                        return; -            // Shadow Flame -            m_caster->CastSpell(unitTarget, 22682, true); -            return; -        } -        break; +                    ((Player*)unitTarget)->ModifyMoney(50000000); -        // Summon Black Qiraji Battle Tank -        case 26656: -        { -            if(!unitTarget) -                return; +                    break; +                } +                // Emblazon Runeblade +                case 51770: +                { +                    if(!unitTarget) +                        return; -            // Prevent stacking of mounts -            unitTarget->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED); +                    unitTarget->CastSpell(unitTarget,51771,false); +                    break; +                } +                // Death Gate +                case 52751: +                { +                    if(!unitTarget || unitTarget->getClass() != CLASS_DEATH_KNIGHT) +                        return; +                    // triggered spell is stored in m_spellInfo->EffectBasePoints[0] +                    unitTarget->CastSpell(unitTarget, damage, false); +                    break; +                } +                // random spell learn instead placeholder +                case 60893:                                 // Northrend Alchemy Research +                case 61177:                                 // Northrend Inscription Research +                case 61288:                                 // Minor Inscription Research +                case 61756:                                 // Northrend Inscription Research (FAST QA VERSION) +                { +                    if(!IsExplicitDiscoverySpell(m_spellInfo)) +                    { +                        sLog.outError("Wrong explicit discowry spell %u structure, or outdated...",m_spellInfo->Id); +                        return; +                    } -            // Two separate mounts depending on area id (allows use both in and out of specific instance) -            if (unitTarget->GetAreaId() == 3428) -                unitTarget->CastSpell(unitTarget, 25863, false); -            else -                unitTarget->CastSpell(unitTarget, 26655, false); -            break; -        } -        // Piccolo of the Flaming Fire -        case 17512: -        { -            if(!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) -                return; -            unitTarget->HandleEmoteCommand(EMOTE_STATE_DANCE); -            break; -        } +                    if(m_caster->GetTypeId()!=TYPEID_PLAYER) +                        return; +                    Player* player = (Player*)m_caster; -        // Netherbloom -        case 28702: -        { -            if(!unitTarget) -                return; -            // 25% chance of casting a random buff -            if(roll_chance_i(75)) -                return; +                    // need replace effect 0 item by loot +                    uint32 reagent_id = m_spellInfo->EffectItemType[0]; +                    if(!player->HasItemCount(reagent_id,1)) +                        return; -            // triggered spells are 28703 to 28707 -            // Note: some sources say, that there was the possibility of -            //       receiving a debuff. However, this seems to be removed by a patch. -            const uint32 spellid = 28703; +                    // remove reagent +                    uint32 count = 1; +                    player->DestroyItemCount (reagent_id,count,true); -            // don't overwrite an existing aura -            for(uint8 i=0; i<5; i++) -                if(unitTarget->HasAura(spellid+i, 0)) +                    if(uint32 discoveredSpell = GetSkillDiscoverySpell(0, m_spellInfo->Id, player)) +                        player->learnSpell(discoveredSpell);                      return; -            unitTarget->CastSpell(unitTarget, spellid+urand(0, 4), true); -            break; -        } - -        // Nightmare Vine -        case 28720: -        { -            if(!unitTarget) -                return; -            // 25% chance of casting Nightmare Pollen -            if(roll_chance_i(75)) -                return; -            unitTarget->CastSpell(unitTarget, 28721, true); -            break; -        } - -        // Mirren's Drinking Hat -        case 29830: -        { -            uint32 item = 0; -            switch ( urand(1,6) ) -            { -                case 1: case 2: case 3: item = 23584; break;// Loch Modan Lager -                case 4: case 5:         item = 23585; break;// Stouthammer Lite -                case 6:                 item = 23586; break;// Aerie Peak Pale Ale +                }              } -            if (item) -                DoCreateItem(effIndex,item);              break;          } -        // Improved Sprint -        case 30918: +        case SPELLFAMILY_WARLOCK:          { -            // Removes snares and roots. -            uint32 mechanic_mask = (1<<MECHANIC_ROOT) | (1<<MECHANIC_SNARE); -            Unit::AuraMap& Auras = unitTarget->GetAuras(); -            for(Unit::AuraMap::iterator iter = Auras.begin(), next; iter != Auras.end(); iter = next) +            switch(m_spellInfo->Id)              { -                next = iter; -                ++next; -                Aura *aur = iter->second; -                if (!aur->IsPositive())             //only remove negative spells +                // Healthstone creating spells +                case  6201: +                case  6202: +                case  5699: +                case 11729: +                case 11730: +                case 27230: +                case 47871: +                case 47878:                  { -                    // check for mechanic mask -                    if(GetSpellMechanicMask(aur->GetSpellProto(), aur->GetEffIndex()) & mechanic_mask) +                    uint32 itemtype; +                    uint32 rank = 0; +                    Unit::AuraList const& mDummyAuras = unitTarget->GetAurasByType(SPELL_AURA_DUMMY); +                    for(Unit::AuraList::const_iterator i = mDummyAuras.begin();i != mDummyAuras.end(); ++i)                      { -                        unitTarget->RemoveAurasDueToSpell(aur->GetId()); -                        if(Auras.empty()) +                        if((*i)->GetId() == 18692) +                        { +                            rank = 1;                              break; -                        else -                            next = Auras.begin(); +                        } +                        else if((*i)->GetId() == 18693) +                        { +                            rank = 2; +                            break; +                        }                      } -                } -            } -            break; -        } -        // Goblin Weather Machine -        case 46203: -        { -            if(!unitTarget) -                return; +                    static uint32 const itypes[8][3] = { +                        { 5512,19004,19005},                // Minor Healthstone +                        { 5511,19006,19007},                // Lesser Healthstone +                        { 5509,19008,19009},                // Healthstone +                        { 5510,19010,19011},                // Greater Healthstone +                        { 9421,19012,19013},                // Major Healthstone +                        {22103,22104,22105},                // Master Healthstone +                        {36889,36890,36891},                // Demonic Healthstone +                        {36892,36893,36894}                 // Fel Healthstone +                    }; -            uint32 spellId; -            switch(rand()%4) -            { -                case 0: -                    spellId=46740; -                    break; -                case 1: -                    spellId=46739; -                    break; -                case 2: -                    spellId=46738; -                    break; -                case 3: -                    spellId=46736; -                    break; +                    switch(m_spellInfo->Id) +                    { +                        case  6201: +                            itemtype=itypes[0][rank];break; // Minor Healthstone +                        case  6202: +                            itemtype=itypes[1][rank];break; // Lesser Healthstone +                        case  5699: +                            itemtype=itypes[2][rank];break; // Healthstone +                        case 11729: +                            itemtype=itypes[3][rank];break; // Greater Healthstone +                        case 11730: +                            itemtype=itypes[4][rank];break; // Major Healthstone +                        case 27230: +                            itemtype=itypes[5][rank];break; // Master Healthstone +                        case 47871: +                            itemtype=itypes[6][rank];break; // Demonic Healthstone +                        case 47878: +                            itemtype=itypes[7][rank];break; // Fel Healthstone +                        default: +                            return; +                    } +                    DoCreateItem( effIndex, itemtype ); +                    return; +                }              } -            unitTarget->CastSpell(unitTarget, spellId, true);              break;          } - -    } - -    if(!unitTarget || !unitTarget->isAlive()) // can we remove this check? -    { -        sLog.outError("Spell %u in EffectScriptEffect does not have unitTarget", m_spellInfo->Id); -        return; -    } - -    switch(m_spellInfo->Id) -    { -        // Dreaming Glory -        case 28698: unitTarget->CastSpell(unitTarget, 28694, true); break; -        // Needle Spine -        //case 39835: unitTarget->CastSpell(unitTarget, 39968, true); break; -        // Draw Soul -        case 40904: unitTarget->CastSpell(m_caster, 40903, true); break; -        // Flame Crash -        //case 41126: unitTarget->CastSpell(unitTarget, 41131, true); break; -        case 41931: +        case SPELLFAMILY_HUNTER:          { -            int bag=19; -            int slot=0; -            Item* item = NULL; -             -            while (bag < 256) +            switch(m_spellInfo->Id)              { -                item = ((Player*)m_caster)->GetItemByPos(bag,slot); -                if (item && item->GetEntry() == 38587) break; -                slot++; -                if (slot == 39) +                // Chimera Shot +                case 53209:                  { -                    slot = 0; -                    bag++; +                    uint32 spellId = 0; +                    int32 basePoint = 0; +                    Unit::AuraMap& Auras = unitTarget->GetAuras(); +                    for(Unit::AuraMap::iterator i = Auras.begin(); i != Auras.end(); ++i) +                    { +                        Aura *aura = (*i).second; +                        if (aura->GetCasterGUID() != m_caster->GetGUID()) +                            continue; +                        // Search only Serpent Sting, Viper Sting, Scorpid Sting auras +                        uint64 familyFlag = aura->GetSpellProto()->SpellFamilyFlags; +                        if (!(familyFlag & 0x000000800000C000LL)) +                            continue; +                        // Refresh aura duration +                        aura->RefreshAura(); + +                        // Serpent Sting - Instantly deals 40% of the damage done by your Serpent Sting. +                        if (familyFlag & 0x0000000000004000LL && aura->GetEffIndex() == 0) +                        { +                            spellId = 53353; // 53353 Chimera Shot - Serpent +                            basePoint = aura->GetModifier()->m_amount * 5 * 40 / 100; +                        } +                        // Viper Sting - Instantly restores mana to you equal to 60% of the total amount drained by your Viper Sting. +                        if (familyFlag & 0x0000008000000000LL && aura->GetEffIndex() == 0) +                        { +                            spellId = 53358; // 53358 Chimera Shot - Viper +                            basePoint = aura->GetModifier()->m_amount * 4 * 60 / 100; +                        } +                        // Scorpid Sting - Attempts to Disarm the target for 10 sec. This effect cannot occur more than once per 1 minute. +                        if (familyFlag & 0x0000000000008000LL) +                            spellId = 53359; // 53359 Chimera Shot - Scorpid +                        // ?? nothing say in spell desc (possibly need addition check) +                        //if (familyFlag & 0x0000010000000000LL || // dot +                        //    familyFlag & 0x0000100000000000LL)   // stun +                        //{ +                        //    spellId = 53366; // 53366 Chimera Shot - Wyvern +                        //} +                    } +                    if (spellId) +                        m_caster->CastCustomSpell(unitTarget, spellId, &basePoint, 0, 0, false); +                    return;                  } +                default: +                    break;              } -            if (bag < 256) -            { -                if (((Player*)m_caster)->GetItemByPos(bag,slot)->GetCount() == 1) ((Player*)m_caster)->RemoveItem(bag,slot,true); -                else ((Player*)m_caster)->GetItemByPos(bag,slot)->SetCount(((Player*)m_caster)->GetItemByPos(bag,slot)->GetCount()-1); -                // Spell 42518 (Braufest - Gratisprobe des Braufest herstellen) -                m_caster->CastSpell(m_caster,42518,true); -                return; -            } -        } -        // Force Cast - Portal Effect: Sunwell Isle -        case 44876: unitTarget->CastSpell(unitTarget, 44870, true); break; -        //5,000 Gold -        case 46642: -        { -            if(unitTarget->GetTypeId() == TYPEID_PLAYER) -                ((Player*)unitTarget)->ModifyMoney(50000000); -            break; -        } -        case 51770: -        { -            if(!unitTarget) -                return; - -            unitTarget->CastSpell(unitTarget,51771,false);              break;          } -    } -    if( m_spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER ) -    { -        switch(m_spellInfo->Id) +        case SPELLFAMILY_PALADIN:          { -            // Chimera Shot -            case 53209: +            // Judgement +            if (m_spellInfo->SpellFamilyFlags & 0x0000000000800000LL)              { -                uint32 spellId = 0; -                int32 basePoint = 0; -                Unit::AuraMap& Auras = unitTarget->GetAuras(); -                for(Unit::AuraMap::iterator i = Auras.begin(); i != Auras.end(); ++i) +                if(!unitTarget || !unitTarget->isAlive()) +                    return; +                uint32 spellId1 = 0; +                uint32 spellId2 = 0; + +                // Judgement self add switch +                switch (m_spellInfo->Id)                  { -                    Aura *aura = (*i).second; -                    if (aura->GetCasterGUID() != m_caster->GetGUID()) +                    case 41467: break;                      // Judgement +                    case 53407: spellId1 = 20184; break;    // Judgement of Justice +                    case 20271:                             // Judgement of Light +                    case 57774: spellId1 = 20185; break;    // Judgement of Light +                    case 53408: spellId1 = 20186; break;    // Judgement of Wisdom +                    default: +                        return; +                } +                // all seals have aura dummy in 2 effect +                Unit::AuraList const& m_dummyAuras = m_caster->GetAurasByType(SPELL_AURA_DUMMY); +                for(Unit::AuraList::const_iterator itr = m_dummyAuras.begin(); itr != m_dummyAuras.end(); ++itr) +                { +                    SpellEntry const *spellInfo = (*itr)->GetSpellProto(); +                    // search seal (all seals have judgement's aura dummy spell id in 2 effect +                    if ((*itr)->GetEffIndex() != 2 || !spellInfo || !IsSealSpell(spellInfo))                          continue; -                    // Search only Serpent Sting, Viper Sting, Scorpid Sting auras -                    uint64 familyFlag = aura->GetSpellProto()->SpellFamilyFlags; -                    if (!(familyFlag & 0x000000800000C000LL)) +                    spellId2 = (*itr)->GetModifier()->m_amount; +                    SpellEntry const *judge = sSpellStore.LookupEntry(spellId2); +                    if (!judge)                          continue; -                    // Refresh aura duration -                    aura->RefreshAura(); - -                    // Serpent Sting - Instantly deals 40% of the damage done by your Serpent Sting. -                    if (familyFlag & 0x0000000000004000LL && aura->GetEffIndex() == 0) -                    { -                        spellId = 53353; // 53353 Chimera Shot - Serpent -                        basePoint = aura->GetModifier()->m_amount * 5 * 40 / 100; -                    } -                    // Viper Sting - Instantly restores mana to you equal to 60% of the total amount drained by your Viper Sting. -                    if (familyFlag & 0x0000008000000000LL && aura->GetEffIndex() == 0) -                    { -                        spellId = 53358; // 53358 Chimera Shot - Viper -                        basePoint = aura->GetModifier()->m_amount * 4 * 60 / 100; -                    } -                    // Scorpid Sting - Attempts to Disarm the target for 10 sec. This effect cannot occur more than once per 1 minute. -                    if (familyFlag & 0x0000000000008000LL) -                        spellId = 53359; // 53359 Chimera Shot - Scorpid -                    // ?? nothing say in spell desc (possibly need addition check) -                    //if (familyFlag & 0x0000010000000000LL || // dot -                    //    familyFlag & 0x0000100000000000LL)   // stun -                    //{ -                    //    spellId = 53366; // 53366 Chimera Shot - Wyvern -                    //} +                    break;                  } -                if (spellId) -                    m_caster->CastCustomSpell(unitTarget, spellId, &basePoint, 0, 0, false); +                if (spellId1) +                    m_caster->CastSpell(unitTarget, spellId1, true); +                if (spellId2) +                    m_caster->CastSpell(unitTarget, spellId2, true);                  return;              } -            default: -                break;          } -    } -    else if( m_spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN ) -    { -        // Judgement -        if (m_spellInfo->SpellFamilyFlags & 0x0000000000800000LL) +        case SPELLFAMILY_POTION:          { -            if(!unitTarget || !unitTarget->isAlive()) -                return; -            uint32 spellId1 = 0; -            uint32 spellId2 = 0; - -            // Judgement self add switch -            switch (m_spellInfo->Id) -            { -                case 41467: break;                           // Judgement -                case 53407: spellId1 = 20184; break;         // Judgement of Justice -                case 20271:                                  // Judgement of Light -                case 57774: spellId1 = 20185; break;         // Judgement of Light -                case 53408: spellId1 = 20186; break;         // Judgement of Wisdom -                default: -                    return; -            } -            // all seals have aura dummy in 2 effect -            Unit::AuraList const& m_dummyAuras = m_caster->GetAurasByType(SPELL_AURA_DUMMY); -            for(Unit::AuraList::const_iterator itr = m_dummyAuras.begin(); itr != m_dummyAuras.end(); ++itr) +            switch(m_spellInfo->Id)              { -                SpellEntry const *spellInfo = (*itr)->GetSpellProto(); -                // search seal (all seals have judgement's aura dummy spell id in 2 effect -                if ((*itr)->GetEffIndex() != 2 || !spellInfo || !IsSealSpell(spellInfo)) -                    continue; -                spellId2 = (*itr)->GetModifier()->m_amount; -                SpellEntry const *judge = sSpellStore.LookupEntry(spellId2); -                if (!judge) -                    continue; -                break; +                // Dreaming Glory +                case 28698: +                { +                    if(!unitTarget) +                        return; +                    unitTarget->CastSpell(unitTarget, 28694, true); +                    break; +                } +                // Netherbloom +                case 28702: +                { +                    if(!unitTarget) +                        return; +                    // 25% chance of casting a random buff +                    if(roll_chance_i(75)) +                        return; + +                    // triggered spells are 28703 to 28707 +                    // Note: some sources say, that there was the possibility of +                    //       receiving a debuff. However, this seems to be removed by a patch. +                    const uint32 spellid = 28703; + +                    // don't overwrite an existing aura +                    for(uint8 i=0; i<5; i++) +                        if(unitTarget->HasAura(spellid+i, 0)) +                            return; +                    unitTarget->CastSpell(unitTarget, spellid+urand(0, 4), true); +                    break; +                } + +                // Nightmare Vine +                case 28720: +                { +                    if(!unitTarget) +                        return; +                    // 25% chance of casting Nightmare Pollen +                    if(roll_chance_i(75)) +                        return; +                    unitTarget->CastSpell(unitTarget, 28721, true); +                    break; +                }              } -            if (spellId1) -                m_caster->CastSpell(unitTarget, spellId1, true); -            if (spellId2) -                m_caster->CastSpell(unitTarget, spellId2, true); -            return; +            break;          }      } diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h index 8dc2d1af35c..5d9e2a3fed3 100644 --- a/src/game/SpellMgr.h +++ b/src/game/SpellMgr.h @@ -348,6 +348,11 @@ inline bool IsElementalShield(SpellEntry const *spellInfo)      return (spellInfo->SpellFamilyFlags & 0x42000000400LL) || spellInfo->Id == 23552;  } +inline bool IsExplicitDiscoverySpell(SpellEntry const *spellInfo) +{ +    return spellInfo->Effect[0]==SPELL_EFFECT_CREATE_ITEM_2 && spellInfo->Effect[1]==SPELL_EFFECT_SCRIPT_EFFECT; +} +  int32 CompareAuraRanks(uint32 spellId_1, uint32 effIndex_1, uint32 spellId_2, uint32 effIndex_2);  bool IsSingleFromSpellSpecificPerCaster(uint32 spellSpec1, uint32 spellSpec2);  bool IsSingleFromSpellSpecificPerTarget(uint32 spellSpec1, uint32 spellSpec2); diff --git a/src/game/ThreatManager.h b/src/game/ThreatManager.h index d4a3910e91e..018c66d4b43 100644 --- a/src/game/ThreatManager.h +++ b/src/game/ThreatManager.h @@ -208,10 +208,10 @@ class TRINITY_DLL_SPEC ThreatManager          // methods to access the lists from the outside to do sume dirty manipulation (scriping and such)          // I hope they are used as little as possible. -        inline std::list<HostilReference*>& getThreatList() { return iThreatContainer.getThreatList(); } -        inline std::list<HostilReference*>& getOfflieThreatList() { return iThreatOfflineContainer.getThreatList(); } -        inline ThreatContainer& getOnlineContainer() { return iThreatContainer; } -        inline ThreatContainer& getOfflineContainer() { return iThreatOfflineContainer; } +        std::list<HostilReference*>& getThreatList() { return iThreatContainer.getThreatList(); } +        std::list<HostilReference*>& getOfflieThreatList() { return iThreatOfflineContainer.getThreatList(); } +        ThreatContainer& getOnlineContainer() { return iThreatContainer; } +        ThreatContainer& getOfflineContainer() { return iThreatOfflineContainer; }  };  //================================================= diff --git a/src/game/Transports.cpp b/src/game/Transports.cpp index c04218ca157..936706f15f5 100644 --- a/src/game/Transports.cpp +++ b/src/game/Transports.cpp @@ -480,11 +480,8 @@ bool Transport::AddPassenger(Player* passenger)  bool Transport::RemovePassenger(Player* passenger)  { -    if (m_passengers.find(passenger) != m_passengers.end()) -    { -        sLog.outDetail("Player %s removed from transport %s.", passenger->GetName(), this->m_name.c_str()); -        m_passengers.erase(passenger); -    } +    if (m_passengers.erase(passenger)) +        sLog.outDetail("Player %s removed from transport %s.", passenger->GetName(), m_name.c_str());      return true;  } diff --git a/src/game/Transports.h b/src/game/Transports.h index 5fb15dbe98f..9093c0d21d0 100644 --- a/src/game/Transports.h +++ b/src/game/Transports.h @@ -38,16 +38,16 @@ class TransportPath              uint32 delay;          }; -        inline void SetLength(const unsigned int sz) +        void SetLength(const unsigned int sz)          {              i_nodes.resize( sz );          } -        inline unsigned int Size(void) const { return i_nodes.size(); } -        inline bool Empty(void) const { return i_nodes.empty(); } -        inline void Resize(unsigned int sz) { i_nodes.resize(sz); } -        inline void Clear(void) { i_nodes.clear(); } -        inline PathNode* GetNodes(void) { return static_cast<PathNode *>(&i_nodes[0]); } +        unsigned int Size(void) const { return i_nodes.size(); } +        bool Empty(void) const { return i_nodes.empty(); } +        void Resize(unsigned int sz) { i_nodes.resize(sz); } +        void Clear(void) { i_nodes.clear(); } +        PathNode* GetNodes(void) { return static_cast<PathNode *>(&i_nodes[0]); }          PathNode& operator[](const unsigned int idx) { return i_nodes[idx]; }          const PathNode& operator()(const unsigned int idx) const { return i_nodes[idx]; } diff --git a/src/game/Traveller.h b/src/game/Traveller.h index 0ac136ff677..2e0bdaf0584 100644 --- a/src/game/Traveller.h +++ b/src/game/Traveller.h @@ -47,10 +47,10 @@ struct TRINITY_DLL_DECL Traveller      operator T&(void) { return i_traveller; }      operator const T&(void) { return i_traveller; } -    inline float GetPositionX() const { return i_traveller.GetPositionX(); } -    inline float GetPositionY() const { return i_traveller.GetPositionY(); } -    inline float GetPositionZ() const { return i_traveller.GetPositionZ(); } -    inline T& GetTraveller(void) { return i_traveller; } +    float GetPositionX() const { return i_traveller.GetPositionX(); } +    float GetPositionY() const { return i_traveller.GetPositionY(); } +    float GetPositionZ() const { return i_traveller.GetPositionZ(); } +    T& GetTraveller(void) { return i_traveller; }      float Speed(void) { assert(false); return 0.0f; }      void Relocation(float x, float y, float z, float orientation) {} diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 34513e87b82..070725090cb 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -2479,6 +2479,24 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit *pVictim, SpellEntry const *spell)      if (roll < tmp)          return SPELL_MISS_MISS; +    // Chance resist mechanic (select max value from every mechanic spell effect) +    int32 resist_mech = 0; +    // Get effects mechanic and chance +    for(int eff = 0; eff < 3; ++eff) +    { +        int32 effect_mech = GetEffectMechanic(spell, eff); +        if (effect_mech) +        { +            int32 temp = pVictim->GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_MECHANIC_RESISTANCE, effect_mech); +            if (resist_mech < temp*100) +                resist_mech = temp*100; +        } +    } +    // Roll chance +    tmp += resist_mech; +    if (roll < tmp) +        return SPELL_MISS_RESIST; +      bool canDodge = true;      bool canParry = true; @@ -8418,8 +8436,7 @@ bool Unit::IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) con          if(itr->type == effect)              return true; -    uint32 mechanic = spellInfo->EffectMechanic[index]; -    if (mechanic) +    if(uint32 mechanic = spellInfo->EffectMechanic[index])      {          SpellImmuneList const& mechanicList = m_spellImmune[IMMUNITY_MECHANIC];          for (SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr) @@ -8427,14 +8444,14 @@ bool Unit::IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) con                  return true;      } -    uint32 aura = spellInfo->EffectApplyAuraName[index]; -    if (aura) +    if(uint32 aura = spellInfo->EffectApplyAuraName[index])      {          SpellImmuneList const& list = m_spellImmune[IMMUNITY_STATE];          for(SpellImmuneList::const_iterator itr = list.begin(); itr != list.end(); ++itr)              if(itr->type == aura)                  return true;      } +      return false;  } @@ -11311,7 +11328,6 @@ Pet* Unit::CreateTamedPetFrom(Creature* creatureTarget,uint32 spell_id)          pet->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);      uint32 level = (creatureTarget->getLevel() < (getLevel() - 5)) ? (getLevel() - 5) : creatureTarget->getLevel(); -    pet->SetFreeTalentPoints(pet->GetMaxTalentPointsForLevel(level));      if(!pet->InitStatsForLevel(level))      { @@ -11324,6 +11340,7 @@ Pet* Unit::CreateTamedPetFrom(Creature* creatureTarget,uint32 spell_id)      // this enables pet details window (Shift+P)      pet->AIM_Initialize();      pet->InitPetCreateSpells(); +    pet->InitTalentForLevel();      pet->SetHealth(pet->GetMaxHealth());      return pet; diff --git a/src/game/Unit.h b/src/game/Unit.h index 4798c179ebd..f48d17fd409 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -658,6 +658,8 @@ uint32 createProcExtendMask(SpellNonMeleeDamage *damageInfo, SpellMissInfo missC  struct UnitActionBarEntry  { +    UnitActionBarEntry() : Raw(0) {} +      union      {          struct  @@ -823,9 +825,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject          }          void _removeAttacker(Unit *pAttacker)               // must be called only from Unit::AttackStop()          { -            AttackerSet::iterator itr = m_attackers.find(pAttacker); -            if(itr != m_attackers.end()) -                m_attackers.erase(itr); +            m_attackers.erase(pAttacker);          }          Unit * getAttackerForHelper()                       // If someone wants to help, who to give them          { @@ -1293,14 +1293,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject          void SetVisibleAura(uint8 slot, uint32 spellid)          {              if(spellid == 0) -            { -                VisibleAuraMap::iterator itr = m_visibleAuras.find(slot); -                if(itr != m_visibleAuras.end()) -                { -                    m_visibleAuras.erase(itr); -                    return; -                } -            } +                m_visibleAuras.erase(slot);              else                  m_visibleAuras[slot] = spellid;          } diff --git a/src/game/UpdateMask.h b/src/game/UpdateMask.h index 9949dd6aa5b..16fa753028f 100644 --- a/src/game/UpdateMask.h +++ b/src/game/UpdateMask.h @@ -36,27 +36,27 @@ class UpdateMask                  delete [] mUpdateMask;          } -        inline void SetBit (uint32 index) +        void SetBit (uint32 index)          {              ( (uint8 *)mUpdateMask )[ index >> 3 ] |= 1 << ( index & 0x7 );          } -        inline void UnsetBit (uint32 index) +        void UnsetBit (uint32 index)          {              ( (uint8 *)mUpdateMask )[ index >> 3 ] &= (0xff ^ (1 <<  ( index & 0x7 ) ) );          } -        inline bool GetBit (uint32 index) +        bool GetBit (uint32 index) const          {              return ( ( (uint8 *)mUpdateMask)[ index >> 3 ] & ( 1 << ( index & 0x7 ) )) != 0;          } -        inline uint32 GetBlockCount() { return mBlocks; } -        inline uint32 GetLength() { return mBlocks << 2; } -        inline uint32 GetCount() { return mCount; } -        inline uint8* GetMask() { return (uint8*)mUpdateMask; } +        uint32 GetBlockCount() const { return mBlocks; } +        uint32 GetLength() const { return mBlocks << 2; } +        uint32 GetCount() const { return mCount; } +        uint8* GetMask() { return (uint8*)mUpdateMask; } -        inline void SetCount (uint32 valuesCount) +        void SetCount (uint32 valuesCount)          {              if(mUpdateMask)                  delete [] mUpdateMask; @@ -68,13 +68,13 @@ class UpdateMask              memset(mUpdateMask, 0, mBlocks << 2);          } -        inline void Clear() +        void Clear()          {              if (mUpdateMask)                  memset(mUpdateMask, 0, mBlocks << 2);          } -        inline UpdateMask& operator = ( const UpdateMask& mask ) +        UpdateMask& operator = ( const UpdateMask& mask )          {              SetCount(mask.mCount);              memcpy(mUpdateMask, mask.mUpdateMask, mBlocks << 2); @@ -82,21 +82,21 @@ class UpdateMask              return *this;          } -        inline void operator &= ( const UpdateMask& mask ) +        void operator &= ( const UpdateMask& mask )          {              ASSERT(mask.mCount <= mCount);              for (uint32 i = 0; i < mBlocks; i++)                  mUpdateMask[i] &= mask.mUpdateMask[i];          } -        inline void operator |= ( const UpdateMask& mask ) +        void operator |= ( const UpdateMask& mask )          {              ASSERT(mask.mCount <= mCount);              for (uint32 i = 0; i < mBlocks; i++)                  mUpdateMask[i] |= mask.mUpdateMask[i];          } -        inline UpdateMask operator & ( const UpdateMask& mask ) const +        UpdateMask operator & ( const UpdateMask& mask ) const          {              ASSERT(mask.mCount <= mCount); @@ -107,7 +107,7 @@ class UpdateMask              return newmask;          } -        inline UpdateMask operator | ( const UpdateMask& mask ) const +        UpdateMask operator | ( const UpdateMask& mask ) const          {              ASSERT(mask.mCount <= mCount); diff --git a/src/game/WaypointMovementGenerator.h b/src/game/WaypointMovementGenerator.h index e9c806a4f7d..21163ded11c 100644 --- a/src/game/WaypointMovementGenerator.h +++ b/src/game/WaypointMovementGenerator.h @@ -48,7 +48,7 @@ class TRINITY_DLL_SPEC PathMovementBase          PathMovementBase() : i_currentNode(0) {}          virtual ~PathMovementBase() {}; -        inline bool MovementInProgress(void) const { return i_currentNode < i_path.Size(); } +        bool MovementInProgress(void) const { return i_currentNode < i_path.Size(); }          void LoadPath(T &);          void ReloadPath(T &); @@ -109,7 +109,7 @@ public PathMovementBase<Player>          Path& GetPath() { return i_path; }          uint32 GetPathAtMapEnd() const; -        inline bool HasArrived() const { return (i_currentNode >= i_path.Size()); } +        bool HasArrived() const { return (i_currentNode >= i_path.Size()); }          void SetCurrentNodeAfterTeleport();          void SkipCurrentNode() { ++i_currentNode; }  		bool GetDestination(float& x, float& y, float& z) const { i_destinationHolder.GetDestination(x,y,z); return true; } diff --git a/src/game/WorldLog.h b/src/game/WorldLog.h index 8ec03d37d6d..5fb0362a6f1 100644 --- a/src/game/WorldLog.h +++ b/src/game/WorldLog.h @@ -51,9 +51,9 @@ class TRINITY_DLL_DECL WorldLog : public Trinity::Singleton<WorldLog, Trinity::C      public:          void Initialize();          /// Is the world logger active? -        inline bool LogWorld(void) const { return (i_file != NULL); } +        bool LogWorld(void) const { return (i_file != NULL); }          /// %Log to the file -        inline void Log(char const *fmt, ...) +        void Log(char const *fmt, ...)          {              if( LogWorld() )              { diff --git a/src/game/WorldSession.h b/src/game/WorldSession.h index 8a50ff2d84e..295f69e0eb2 100644 --- a/src/game/WorldSession.h +++ b/src/game/WorldSession.h @@ -51,7 +51,7 @@ class CharacterHandler;  struct AccountData  { -    AccountData() : Time(NULL), Data("") {} +    AccountData() : Time(0), Data("") {}      time_t Time;      std::string Data; diff --git a/src/mangosd/mangosd.conf.dist.in b/src/mangosd/mangosd.conf.dist.in index e58d5d68f25..5d303e0c131 100644 --- a/src/mangosd/mangosd.conf.dist.in +++ b/src/mangosd/mangosd.conf.dist.in @@ -920,9 +920,9 @@ GM.LowerSecurity  = 0  #    Visibility.Distance.Creature  #    Visibility.Distance.Player  #        Visibility distance for different in game object -#        Max limited by active player zone: ~ 333 +#        Max limited by active player zone: ~ 166  #        Min limit dependent from objects -#        Default: 132 (cell size) +#        Default: 66 (cell size)  #        Min limit is max aggro radius (45) * Rate.Creature.Aggro  #  #    Visibility.Distance.Object @@ -948,10 +948,10 @@ GM.LowerSecurity  = 0  ###################################################################################################################  Visibility.GroupMode = 0 -Visibility.Distance.Creature      = 132 -Visibility.Distance.Player        = 132 -Visibility.Distance.Object        = 132 -Visibility.Distance.InFlight      = 132 +Visibility.Distance.Creature      = 66 +Visibility.Distance.Player        = 66 +Visibility.Distance.Object        = 66 +Visibility.Distance.InFlight      = 66  Visibility.Distance.Grey.Unit   = 1  Visibility.Distance.Grey.Object = 10 diff --git a/src/shared/Database/SqlDelayThread.h b/src/shared/Database/SqlDelayThread.h index 707a3cab941..373b83604f1 100644 --- a/src/shared/Database/SqlDelayThread.h +++ b/src/shared/Database/SqlDelayThread.h @@ -42,7 +42,7 @@ class SqlDelayThread : public ZThread::Runnable          SqlDelayThread(Database* db);          ///< Put sql statement to delay queue -        inline bool Delay(SqlOperation* sql) { m_sqlQueue.add(sql); return true; } +        bool Delay(SqlOperation* sql) { m_sqlQueue.add(sql); return true; }          virtual void Stop();                                ///< Stop event          virtual void run();                                 ///< Main Thread loop diff --git a/src/shared/revision.h b/src/shared/revision.h index e2fa39e47fd..c2c9ba4ece8 100644 --- a/src/shared/revision.h +++ b/src/shared/revision.h @@ -1,7 +1,7 @@  #ifndef __REVISION_H__  #define __REVISION_H__ - #define _REVISION "1008" - #define _HASH "30a554889aa4" + #define _REVISION "1024" + #define _HASH "b39265a18e57"   #define _REVISION_DATE "*"   #define _REVISION_TIME "*"  #endif // __REVISION_H__ diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 0dc131817cc..c9cdb24bc63 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@  #ifndef __REVISION_NR_H__  #define __REVISION_NR_H__ - #define REVISION_NR "7111" + #define REVISION_NR "7125"  #endif // __REVISION_NR_H__  | 
