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__ |