aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2012-07-09 11:08:33 +0200
committerShauren <shauren.trinity@gmail.com>2012-07-09 11:08:33 +0200
commit06a4ade88a9aee90e66c02852752c6acc30b7a6d (patch)
tree793bb32595362d64ccc7a3c5c4377a36fa4747ce
parentccaca5f7cafc38292aeaf8a44c3a1a4a447dadb1 (diff)
Core/Achievements: Implemented guild achievements
-rw-r--r--sql/base/characters_database.sql51
-rw-r--r--sql/updates/characters/2012_07_09_00_characters_guild_achievement_4x.sql24
-rw-r--r--sql/updates/characters/2012_07_09_00_characters_guild_achievement_progress_4x.sql25
-rwxr-xr-xsrc/server/game/Achievements/AchievementMgr.cpp1118
-rwxr-xr-xsrc/server/game/Achievements/AchievementMgr.h51
-rw-r--r--src/server/game/AuctionHouse/AuctionHouseMgr.cpp6
-rwxr-xr-xsrc/server/game/Battlegrounds/Battleground.cpp20
-rwxr-xr-xsrc/server/game/Battlegrounds/Zones/BattlegroundAB.cpp4
-rwxr-xr-xsrc/server/game/Battlegrounds/Zones/BattlegroundAV.cpp8
-rwxr-xr-xsrc/server/game/Battlegrounds/Zones/BattlegroundEY.cpp2
-rwxr-xr-xsrc/server/game/Battlegrounds/Zones/BattlegroundWS.cpp4
-rwxr-xr-xsrc/server/game/DataStores/DBCEnums.h254
-rwxr-xr-xsrc/server/game/DungeonFinding/LFGMgr.cpp2
-rwxr-xr-xsrc/server/game/Entities/Player/Player.cpp107
-rwxr-xr-xsrc/server/game/Entities/Player/Player.h8
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.cpp16
-rwxr-xr-xsrc/server/game/Groups/Group.cpp4
-rwxr-xr-xsrc/server/game/Guilds/Guild.cpp4
-rwxr-xr-xsrc/server/game/Guilds/Guild.h7
-rw-r--r--src/server/game/Guilds/GuildMgr.cpp20
-rwxr-xr-xsrc/server/game/Handlers/AuctionHouseHandler.cpp8
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp4
-rwxr-xr-xsrc/server/game/Handlers/ChatHandler.cpp2
-rwxr-xr-xsrc/server/game/Handlers/GroupHandler.cpp4
-rwxr-xr-xsrc/server/game/Handlers/ItemHandler.cpp6
-rwxr-xr-xsrc/server/game/Handlers/LootHandler.cpp10
-rwxr-xr-xsrc/server/game/Handlers/MailHandler.cpp2
-rwxr-xr-xsrc/server/game/Handlers/MiscHandler.cpp11
-rwxr-xr-xsrc/server/game/Handlers/QuestHandler.cpp2
-rwxr-xr-xsrc/server/game/Handlers/SpellHandler.cpp4
-rwxr-xr-xsrc/server/game/Maps/Map.h1
-rwxr-xr-xsrc/server/game/Reputation/ReputationMgr.cpp10
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp14
-rwxr-xr-xsrc/server/game/Server/Protocol/Opcodes.h15
-rwxr-xr-xsrc/server/game/Server/WorldSession.h1
-rwxr-xr-xsrc/server/game/Server/WorldSocket.cpp2
-rwxr-xr-xsrc/server/game/Spells/Spell.cpp10
-rw-r--r--src/server/scripts/Commands/cs_reset.cpp2
-rwxr-xr-xsrc/server/shared/DataStores/DBCStore.h2
-rwxr-xr-xsrc/server/shared/Database/Implementation/CharacterDatabase.cpp8
-rwxr-xr-xsrc/server/shared/Database/Implementation/CharacterDatabase.h8
-rwxr-xr-xsrc/server/shared/Packets/ByteBuffer.h2
42 files changed, 1345 insertions, 518 deletions
diff --git a/sql/base/characters_database.sql b/sql/base/characters_database.sql
index bbbc799a6af..3016614cd0e 100644
--- a/sql/base/characters_database.sql
+++ b/sql/base/characters_database.sql
@@ -1559,6 +1559,57 @@ LOCK TABLES `guild` WRITE;
UNLOCK TABLES;
--
+-- Table structure for table `guild_achievement`
+--
+
+DROP TABLE IF EXISTS `guild_achievement`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `guild_achievement` (
+ `guildId` int(10) unsigned NOT NULL,
+ `achievement` smallint(5) unsigned NOT NULL,
+ `date` int(10) unsigned NOT NULL DEFAULT '0',
+ `guids` text NOT NULL,
+ PRIMARY KEY (`guildId`,`achievement`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `guild_achievement`
+--
+
+LOCK TABLES `guild_achievement` WRITE;
+/*!40000 ALTER TABLE `guild_achievement` DISABLE KEYS */;
+/*!40000 ALTER TABLE `guild_achievement` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `guild_achievement_progress`
+--
+
+DROP TABLE IF EXISTS `guild_achievement_progress`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `guild_achievement_progress` (
+ `guildId` int(10) unsigned NOT NULL,
+ `criteria` smallint(5) unsigned NOT NULL,
+ `counter` int(10) unsigned NOT NULL,
+ `date` int(10) unsigned NOT NULL DEFAULT '0',
+ `completedGuid` int(10) unsigned NOT NULL DEFAULT '0',
+ PRIMARY KEY (`guildId`,`criteria`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `guild_achievement_progress`
+--
+
+LOCK TABLES `guild_achievement_progress` WRITE;
+/*!40000 ALTER TABLE `guild_achievement_progress` DISABLE KEYS */;
+/*!40000 ALTER TABLE `guild_achievement_progress` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
-- Table structure for table `guild_bank_eventlog`
--
diff --git a/sql/updates/characters/2012_07_09_00_characters_guild_achievement_4x.sql b/sql/updates/characters/2012_07_09_00_characters_guild_achievement_4x.sql
new file mode 100644
index 00000000000..fffe375b464
--- /dev/null
+++ b/sql/updates/characters/2012_07_09_00_characters_guild_achievement_4x.sql
@@ -0,0 +1,24 @@
+--
+-- Table structure for table `guild_achievement`
+--
+
+DROP TABLE IF EXISTS `guild_achievement`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `guild_achievement` (
+ `guildId` int(10) unsigned NOT NULL,
+ `achievement` smallint(5) unsigned NOT NULL,
+ `date` int(10) unsigned NOT NULL DEFAULT '0',
+ `guids` text NOT NULL DEFAULT '',
+ PRIMARY KEY (`guildId`,`achievement`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `guild_achievement`
+--
+
+LOCK TABLES `guild_achievement` WRITE;
+/*!40000 ALTER TABLE `guild_achievement` DISABLE KEYS */;
+/*!40000 ALTER TABLE `guild_achievement` ENABLE KEYS */;
+UNLOCK TABLES;
diff --git a/sql/updates/characters/2012_07_09_00_characters_guild_achievement_progress_4x.sql b/sql/updates/characters/2012_07_09_00_characters_guild_achievement_progress_4x.sql
new file mode 100644
index 00000000000..c69e41a4ad4
--- /dev/null
+++ b/sql/updates/characters/2012_07_09_00_characters_guild_achievement_progress_4x.sql
@@ -0,0 +1,25 @@
+--
+-- Table structure for table `guild_achievement_progress`
+--
+
+DROP TABLE IF EXISTS `guild_achievement_progress`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `guild_achievement_progress` (
+ `guildId` int(10) unsigned NOT NULL,
+ `criteria` smallint(5) unsigned NOT NULL,
+ `counter` int(10) unsigned NOT NULL,
+ `date` int(10) unsigned NOT NULL DEFAULT '0',
+ `completedGuid` int(10) unsigned NOT NULL DEFAULT '0',
+ PRIMARY KEY (`guildId`,`criteria`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `guild_achievement_progress`
+--
+
+LOCK TABLES `guild_achievement_progress` WRITE;
+/*!40000 ALTER TABLE `guild_achievement_progress` DISABLE KEYS */;
+/*!40000 ALTER TABLE `guild_achievement_progress` ENABLE KEYS */;
+UNLOCK TABLES;
diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp
index 252e120f0c9..7ff744a1dc8 100755
--- a/src/server/game/Achievements/AchievementMgr.cpp
+++ b/src/server/game/Achievements/AchievementMgr.cpp
@@ -377,45 +377,90 @@ bool AchievementCriteriaDataSet::Meets(Player const* source, Unit const* target,
return true;
}
-AchievementMgr::AchievementMgr(Player* player)
+template<class T>
+AchievementMgr<T>::AchievementMgr(T* owner)
{
- m_player = player;
+ _owner = owner;
}
-AchievementMgr::~AchievementMgr()
+template<class T>
+AchievementMgr<T>::~AchievementMgr()
{
}
-void AchievementMgr::Reset()
+template<class T>
+void AchievementMgr<T>::SendPacket(WorldPacket* data) const
{
- for (CompletedAchievementMap::const_iterator iter = m_completedAchievements.begin(); iter != m_completedAchievements.end(); ++iter)
- {
- WorldPacket data(SMSG_ACHIEVEMENT_DELETED, 4);
- data << uint32(iter->first);
- m_player->SendDirectMessage(&data);
- }
+}
- for (CriteriaProgressMap::const_iterator iter = m_criteriaProgress.begin(); iter != m_criteriaProgress.end(); ++iter)
- {
- WorldPacket data(SMSG_CRITERIA_DELETED, 4);
- data << uint32(iter->first);
- m_player->SendDirectMessage(&data);
- }
+template<>
+void AchievementMgr<Guild>::SendPacket(WorldPacket* data) const
+{
+ GetOwner()->BroadcastPacket(data);
+}
- m_completedAchievements.clear();
- m_criteriaProgress.clear();
- DeleteFromDB(m_player->GetGUIDLow());
+template<>
+void AchievementMgr<Player>::SendPacket(WorldPacket* data) const
+{
+ GetOwner()->GetSession()->SendPacket(data);
+}
- // re-fill data
- CheckAllAchievementCriteria();
+template<class T>
+void AchievementMgr<T>::RemoveCriteriaProgress(const AchievementCriteriaEntry* entry)
+{
+ CriteriaProgressMap::iterator criteriaProgress = m_criteriaProgress.find(entry->ID);
+ if (criteriaProgress == m_criteriaProgress.end())
+ return;
+
+ WorldPacket data(SMSG_CRITERIA_DELETED, 4);
+ data << uint32(entry->ID);
+ SendPacket(&data);
+
+ m_criteriaProgress.erase(criteriaProgress);
+}
+
+template<>
+void AchievementMgr<Guild>::RemoveCriteriaProgress(const AchievementCriteriaEntry* entry)
+{
+ CriteriaProgressMap::iterator criteriaProgress = m_criteriaProgress.find(entry->ID);
+ if (criteriaProgress == m_criteriaProgress.end())
+ return;
+
+ uint8 guidBytes[8];
+ *reinterpret_cast<uint64*>(&guidBytes[0]) = GetOwner()->GetGUID();
+
+ WorldPacket data(SMSG_GUILD_CRITERIA_DELETED, 4 + 8);
+ data.WriteBit(guidBytes[6]);
+ data.WriteBit(guidBytes[5]);
+ data.WriteBit(guidBytes[7]);
+ data.WriteBit(guidBytes[0]);
+ data.WriteBit(guidBytes[1]);
+ data.WriteBit(guidBytes[3]);
+ data.WriteBit(guidBytes[2]);
+ data.WriteBit(guidBytes[4]);
+
+ data.WriteByteSeq(guidBytes[2]);
+ data.WriteByteSeq(guidBytes[3]);
+ data.WriteByteSeq(guidBytes[4]);
+ data.WriteByteSeq(guidBytes[1]);
+ data.WriteByteSeq(guidBytes[7]);
+ data << uint32(entry->ID);
+ data.WriteByteSeq(guidBytes[5]);
+ data.WriteByteSeq(guidBytes[0]);
+ data.WriteByteSeq(guidBytes[6]);
+
+ SendPacket(&data);
+
+ m_criteriaProgress.erase(criteriaProgress);
}
-void AchievementMgr::ResetAchievementCriteria(AchievementCriteriaTypes type, uint32 miscvalue1, uint32 miscvalue2, bool evenIfCriteriaComplete)
+template<class T>
+void AchievementMgr<T>::ResetAchievementCriteria(AchievementCriteriaTypes type, uint32 miscvalue1, uint32 miscvalue2, bool evenIfCriteriaComplete)
{
sLog->outDebug(LOG_FILTER_ACHIEVEMENTSYS, "AchievementMgr::ResetAchievementCriteria(%u, %u, %u)", type, miscvalue1, miscvalue2);
// disable for gamemasters with GM-mode enabled
- if (m_player->isGameMaster())
+ if (GetOwner()->isGameMaster())
return;
AchievementCriteriaEntryList const& achievementCriteriaList = sAchievementMgr->GetAchievementCriteriaByType(type);
@@ -442,7 +487,19 @@ void AchievementMgr::ResetAchievementCriteria(AchievementCriteriaTypes type, uin
}
}
-void AchievementMgr::DeleteFromDB(uint32 lowguid)
+template<>
+void AchievementMgr<Guild>::ResetAchievementCriteria(AchievementCriteriaTypes /*type*/, uint32 /*miscvalue1*/, uint32 /*miscvalue2*/, bool /*evenIfCriteriaComplete*/)
+{
+ // Not needed
+}
+
+template<class T>
+void AchievementMgr<T>::DeleteFromDB(uint32 /*lowguid*/)
+{
+}
+
+template<>
+void AchievementMgr<Player>::DeleteFromDB(uint32 lowguid)
{
SQLTransaction trans = CharacterDatabase.BeginTransaction();
@@ -457,7 +514,29 @@ void AchievementMgr::DeleteFromDB(uint32 lowguid)
CharacterDatabase.CommitTransaction(trans);
}
-void AchievementMgr::SaveToDB(SQLTransaction& trans)
+template<>
+void AchievementMgr<Guild>::DeleteFromDB(uint32 lowguid)
+{
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ALL_GUILD_ACHIEVEMENTS);
+ stmt->setUInt32(0, lowguid);
+ trans->Append(stmt);
+
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ALL_GUILD_ACHIEVEMENT_CRITERIA);
+ stmt->setUInt32(0, lowguid);
+ trans->Append(stmt);
+
+ CharacterDatabase.CommitTransaction(trans);
+}
+
+template<class T>
+void AchievementMgr<T>::SaveToDB(SQLTransaction& /*trans*/)
+{
+}
+
+template<>
+void AchievementMgr<Player>::SaveToDB(SQLTransaction& trans)
{
if (!m_completedAchievements.empty())
{
@@ -472,7 +551,7 @@ void AchievementMgr::SaveToDB(SQLTransaction& trans)
/// first new/changed record prefix
if (!need_execute)
{
- ssdel << "DELETE FROM character_achievement WHERE guid = " << GetPlayer()->GetGUIDLow() << " AND achievement IN (";
+ ssdel << "DELETE FROM character_achievement WHERE guid = " << GetOwner()->GetGUIDLow() << " AND achievement IN (";
ssins << "INSERT INTO character_achievement (guid, achievement, date) VALUES ";
need_execute = true;
}
@@ -485,7 +564,7 @@ void AchievementMgr::SaveToDB(SQLTransaction& trans)
// new/changed record data
ssdel << iter->first;
- ssins << '(' << GetPlayer()->GetGUIDLow() << ',' << iter->first << ',' << uint64(iter->second.date) << ')';
+ ssins << '(' << GetOwner()->GetGUIDLow() << ',' << iter->first << ',' << uint64(iter->second.date) << ')';
/// mark as saved in db
iter->second.changed = false;
@@ -516,7 +595,7 @@ void AchievementMgr::SaveToDB(SQLTransaction& trans)
/// 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 (";
+ ssdel << "DELETE FROM character_achievement_progress WHERE guid = " << GetOwner()->GetGUIDLow() << " AND criteria IN (";
need_execute_del = true;
}
/// next new/changed record prefix
@@ -541,7 +620,7 @@ void AchievementMgr::SaveToDB(SQLTransaction& trans)
ssins << ',';
// new/changed record data
- ssins << '(' << GetPlayer()->GetGUIDLow() << ',' << iter->first << ',' << iter->second.counter << ',' << iter->second.date << ')';
+ ssins << '(' << GetOwner()->GetGUIDLow() << ',' << iter->first << ',' << iter->second.counter << ',' << iter->second.date << ')';
}
/// mark as updated in db
@@ -561,7 +640,61 @@ void AchievementMgr::SaveToDB(SQLTransaction& trans)
}
}
-void AchievementMgr::LoadFromDB(PreparedQueryResult achievementResult, PreparedQueryResult criteriaResult)
+template<>
+void AchievementMgr<Guild>::SaveToDB(SQLTransaction& trans)
+{
+ PreparedStatement* stmt;
+ std::ostringstream guidstr;
+ for (CompletedAchievementMap::const_iterator itr = m_completedAchievements.begin(); itr != m_completedAchievements.end(); ++itr)
+ {
+ if (!itr->second.changed)
+ continue;
+
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_ACHIEVEMENT);
+ stmt->setUInt32(0, GetOwner()->GetId());
+ stmt->setUInt16(1, itr->first);
+ trans->Append(stmt);
+
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_ACHIEVEMENT);
+ stmt->setUInt32(0, GetOwner()->GetId());
+ stmt->setUInt16(1, itr->first);
+ stmt->setUInt32(2, itr->second.date);
+ for (std::set<uint64>::const_iterator gItr = itr->second.guids.begin(); gItr != itr->second.guids.end(); ++gItr)
+ guidstr << GUID_LOPART(*gItr) << ',';
+
+ stmt->setString(3, guidstr.str());
+ trans->Append(stmt);
+
+ guidstr.str("");
+ }
+
+ for (CriteriaProgressMap::const_iterator itr = m_criteriaProgress.begin(); itr != m_criteriaProgress.end(); ++itr)
+ {
+ if (!itr->second.changed)
+ continue;
+
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_ACHIEVEMENT_CRITERIA);
+ stmt->setUInt32(0, GetOwner()->GetId());
+ stmt->setUInt16(1, itr->first);
+ trans->Append(stmt);
+
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_ACHIEVEMENT_CRITERIA);
+ stmt->setUInt32(0, GetOwner()->GetId());
+ stmt->setUInt16(1, itr->first);
+ stmt->setUInt32(2, itr->second.counter);
+ stmt->setUInt32(3, itr->second.date);
+ stmt->setUInt32(4, GUID_LOPART(itr->second.CompletedGUID));
+ trans->Append(stmt);
+ }
+}
+
+template<class T>
+void AchievementMgr<T>::LoadFromDB(PreparedQueryResult achievementResult, PreparedQueryResult criteriaResult)
+{
+}
+
+template<>
+void AchievementMgr<Player>::LoadFromDB(PreparedQueryResult achievementResult, PreparedQueryResult criteriaResult)
{
if (achievementResult)
{
@@ -581,10 +714,10 @@ void AchievementMgr::LoadFromDB(PreparedQueryResult achievementResult, PreparedQ
// title achievement rewards are retroactive
if (AchievementReward const* reward = sAchievementMgr->GetAchievementReward(achievement))
- if (uint32 titleId = reward->titleId[Player::TeamForRace(GetPlayer()->getRace()) == ALLIANCE ? 0 : 1])
+ if (uint32 titleId = reward->titleId[Player::TeamForRace(GetOwner()->getRace()) == ALLIANCE ? 0 : 1])
if (CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(titleId))
- if (!GetPlayer()->HasTitle(titleEntry))
- GetPlayer()->SetTitle(titleEntry);
+ if (!GetOwner()->HasTitle(titleEntry))
+ GetOwner()->SetTitle(titleEntry);
} while (achievementResult->NextRow());
}
@@ -605,9 +738,7 @@ void AchievementMgr::LoadFromDB(PreparedQueryResult achievementResult, PreparedQ
sLog->outError("Non-existing achievement criteria %u data removed from table `character_achievement_progress`.", id);
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INVALID_ACHIEV_PROGRESS_CRITERIA);
-
stmt->setUInt16(0, uint16(id));
-
CharacterDatabase.Execute(stmt);
continue;
@@ -624,11 +755,136 @@ void AchievementMgr::LoadFromDB(PreparedQueryResult achievementResult, PreparedQ
}
}
-void AchievementMgr::SendAchievementEarned(AchievementEntry const* achievement) const
+template<>
+void AchievementMgr<Guild>::LoadFromDB(PreparedQueryResult achievementResult, PreparedQueryResult criteriaResult)
{
- if (GetPlayer()->GetSession()->PlayerLoading())
- return;
+ if (achievementResult)
+ {
+ do
+ {
+ Field* fields = achievementResult->Fetch();
+ uint32 achievementid = fields[0].GetUInt16();
+
+ // must not happen: cleanup at server startup in sAchievementMgr->LoadCompletedAchievements()
+ AchievementEntry const* achievement = sAchievementStore.LookupEntry(achievementid);
+ if (!achievement)
+ continue;
+
+ CompletedAchievementData& ca = m_completedAchievements[achievementid];
+ ca.date = time_t(fields[1].GetUInt32());
+ Tokens guids(fields[2].GetString(), ' ');
+ for (uint32 i = 0; i < guids.size(); ++i)
+ ca.guids.insert(MAKE_NEW_GUID(atol(guids[i]), 0, HIGHGUID_PLAYER));
+
+ ca.changed = false;
+
+ } while (achievementResult->NextRow());
+ }
+ if (criteriaResult)
+ {
+ time_t now = time(NULL);
+ do
+ {
+ Field* fields = criteriaResult->Fetch();
+ uint32 id = fields[0].GetUInt16();
+ uint32 counter = fields[1].GetUInt32();
+ time_t date = time_t(fields[2].GetUInt32());
+ uint64 guid = fields[3].GetUInt32();
+
+ AchievementCriteriaEntry const* criteria = sAchievementCriteriaStore.LookupEntry(id);
+ if (!criteria)
+ {
+ // we will remove not existed criteria for all guilds
+ sLog->outError("Non-existing achievement criteria %u data removed from table `guild_achievement_progress`.", id);
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INVALID_ACHIEV_PROGRESS_CRITERIA);
+ stmt->setUInt16(0, uint16(id));
+ CharacterDatabase.Execute(stmt);
+ continue;
+ }
+
+ if (criteria->timeLimit && time_t(date + criteria->timeLimit) < now)
+ continue;
+
+ CriteriaProgress& progress = m_criteriaProgress[id];
+ progress.counter = counter;
+ progress.date = date;
+ progress.CompletedGUID = MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER);
+ progress.changed = false;
+ } while (criteriaResult->NextRow());
+ }
+}
+
+template<class T>
+void AchievementMgr<T>::Reset()
+{
+ for (CompletedAchievementMap::const_iterator iter = m_completedAchievements.begin(); iter != m_completedAchievements.end(); ++iter)
+ {
+ WorldPacket data(SMSG_ACHIEVEMENT_DELETED, 4);
+ data << uint32(iter->first);
+ SendPacket(&data);
+ }
+
+ for (CriteriaProgressMap::const_iterator iter = m_criteriaProgress.begin(); iter != m_criteriaProgress.end(); ++iter)
+ {
+ WorldPacket data(SMSG_CRITERIA_DELETED, 4);
+ data << uint32(iter->first);
+ SendPacket(&data);
+ }
+
+ m_completedAchievements.clear();
+ m_criteriaProgress.clear();
+ DeleteFromDB(_owner->GetGUIDLow());
+
+ // re-fill data
+ CheckAllAchievementCriteria();
+}
+
+template<>
+void AchievementMgr<Guild>::Reset()
+{
+ uint8 guidBytes[8];
+ *reinterpret_cast<uint64*>(&guidBytes[0]) = GetOwner()->GetGUID();
+
+ for (CompletedAchievementMap::const_iterator iter = m_completedAchievements.begin(); iter != m_completedAchievements.end(); ++iter)
+ {
+ WorldPacket data(SMSG_GUILD_ACHIEVEMENT_DELETED, 4);
+ data.WriteBit(guidBytes[4]);
+ data.WriteBit(guidBytes[1]);
+ data.WriteBit(guidBytes[2]);
+ data.WriteBit(guidBytes[3]);
+ data.WriteBit(guidBytes[0]);
+ data.WriteBit(guidBytes[7]);
+ data.WriteBit(guidBytes[5]);
+ data.WriteBit(guidBytes[6]);
+ data << uint32(iter->first);
+ data.WriteByteSeq(guidBytes[5]);
+ data.WriteByteSeq(guidBytes[1]);
+ data.WriteByteSeq(guidBytes[3]);
+ data.WriteByteSeq(guidBytes[6]);
+ data.WriteByteSeq(guidBytes[0]);
+ data.WriteByteSeq(guidBytes[7]);
+ data << uint32(secsToTimeBitFields(iter->second.date));
+ data.WriteByteSeq(guidBytes[4]);
+ data.WriteByteSeq(guidBytes[2]);
+ SendPacket(&data);
+ }
+
+ while (!m_criteriaProgress.empty())
+ if (AchievementCriteriaEntry const* criteria = sAchievementCriteriaStore.LookupEntry(m_criteriaProgress.begin()->first))
+ RemoveCriteriaProgress(criteria);
+
+ m_completedAchievements.clear();
+ DeleteFromDB(_owner->GetId());
+
+ // re-fill data
+ CheckAllAchievementCriteria();
+}
+
+template<class T>
+void AchievementMgr<T>::SendAchievementEarned(AchievementEntry const* achievement) const
+{
// Don't send for achievements with ACHIEVEMENT_FLAG_TRACKING
if (achievement->flags & ACHIEVEMENT_FLAG_HIDDEN)
return;
@@ -637,47 +893,83 @@ void AchievementMgr::SendAchievementEarned(AchievementEntry const* achievement)
sLog->outDebug(LOG_FILTER_ACHIEVEMENTSYS, "AchievementMgr::SendAchievementEarned(%u)", achievement->ID);
#endif
- if (Guild* guild = sGuildMgr->GetGuildById(GetPlayer()->GetGuildId()))
+ if (Guild* guild = sGuildMgr->GetGuildById(GetOwner()->GetGuildId()))
{
- Trinity::AchievementChatBuilder say_builder(*GetPlayer(), CHAT_MSG_GUILD_ACHIEVEMENT, LANG_ACHIEVEMENT_EARNED, achievement->ID);
+ Trinity::AchievementChatBuilder say_builder(*GetOwner(), CHAT_MSG_GUILD_ACHIEVEMENT, LANG_ACHIEVEMENT_EARNED, achievement->ID);
Trinity::LocalizedPacketDo<Trinity::AchievementChatBuilder> say_do(say_builder);
- guild->BroadcastWorker(say_do, GetPlayer());
+ guild->BroadcastWorker(say_do);
}
- if (achievement->flags & (ACHIEVEMENT_FLAG_REALM_FIRST_KILL|ACHIEVEMENT_FLAG_REALM_FIRST_REACH))
+ if (achievement->flags & (ACHIEVEMENT_FLAG_REALM_FIRST_KILL | ACHIEVEMENT_FLAG_REALM_FIRST_REACH))
{
// broadcast realm first reached
- WorldPacket data(SMSG_SERVER_FIRST_ACHIEVEMENT, strlen(GetPlayer()->GetName())+1+8+4+4);
- data << GetPlayer()->GetName();
- data << uint64(GetPlayer()->GetGUID());
+ WorldPacket data(SMSG_SERVER_FIRST_ACHIEVEMENT, strlen(GetOwner()->GetName())+1+8+4+4);
+ data << GetOwner()->GetName();
+ data << uint64(GetOwner()->GetGUID());
data << uint32(achievement->ID);
data << uint32(0); // 1=link supplied string as player name, 0=display plain string
sWorld->SendGlobalMessage(&data);
}
// if player is in world he can tell his friends about new achievement
- else if (GetPlayer()->IsInWorld())
+ else if (GetOwner()->IsInWorld())
{
- CellCoord p = Trinity::ComputeCellCoord(GetPlayer()->GetPositionX(), GetPlayer()->GetPositionY());
+ CellCoord p = Trinity::ComputeCellCoord(GetOwner()->GetPositionX(), GetOwner()->GetPositionY());
Cell cell(p);
cell.SetNoCreate();
- Trinity::AchievementChatBuilder say_builder(*GetPlayer(), CHAT_MSG_ACHIEVEMENT, LANG_ACHIEVEMENT_EARNED, achievement->ID);
+ Trinity::AchievementChatBuilder say_builder(*GetOwner(), CHAT_MSG_ACHIEVEMENT, LANG_ACHIEVEMENT_EARNED, achievement->ID);
Trinity::LocalizedPacketDo<Trinity::AchievementChatBuilder> say_do(say_builder);
- Trinity::PlayerDistWorker<Trinity::LocalizedPacketDo<Trinity::AchievementChatBuilder> > say_worker(GetPlayer(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), say_do);
+ Trinity::PlayerDistWorker<Trinity::LocalizedPacketDo<Trinity::AchievementChatBuilder> > say_worker(GetOwner(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), say_do);
TypeContainerVisitor<Trinity::PlayerDistWorker<Trinity::LocalizedPacketDo<Trinity::AchievementChatBuilder> >, WorldTypeMapContainer > message(say_worker);
- cell.Visit(p, message, *GetPlayer()->GetMap(), *GetPlayer(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY));
+ cell.Visit(p, message, *GetOwner()->GetMap(), *GetOwner(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY));
}
WorldPacket data(SMSG_ACHIEVEMENT_EARNED, 8+4+8);
- data.append(GetPlayer()->GetPackGUID());
+ data.append(GetOwner()->GetPackGUID());
data << uint32(achievement->ID);
data << uint32(secsToTimeBitFields(time(NULL)));
- data << uint32(0);
- GetPlayer()->SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), true);
+ data << uint32(0); // does not notify player ingame
+ GetOwner()->SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), true);
}
-void AchievementMgr::SendCriteriaUpdate(AchievementCriteriaEntry const* entry, CriteriaProgress const* progress, uint32 timeElapsed, bool timedCompleted) const
+template<>
+void AchievementMgr<Guild>::SendAchievementEarned(AchievementEntry const* achievement) const
+{
+ uint8 guidBytes[8];
+ *reinterpret_cast<uint64*>(&guidBytes[0]) = GetOwner()->GetGUID();
+
+ WorldPacket data(SMSG_GUILD_ACHIEVEMENT_EARNED, 8+4+8);
+ data.WriteByteMask(guidBytes[3]);
+ data.WriteByteMask(guidBytes[1]);
+ data.WriteByteMask(guidBytes[0]);
+ data.WriteByteMask(guidBytes[7]);
+ data.WriteByteMask(guidBytes[4]);
+ data.WriteByteMask(guidBytes[6]);
+ data.WriteByteMask(guidBytes[2]);
+ data.WriteByteMask(guidBytes[5]);
+
+ data.WriteByteSeq(guidBytes[2]);
+ data << uint32(secsToTimeBitFields(time(NULL)));
+ data.WriteByteSeq(guidBytes[0]);
+ data.WriteByteSeq(guidBytes[4]);
+ data.WriteByteSeq(guidBytes[1]);
+ data.WriteByteSeq(guidBytes[3]);
+ data << uint32(achievement->ID);
+ data.WriteByteSeq(guidBytes[7]);
+ data.WriteByteSeq(guidBytes[5]);
+ data.WriteByteSeq(guidBytes[6]);
+
+ SendPacket(&data);
+}
+
+template<class T>
+void AchievementMgr<T>::SendCriteriaUpdate(AchievementCriteriaEntry const* /*entry*/, CriteriaProgress const* /*progress*/, uint32 /*timeElapsed*/, bool /*timedCompleted*/) const
+{
+}
+
+template<>
+void AchievementMgr<Player>::SendCriteriaUpdate(AchievementCriteriaEntry const* entry, CriteriaProgress const* progress, uint32 timeElapsed, bool timedCompleted) const
{
WorldPacket data(SMSG_CRITERIA_UPDATE, 8+4+8);
data << uint32(entry->ID);
@@ -685,7 +977,7 @@ void AchievementMgr::SendCriteriaUpdate(AchievementCriteriaEntry const* entry, C
// the counter is packed like a packed Guid
data.appendPackGUID(progress->counter);
- data.append(GetPlayer()->GetPackGUID());
+ data.appendPackGUID(GetOwner()->GetGUID());
if (!entry->timeLimit)
data << uint32(0);
else
@@ -693,13 +985,68 @@ void AchievementMgr::SendCriteriaUpdate(AchievementCriteriaEntry const* entry, C
data << uint32(secsToTimeBitFields(progress->date));
data << uint32(timeElapsed); // time elapsed in seconds
data << uint32(0); // unk
- GetPlayer()->SendDirectMessage(&data);
+ SendPacket(&data);
+}
+
+template<>
+void AchievementMgr<Guild>::SendCriteriaUpdate(AchievementCriteriaEntry const* entry, CriteriaProgress const* progress, uint32 /*timeElapsed*/, bool /*timedCompleted*/) const
+{
+ //will send response to criteria progress request
+ WorldPacket data(SMSG_GUILD_CRITERIA_DATA, 3 + 1 + 1 + 8 + 8 + 4 + 4 + 4 + 4 + 4);
+
+ uint8 criteriaProgress[8];
+ uint8 criteriaGuid[8];
+ *reinterpret_cast<uint64*>(&criteriaProgress[0]) = progress->counter;
+ *reinterpret_cast<uint64*>(&criteriaGuid[0]) = progress->CompletedGUID;
+
+ data.WriteBits(1, 21);
+ data.WriteBit(criteriaProgress[4]);
+ data.WriteBit(criteriaProgress[1]);
+ data.WriteBit(criteriaGuid[2]);
+ data.WriteBit(criteriaProgress[3]);
+ data.WriteBit(criteriaGuid[1]);
+ data.WriteBit(criteriaProgress[5]);
+ data.WriteBit(criteriaProgress[0]);
+ data.WriteBit(criteriaGuid[3]);
+ data.WriteBit(criteriaProgress[2]);
+ data.WriteBit(criteriaGuid[7]);
+ data.WriteBit(criteriaGuid[5]);
+ data.WriteBit(criteriaGuid[0]);
+ data.WriteBit(criteriaProgress[6]);
+ data.WriteBit(criteriaGuid[6]);
+ data.WriteBit(criteriaProgress[7]);
+ data.WriteBit(criteriaGuid[4]);
+
+ data.WriteByteSeq(criteriaGuid[5]);
+ data << uint32(progress->date); // unknown date
+ data.WriteByteSeq(criteriaProgress[3]);
+ data.WriteByteSeq(criteriaProgress[7]);
+ data << uint32(progress->date); // unknown date
+ data.WriteByteSeq(criteriaProgress[6]);
+ data.WriteByteSeq(criteriaGuid[4]);
+ data.WriteByteSeq(criteriaGuid[1]);
+ data.WriteByteSeq(criteriaProgress[4]);
+ data.WriteByteSeq(criteriaGuid[3]);
+ data.WriteByteSeq(criteriaProgress[0]);
+ data.WriteByteSeq(criteriaGuid[2]);
+ data.WriteByteSeq(criteriaProgress[1]);
+ data.WriteByteSeq(criteriaGuid[6]);
+ data << uint32(progress->date); // last update time (not packed!)
+ data << uint32(entry->ID);
+ data.WriteByteSeq(criteriaProgress[5]);
+ data << uint32(0);
+ data.WriteByteSeq(criteriaGuid[7]);
+ data.WriteByteSeq(criteriaProgress[2]);
+ data.WriteByteSeq(criteriaGuid[0]);
+
+ SendPacket(&data);
}
/**
* called at player login. The player might have fulfilled some achievements when the achievement system wasn't working yet
*/
-void AchievementMgr::CheckAllAchievementCriteria()
+template<class T>
+void AchievementMgr<T>::CheckAllAchievementCriteria()
{
// suppress sending packets
for (uint32 i=0; i<ACHIEVEMENT_CRITERIA_TYPE_TOTAL; ++i)
@@ -718,18 +1065,23 @@ static const uint32 achievIdForDungeon[][4] =
{ 0, false, false, false }
};
+// Helper function to avoid having to specialize template for a 800 line long function
+template <typename T> static bool IsGuild() { return false; }
+template<> static bool IsGuild<Guild>() { return true; }
+
/**
* this function will be called whenever the user might have done a criteria relevant action
*/
-void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 /*= 0*/, uint32 miscValue2 /*= 0*/, Unit* unit /*= NULL*/)
+template<class T>
+void AchievementMgr<T>::UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 /*= 0*/, uint32 miscValue2 /*= 0*/, Unit* unit /*= NULL*/, Player* referencePlayer /*= NULL*/)
{
sLog->outDebug(LOG_FILTER_ACHIEVEMENTSYS, "AchievementMgr::UpdateAchievementCriteria(%u, %u, %u)", type, miscValue1, miscValue2);
// disable for gamemasters with GM-mode enabled
- if (m_player->isGameMaster())
+ if (referencePlayer->isGameMaster())
return;
- AchievementCriteriaEntryList const& achievementCriteriaList = sAchievementMgr->GetAchievementCriteriaByType(type);
+ AchievementCriteriaEntryList const& achievementCriteriaList = sAchievementMgr->GetAchievementCriteriaByType(type, IsGuild<T>());
for (AchievementCriteriaEntryList::const_iterator i = achievementCriteriaList.begin(); i != achievementCriteriaList.end(); ++i)
{
AchievementCriteriaEntry const* achievementCriteria = (*i);
@@ -737,12 +1089,12 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
if (!achievement)
continue;
- if (!CanUpdateCriteria(achievementCriteria, achievement, miscValue1, miscValue2, unit))
+ if (!CanUpdateCriteria(achievementCriteria, achievement, miscValue1, miscValue2, unit, referencePlayer))
continue;
// requirements not found in the dbc
if (AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria))
- if (!data->Meets(GetPlayer(), unit, miscValue1))
+ if (!data->Meets(referencePlayer, unit, miscValue1))
continue;
switch (type)
@@ -761,7 +1113,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
// AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
if (!miscValue1)
continue;
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
+ SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE);
break;
// std case: increment at miscvalue1
case ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_VENDORS:
@@ -777,7 +1129,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
// AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
if (!miscValue1)
continue;
- SetCriteriaProgress(achievementCriteria, miscValue1, PROGRESS_ACCUMULATE);
+ SetCriteriaProgress(achievementCriteria, miscValue1, referencePlayer, PROGRESS_ACCUMULATE);
break;
// std case: high value at miscvalue1
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID:
@@ -789,7 +1141,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
// AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
if (!miscValue1)
continue;
- SetCriteriaProgress(achievementCriteria, miscValue1, PROGRESS_HIGHEST);
+ SetCriteriaProgress(achievementCriteria, miscValue1, referencePlayer, PROGRESS_HIGHEST);
break;
// specialized cases
@@ -799,7 +1151,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
if (!miscValue1)
continue;
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
+ SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE);
break;
}
case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG:
@@ -807,10 +1159,10 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
// AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
if (!miscValue1)
continue;
- if (achievementCriteria->win_bg.bgMapID != GetPlayer()->GetMapId())
+ if (achievementCriteria->win_bg.bgMapID != referencePlayer->GetMapId())
continue;
- SetCriteriaProgress(achievementCriteria, miscValue1, PROGRESS_ACCUMULATE);
+ SetCriteriaProgress(achievementCriteria, miscValue1, referencePlayer, PROGRESS_ACCUMULATE);
break;
}
case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE:
@@ -821,33 +1173,33 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
if (achievementCriteria->kill_creature.creatureID != miscValue1)
continue;
- SetCriteriaProgress(achievementCriteria, miscValue2, PROGRESS_ACCUMULATE);
+ SetCriteriaProgress(achievementCriteria, miscValue2, referencePlayer, PROGRESS_ACCUMULATE);
break;
}
case ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL:
- SetCriteriaProgress(achievementCriteria, GetPlayer()->getLevel());
+ SetCriteriaProgress(achievementCriteria, referencePlayer->getLevel(), referencePlayer);
break;
case ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL:
// update at loading or specific skill update
if (miscValue1 && miscValue1 != achievementCriteria->reach_skill_level.skillID)
continue;
- if (uint32 skillvalue = GetPlayer()->GetBaseSkillValue(achievementCriteria->reach_skill_level.skillID))
- SetCriteriaProgress(achievementCriteria, skillvalue);
+ if (uint32 skillvalue = referencePlayer->GetBaseSkillValue(achievementCriteria->reach_skill_level.skillID))
+ SetCriteriaProgress(achievementCriteria, skillvalue, referencePlayer);
break;
case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL:
// update at loading or specific skill update
if (miscValue1 && miscValue1 != achievementCriteria->learn_skill_level.skillID)
continue;
- if (uint32 maxSkillvalue = GetPlayer()->GetPureMaxSkillValue(achievementCriteria->learn_skill_level.skillID))
- SetCriteriaProgress(achievementCriteria, maxSkillvalue);
+ if (uint32 maxSkillvalue = referencePlayer->GetPureMaxSkillValue(achievementCriteria->learn_skill_level.skillID))
+ SetCriteriaProgress(achievementCriteria, maxSkillvalue, referencePlayer);
break;
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT:
if (m_completedAchievements.find(achievementCriteria->complete_achievement.linkedAchievement) != m_completedAchievements.end())
- SetCriteriaProgress(achievementCriteria, 1);
+ SetCriteriaProgress(achievementCriteria, 1, referencePlayer);
break;
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT:
{
- SetCriteriaProgress(achievementCriteria, GetPlayer()->GetRewardedQuestCount());
+ SetCriteriaProgress(achievementCriteria, referencePlayer->GetRewardedQuestCount(), referencePlayer);
break;
}
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY:
@@ -859,7 +1211,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
{
// reset if player missed one day.
if (progress && progress->date < (nextDailyResetTime - 2 * DAY))
- SetCriteriaProgress(achievementCriteria, 0, PROGRESS_SET);
+ SetCriteriaProgress(achievementCriteria, 0, referencePlayer, PROGRESS_SET);
continue;
}
@@ -877,7 +1229,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
// last progress is within the day before the reset => Already counted today.
continue;
- SetCriteriaProgress(achievementCriteria, 1, progressType);
+ SetCriteriaProgress(achievementCriteria, 1, referencePlayer, progressType);
break;
}
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE:
@@ -888,31 +1240,31 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
uint32 counter = 0;
- const RewardedQuestSet &rewQuests = GetPlayer()->getRewardedQuests();
+ const RewardedQuestSet &rewQuests = referencePlayer->getRewardedQuests();
for (RewardedQuestSet::const_iterator itr = rewQuests.begin(); itr != rewQuests.end(); ++itr)
{
Quest const* quest = sObjectMgr->GetQuestTemplate(*itr);
if (quest && quest->GetZoneOrSort() >= 0 && uint32(quest->GetZoneOrSort()) == achievementCriteria->complete_quests_in_zone.zoneID)
++counter;
}
- SetCriteriaProgress(achievementCriteria, counter);
+ SetCriteriaProgress(achievementCriteria, counter, referencePlayer);
break;
}
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND:
// AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
if (!miscValue1)
continue;
- if (GetPlayer()->GetMapId() != achievementCriteria->complete_battleground.mapID)
+ if (referencePlayer->GetMapId() != achievementCriteria->complete_battleground.mapID)
continue;
- SetCriteriaProgress(achievementCriteria, miscValue1, PROGRESS_ACCUMULATE);
+ SetCriteriaProgress(achievementCriteria, miscValue1, referencePlayer, PROGRESS_ACCUMULATE);
break;
case ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP:
// AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
if (!miscValue1)
continue;
- if (GetPlayer()->GetMapId() != achievementCriteria->death_at_map.mapID)
+ if (referencePlayer->GetMapId() != achievementCriteria->death_at_map.mapID)
continue;
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
+ SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE);
break;
case ACHIEVEMENT_CRITERIA_TYPE_DEATH:
{
@@ -925,7 +1277,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
{
if (achievIdByArenaSlot[j] == achievement->ID)
{
- Battleground* bg = GetPlayer()->GetBattleground();
+ Battleground* bg = referencePlayer->GetBattleground();
if (!bg || !bg->isArena() || ArenaTeam::GetSlotByType(bg->GetArenaType()) != j)
notfit = true;
@@ -935,7 +1287,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
if (notfit)
continue;
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
+ SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE);
break;
}
case ACHIEVEMENT_CRITERIA_TYPE_DEATH_IN_DUNGEON:
@@ -944,7 +1296,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
if (!miscValue1)
continue;
- Map const* map = GetPlayer()->IsInWorld() ? GetPlayer()->GetMap() : sMapMgr->FindMap(GetPlayer()->GetMapId(), GetPlayer()->GetInstanceId());
+ Map const* map = referencePlayer->IsInWorld() ? referencePlayer->GetMap() : sMapMgr->FindMap(referencePlayer->GetMapId(), referencePlayer->GetInstanceId());
if (!map || !map->IsDungeon())
continue;
@@ -960,7 +1312,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
if (!achievIdForDungeon[j][2])
break; // for
}
- else if (GetPlayer()->GetDungeonDifficulty() == DUNGEON_DIFFICULTY_NORMAL)
+ else if (referencePlayer->GetDungeonDifficulty() == DUNGEON_DIFFICULTY_NORMAL)
{
// dungeon in normal mode accepted
if (!achievIdForDungeon[j][1])
@@ -983,7 +1335,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
//FIXME: work only for instances where max == min for players
if (((InstanceMap*)map)->GetMaxPlayers() != achievementCriteria->death_in_dungeon.manLimit)
continue;
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
+ SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE);
break;
}
@@ -993,7 +1345,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
continue;
if (miscValue1 != achievementCriteria->killed_by_creature.creatureEntry)
continue;
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
+ SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE);
break;
case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER:
// AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
@@ -1001,10 +1353,10 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
continue;
// if team check required: must kill by opposition faction
- if (achievement->ID == 318 && miscValue2 == GetPlayer()->GetTeam())
+ if (achievement->ID == 318 && miscValue2 == referencePlayer->GetTeam())
continue;
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
+ SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE);
break;
case ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING:
{
@@ -1013,7 +1365,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
continue;
// miscvalue1 is the ingame fallheight*100 as stored in dbc
- SetCriteriaProgress(achievementCriteria, miscValue1);
+ SetCriteriaProgress(achievementCriteria, miscValue1, referencePlayer);
break;
}
case ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM:
@@ -1022,7 +1374,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
continue;
if (miscValue2 != achievementCriteria->death_from.type)
continue;
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
+ SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE);
break;
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST:
{
@@ -1035,15 +1387,15 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
else
{
// login case.
- if (!GetPlayer()->GetQuestRewardStatus(achievementCriteria->complete_quest.questID))
+ if (!referencePlayer->GetQuestRewardStatus(achievementCriteria->complete_quest.questID))
continue;
}
if (AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria))
- if (!data->Meets(GetPlayer(), unit))
+ if (!data->Meets(referencePlayer, unit))
continue;
- SetCriteriaProgress(achievementCriteria, 1);
+ SetCriteriaProgress(achievementCriteria, 1, referencePlayer);
break;
}
case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET:
@@ -1052,7 +1404,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
if (!miscValue1 || miscValue1 != achievementCriteria->be_spell_target.spellID)
continue;
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
+ SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE);
break;
}
case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL:
@@ -1061,15 +1413,15 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
if (!miscValue1 || miscValue1 != achievementCriteria->cast_spell.spellID)
continue;
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
+ SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE);
break;
}
case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL:
if (miscValue1 && miscValue1 != achievementCriteria->learn_spell.spellID)
continue;
- if (GetPlayer()->HasSpell(achievementCriteria->learn_spell.spellID))
- SetCriteriaProgress(achievementCriteria, 1);
+ if (referencePlayer->HasSpell(achievementCriteria->learn_spell.spellID))
+ SetCriteriaProgress(achievementCriteria, 1, referencePlayer);
break;
case ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE:
{
@@ -1080,20 +1432,20 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
if (miscValue1 != achievementCriteria->loot_type.lootType)
continue;
- SetCriteriaProgress(achievementCriteria, miscValue2, PROGRESS_ACCUMULATE);
+ SetCriteriaProgress(achievementCriteria, miscValue2, referencePlayer, PROGRESS_ACCUMULATE);
break;
}
case ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM:
// speedup for non-login case
if (miscValue1 && achievementCriteria->own_item.itemID != miscValue1)
continue;
- SetCriteriaProgress(achievementCriteria, miscValue2, PROGRESS_ACCUMULATE);
+ SetCriteriaProgress(achievementCriteria, miscValue2, referencePlayer, PROGRESS_ACCUMULATE);
break;
case ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA:
if (!miscValue1) // no update at login
continue;
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
+ SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE);
break;
case ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM:
// AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
@@ -1103,7 +1455,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
if (achievementCriteria->use_item.itemID != miscValue1)
continue;
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
+ SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE);
break;
case ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM:
// You _have_ to loot that item, just owning it when logging in does _not_ count!
@@ -1111,7 +1463,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
continue;
if (miscValue1 != achievementCriteria->own_item.itemID)
continue;
- SetCriteriaProgress(achievementCriteria, miscValue2, PROGRESS_ACCUMULATE);
+ SetCriteriaProgress(achievementCriteria, miscValue2, referencePlayer, PROGRESS_ACCUMULATE);
break;
case ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA:
{
@@ -1133,7 +1485,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
uint32 playerIndexOffset = uint32(exploreFlag) / 32;
uint32 mask = 1<< (uint32(exploreFlag) % 32);
- if (GetPlayer()->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + playerIndexOffset) & mask)
+ if (referencePlayer->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + playerIndexOffset) & mask)
{
matchFound = true;
break;
@@ -1141,11 +1493,11 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
}
if (matchFound)
- SetCriteriaProgress(achievementCriteria, 1);
+ SetCriteriaProgress(achievementCriteria, 1, referencePlayer);
break;
}
case ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT:
- SetCriteriaProgress(achievementCriteria, GetPlayer()->GetBankBagSlotCount());
+ SetCriteriaProgress(achievementCriteria, referencePlayer->GetBankBagSlotCount(), referencePlayer);
break;
case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION:
{
@@ -1153,14 +1505,14 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
if (miscValue1 && miscValue1 != achievementCriteria->gain_reputation.factionID)
continue;
- int32 reputation = GetPlayer()->GetReputationMgr().GetReputation(achievementCriteria->gain_reputation.factionID);
+ int32 reputation = referencePlayer->GetReputationMgr().GetReputation(achievementCriteria->gain_reputation.factionID);
if (reputation > 0)
- SetCriteriaProgress(achievementCriteria, reputation);
+ SetCriteriaProgress(achievementCriteria, reputation, referencePlayer);
break;
}
case ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION:
{
- SetCriteriaProgress(achievementCriteria, GetPlayer()->GetReputationMgr().GetExaltedFactionCount());
+ SetCriteriaProgress(achievementCriteria, referencePlayer->GetReputationMgr().GetExaltedFactionCount(), referencePlayer);
break;
}
case ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP:
@@ -1168,7 +1520,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
// skip for login case
if (!miscValue1)
continue;
- SetCriteriaProgress(achievementCriteria, 1);
+ SetCriteriaProgress(achievementCriteria, 1, referencePlayer);
break;
}
case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM:
@@ -1181,7 +1533,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
if (miscValue2 != achievementCriteria->equip_epic_item.itemSlot)
continue;
- SetCriteriaProgress(achievementCriteria, 1);
+ SetCriteriaProgress(achievementCriteria, 1, referencePlayer);
break;
}
@@ -1199,7 +1551,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
if (!pProto)
continue;
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
+ SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE);
break;
}
case ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE:
@@ -1210,7 +1562,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
if (miscValue1 != achievementCriteria->do_emote.emoteID)
continue;
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
+ SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE);
break;
}
case ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE:
@@ -1221,7 +1573,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
if (achievementCriteria->additionalRequirements[0].additionalRequirement_type == ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP)
{
- if (GetPlayer()->GetMapId() != achievementCriteria->additionalRequirements[0].additionalRequirement_value)
+ if (referencePlayer->GetMapId() != achievementCriteria->additionalRequirements[0].additionalRequirement_value)
continue;
// map specific case (BG in fact) expected player targeted damage/heal
@@ -1229,7 +1581,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
continue;
}
- SetCriteriaProgress(achievementCriteria, miscValue1, PROGRESS_ACCUMULATE);
+ SetCriteriaProgress(achievementCriteria, miscValue1, referencePlayer, PROGRESS_ACCUMULATE);
break;
}
case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM:
@@ -1239,7 +1591,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
if (miscValue1 != achievementCriteria->equip_item.itemID)
continue;
- SetCriteriaProgress(achievementCriteria, 1);
+ SetCriteriaProgress(achievementCriteria, 1, referencePlayer);
break;
case ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT:
// miscvalue1 = go entry
@@ -1248,7 +1600,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
if (miscValue1 != achievementCriteria->use_gameobject.goEntry)
continue;
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
+ SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE);
break;
case ACHIEVEMENT_CRITERIA_TYPE_FISH_IN_GAMEOBJECT:
if (!miscValue1)
@@ -1256,7 +1608,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
if (miscValue1 != achievementCriteria->fish_in_gameobject.goEntry)
continue;
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
+ SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE);
break;
case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS:
{
@@ -1264,8 +1616,8 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
continue;
uint32 spellCount = 0;
- for (PlayerSpellMap::const_iterator spellIter = GetPlayer()->GetSpellMap().begin();
- spellIter != GetPlayer()->GetSpellMap().end();
+ for (PlayerSpellMap::const_iterator spellIter = referencePlayer->GetSpellMap().begin();
+ spellIter != referencePlayer->GetSpellMap().end();
++spellIter)
{
SkillLineAbilityMapBounds bounds = sSpellMgr->GetSkillLineAbilityMapBounds(spellIter->first);
@@ -1275,7 +1627,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
spellCount++;
}
}
- SetCriteriaProgress(achievementCriteria, spellCount);
+ SetCriteriaProgress(achievementCriteria, spellCount, referencePlayer);
break;
}
case ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL:
@@ -1283,16 +1635,16 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
if (!miscValue1)
continue;
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
+ SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE);
break;
case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REVERED_REPUTATION:
- SetCriteriaProgress(achievementCriteria, GetPlayer()->GetReputationMgr().GetReveredFactionCount());
+ SetCriteriaProgress(achievementCriteria, referencePlayer->GetReputationMgr().GetReveredFactionCount(), referencePlayer);
break;
case ACHIEVEMENT_CRITERIA_TYPE_GAIN_HONORED_REPUTATION:
- SetCriteriaProgress(achievementCriteria, GetPlayer()->GetReputationMgr().GetHonoredFactionCount());
+ SetCriteriaProgress(achievementCriteria, referencePlayer->GetReputationMgr().GetHonoredFactionCount(), referencePlayer);
break;
case ACHIEVEMENT_CRITERIA_TYPE_KNOWN_FACTIONS:
- SetCriteriaProgress(achievementCriteria, GetPlayer()->GetReputationMgr().GetVisibleFactionCount());
+ SetCriteriaProgress(achievementCriteria, referencePlayer->GetReputationMgr().GetVisibleFactionCount(), referencePlayer);
break;
case ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM:
case ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM:
@@ -1303,7 +1655,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
ItemTemplate const* proto = sObjectMgr->GetItemTemplate(miscValue1);
if (!proto || proto->Quality < ITEM_QUALITY_EPIC)
continue;
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
+ SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE);
break;
}
case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE:
@@ -1312,8 +1664,8 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
continue;
uint32 spellCount = 0;
- for (PlayerSpellMap::const_iterator spellIter = GetPlayer()->GetSpellMap().begin();
- spellIter != GetPlayer()->GetSpellMap().end();
+ for (PlayerSpellMap::const_iterator spellIter = referencePlayer->GetSpellMap().begin();
+ spellIter != referencePlayer->GetSpellMap().end();
++spellIter)
{
SkillLineAbilityMapBounds bounds = sSpellMgr->GetSkillLineAbilityMapBounds(spellIter->first);
@@ -1321,26 +1673,26 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
if (skillIter->second->skillId == achievementCriteria->learn_skill_line.skillLine)
spellCount++;
}
- SetCriteriaProgress(achievementCriteria, spellCount);
+ SetCriteriaProgress(achievementCriteria, spellCount, referencePlayer);
break;
}
case ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL:
- SetCriteriaProgress(achievementCriteria, GetPlayer()->GetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS));
+ SetCriteriaProgress(achievementCriteria, referencePlayer->GetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS), referencePlayer);
break;
case ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS:
if (!miscValue1 || miscValue1 != achievementCriteria->hk_class.classID)
continue;
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
+ SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE);
break;
case ACHIEVEMENT_CRITERIA_TYPE_HK_RACE:
if (!miscValue1 || miscValue1 != achievementCriteria->hk_race.raceID)
continue;
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
+ SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE);
break;
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_GOLD_VALUE_OWNED:
- SetCriteriaProgress(achievementCriteria, GetPlayer()->GetMoney(), PROGRESS_HIGHEST);
+ SetCriteriaProgress(achievementCriteria, referencePlayer->GetMoney(), referencePlayer, PROGRESS_HIGHEST);
break;
case ACHIEVEMENT_CRITERIA_TYPE_EARN_ACHIEVEMENT_POINTS:
{
@@ -1350,10 +1702,10 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
for (CompletedAchievementMap::iterator itr = m_completedAchievements.begin(); itr != m_completedAchievements.end(); ++itr)
if (AchievementEntry const* pAchievement = sAchievementStore.LookupEntry(itr->first))
points += pAchievement->points;
- SetCriteriaProgress(achievementCriteria, points, PROGRESS_SET);
+ SetCriteriaProgress(achievementCriteria, points, referencePlayer, PROGRESS_SET);
}
else
- SetCriteriaProgress(achievementCriteria, miscValue1, PROGRESS_ACCUMULATE);
+ SetCriteriaProgress(achievementCriteria, miscValue1, referencePlayer, PROGRESS_ACCUMULATE);
break;
}
case ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE:
@@ -1361,7 +1713,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
if (!miscValue1 || miscValue1 != achievementCriteria->bg_objective.objectiveId)
continue;
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
+ SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE);
break;
}
case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL:
@@ -1372,7 +1724,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
if (!miscValue1)
continue;
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
+ SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE);
break;
}
case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA:
@@ -1380,7 +1732,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
if (!miscValue1 || miscValue1 != achievementCriteria->honorable_kill_at_area.areaID)
continue;
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
+ SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE);
break;
}
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_TEAM_RATING:
@@ -1392,13 +1744,13 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
if (miscValue2 != reqTeamType)
continue;
- SetCriteriaProgress(achievementCriteria, miscValue1, PROGRESS_HIGHEST);
+ SetCriteriaProgress(achievementCriteria, miscValue1, referencePlayer, PROGRESS_HIGHEST);
}
else // login case
{
for (uint32 arena_slot = 0; arena_slot < MAX_ARENA_SLOT; ++arena_slot)
{
- uint32 teamId = GetPlayer()->GetArenaTeamId(arena_slot);
+ uint32 teamId = referencePlayer->GetArenaTeamId(arena_slot);
if (!teamId)
continue;
@@ -1406,7 +1758,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
if (!team || team->GetType() != reqTeamType)
continue;
- SetCriteriaProgress(achievementCriteria, team->GetStats().Rating, PROGRESS_HIGHEST);
+ SetCriteriaProgress(achievementCriteria, team->GetStats().Rating, referencePlayer, PROGRESS_HIGHEST);
break;
}
}
@@ -1422,13 +1774,13 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
if (miscValue2 != reqTeamType)
continue;
- SetCriteriaProgress(achievementCriteria, miscValue1, PROGRESS_HIGHEST);
+ SetCriteriaProgress(achievementCriteria, miscValue1, referencePlayer, PROGRESS_HIGHEST);
}
else // login case
{
for (uint32 arena_slot = 0; arena_slot < MAX_ARENA_SLOT; ++arena_slot)
{
- uint32 teamId = GetPlayer()->GetArenaTeamId(arena_slot);
+ uint32 teamId = referencePlayer->GetArenaTeamId(arena_slot);
if (!teamId)
continue;
@@ -1436,9 +1788,9 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
if (!team || team->GetType() != reqTeamType)
continue;
- if (ArenaTeamMember const* member = team->GetMember(GetPlayer()->GetGUID()))
+ if (ArenaTeamMember const* member = team->GetMember(referencePlayer->GetGUID()))
{
- SetCriteriaProgress(achievementCriteria, member->PersonalRating, PROGRESS_HIGHEST);
+ SetCriteriaProgress(achievementCriteria, member->PersonalRating, referencePlayer, PROGRESS_HIGHEST);
break;
}
}
@@ -1453,7 +1805,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
continue;
if (int64(miscValue2) < 0)
continue;
- SetCriteriaProgress(achievementCriteria, miscValue2, PROGRESS_ACCUMULATE);
+ SetCriteriaProgress(achievementCriteria, miscValue2, referencePlayer, PROGRESS_ACCUMULATE);
break;
// FIXME: not triggered in code as result, need to implement
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_RAID:
@@ -1479,22 +1831,23 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
}
if (IsCompletedCriteria(achievementCriteria, achievement))
- CompletedCriteriaFor(achievement);
+ CompletedCriteriaFor(achievement, referencePlayer);
// check again the completeness for SUMM and REQ COUNT achievements,
// as they don't depend on the completed criteria but on the sum of the progress of each individual criteria
if (achievement->flags & ACHIEVEMENT_FLAG_SUMM)
if (IsCompletedAchievement(achievement))
- CompletedAchievement(achievement);
+ CompletedAchievement(achievement, referencePlayer);
if (AchievementEntryList const* achRefList = sAchievementMgr->GetAchievementByReferencedId(achievement->ID))
for (AchievementEntryList::const_iterator itr = achRefList->begin(); itr != achRefList->end(); ++itr)
if (IsCompletedAchievement(*itr))
- CompletedAchievement(*itr);
+ CompletedAchievement(*itr, referencePlayer);
}
}
-bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achievementCriteria, AchievementEntry const* achievement)
+template<class T>
+bool AchievementMgr<T>::IsCompletedCriteria(AchievementCriteriaEntry const* achievementCriteria, AchievementEntry const* achievement)
{
// counter can never complete
if (achievement->flags & ACHIEVEMENT_FLAG_COUNTER)
@@ -1651,7 +2004,8 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve
return false;
}
-void AchievementMgr::CompletedCriteriaFor(AchievementEntry const* achievement)
+template<class T>
+void AchievementMgr<T>::CompletedCriteriaFor(AchievementEntry const* achievement, Player* referencePlayer)
{
// counter can never complete
if (achievement->flags & ACHIEVEMENT_FLAG_COUNTER)
@@ -1662,10 +2016,11 @@ void AchievementMgr::CompletedCriteriaFor(AchievementEntry const* achievement)
return;
if (IsCompletedAchievement(achievement))
- CompletedAchievement(achievement);
+ CompletedAchievement(achievement, referencePlayer);
}
-bool AchievementMgr::IsCompletedAchievement(AchievementEntry const* entry)
+template<class T>
+bool AchievementMgr<T>::IsCompletedAchievement(AchievementEntry const* entry)
{
// counter can never complete
if (entry->flags & ACHIEVEMENT_FLAG_COUNTER)
@@ -1727,7 +2082,8 @@ bool AchievementMgr::IsCompletedAchievement(AchievementEntry const* entry)
return false;
}
-CriteriaProgress* AchievementMgr::GetCriteriaProgress(AchievementCriteriaEntry const* entry)
+template<class T>
+CriteriaProgress* AchievementMgr<T>::GetCriteriaProgress(AchievementCriteriaEntry const* entry)
{
CriteriaProgressMap::iterator iter = m_criteriaProgress.find(entry->ID);
@@ -1737,14 +2093,15 @@ CriteriaProgress* AchievementMgr::GetCriteriaProgress(AchievementCriteriaEntry c
return &(iter->second);
}
-void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint32 changeValue, ProgressType ptype)
+template<class T>
+void AchievementMgr<T>::SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint32 changeValue, Player* referencePlayer, ProgressType ptype)
{
// Don't allow to cheat - doing timed achievements without timer active
TimedAchievementMap::iterator timedIter = m_timedAchievements.find(entry->ID);
if (entry->timeLimit && timedIter == m_timedAchievements.end())
return;
- sLog->outDebug(LOG_FILTER_ACHIEVEMENTSYS, "AchievementMgr::SetCriteriaProgress(%u, %u) for (GUID:%u)", entry->ID, changeValue, m_player->GetGUIDLow());
+ sLog->outDebug(LOG_FILTER_ACHIEVEMENTSYS, "AchievementMgr::SetCriteriaProgress(%u, %u) for (%s GUID: "UI64FMTD")", entry->ID, changeValue, GetLogNameForGuid(GetOwner()->GetGUID()), GetOwner()->GetGUID());
CriteriaProgress* progress = GetCriteriaProgress(entry);
if (!progress)
@@ -1787,38 +2144,28 @@ void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry,
progress->changed = true;
progress->date = time(NULL); // set the date to the latest update.
+ AchievementEntry const* achievement = sAchievementStore.LookupEntry(entry->referredAchievement);
uint32 timeElapsed = 0;
- bool timedCompleted = false;
+ bool criteriaComplete = IsCompletedCriteria(entry, achievement);
if (entry->timeLimit)
{
- // has to exist else we wouldn't be here
- timedCompleted = IsCompletedCriteria(entry, sAchievementStore.LookupEntry(entry->referredAchievement));
// Client expects this in packet
timeElapsed = entry->timeLimit - (timedIter->second/IN_MILLISECONDS);
// Remove the timer, we wont need it anymore
- if (timedCompleted)
+ if (criteriaComplete)
m_timedAchievements.erase(timedIter);
}
- SendCriteriaUpdate(entry, progress, timeElapsed, timedCompleted);
-}
-
-void AchievementMgr::RemoveCriteriaProgress(const AchievementCriteriaEntry* entry)
-{
- CriteriaProgressMap::iterator criteriaProgress = m_criteriaProgress.find(entry->ID);
- if (criteriaProgress == m_criteriaProgress.end())
- return;
-
- WorldPacket data(SMSG_CRITERIA_DELETED, 4);
- data << uint32(entry->ID);
- m_player->SendDirectMessage(&data);
+ if (criteriaComplete && achievement->flags & ACHIEVEMENT_FLAG_SHOW_CRITERIA_MEMBERS && !progress->CompletedGUID)
+ progress->CompletedGUID = referencePlayer->GetGUID();
- m_criteriaProgress.erase(criteriaProgress);
+ SendCriteriaUpdate(entry, progress, timeElapsed, criteriaComplete);
}
-void AchievementMgr::UpdateTimedAchievements(uint32 timeDiff)
+template<class T>
+void AchievementMgr<T>::UpdateTimedAchievements(uint32 timeDiff)
{
if (!m_timedAchievements.empty())
{
@@ -1840,7 +2187,13 @@ void AchievementMgr::UpdateTimedAchievements(uint32 timeDiff)
}
}
-void AchievementMgr::StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry, uint32 timeLost /*= 0*/)
+template<class T>
+void AchievementMgr<T>::StartTimedAchievement(AchievementCriteriaTimedTypes /*type*/, uint32 /*entry*/, uint32 /*timeLost = 0*/)
+{
+}
+
+template<>
+void AchievementMgr<Player>::StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry, uint32 timeLost /* = 0 */)
{
AchievementCriteriaEntryList const& achievementCriteriaList = sAchievementMgr->GetTimedAchievementCriteriaByType(type);
for (AchievementCriteriaEntryList::const_iterator i = achievementCriteriaList.begin(); i != achievementCriteriaList.end(); ++i)
@@ -1857,13 +2210,14 @@ void AchievementMgr::StartTimedAchievement(AchievementCriteriaTimedTypes type, u
m_timedAchievements[(*i)->ID] = (*i)->timeLimit * IN_MILLISECONDS - timeLost;
// and at client too
- SetCriteriaProgress(*i, 0, PROGRESS_SET);
+ SetCriteriaProgress(*i, 0, GetOwner(), PROGRESS_SET);
}
}
}
}
-void AchievementMgr::RemoveTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry)
+template<class T>
+void AchievementMgr<T>::RemoveTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry)
{
AchievementCriteriaEntryList const& achievementCriteriaList = sAchievementMgr->GetTimedAchievementCriteriaByType(type);
for (AchievementCriteriaEntryList::const_iterator i = achievementCriteriaList.begin(); i!=achievementCriteriaList.end(); ++i)
@@ -1884,18 +2238,21 @@ void AchievementMgr::RemoveTimedAchievement(AchievementCriteriaTimedTypes type,
}
}
-void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement)
+template<class T>
+void AchievementMgr<T>::CompletedAchievement(AchievementEntry const* achievement, Player* /*referencePlayer*/)
{
sLog->outDetail("AchievementMgr::CompletedAchievement(%u)", achievement->ID);
// disable for gamemasters with GM-mode enabled
- if (m_player->isGameMaster())
+ if (_owner->isGameMaster())
return;
if (achievement->flags & ACHIEVEMENT_FLAG_COUNTER || HasAchieved(achievement->ID))
return;
- SendAchievementEarned(achievement);
+ if (!GetOwner()->GetSession()->PlayerLoading())
+ SendAchievementEarned(achievement);
+
CompletedAchievementData& ca = m_completedAchievements[achievement->ID];
ca.date = time(NULL);
ca.changed = true;
@@ -1920,16 +2277,16 @@ void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement)
//! Since no common attributes were found, (not even in titleRewardFlags field)
//! we explicitly check by ID. Maybe in the future we could move the achievement_reward
//! condition fields to the condition system.
- if (uint32 titleId = reward->titleId[achievement->ID == 1793 ? GetPlayer()->getGender() : (GetPlayer()->GetTeam() == ALLIANCE ? 0 : 1)])
+ if (uint32 titleId = reward->titleId[achievement->ID == 1793 ? GetOwner()->getGender() : (GetOwner()->GetTeam() == ALLIANCE ? 0 : 1)])
if (CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(titleId))
- GetPlayer()->SetTitle(titleEntry);
+ GetOwner()->SetTitle(titleEntry);
// mail
if (reward->sender)
{
- Item* item = reward->itemId ? Item::CreateItem(reward->itemId, 1, GetPlayer()) : NULL;
+ Item* item = reward->itemId ? Item::CreateItem(reward->itemId, 1, GetOwner()) : NULL;
- int loc_idx = GetPlayer()->GetSession()->GetSessionDbLocaleIndex();
+ int loc_idx = GetOwner()->GetSession()->GetSessionDbLocaleIndex();
// subject and text
std::string subject = reward->subject;
@@ -1955,100 +2312,336 @@ void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement)
draft.AddItem(item);
}
- draft.SendMailTo(trans, GetPlayer(), MailSender(MAIL_CREATURE, reward->sender));
+ draft.SendMailTo(trans, GetOwner(), MailSender(MAIL_CREATURE, reward->sender));
CharacterDatabase.CommitTransaction(trans);
}
}
-void AchievementMgr::SendAllAchievementData() const
+template<>
+void AchievementMgr<Guild>::CompletedAchievement(AchievementEntry const* achievement, Player* referencePlayer)
{
- WorldPacket data(SMSG_ALL_ACHIEVEMENT_DATA, m_completedAchievements.size()*8+4+m_criteriaProgress.size()*38+4);
- BuildAllDataPacket(&data);
+ sLog->outDetail("AchievementMgr<Guild>::CompletedAchievement(%u)", achievement->ID);
+
+ if (achievement->flags & ACHIEVEMENT_FLAG_COUNTER || HasAchieved(achievement->ID))
+ return;
+
+ SendAchievementEarned(achievement);
+ CompletedAchievementData& ca = m_completedAchievements[achievement->ID];
+ ca.date = time(NULL);
+ ca.changed = true;
+
+ if (achievement->flags & ACHIEVEMENT_FLAG_SHOW_GUILD_MEMBERS)
+ {
+ if (referencePlayer->GetGuildId() == GetOwner()->GetId())
+ ca.guids.insert(referencePlayer->GetGUID());
+
+ if (Group const* group = referencePlayer->GetGroup())
+ for (GroupReference const* ref = group->GetFirstMember(); ref != NULL; ref = ref->next())
+ if (Player const* groupMember = ref->getSource())
+ if (groupMember->GetGuildId() == GetOwner()->GetId())
+ ca.guids.insert(groupMember->GetGUID());
+ }
+
+ sAchievementMgr->SetRealmCompleted(achievement);
+
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_ACHIEVEMENT_POINTS, achievement->points);
+}
+
+struct VisibleAchievementPred
+{
+ bool operator()(CompletedAchievementMap::value_type const& val)
+ {
+ AchievementEntry const* achievement = sAchievementStore.LookupEntry(val.first);
+ return achievement && !(achievement->flags & ACHIEVEMENT_FLAG_HIDDEN);
+ }
+};
+
+template<class T>
+void AchievementMgr<T>::SendAllAchievementData(Player* /*receiver*/) const
+{
+ VisibleAchievementPred isVisible;
+ size_t numCriteria = m_criteriaProgress.size();
+ size_t numAchievements = std::count_if(m_completedAchievements.begin(), m_completedAchievements.end(), isVisible);
+ ByteBuffer criteriaData(numCriteria * (4 + 4 + 4 + 4 + 8 + 8));
+ uint8 guidBytes[8];
+ uint8 progressBytes[8];
+ *reinterpret_cast<uint64*>(&guidBytes[0]) = GetOwner()->GetGUID();
+
+ WorldPacket data(SMSG_ALL_ACHIEVEMENT_DATA, 4 + numAchievements * (4 + 4) + 4 + numCriteria * (4 + 4 + 4 + 4 + 8 + 8));
+ data.WriteBits(21, numCriteria);
+ for (CriteriaProgressMap::const_iterator itr = m_criteriaProgress.begin(); itr != m_criteriaProgress.end(); ++itr)
+ {
+ *reinterpret_cast<uint64*>(&progressBytes[0]) = itr->second.counter;
+
+ data.WriteBit(guidBytes[4]);
+ data.WriteBit(progressBytes[3]);
+ data.WriteBit(guidBytes[5]);
+ data.WriteBit(progressBytes[0]);
+ data.WriteBit(progressBytes[6]);
+ data.WriteBit(guidBytes[3]);
+ data.WriteBit(guidBytes[0]);
+ data.WriteBit(progressBytes[4]);
+ data.WriteBit(guidBytes[2]);
+ data.WriteBit(progressBytes[7]);
+ data.WriteBit(guidBytes[7]);
+ data.WriteBits(0, 2);
+ data.WriteBit(guidBytes[6]);
+ data.WriteBit(progressBytes[2]);
+ data.WriteBit(progressBytes[1]);
+ data.WriteBit(progressBytes[5]);
+ data.WriteBit(guidBytes[1]);
+
+ criteriaData.WriteByteSeq(guidBytes[3]);
+ criteriaData.WriteByteSeq(progressBytes[5]);
+ criteriaData.WriteByteSeq(progressBytes[6]);
+ criteriaData.WriteByteSeq(guidBytes[4]);
+ criteriaData.WriteByteSeq(guidBytes[6]);
+ criteriaData.WriteByteSeq(progressBytes[2]);
+ criteriaData << uint32(0); // timer 2
+ criteriaData.WriteByteSeq(guidBytes[2]);
+ criteriaData << uint32(itr->first); // criteria id
+ criteriaData.WriteByteSeq(guidBytes[5]);
+ criteriaData.WriteByteSeq(progressBytes[0]);
+ criteriaData.WriteByteSeq(progressBytes[3]);
+ criteriaData.WriteByteSeq(progressBytes[1]);
+ criteriaData.WriteByteSeq(progressBytes[4]);
+ criteriaData.WriteByteSeq(guidBytes[0]);
+ criteriaData.WriteByteSeq(guidBytes[7]);
+ criteriaData.WriteByteSeq(progressBytes[7]);
+ criteriaData << uint32(0); // timer 1
+ criteriaData << uint32(secsToTimeBitFields(itr->second.date)); // criteria date
+ criteriaData.WriteByteSeq(guidBytes[1]);
+ }
+
+ data.WriteBits(numAchievements, 23);
+ data.append(criteriaData);
+
+ for (CompletedAchievementMap::const_iterator itr = m_completedAchievements.begin(); itr != m_completedAchievements.end(); ++itr)
+ {
+ if (!isVisible(*itr))
+ continue;
+
+ data << uint32(secsToTimeBitFields(itr->second.date));
+ data << uint32(itr->first);
+ }
+
if (data.size() > 0x1000)
data.Compress(SMSG_COMPRESSED_ACHIEVEMENT_DATA);
- GetPlayer()->GetSession()->SendPacket(&data);
+ SendPacket(&data);
}
-void AchievementMgr::SendRespondInspectAchievements(Player* player) const
+template<>
+void AchievementMgr<Guild>::SendAllAchievementData(Player* receiver) const
{
- WorldPacket data(SMSG_RESPOND_INSPECT_ACHIEVEMENTS, 9+m_completedAchievements.size()*8+4+m_criteriaProgress.size()*38+4);
- data.append(GetPlayer()->GetPackGUID());
- BuildAllDataPacket(&data);
- player->GetSession()->SendPacket(&data);
+ WorldPacket data(SMSG_GUILD_ACHIEVEMENT_DATA, m_completedAchievements.size() * (4 + 4) + 4);
+ data.WriteBits(m_completedAchievements.size(), 23);
+ for (CompletedAchievementMap::const_iterator itr = m_completedAchievements.begin(); itr != m_completedAchievements.end(); ++itr)
+ {
+ data << uint32(secsToTimeBitFields(itr->second.date));
+ data << uint32(itr->first);
+ }
+
+ receiver->GetSession()->SendPacket(&data);
}
-/**
- * used by SMSG_RESPOND_INSPECT_ACHIEVEMENT and SMSG_ALL_ACHIEVEMENT_DATA
- */
-void AchievementMgr::BuildAllDataPacket(WorldPacket* data) const
+template<class T>
+void AchievementMgr<T>::SendAchievementInfo(Player* receiver, uint32 achievementId /*= 0*/) const
{
- size_t numCriterias = m_criteriaProgress.size();
- uint32 achievementCount = 0;
- ByteBuffer bitBuffer(numCriterias * 2 / 8 + 1); // 2 bits per criteria/8 bits per byte
- ByteBuffer counterBuffer(numCriterias * 8); // uint64 values
- ByteBuffer guidBuffer(numCriterias * 8);
- ByteBuffer criteriaDateBuffer(numCriterias * 4);
- ByteBuffer zeros(numCriterias * 4, true); // fill with zeros
- ByteBuffer criteriaIdBuffer(numCriterias * 4);
- ByteBuffer achievementDateBuffer(m_completedAchievements.size() * 4);
- ByteBuffer achievementIdBuffer(m_completedAchievements.size() * 4);
-
- AchievementEntry const* achievement = NULL;
- for (CompletedAchievementMap::const_iterator iter = m_completedAchievements.begin(); iter != m_completedAchievements.end(); ++iter)
+}
+
+template<>
+void AchievementMgr<Player>::SendAchievementInfo(Player* receiver, uint32 /*achievementId = 0 */) const
+{
+ uint8 guidBytes[8];
+ uint8 progressBytes[8];
+
+ VisibleAchievementPred isVisible;
+ size_t numCriteria = m_criteriaProgress.size();
+ size_t numAchievements = std::count_if(m_completedAchievements.begin(), m_completedAchievements.end(), isVisible);
+ ByteBuffer criteriaData(numCriteria * (0));
+ *reinterpret_cast<uint64*>(&guidBytes[0]) = GetOwner()->GetGUID();
+
+ WorldPacket data(SMSG_RESPOND_INSPECT_ACHIEVEMENTS, 1 + 8 + 3 + 3 + numAchievements * (4 + 4) + numCriteria * (0));
+ data.WriteBit(guidBytes[7]);
+ data.WriteBit(guidBytes[4]);
+ data.WriteBit(guidBytes[1]);
+ data.WriteBits(numAchievements, 23);
+ data.WriteBit(guidBytes[0]);
+ data.WriteBit(guidBytes[3]);
+ data.WriteBits(numCriteria, 21);
+ data.WriteBit(guidBytes[2]);
+ for (CriteriaProgressMap::const_iterator itr = m_criteriaProgress.begin(); itr != m_criteriaProgress.end(); ++itr)
+ {
+ *reinterpret_cast<uint64*>(&progressBytes[0]) = itr->second.counter;
+ data.WriteBit(progressBytes[5]);
+ data.WriteBit(progressBytes[3]);
+ data.WriteBit(guidBytes[1]);
+ data.WriteBit(guidBytes[4]);
+ data.WriteBit(guidBytes[2]);
+ data.WriteBit(progressBytes[6]);
+ data.WriteBit(guidBytes[0]);
+ data.WriteBit(progressBytes[4]);
+ data.WriteBit(progressBytes[1]);
+ data.WriteBit(progressBytes[2]);
+ data.WriteBit(guidBytes[3]);
+ data.WriteBit(guidBytes[7]);
+ data.WriteBits(0, 2); // criteria progress flags
+ data.WriteBit(progressBytes[0]);
+ data.WriteBit(guidBytes[5]);
+ data.WriteBit(guidBytes[6]);
+ data.WriteBit(progressBytes[7]);
+
+ criteriaData.WriteByteSeq(guidBytes[3]);
+ criteriaData.WriteByteSeq(progressBytes[4]);
+ criteriaData << uint32(0); // timer 1
+ criteriaData.WriteByteSeq(guidBytes[1]);
+ criteriaData << uint32(secsToTimeBitFields(itr->second.date));
+ criteriaData.WriteByteSeq(progressBytes[3]);
+ criteriaData.WriteByteSeq(progressBytes[7]);
+ criteriaData.WriteByteSeq(guidBytes[5]);
+ criteriaData.WriteByteSeq(progressBytes[0]);
+ criteriaData.WriteByteSeq(guidBytes[4]);
+ criteriaData.WriteByteSeq(guidBytes[2]);
+ criteriaData.WriteByteSeq(guidBytes[6]);
+ criteriaData.WriteByteSeq(guidBytes[7]);
+ criteriaData.WriteByteSeq(progressBytes[6]);
+ criteriaData << uint32(itr->first);
+ criteriaData << uint32(0); // timer 2
+ criteriaData.WriteByteSeq(progressBytes[1]);
+ criteriaData.WriteByteSeq(progressBytes[5]);
+ criteriaData.WriteByteSeq(guidBytes[0]);
+ criteriaData.WriteByteSeq(progressBytes[2]);
+ }
+
+ data.WriteBit(guidBytes[6]);
+ data.WriteBit(guidBytes[5]);
+ data.append(criteriaData);
+ data.WriteByteSeq(guidBytes[1]);
+ data.WriteByteSeq(guidBytes[6]);
+ data.WriteByteSeq(guidBytes[3]);
+ data.WriteByteSeq(guidBytes[0]);
+ data.WriteByteSeq(guidBytes[2]);
+
+ for (CompletedAchievementMap::const_iterator itr = m_completedAchievements.begin(); itr != m_completedAchievements.end(); ++itr)
{
- // Skip hidden achievements
- achievement = sAchievementStore.LookupEntry(iter->first);
- if (achievement->flags & ACHIEVEMENT_FLAG_HIDDEN)
+ if (!isVisible(*itr))
continue;
- achievementDateBuffer << uint32(secsToTimeBitFields(iter->second.date));
- achievementIdBuffer << uint32(achievement->ID);
- ++achievementCount;
+ data << uint32(itr->first);
+ data << uint32(secsToTimeBitFields(itr->second.date));
}
- for (CriteriaProgressMap::const_iterator itr = m_criteriaProgress.begin(); itr != m_criteriaProgress.end(); ++itr)
+ data.WriteByteSeq(guidBytes[7]);
+ data.WriteByteSeq(guidBytes[4]);
+ data.WriteByteSeq(guidBytes[5]);
+
+ receiver->GetSession()->SendPacket(&data);
+}
+
+template<>
+void AchievementMgr<Guild>::SendAchievementInfo(Player* receiver, uint32 achievementId /*= 0*/) const
+{
+ //will send response to criteria progress request
+ AchievementCriteriaEntryList const* criteria = sAchievementMgr->GetAchievementCriteriaByAchievement(achievementId);
+ if (!criteria)
+ {
+ // send empty packet
+ WorldPacket data(SMSG_GUILD_CRITERIA_DATA, 3);
+ data.WriteBits(0, 21);
+ receiver->GetSession()->SendPacket(&data);
+ return;
+ }
+
+ uint8 criteriaProgress[8];
+ uint8 criteriaGuid[8];
+ uint32 numCriteria = 0;
+ ByteBuffer criteriaData(criteria->size() * (8 + 8 + 4 + 4 + 4));
+ ByteBuffer criteriaBits(criteria->size() * (8 + 8) / 8);
+ for (AchievementCriteriaEntryList::const_iterator itr = criteria->begin(); itr != criteria->end(); ++itr)
+ {
+ uint32 criteriaId = (*itr)->ID;
+ CriteriaProgressMap::const_iterator progress = m_criteriaProgress.find(criteriaId);
+ if (progress == m_criteriaProgress.end())
+ continue;
+
+ ++numCriteria;
+ *reinterpret_cast<uint64*>(&criteriaProgress[0]) = progress->second.counter;
+ *reinterpret_cast<uint64*>(&criteriaGuid[0]) = progress->second.CompletedGUID;
+
+ criteriaBits.WriteBit(criteriaProgress[4]);
+ criteriaBits.WriteBit(criteriaProgress[1]);
+ criteriaBits.WriteBit(criteriaGuid[2]);
+ criteriaBits.WriteBit(criteriaProgress[3]);
+ criteriaBits.WriteBit(criteriaGuid[1]);
+ criteriaBits.WriteBit(criteriaProgress[5]);
+ criteriaBits.WriteBit(criteriaProgress[0]);
+ criteriaBits.WriteBit(criteriaGuid[3]);
+ criteriaBits.WriteBit(criteriaProgress[2]);
+ criteriaBits.WriteBit(criteriaGuid[7]);
+ criteriaBits.WriteBit(criteriaGuid[5]);
+ criteriaBits.WriteBit(criteriaGuid[0]);
+ criteriaBits.WriteBit(criteriaProgress[6]);
+ criteriaBits.WriteBit(criteriaGuid[6]);
+ criteriaBits.WriteBit(criteriaProgress[7]);
+ criteriaBits.WriteBit(criteriaGuid[4]);
+
+ criteriaData.WriteByteSeq(criteriaGuid[5]);
+ criteriaData << uint32(progress->second.date); // unknown date
+ criteriaData.WriteByteSeq(criteriaProgress[3]);
+ criteriaData.WriteByteSeq(criteriaProgress[7]);
+ criteriaData << uint32(progress->second.date); // unknown date
+ criteriaData.WriteByteSeq(criteriaProgress[6]);
+ criteriaData.WriteByteSeq(criteriaGuid[4]);
+ criteriaData.WriteByteSeq(criteriaGuid[1]);
+ criteriaData.WriteByteSeq(criteriaProgress[4]);
+ criteriaData.WriteByteSeq(criteriaGuid[3]);
+ criteriaData.WriteByteSeq(criteriaProgress[0]);
+ criteriaData.WriteByteSeq(criteriaGuid[2]);
+ criteriaData.WriteByteSeq(criteriaProgress[1]);
+ criteriaData.WriteByteSeq(criteriaGuid[6]);
+ criteriaData << uint32(progress->second.date); // last update time (not packed!)
+ criteriaData << uint32(criteriaId);
+ criteriaData.WriteByteSeq(criteriaProgress[5]);
+ criteriaData << uint32(0);
+ criteriaData.WriteByteSeq(criteriaGuid[7]);
+ criteriaData.WriteByteSeq(criteriaProgress[2]);
+ criteriaData.WriteByteSeq(criteriaGuid[0]);
+ }
+
+ WorldPacket data(SMSG_GUILD_CRITERIA_DATA, 3 + criteriaBits.size() + criteriaData.size());
+ data.WriteBits(numCriteria, 21);
+ if (numCriteria)
{
- bitBuffer.WriteBits(0, 2);
- counterBuffer << uint64(itr->second.counter);
- guidBuffer << uint64(GetPlayer()->GetGUID());
- criteriaDateBuffer << uint32(secsToTimeBitFields(itr->second.date));
- criteriaIdBuffer << uint32(itr->first);
+ data.append(criteriaBits);
+ data.append(criteriaData);
}
- bitBuffer.FlushBits();
- *data << uint32(numCriterias);
- data->append(bitBuffer);
- data->append(counterBuffer);
- *data << uint32(achievementCount);
- data->append(achievementDateBuffer);
- data->append(guidBuffer);
- data->append(criteriaDateBuffer);
- data->append(zeros);
- data->append(achievementIdBuffer);
- data->append(criteriaIdBuffer);
- data->append(zeros);
+ receiver->GetSession()->SendPacket(&data);
}
-bool AchievementMgr::HasAchieved(uint32 achievementId) const
+template<class T>
+bool AchievementMgr<T>::HasAchieved(uint32 achievementId) const
{
return m_completedAchievements.find(achievementId) != m_completedAchievements.end();
}
-bool AchievementMgr::CanUpdateCriteria(AchievementCriteriaEntry const* criteria, AchievementEntry const* achievement, uint64 miscValue1, uint64 miscValue2, Unit* unit)
+template<class T>
+bool AchievementMgr<T>::CanUpdateCriteria(AchievementCriteriaEntry const* criteria, AchievementEntry const* achievement, uint64 miscValue1, uint64 /*miscValue2*/, Unit* unit, Player* referencePlayer)
{
if (DisableMgr::IsDisabledFor(DISABLE_TYPE_ACHIEVEMENT_CRITERIA, criteria->ID, NULL))
return false;
- if (achievement->mapID != -1 && GetPlayer()->GetMapId() != uint32(achievement->mapID))
+ if (achievement->mapID != -1 && referencePlayer->GetMapId() != uint32(achievement->mapID))
return false;
// don't update already completed criteria
if (IsCompletedCriteria(criteria, achievement))
return false;
- if ((achievement->requiredFaction == ACHIEVEMENT_FACTION_HORDE && GetPlayer()->GetTeam() != HORDE) ||
- (achievement->requiredFaction == ACHIEVEMENT_FACTION_ALLIANCE && GetPlayer()->GetTeam() != ALLIANCE))
+ if ((achievement->requiredFaction == ACHIEVEMENT_FACTION_HORDE && referencePlayer->GetTeam() != HORDE) ||
+ (achievement->requiredFaction == ACHIEVEMENT_FACTION_ALLIANCE && referencePlayer->GetTeam() != ALLIANCE))
return false;
for (uint32 i = 0; i < MAX_CRITERIA_REQUIREMENTS; ++i)
@@ -2059,11 +2652,11 @@ bool AchievementMgr::CanUpdateCriteria(AchievementCriteriaEntry const* criteria,
switch (criteria->additionalRequirements[i].additionalRequirement_type)
{
case ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP:
- if (GetPlayer()->GetMapId() != criteria->additionalRequirements[i].additionalRequirement_value)
+ if (referencePlayer->GetMapId() != criteria->additionalRequirements[i].additionalRequirement_value)
return false;
break;
case ACHIEVEMENT_CRITERIA_CONDITION_NOT_IN_GROUP:
- if (GetPlayer()->GetGroup())
+ if (referencePlayer->GetGroup())
return false;
break;
default:
@@ -2093,26 +2686,26 @@ bool AchievementMgr::CanUpdateCriteria(AchievementCriteriaEntry const* criteria,
return false;
break;
case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_MAP_DIFFICULTY:
- if (GetPlayer()->GetDifficulty(GetPlayer()->GetMap()->IsRaid()) != value)
+ if (uint32(referencePlayer->GetMap()->GetDifficulty()) != value)
return false;
break;
case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_MAP:
- if (GetPlayer()->GetMapId() != value)
+ if (referencePlayer->GetMapId() != value)
return false;
break;
case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_ZONE:
- if (GetPlayer()->GetZoneId() != value)
+ if (referencePlayer->GetZoneId() != value)
return false;
break;
case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_AREA:
- if (GetPlayer()->GetAreaId() != value)
+ if (referencePlayer->GetAreaId() != value)
return false;
break;
case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_MUST_BE_ENEMY:
if (!unit)
return false;
if (const Player* player = unit->ToPlayer())
- if (player->GetTeam() == GetPlayer()->GetTeam())
+ if (player->GetTeam() == referencePlayer->GetTeam())
return false;
break;
case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_CREATURE_ENTRY:
@@ -2122,7 +2715,7 @@ bool AchievementMgr::CanUpdateCriteria(AchievementCriteriaEntry const* criteria,
return false;
break;
case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_HAS_AURA:
- if (!GetPlayer()->HasAura(value))
+ if (!referencePlayer->HasAura(value))
return false;
break;
case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_HAS_AURA:
@@ -2139,11 +2732,11 @@ bool AchievementMgr::CanUpdateCriteria(AchievementCriteriaEntry const* criteria,
return false;
break;
case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_RACE:
- if (GetPlayer()->getRace() != value)
+ if (referencePlayer->getRace() != value)
return false;
break;
case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_CLASS:
- if (GetPlayer()->getClass() != value)
+ if (referencePlayer->getClass() != value)
return false;
break;
case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_RACE:
@@ -2159,7 +2752,7 @@ bool AchievementMgr::CanUpdateCriteria(AchievementCriteriaEntry const* criteria,
return false;
break;
case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_MAX_GROUP_MEMBERS:
- if (GetPlayer()->GetGroup() && GetPlayer()->GetGroup()->GetMembersCount() >= value)
+ if (referencePlayer->GetGroup() && referencePlayer->GetGroup()->GetMembersCount() >= value)
return false;
break;
case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_CREATURE_TYPE:
@@ -2169,7 +2762,7 @@ bool AchievementMgr::CanUpdateCriteria(AchievementCriteriaEntry const* criteria,
return false;
break;
case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_LEVEL:
- if (GetPlayer()->getLevel() != value)
+ if (referencePlayer->getLevel() != value)
return false;
break;
case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_LEVEL:
@@ -2193,6 +2786,9 @@ bool AchievementMgr::CanUpdateCriteria(AchievementCriteriaEntry const* criteria,
return true;
}
+template class AchievementMgr<Guild>;
+template class AchievementMgr<Player>;
+
//==========================================================
void AchievementGlobalMgr::LoadAchievementCriteriaList()
{
@@ -2205,20 +2801,28 @@ void AchievementGlobalMgr::LoadAchievementCriteriaList()
return;
}
+ uint32 criterias = 0;
+ uint32 guildCriterias = 0;
for (uint32 entryId = 0; entryId < sAchievementCriteriaStore.GetNumRows(); ++entryId)
{
AchievementCriteriaEntry const* criteria = sAchievementCriteriaStore.LookupEntry(entryId);
if (!criteria)
continue;
- m_AchievementCriteriasByType[criteria->requiredType].push_back(criteria);
+ AchievementEntry const* achievement = sAchievementStore.LookupEntry(criteria->referredAchievement);
+
m_AchievementCriteriaListByAchievement[criteria->referredAchievement].push_back(criteria);
+ if (achievement && achievement->flags & ACHIEVEMENT_FLAG_GUILD)
+ ++guildCriterias, m_GuildAchievementCriteriasByType[criteria->requiredType].push_back(criteria);
+ else
+ ++criterias, m_AchievementCriteriasByType[criteria->requiredType].push_back(criteria);
+
if (criteria->timeLimit)
m_AchievementCriteriasByTimedType[criteria->timedCriteriaStartType].push_back(criteria);
}
- sLog->outString(">> Loaded %lu achievement criteria in %u ms", (unsigned long)m_AchievementCriteriasByType->size(), GetMSTimeDiffToNow(oldMSTime));
+ sLog->outString(">> Loaded %u achievement criteria and %u guild achievement crieteria in %u ms", criterias, guildCriterias, GetMSTimeDiffToNow(oldMSTime));
sLog->outString();
}
diff --git a/src/server/game/Achievements/AchievementMgr.h b/src/server/game/Achievements/AchievementMgr.h
index 7e0f715f2d2..636160d4437 100755
--- a/src/server/game/Achievements/AchievementMgr.h
+++ b/src/server/game/Achievements/AchievementMgr.h
@@ -37,6 +37,7 @@ struct CriteriaProgress
{
uint32 counter;
time_t date; // latest update time.
+ uint64 CompletedGUID; // GUID of the player that completed this criteria (guild achievements)
bool changed;
};
@@ -52,6 +53,7 @@ enum AchievementCriteriaDataType
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_LEVEL = 9, // minlevel minlevel of target
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_GENDER = 10, // gender 0=male; 1=female
ACHIEVEMENT_CRITERIA_DATA_TYPE_SCRIPT = 11, // scripted requirement
+ // REUSE
ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_PLAYER_COUNT = 13, // count "with less than %u people in the zone"
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_TEAM = 14, // team HORDE(67), ALLIANCE(469)
ACHIEVEMENT_CRITERIA_DATA_TYPE_S_DRUNK = 15, // drunken_state 0 (enum DrunkenState) of player
@@ -208,6 +210,7 @@ typedef std::map<uint32, AchievementRewardLocale> AchievementRewardLocales;
struct CompletedAchievementData
{
time_t date;
+ std::set<uint64> guids;
bool changed;
};
@@ -218,10 +221,11 @@ class Unit;
class Player;
class WorldPacket;
+template<class T>
class AchievementMgr
{
public:
- AchievementMgr(Player* player);
+ AchievementMgr(T* owner);
~AchievementMgr();
void Reset();
@@ -229,13 +233,14 @@ class AchievementMgr
void LoadFromDB(PreparedQueryResult achievementResult, PreparedQueryResult criteriaResult);
void SaveToDB(SQLTransaction& trans);
void ResetAchievementCriteria(AchievementCriteriaTypes type, uint32 miscvalue1 = 0, uint32 miscvalue2 = 0, bool evenIfCriteriaComplete = false);
- void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 = 0, uint32 miscValue2 = 0, Unit* unit = NULL);
- void CompletedAchievement(AchievementEntry const* entry);
+ void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 = 0, uint32 miscValue2 = 0, Unit* unit = NULL, Player* referencePlayer = NULL);
+ void CompletedAchievement(AchievementEntry const* entry, Player* referencePlayer);
void CheckAllAchievementCriteria();
- void SendAllAchievementData() const;
- void SendRespondInspectAchievements(Player* player) const;
+ void SendAllAchievementData(Player* receiver) const;
+ void SendAchievementInfo(Player* receiver, uint32 achievementId = 0) const;
bool HasAchieved(uint32 achievementId) const;
- Player* GetPlayer() const { return m_player; }
+ T* GetOwner() const { return _owner; }
+
void UpdateTimedAchievements(uint32 timeDiff);
void StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry, uint32 timeLost = 0);
void RemoveTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry); // used for quest and scripted timed achievements
@@ -245,15 +250,15 @@ class AchievementMgr
void SendAchievementEarned(AchievementEntry const* achievement) const;
void SendCriteriaUpdate(AchievementCriteriaEntry const* entry, CriteriaProgress const* progress, uint32 timeElapsed, bool timedCompleted) const;
CriteriaProgress* GetCriteriaProgress(AchievementCriteriaEntry const* entry);
- void SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint32 changeValue, ProgressType ptype = PROGRESS_SET);
+ void SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint32 changeValue, Player* referencePlayer, ProgressType ptype = PROGRESS_SET);
void RemoveCriteriaProgress(AchievementCriteriaEntry const* entry);
- void CompletedCriteriaFor(AchievementEntry const* achievement);
+ void CompletedCriteriaFor(AchievementEntry const* achievement, Player* referencePlayer);
bool IsCompletedCriteria(AchievementCriteriaEntry const* achievementCriteria, AchievementEntry const* achievement);
bool IsCompletedAchievement(AchievementEntry const* entry);
- bool CanUpdateCriteria(AchievementCriteriaEntry const* criteria, AchievementEntry const* achievement, uint64 miscValue1, uint64 miscValue2, Unit* unit);
- void BuildAllDataPacket(WorldPacket* data) const;
+ bool CanUpdateCriteria(AchievementCriteriaEntry const* criteria, AchievementEntry const* achievement, uint64 miscValue1, uint64 miscValue2, Unit* unit, Player* referencePlayer);
+ void SendPacket(WorldPacket* data) const;
- Player* m_player;
+ T* _owner;
CriteriaProgressMap m_criteriaProgress;
CompletedAchievementMap m_completedAchievements;
typedef std::map<uint32, uint32> TimedAchievementMap;
@@ -267,9 +272,9 @@ class AchievementGlobalMgr
~AchievementGlobalMgr() {}
public:
- AchievementCriteriaEntryList const& GetAchievementCriteriaByType(AchievementCriteriaTypes type) const
+ AchievementCriteriaEntryList const& GetAchievementCriteriaByType(AchievementCriteriaTypes type, bool guild = false) const
{
- return m_AchievementCriteriasByType[type];
+ return guild ? m_GuildAchievementCriteriasByType[type] : m_AchievementCriteriasByType[type];
}
AchievementCriteriaEntryList const& GetTimedAchievementCriteriaByType(AchievementCriteriaTimedTypes type) const
@@ -317,6 +322,22 @@ class AchievementGlobalMgr
m_allCompletedAchievements.insert(achievement->ID);
}
+ bool IsGroupCriteriaType(AchievementCriteriaTypes type) const
+ {
+ switch (type)
+ {
+ case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE:
+ case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG:
+ case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET: // NYI
+ case ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA:
+ case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2: // NYI
+ case ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_BATTLEGROUND: // NYI
+ return true;
+ }
+
+ return false;
+ }
+
void LoadAchievementCriteriaList();
void LoadAchievementCriteriaData();
void LoadAchievementReferenceList();
@@ -328,9 +349,13 @@ class AchievementGlobalMgr
// store achievement criterias by type to speed up lookup
AchievementCriteriaEntryList m_AchievementCriteriasByType[ACHIEVEMENT_CRITERIA_TYPE_TOTAL];
+ AchievementCriteriaEntryList m_GuildAchievementCriteriasByType[ACHIEVEMENT_CRITERIA_TYPE_TOTAL];
+
AchievementCriteriaEntryList m_AchievementCriteriasByTimedType[ACHIEVEMENT_TIMED_TYPE_MAX];
+
// store achievement criterias by achievement to speed up lookup
AchievementCriteriaListByAchievement m_AchievementCriteriaListByAchievement;
+
// store achievements by referenced achievement id to speed up lookup
AchievementListByReferencedId m_AchievementListByReferencedId;
diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
index a156583a006..cb119884558 100644
--- a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
+++ b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
@@ -154,7 +154,7 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry* auction, SQLTransaction&
{
bidder->GetSession()->SendAuctionBidderNotification(auction->GetHouseId(), auction->Id, bidder_guid, 0, 0, auction->item_template);
// FIXME: for offline player need also
- bidder->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WON_AUCTIONS, 1);
+ bidder->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WON_AUCTIONS, 1);
}
MailDraft(msgAuctionWonSubject.str(), msgAuctionWonBody.str())
@@ -219,8 +219,8 @@ void AuctionHouseMgr::SendAuctionSuccessfulMail(AuctionEntry* auction, SQLTransa
//FIXME: what do if owner offline
if (owner)
{
- owner->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_EARNED_BY_AUCTIONS, profit);
- owner->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_SOLD, auction->bid);
+ owner->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_EARNED_BY_AUCTIONS, profit);
+ owner->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_SOLD, auction->bid);
//send auction owner notification, bidder must be current!
owner->GetSession()->SendAuctionOwnerNotification(auction);
}
diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp
index ebcf5495a55..3c47b739072 100755
--- a/src/server/game/Battlegrounds/Battleground.cpp
+++ b/src/server/game/Battlegrounds/Battleground.cpp
@@ -34,6 +34,8 @@
#include "SpellAuras.h"
#include "SpellAuraEffects.h"
#include "Util.h"
+#include "Guild.h"
+#include "GuildMgr.h"
namespace Trinity
{
@@ -799,6 +801,7 @@ void Battleground::EndBattleground(uint32 winner)
}
}
+ bool guildAwarded = false;
uint8 aliveWinners = GetAlivePlayersCountByTeam(winner);
for (BattlegroundPlayerMap::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
{
@@ -851,7 +854,7 @@ void Battleground::EndBattleground(uint32 winner)
{
// update achievement BEFORE personal rating update
uint32 rating = player->GetArenaPersonalRating(winner_arena_team->GetSlot());
- player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, rating ? rating : 1);
+ player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, rating ? rating : 1);
winner_arena_team->MemberWon(player, loser_matchmaker_rating, winner_matchmaker_change);
}
@@ -883,7 +886,18 @@ void Battleground::EndBattleground(uint32 winner)
player->SetRandomWinner(true);
}
- player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_BG, 1);
+ player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_BG, 1);
+ if (!guildAwarded)
+ {
+ guildAwarded = true;
+ if (uint32 guildId = GetBgMap()->GetOwnerGuildId(player->GetTeam()))
+ if (Guild* guild = sGuildMgr->GetGuildById(guildId))
+ {
+ guild->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_BG, 1, 0, NULL, player);
+ if (isArena() && isRated() && winner_arena_team && loser_arena_team && winner_arena_team != loser_arena_team)
+ guild->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, std::max<uint32>(winner_arena_team->GetRating(), 1), 0, NULL, player);
+ }
+ }
}
else
{
@@ -902,7 +916,7 @@ void Battleground::EndBattleground(uint32 winner)
BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(GetTypeID(), GetArenaType());
sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime(), GetArenaType());
player->GetSession()->SendPacket(&data);
- player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND, 1);
+ player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND, 1);
}
if (isArena() && isRated() && winner_arena_team && loser_arena_team && winner_arena_team != loser_arena_team)
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp
index d28f5ddfe6a..86f3d5c54cb 100755
--- a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp
@@ -681,11 +681,11 @@ void BattlegroundAB::UpdatePlayerScore(Player* Source, uint32 type, uint32 value
{
case SCORE_BASES_ASSAULTED:
((BattlegroundABScore*)itr->second)->BasesAssaulted += value;
- Source->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, AB_OBJECTIVE_ASSAULT_BASE);
+ Source->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, AB_OBJECTIVE_ASSAULT_BASE);
break;
case SCORE_BASES_DEFENDED:
((BattlegroundABScore*)itr->second)->BasesDefended += value;
- Source->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, AB_OBJECTIVE_DEFEND_BASE);
+ Source->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, AB_OBJECTIVE_DEFEND_BASE);
break;
default:
Battleground::UpdatePlayerScore(Source, type, value, doAddHonor);
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp
index d2cbab2be54..715564d3252 100755
--- a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp
@@ -540,19 +540,19 @@ void BattlegroundAV::UpdatePlayerScore(Player* Source, uint32 type, uint32 value
{
case SCORE_GRAVEYARDS_ASSAULTED:
((BattlegroundAVScore*)itr->second)->GraveyardsAssaulted += value;
- Source->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, AV_OBJECTIVE_ASSAULT_GRAVEYARD);
+ Source->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, AV_OBJECTIVE_ASSAULT_GRAVEYARD);
break;
case SCORE_GRAVEYARDS_DEFENDED:
((BattlegroundAVScore*)itr->second)->GraveyardsDefended += value;
- Source->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, AV_OBJECTIVE_DEFEND_GRAVEYARD);
+ Source->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, AV_OBJECTIVE_DEFEND_GRAVEYARD);
break;
case SCORE_TOWERS_ASSAULTED:
((BattlegroundAVScore*)itr->second)->TowersAssaulted += value;
- Source->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, AV_OBJECTIVE_ASSAULT_TOWER);
+ Source->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, AV_OBJECTIVE_ASSAULT_TOWER);
break;
case SCORE_TOWERS_DEFENDED:
((BattlegroundAVScore*)itr->second)->TowersDefended += value;
- Source->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, AV_OBJECTIVE_DEFEND_TOWER);
+ Source->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, AV_OBJECTIVE_DEFEND_TOWER);
break;
case SCORE_MINES_CAPTURED:
((BattlegroundAVScore*)itr->second)->MinesCaptured += value;
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp
index 8269a04a383..2b02caaf5a2 100755
--- a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp
@@ -816,7 +816,7 @@ void BattlegroundEY::UpdatePlayerScore(Player* Source, uint32 type, uint32 value
{
case SCORE_FLAG_CAPTURES: // flags captured
((BattlegroundEYScore*)itr->second)->FlagCaptures += value;
- Source->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, EY_OBJECTIVE_CAPTURE_FLAG);
+ Source->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, EY_OBJECTIVE_CAPTURE_FLAG);
break;
default:
Battleground::UpdatePlayerScore(Source, type, value, doAddHonor);
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp
index d100dc645a2..0c583ddde3f 100755
--- a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp
@@ -759,11 +759,11 @@ void BattlegroundWS::UpdatePlayerScore(Player* Source, uint32 type, uint32 value
{
case SCORE_FLAG_CAPTURES: // flags captured
((BattlegroundWGScore*)itr->second)->FlagCaptures += value;
- Source->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, WS_OBJECTIVE_CAPTURE_FLAG);
+ Source->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, WS_OBJECTIVE_CAPTURE_FLAG);
break;
case SCORE_FLAG_RETURNS: // flags returned
((BattlegroundWGScore*)itr->second)->FlagReturns += value;
- Source->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, WS_OBJECTIVE_RETURN_FLAG);
+ Source->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, WS_OBJECTIVE_RETURN_FLAG);
break;
default:
Battleground::UpdatePlayerScore(Source, type, value, doAddHonor);
diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h
index e032335c3bc..cd8accd3759 100755
--- a/src/server/game/DataStores/DBCEnums.h
+++ b/src/server/game/DataStores/DBCEnums.h
@@ -60,7 +60,7 @@ enum AchievementFlags
{
ACHIEVEMENT_FLAG_COUNTER = 0x00000001, // Just count statistic (never stop and complete)
ACHIEVEMENT_FLAG_HIDDEN = 0x00000002, // Not sent to client - internal use only
- ACHIEVEMENT_FLAG_STORE_MAX_VALUE = 0x00000004, // Store only max value? used only in "Reach level xx"
+ ACHIEVEMENT_FLAG_PLAY_NO_VISUAL = 0x00000004, // Client does not play achievement earned visual
ACHIEVEMENT_FLAG_SUMM = 0x00000008, // Use summ criteria value from all reqirements (and calculate max value)
ACHIEVEMENT_FLAG_MAX_USED = 0x00000010, // Show max criteria (and calculate max value ??)
ACHIEVEMENT_FLAG_REQ_COUNT = 0x00000020, // Use not zero req count (and calculate max value)
@@ -70,8 +70,8 @@ enum AchievementFlags
ACHIEVEMENT_FLAG_REALM_FIRST_KILL = 0x00000200, //
ACHIEVEMENT_FLAG_UNK3 = 0x00000400, // ACHIEVEMENT_FLAG_HIDE_NAME_IN_TIE
ACHIEVEMENT_FLAG_REALM_FIRST_GUILD = 0x00000800, // first guild on realm done something
- ACHIEVEMENT_FLAG_UNK4 = 0x00001000, // as guild group?
- ACHIEVEMENT_FLAG_UNK5 = 0x00002000, // as guild group?
+ ACHIEVEMENT_FLAG_SHOW_IN_GUILD_NEWS = 0x00001000, // Shows in guild news
+ ACHIEVEMENT_FLAG_SHOW_IN_GUILD_HEADER = 0x00002000, // Shows in guild news header
ACHIEVEMENT_FLAG_GUILD = 0x00004000, //
ACHIEVEMENT_FLAG_SHOW_GUILD_MEMBERS = 0x00008000, //
ACHIEVEMENT_FLAG_SHOW_CRITERIA_MEMBERS = 0x00010000, //
@@ -191,137 +191,143 @@ enum AchievementCriteriaTimedTypes
enum AchievementCriteriaTypes
{
- ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE = 0,
- ACHIEVEMENT_CRITERIA_TYPE_WIN_BG = 1,
- ACHIEVEMENT_CRITERIA_TYPE_UNK3 = 3, // struct { uint32 itemCount; }
- ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL = 5,
- ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL = 7,
- ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT = 8,
- ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT = 9,
+ ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE = 0,
+ ACHIEVEMENT_CRITERIA_TYPE_WIN_BG = 1,
+ ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ARCHAEOLOGY_PROJECTS = 3, // struct { uint32 itemCount; }
+ ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL = 5,
+ ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL = 7,
+ ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT = 8,
+ ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT = 9,
// you have to complete a daily quest x times in a row
- ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY = 10,
- ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE = 11,
- ACHIEVEMENT_CRITERIA_TYPE_CURRENCY = 12,
- ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE = 13,
- ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST = 14,
- ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND= 15,
- ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP= 16,
- ACHIEVEMENT_CRITERIA_TYPE_DEATH= 17,
- ACHIEVEMENT_CRITERIA_TYPE_DEATH_IN_DUNGEON = 18,
- ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_RAID = 19,
- ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE = 20,
- ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER = 23,
- ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING = 24,
- ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM = 26,
- ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST = 27,
- ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET = 28,
- ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL= 29,
- ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE = 30,
- ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA = 31,
- ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA = 32,
- ACHIEVEMENT_CRITERIA_TYPE_PLAY_ARENA = 33,
- ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL = 34,
- ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL = 35,
- ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM = 36,
- ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA = 37,
- ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_TEAM_RATING = 38,
- ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_PERSONAL_RATING = 39,
- ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL = 40,
- ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM = 41,
- ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM= 42,
- ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA = 43,
- ACHIEVEMENT_CRITERIA_TYPE_OWN_RANK= 44,
- ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT= 45,
- ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION= 46,
- ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION= 47,
+ ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY = 10,
+ ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE = 11,
+ ACHIEVEMENT_CRITERIA_TYPE_CURRENCY = 12,
+ ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE = 13,
+ ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST = 14,
+ ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND = 15,
+ ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP = 16,
+ ACHIEVEMENT_CRITERIA_TYPE_DEATH = 17,
+ ACHIEVEMENT_CRITERIA_TYPE_DEATH_IN_DUNGEON = 18,
+ ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_RAID = 19,
+ ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE = 20,
+ ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER = 23,
+ ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING = 24,
+ ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM = 26,
+ ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST = 27,
+ ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET = 28,
+ ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL = 29,
+ ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE = 30,
+ ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA = 31,
+ ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA = 32,
+ ACHIEVEMENT_CRITERIA_TYPE_PLAY_ARENA = 33,
+ ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL = 34,
+ ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL = 35,
+ ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM = 36,
+ ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA = 37,
+ ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_TEAM_RATING = 38,
+ ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_PERSONAL_RATING = 39,
+ ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL = 40,
+ ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM = 41,
+ ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM = 42,
+ ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA = 43,
+ ACHIEVEMENT_CRITERIA_TYPE_OWN_RANK = 44,
+ ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT = 45,
+ ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION = 46,
+ ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION = 47,
// noted: rewarded as soon as the player payed, not at taking place at the seat
- ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP= 48,
- ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM = 49,
+ ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP = 48,
+ ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM = 49,
// TODO: itemlevel is mentioned in text but not present in dbc
- ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT = 50,
- ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT= 51,
- ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS = 52,
- ACHIEVEMENT_CRITERIA_TYPE_HK_RACE = 53,
- ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE = 54,
- ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE = 55,
+ ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT = 50,
+ ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT = 51,
+ ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS = 52,
+ ACHIEVEMENT_CRITERIA_TYPE_HK_RACE = 53,
+ ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE = 54,
+ ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE = 55,
// TODO: in some cases map not present, and in some cases need do without die
- ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS = 56,
- ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM = 57,
- ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_VENDORS = 59,
- ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TALENTS = 60,
- ACHIEVEMENT_CRITERIA_TYPE_NUMBER_OF_TALENT_RESETS = 61,
- ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_QUEST_REWARD = 62,
- ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TRAVELLING = 63,
- ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_AT_BARBER = 65,
- ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL = 66,
- ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY = 67,
- ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT = 68,
- ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2= 69,
- ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL= 70,
- ACHIEVEMENT_CRITERIA_TYPE_FISH_IN_GAMEOBJECT = 72,
+ ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS = 56,
+ ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM = 57,
+ ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_VENDORS = 59,
+ ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TALENTS = 60,
+ ACHIEVEMENT_CRITERIA_TYPE_NUMBER_OF_TALENT_RESETS = 61,
+ ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_QUEST_REWARD = 62,
+ ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TRAVELLING = 63,
+ ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_AT_BARBER = 65,
+ ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL = 66,
+ ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY = 67,
+ ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT = 68,
+ ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2 = 69,
+ ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL = 70,
+ ACHIEVEMENT_CRITERIA_TYPE_FISH_IN_GAMEOBJECT = 72,
// TODO: title id is not mentioned in dbc
- ACHIEVEMENT_CRITERIA_TYPE_EARNED_PVP_TITLE = 74,
- ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS= 75,
- ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL = 76,
- ACHIEVEMENT_CRITERIA_TYPE_LOSE_DUEL = 77,
+ ACHIEVEMENT_CRITERIA_TYPE_EARNED_PVP_TITLE = 74,
+ ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS = 75,
+ ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL = 76,
+ ACHIEVEMENT_CRITERIA_TYPE_LOSE_DUEL = 77,
// TODO: creature type (demon, undead etc.) is not stored in dbc
- ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE = 78,
- ACHIEVEMENT_CRITERIA_TYPE_GOLD_EARNED_BY_AUCTIONS= 80,
- ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION= 82,
- ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID= 83,
- ACHIEVEMENT_CRITERIA_TYPE_WON_AUCTIONS= 84,
- ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_SOLD = 85,
- ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_GOLD_VALUE_OWNED = 86,
- ACHIEVEMENT_CRITERIA_TYPE_GAIN_REVERED_REPUTATION = 87,
- ACHIEVEMENT_CRITERIA_TYPE_GAIN_HONORED_REPUTATION = 88,
- ACHIEVEMENT_CRITERIA_TYPE_KNOWN_FACTIONS = 89,
- ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM = 90,
- ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM = 91,
- ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED = 93,
- ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED = 94,
- ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_DEALT = 101,
- ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_RECEIVED = 102,
- ACHIEVEMENT_CRITERIA_TYPE_TOTAL_DAMAGE_RECEIVED = 103,
- ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEAL_CASTED = 104,
- ACHIEVEMENT_CRITERIA_TYPE_TOTAL_HEALING_RECEIVED = 105,
- ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALING_RECEIVED = 106,
- ACHIEVEMENT_CRITERIA_TYPE_QUEST_ABANDONED = 107,
- ACHIEVEMENT_CRITERIA_TYPE_FLIGHT_PATHS_TAKEN = 108,
- ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE = 109,
+ ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE = 78,
+ ACHIEVEMENT_CRITERIA_TYPE_GOLD_EARNED_BY_AUCTIONS = 80,
+ ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION = 82,
+ ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID = 83,
+ ACHIEVEMENT_CRITERIA_TYPE_WON_AUCTIONS = 84,
+ ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_SOLD = 85,
+ ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_GOLD_VALUE_OWNED = 86,
+ ACHIEVEMENT_CRITERIA_TYPE_GAIN_REVERED_REPUTATION = 87,
+ ACHIEVEMENT_CRITERIA_TYPE_GAIN_HONORED_REPUTATION = 88,
+ ACHIEVEMENT_CRITERIA_TYPE_KNOWN_FACTIONS = 89,
+ ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM = 90,
+ ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM = 91,
+ ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED = 93,
+ ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED = 94,
+ ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_DEALT = 101,
+ ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_RECEIVED = 102,
+ ACHIEVEMENT_CRITERIA_TYPE_TOTAL_DAMAGE_RECEIVED = 103,
+ ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEAL_CASTED = 104,
+ ACHIEVEMENT_CRITERIA_TYPE_TOTAL_HEALING_RECEIVED = 105,
+ ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALING_RECEIVED = 106,
+ ACHIEVEMENT_CRITERIA_TYPE_QUEST_ABANDONED = 107,
+ ACHIEVEMENT_CRITERIA_TYPE_FLIGHT_PATHS_TAKEN = 108,
+ ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE = 109,
// TODO: target entry is missing
- ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2 = 110,
- ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE= 112,
- ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL = 113,
- ACHIEVEMENT_CRITERIA_TYPE_ACCEPTED_SUMMONINGS = 114,
- ACHIEVEMENT_CRITERIA_TYPE_EARN_ACHIEVEMENT_POINTS = 115,
- ACHIEVEMENT_CRITERIA_TYPE_UNK118 = 118,
+ ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2 = 110,
+ ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE = 112,
+ ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL = 113,
+ ACHIEVEMENT_CRITERIA_TYPE_ACCEPTED_SUMMONINGS = 114,
+ ACHIEVEMENT_CRITERIA_TYPE_EARN_ACHIEVEMENT_POINTS = 115,
+ ACHIEVEMENT_CRITERIA_TYPE_UNK118 = 118,
ACHIEVEMENT_CRITERIA_TYPE_USE_LFD_TO_GROUP_WITH_PLAYERS = 119,
- ACHIEVEMENT_CRITERIA_TYPE_UNK120 = 120,
- ACHIEVEMENT_CRITERIA_TYPE_UNK121 = 121,
- ACHIEVEMENT_CRITERIA_TYPE_UNK122 = 122,
- ACHIEVEMENT_CRITERIA_TYPE_UNK123 = 123,
- ACHIEVEMENT_CRITERIA_TYPE_SPENT_GOLD_GUILD_REPAIRS = 124,
- ACHIEVEMENT_CRITERIA_TYPE_REACH_GUILD_LEVEL = 125,
- ACHIEVEMENT_CRITERIA_TYPE_CRAFT_ITEMS_GUILD = 126,
- ACHIEVEMENT_CRITERIA_TYPE_CATCH_FROM_POOL = 127,
- ACHIEVEMENT_CRITERIA_TYPE_BUY_GUILD_BANK_SLOTS = 128,
+ ACHIEVEMENT_CRITERIA_TYPE_UNK120 = 120,
+ ACHIEVEMENT_CRITERIA_TYPE_UNK121 = 121,
+ ACHIEVEMENT_CRITERIA_TYPE_UNK122 = 122,
+ ACHIEVEMENT_CRITERIA_TYPE_UNK123 = 123,
+ ACHIEVEMENT_CRITERIA_TYPE_SPENT_GOLD_GUILD_REPAIRS = 124,
+ ACHIEVEMENT_CRITERIA_TYPE_REACH_GUILD_LEVEL = 125,
+ ACHIEVEMENT_CRITERIA_TYPE_CRAFT_ITEMS_GUILD = 126,
+ ACHIEVEMENT_CRITERIA_TYPE_CATCH_FROM_POOL = 127,
+ ACHIEVEMENT_CRITERIA_TYPE_BUY_GUILD_BANK_SLOTS = 128,
ACHIEVEMENT_CRITERIA_TYPE_EARN_GUILD_ACHIEVEMENT_POINTS = 129,
- ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_BATTLEGROUND = 130,
- ACHIEVEMENT_CRITERIA_TYPE_REACH_BG_RATING = 132,
- ACHIEVEMENT_CRITERIA_TYPE_BUY_GUILD_TABARD = 133,
- ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_GUILD = 134,
- ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILLS_GUILD = 135,
- ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE_GUILD = 136,
- ACHIEVEMENT_CRITERIA_TYPE_UNK137 = 137,
- ACHIEVEMENT_CRITERIA_TYPE_UNK138 = 138, //struct { Flag flag; uint32 count; } 1: Guild Dungeon, 2:Guild Challenge, 3:Guild battlefield
- ACHIEVEMENT_CRITERIA_TYPE_UNK139 = 139, //struct { uint32 count; } Guild Challenge
- ACHIEVEMENT_CRITERIA_TYPE_UNK140 = 140,
- ACHIEVEMENT_CRITERIA_TYPE_UNK141 = 141,
- ACHIEVEMENT_CRITERIA_TYPE_UNK142 = 142,
- ACHIEVEMENT_CRITERIA_TYPE_UNK143 = 143,
- ACHIEVEMENT_CRITERIA_TYPE_UNK144 = 144,
+ ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_BATTLEGROUND = 130,
+ ACHIEVEMENT_CRITERIA_TYPE_REACH_BG_RATING = 132,
+ ACHIEVEMENT_CRITERIA_TYPE_BUY_GUILD_TABARD = 133,
+ ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_GUILD = 134,
+ ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILLS_GUILD = 135,
+ ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE_GUILD = 136,
+ ACHIEVEMENT_CRITERIA_TYPE_UNK137 = 137,
+ ACHIEVEMENT_CRITERIA_TYPE_UNK138 = 138, //struct { Flag flag; uint32 count; } 1: Guild Dungeon, 2:Guild Challenge, 3:Guild battlefield
+ ACHIEVEMENT_CRITERIA_TYPE_UNK139 = 139, //struct { uint32 count; } Guild Challenge
+ ACHIEVEMENT_CRITERIA_TYPE_UNK140 = 140,
+ ACHIEVEMENT_CRITERIA_TYPE_UNK141 = 141,
+ ACHIEVEMENT_CRITERIA_TYPE_UNK142 = 142,
+ ACHIEVEMENT_CRITERIA_TYPE_UNK143 = 143,
+ ACHIEVEMENT_CRITERIA_TYPE_UNK144 = 144,
+ ACHIEVEMENT_CRITERIA_TYPE_UNK145 = 145,
+ ACHIEVEMENT_CRITERIA_TYPE_UNK146 = 146,
+ ACHIEVEMENT_CRITERIA_TYPE_UNK147 = 147,
+ ACHIEVEMENT_CRITERIA_TYPE_UNK148 = 148,
+ ACHIEVEMENT_CRITERIA_TYPE_UNK149 = 149,
+ ACHIEVEMENT_CRITERIA_TYPE_UNK150 = 150,
// 0..144 => 145 criteria types total
- ACHIEVEMENT_CRITERIA_TYPE_TOTAL = 145,
+ ACHIEVEMENT_CRITERIA_TYPE_TOTAL = 151,
};
enum AchievementCategory
diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp
index 91f9104b0b1..b3e5f2a3eab 100755
--- a/src/server/game/DungeonFinding/LFGMgr.cpp
+++ b/src/server/game/DungeonFinding/LFGMgr.cpp
@@ -1901,7 +1901,7 @@ void LFGMgr::RewardDungeonDoneFor(const uint32 dungeonId, Player* player)
// Update achievements
if (dungeon->difficulty == DUNGEON_DIFFICULTY_HEROIC)
- player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_LFD_TO_GROUP_WITH_PLAYERS, 1);
+ player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_LFD_TO_GROUP_WITH_PLAYERS, 1);
LfgReward const* reward = GetRandomDungeonReward(rDungeonId, player->getLevel());
if (!reward)
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index ba7ca524521..f66f3b95128 100755
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -432,6 +432,7 @@ void TradeData::SetAccepted(bool state, bool crosssend /*= false*/)
// 4.3. Give reputation (player must not be on BG).
// 4.4. Give kill credit (player must not be in group, or he must be alive or without corpse).
// 5. Credit instance encounter.
+// 6. Update guild achievements.
KillRewarder::KillRewarder(Player* killer, Unit* victim, bool isBattleGround) :
// 1. Initialize internal variables to default values.
_killer(killer), _victim(victim), _group(killer->GetGroup()),
@@ -623,10 +624,18 @@ void KillRewarder::Reward()
}
// 5. Credit instance encounter.
+ // 6. Update guild achievements.
if (Creature* victim = _victim->ToCreature())
+ {
if (victim->IsDungeonBoss())
if (InstanceScript* instance = _victim->GetInstanceScript())
instance->UpdateEncounterState(ENCOUNTER_CREDIT_KILL_CREATURE, _victim->GetEntry(), _victim);
+
+ if (uint32 guildId = victim->GetMap()->GetOwnerGuildId())
+ if (Guild* guild = sGuildMgr->GetGuildById(guildId))
+ guild->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, victim->GetEntry(), 1, victim, _killer);
+ }
+
}
// == Player ====================================================
@@ -1277,7 +1286,7 @@ uint32 Player::EnvironmentalDamage(EnviromentalDamage type, uint32 damage)
GetSession()->SendPacket(&data2);
}
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM, 1, type);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM, 1, type);
}
return final_damage;
@@ -1816,9 +1825,9 @@ void Player::setDeathState(DeathState s)
// passive spell
if (!ressSpellId)
ressSpellId = GetResurrectionSpellId();
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP, 1);
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DEATH, 1);
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DEATH_IN_DUNGEON, 1);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP, 1);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DEATH, 1);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DEATH_IN_DUNGEON, 1);
GetAchievementMgr().ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, ACHIEVEMENT_CRITERIA_CONDITION_NO_DEATH);
GetAchievementMgr().ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL, ACHIEVEMENT_CRITERIA_CONDITION_NO_DEATH);
GetAchievementMgr().ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS, ACHIEVEMENT_CRITERIA_CONDITION_NO_DEATH);
@@ -3158,7 +3167,7 @@ void Player::GiveLevel(uint8 level)
CharacterDatabase.CommitTransaction(trans);
}
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL);
// Refer-A-Friend
if (GetSession()->GetRecruiterId())
@@ -3939,11 +3948,11 @@ bool Player::addSpell(uint32 spellId, bool active, bool learning, bool dependent
// not ranked skills
for (SkillLineAbilityMap::const_iterator _spell_idx = skill_bounds.first; _spell_idx != skill_bounds.second; ++_spell_idx)
{
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE, _spell_idx->second->skillId);
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS, _spell_idx->second->skillId);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE, _spell_idx->second->skillId);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS, _spell_idx->second->skillId);
}
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL, spellId);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL, spellId);
}
// return true (for send learn packet) only if spell active (in case ranked spells) and not replace old spell
@@ -4511,8 +4520,8 @@ bool Player::ResetTalents(bool no_cost)
if (!no_cost)
{
ModifyMoney(-(int32)cost);
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TALENTS, cost);
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_NUMBER_OF_TALENT_RESETS, 1);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TALENTS, cost);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_NUMBER_OF_TALENT_RESETS, 1);
SetTalentResetCost(cost);
SetTalentResetTime(time(NULL));
@@ -6219,7 +6228,7 @@ bool Player::UpdateSkill(uint32 skill_id, uint32 step)
if (itr->second.uState != SKILL_NEW)
itr->second.uState = SKILL_CHANGED;
UpdateSkillEnchantments(skill_id, value, new_value);
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL, skill_id);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL, skill_id);
return true;
}
@@ -6362,7 +6371,7 @@ bool Player::UpdateSkillPro(uint16 SkillId, int32 Chance, uint32 step)
}
}
UpdateSkillEnchantments(SkillId, SkillValue, new_value);
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL, SkillId);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL, SkillId);
sLog->outDebug(LOG_FILTER_PLAYER_SKILLS, "Player::UpdateSkillPro Chance=%3.1f%% taken", Chance / 10.0f);
return true;
}
@@ -6552,8 +6561,8 @@ void Player::SetSkill(uint16 id, uint16 step, uint16 newVal, uint16 maxVal)
// if skill value is going up, update enchantments after setting the new value
if (newVal > currVal)
UpdateSkillEnchantments(id, currVal, newVal);
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL, id);
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL, id);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL, id);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL, id);
}
else //remove
{
@@ -6593,8 +6602,8 @@ void Player::SetSkill(uint16 id, uint16 step, uint16 newVal, uint16 maxVal)
SetUInt32Value(PLAYER_SKILL_INDEX(i), MAKE_PAIR32(id, step));
SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i), MAKE_SKILL_VALUE(newVal, maxVal));
UpdateSkillEnchantments(id, currVal, newVal);
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL, id);
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL, id);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL, id);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL, id);
// insert new entry or update if not deleted old entry yet
if (itr != mSkillStatus.end())
@@ -6964,7 +6973,7 @@ void Player::CheckAreaExploreAndOutdoor()
{
SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields | val));
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA);
AreaTableEntry const* areaEntry = GetAreaEntryByAreaFlagAndMap(areaFlag, GetMapId());
if (!areaEntry)
@@ -7494,7 +7503,7 @@ void Player::ModifyCurrency(uint32 id, int32 count)
if (IsInWorld() && !GetSession()->PlayerLoading())
{
if (count > 0)
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CURRENCY, id, count);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CURRENCY, id, count);
WorldPacket packet(SMSG_UPDATE_CURRENCY, 12);
packet << uint32(id);
@@ -7870,10 +7879,10 @@ void Player::DuelComplete(DuelCompleteType type)
}
break;
case DUEL_WON:
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOSE_DUEL, 1);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOSE_DUEL, 1);
if (duel->opponent)
{
- duel->opponent->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL, 1);
+ duel->opponent->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL, 1);
//Credit for quest Death's Challenge
if (getClass() == CLASS_DEATH_KNIGHT && duel->opponent->GetQuestStatus(12733) == QUEST_STATUS_INCOMPLETE)
@@ -12163,8 +12172,8 @@ Item* Player::StoreNewItem(ItemPosCountVec const& dest, uint32 item, bool update
if (pItem)
{
ItemAddedQuestCheck(item, count);
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM, item, count);
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM, item, 1);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM, item, count);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM, item, 1);
if (randomPropertyId)
pItem->SetItemRandomProperties(randomPropertyId);
pItem = StoreItem(dest, pItem, update);
@@ -12334,7 +12343,7 @@ Item* Player::EquipNewItem(uint16 pos, uint32 item, bool update)
if (Item* pItem = Item::CreateItem(item, 1, this))
{
ItemAddedQuestCheck(item, 1);
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM, item, 1);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM, item, 1);
return EquipItem(pos, pItem, update);
}
@@ -12444,8 +12453,8 @@ Item* Player::EquipItem(uint16 pos, Item* pItem, bool update)
}
// only for full equip instead adding to stack
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM, pItem->GetEntry());
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM, pItem->GetEntry(), slot);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM, pItem->GetEntry());
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM, pItem->GetEntry(), slot);
return pItem;
}
@@ -12466,8 +12475,8 @@ void Player::QuickEquipItem(uint16 pos, Item* pItem)
pItem->SendUpdateToPlayer(this);
}
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM, pItem->GetEntry());
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM, pItem->GetEntry(), slot);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM, pItem->GetEntry());
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM, pItem->GetEntry(), slot);
}
}
@@ -12613,7 +12622,7 @@ void Player::MoveItemToInventory(ItemPosCountVec const& dest, Item* pItem, bool
{
// update quest counters
ItemAddedQuestCheck(pItem->GetEntry(), pItem->GetCount());
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM, pItem->GetEntry(), pItem->GetCount());
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM, pItem->GetEntry(), pItem->GetCount());
// store item
Item* pLastItem = StoreItem(dest, pItem, update);
@@ -15210,7 +15219,7 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
ModifyMoney(moneyRew);
if (moneyRew > 0)
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_QUEST_REWARD, uint32(moneyRew));
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_QUEST_REWARD, uint32(moneyRew));
}
// honor reward
@@ -15244,8 +15253,8 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
SetDailyQuestStatus(quest_id);
if (quest->IsDaily())
{
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST, quest_id);
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY, quest_id);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST, quest_id);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY, quest_id);
}
}
else if (quest->IsWeekly())
@@ -15273,9 +15282,9 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
CastSpell(this, quest->GetRewSpell(), true);
if (quest->GetZoneOrSort() > 0)
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE, quest->GetZoneOrSort());
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT);
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST, quest->GetQuestId());
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE, quest->GetZoneOrSort());
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST, quest->GetQuestId());
uint32 zone = 0;
uint32 area = 0;
@@ -16055,7 +16064,7 @@ void Player::KilledMonsterCredit(uint32 entry, uint64 guid)
}
GetAchievementMgr().StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_CREATURE, real_entry); // MUST BE CALLED FIRST
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, real_entry, addkillcount, guid ? GetMap()->GetCreature(guid) : NULL);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, real_entry, addkillcount, guid ? GetMap()->GetCreature(guid) : NULL);
for (uint8 i = 0; i < MAX_QUEST_LOG_SIZE; ++i)
{
@@ -20883,8 +20892,8 @@ bool Player::ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc
//Checks and preparations done, DO FLIGHT
ModifyMoney(-(int32)totalcost);
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TRAVELLING, totalcost);
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_FLIGHT_PATHS_TAKEN, 1);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TRAVELLING, totalcost);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_FLIGHT_PATHS_TAKEN, 1);
// prevent stealth flight
//RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TALK);
@@ -22218,7 +22227,7 @@ void Player::SendInitialPacketsBeforeAddToMap()
SendInitialActionButtons();
m_reputationMgr.SendInitialReputations();
- m_achievementMgr.SendAllAchievementData();
+ m_achievementMgr.SendAllAchievementData(this);
SendEquipmentSetList();
@@ -22852,7 +22861,7 @@ void Player::SummonIfPossible(bool agree)
m_summon_expire = 0;
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ACCEPTED_SUMMONINGS, 1);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ACCEPTED_SUMMONINGS, 1);
TeleportTo(m_summon_mapid, m_summon_x, m_summon_y, m_summon_z, GetOrientation());
}
@@ -24021,9 +24030,9 @@ void Player::StoreLootItem(uint8 lootSlot, Loot* loot)
--loot->unlootedCount;
SendNewItem(newitem, uint32(item->count), false, false, true);
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM, item->itemid, item->count);
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE, loot->loot_type, item->count);
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM, item->itemid, item->count);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM, item->itemid, item->count);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE, loot->loot_type, item->count);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM, item->itemid, item->count);
}
else
SendEquipError(msg, NULL, NULL, item->itemid);
@@ -24303,7 +24312,7 @@ void Player::HandleFall(MovementInfo const& movementInfo)
// recheck alive, might have died of EnvironmentalDamage, avoid cases when player die in fact like Spirit of Redemption case
if (isAlive() && final_damage < original_health)
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING, uint32(z_diff*100));
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING, uint32(z_diff*100));
}
//Z given by moveinfo, LastZ, FallTime, WaterZ, MapZ, Damage, Safefall reduction
@@ -24315,12 +24324,20 @@ void Player::HandleFall(MovementInfo const& movementInfo)
void Player::UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 /*= 0*/, uint32 miscValue2 /*= 0*/, Unit* unit /*= NULL*/)
{
- GetAchievementMgr().UpdateAchievementCriteria(type, miscValue1, miscValue2, unit);
+ GetAchievementMgr().UpdateAchievementCriteria(type, miscValue1, miscValue2, unit, this);
+
+ // Update only individual achievement criteria here, otherwise we may get multiple updates
+ // from a single boss kill
+ if (sAchievementMgr->IsGroupCriteriaType(type))
+ return;
+
+ if (Guild* guild = sGuildMgr->GetGuildById(m_guildId))
+ guild->GetAchievementMgr().UpdateAchievementCriteria(type, miscValue1, miscValue2, unit, this);
}
void Player::CompletedAchievement(AchievementEntry const* entry)
{
- GetAchievementMgr().CompletedAchievement(entry);
+ GetAchievementMgr().CompletedAchievement(entry, this);
}
bool Player::LearnTalent(uint32 talentId, uint32 talentRank)
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index dbe9cd94a21..e273ba81077 100755
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -1887,7 +1887,7 @@ class Player : public Unit, public GridObject<Player>
CharacterDatabase.Execute(stmt);
m_guildId = GuildId;
}
- uint32 GetGuildId() { return m_guildId; }
+ uint32 GetGuildId() const { return m_guildId; }
static uint32 GetGuildIdFromDB(uint64 guid);
void SetRank(uint8 rankId) { SetUInt32Value(PLAYER_GUILDRANK, rankId); }
@@ -2532,8 +2532,8 @@ class Player : public Unit, public GridObject<Player>
void AddRunePower(uint8 index);
void InitRunes();
- AchievementMgr& GetAchievementMgr() { return m_achievementMgr; }
- AchievementMgr const& GetAchievementMgr() const { return m_achievementMgr; }
+ AchievementMgr<Player>& GetAchievementMgr() { return m_achievementMgr; }
+ AchievementMgr<Player> const& GetAchievementMgr() const { return m_achievementMgr; }
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 = 0, uint32 miscValue2 = 0, Unit* unit = NULL);
void CompletedAchievement(AchievementEntry const* entry);
@@ -2914,7 +2914,7 @@ class Player : public Unit, public GridObject<Player>
uint32 m_temporaryUnsummonedPetNumber;
uint32 m_oldpetspell;
- AchievementMgr m_achievementMgr;
+ AchievementMgr<Player> m_achievementMgr;
ReputationMgr m_reputationMgr;
SpellCooldowns m_spellCooldowns;
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 5fe8f0bf657..599c79dedbd 100755
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -693,7 +693,7 @@ uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDam
// call before auras are removed
if (Player* killer = GetCharmerOrOwnerPlayerOrPlayerItself())
- killer->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL, 1, 0, victim);
+ killer->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL, 1, 0, victim);
}
Kill(victim, durabilityLoss);
@@ -10019,15 +10019,15 @@ int32 Unit::DealHeal(Unit* victim, uint32 addhealth)
// use the actual gain, as the overheal shall not be counted, skip gain 0 (it ignored anyway in to criteria)
if (gain)
- player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE, gain, 0, victim);
+ player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE, gain, 0, victim);
- player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEAL_CASTED, addhealth);
+ player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEAL_CASTED, addhealth);
}
if (Player* player = victim->ToPlayer())
{
- player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_TOTAL_HEALING_RECEIVED, gain);
- player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALING_RECEIVED, addhealth);
+ player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_TOTAL_HEALING_RECEIVED, gain);
+ player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALING_RECEIVED, addhealth);
}
return gain;
@@ -15971,7 +15971,7 @@ void Unit::Kill(Unit* victim, bool durabilityLoss)
// update get killing blow achievements, must be done before setDeathState to be able to require auras on target
// and before Spirit of Redemption as it also removes auras
if (player)
- player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS, 1, 0, victim);
+ player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS, 1, 0, victim);
// if talent known but not triggered (check priest class for speedup check)
bool spiritOfRedemption = false;
@@ -16122,9 +16122,9 @@ void Unit::Kill(Unit* victim, bool durabilityLoss)
if (victim->GetTypeId() == TYPEID_PLAYER)
{
if (GetTypeId() == TYPEID_UNIT)
- victim->ToPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE, GetEntry());
+ victim->ToPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE, GetEntry());
else if (GetTypeId() == TYPEID_PLAYER && victim != this)
- victim->ToPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER, 1, ToPlayer()->GetTeam());
+ victim->ToPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER, 1, ToPlayer()->GetTeam());
}
// Hook for OnPVPKill Event
diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp
index 743d56886f0..da363fbbb15 100755
--- a/src/server/game/Groups/Group.cpp
+++ b/src/server/game/Groups/Group.cpp
@@ -1194,7 +1194,7 @@ void Group::CountTheRoll(Rolls::iterator rollI)
if (player && player->GetSession())
{
- player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT, roll->itemid, maxresul);
+ player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT, roll->itemid, maxresul);
ItemPosCountVec dest;
LootItem* item = &(roll->getLoot()->items[roll->itemSlot]);
@@ -1244,7 +1244,7 @@ void Group::CountTheRoll(Rolls::iterator rollI)
if (player && player->GetSession())
{
- player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT, roll->itemid, maxresul);
+ player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT, roll->itemid, maxresul);
LootItem* item = &(roll->getLoot()->items[roll->itemSlot]);
diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp
index b57e9970dab..94a9aff18bc 100755
--- a/src/server/game/Guilds/Guild.cpp
+++ b/src/server/game/Guilds/Guild.cpp
@@ -1070,7 +1070,7 @@ InventoryResult Guild::BankMoveItemData::CanStore(Item* pItem, bool swap)
///////////////////////////////////////////////////////////////////////////////
// Guild
-Guild::Guild() : m_id(0), m_leaderGuid(0), m_createdDate(0), m_accountsNumber(0), m_bankMoney(0), m_eventLog(NULL)
+Guild::Guild() : m_id(0), m_leaderGuid(0), m_createdDate(0), m_accountsNumber(0), m_bankMoney(0), m_eventLog(NULL), m_achievementMgr(this)
{
memset(&m_bankEventLog, 0, (GUILD_BANK_MAX_TABS + 1) * sizeof(LogHolder*));
}
@@ -1227,7 +1227,7 @@ void Guild::HandleQuery(WorldSession* session)
{
WorldPacket data(SMSG_GUILD_QUERY_RESPONSE, 8 * 32 + 200); // Guess size
- data << uint64(GetGuid());
+ data << uint64(GetGUID());
data << m_name;
// Rank name
diff --git a/src/server/game/Guilds/Guild.h b/src/server/game/Guilds/Guild.h
index f5d71d50023..59552da2c41 100755
--- a/src/server/game/Guilds/Guild.h
+++ b/src/server/game/Guilds/Guild.h
@@ -600,7 +600,7 @@ public:
// Getters
uint32 GetId() const { return m_id; }
- uint64 GetGuid() const { return MAKE_NEW_GUID(m_id, 0, HIGHGUID_GUILD); }
+ uint64 GetGUID() const { return MAKE_NEW_GUID(m_id, 0, HIGHGUID_GUILD); }
uint64 GetLeaderGUID() const { return m_leaderGuid; }
const std::string& GetName() const { return m_name; }
const std::string& GetMOTD() const { return m_motd; }
@@ -679,6 +679,9 @@ public:
// Bank tabs
void SetBankTabText(uint8 tabId, const std::string& text);
+ AchievementMgr<Guild>& GetAchievementMgr() { return m_achievementMgr; }
+ AchievementMgr<Guild> const& GetAchievementMgr() const { return m_achievementMgr; }
+
protected:
uint32 m_id;
std::string m_name;
@@ -699,6 +702,8 @@ protected:
LogHolder* m_eventLog;
LogHolder* m_bankEventLog[GUILD_BANK_MAX_TABS + 1];
+ AchievementMgr<Guild> m_achievementMgr;
+
private:
inline uint8 _GetRanksSize() const { return uint8(m_ranks.size()); }
inline const RankInfo* GetRankInfo(uint8 rankId) const { return rankId < _GetRanksSize() ? &m_ranks[rankId] : NULL; }
diff --git a/src/server/game/Guilds/GuildMgr.cpp b/src/server/game/Guilds/GuildMgr.cpp
index 450a49e345c..a6b73664695 100644
--- a/src/server/game/Guilds/GuildMgr.cpp
+++ b/src/server/game/Guilds/GuildMgr.cpp
@@ -405,7 +405,25 @@ void GuildMgr::LoadGuilds()
}
}
- // 9. Validate loaded guild data
+ // 9. Load guild achievements
+ {
+ PreparedQueryResult achievementResult;
+ PreparedQueryResult criteriaResult;
+ for (GuildContainer::const_iterator itr = GuildStore.begin(); itr != GuildStore.end(); ++itr)
+ {
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_ACHIEVEMENT);
+ stmt->setUInt32(0, itr->first);
+ achievementResult = CharacterDatabase.Query(stmt);
+
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_ACHIEVEMENT_CRITERIA);
+ stmt->setUInt32(0, itr->first);
+ criteriaResult = CharacterDatabase.Query(stmt);
+
+ itr->second->GetAchievementMgr().LoadFromDB(achievementResult, criteriaResult);
+ }
+ }
+
+ // 10. Validate loaded guild data
sLog->outString("Validating data of loaded guilds...");
{
uint32 oldMSTime = getMSTime();
diff --git a/src/server/game/Handlers/AuctionHouseHandler.cpp b/src/server/game/Handlers/AuctionHouseHandler.cpp
index 95204dfa353..f26379f4101 100755
--- a/src/server/game/Handlers/AuctionHouseHandler.cpp
+++ b/src/server/game/Handlers/AuctionHouseHandler.cpp
@@ -276,7 +276,7 @@ void WorldSession::HandleAuctionSellItem(WorldPacket & recv_data)
SendAuctionCommandResult(AH->Id, AUCTION_SELL_ITEM, AUCTION_OK);
- GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION, 1);
+ GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION, 1);
return;
}
else // Required stack size of auction does not match to current item stack size, clone item and set correct stack size
@@ -345,7 +345,7 @@ void WorldSession::HandleAuctionSellItem(WorldPacket & recv_data)
SendAuctionCommandResult(AH->Id, AUCTION_SELL_ITEM, AUCTION_OK);
- GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION, 1);
+ GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION, 1);
return;
}
}
@@ -437,7 +437,7 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket& recv_data)
auction->bidder = player->GetGUIDLow();
auction->bid = price;
- GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, price);
+ GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, price);
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_AUCTION_BID);
stmt->setUInt32(0, auction->bidder);
@@ -460,7 +460,7 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket& recv_data)
}
auction->bidder = player->GetGUIDLow();
auction->bid = auction->buyout;
- GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, auction->buyout);
+ GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, auction->buyout);
//- Mails must be under transaction control too to prevent data loss
sAuctionMgr->SendAuctionSalePendingMail(auction, trans);
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index 1c79b20ce81..26a3e7c67ea 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -1441,7 +1441,7 @@ void WorldSession::HandleAlterAppearance(WorldPacket & recv_data)
}
_player->ModifyMoney(-int32(Cost)); // it isn't free
- _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_AT_BARBER, Cost);
+ _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_AT_BARBER, Cost);
_player->SetByteValue(PLAYER_BYTES, 2, uint8(bs_hair->hair_id));
_player->SetByteValue(PLAYER_BYTES, 3, uint8(Color));
@@ -1449,7 +1449,7 @@ void WorldSession::HandleAlterAppearance(WorldPacket & recv_data)
if (bs_skinColor)
_player->SetByteValue(PLAYER_BYTES, 0, uint8(bs_skinColor->hair_id));
- _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP, 1);
+ _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP, 1);
_player->SetStandState(0); // stand up
}
diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp
index c1246799e4b..08d36328cf0 100755
--- a/src/server/game/Handlers/ChatHandler.cpp
+++ b/src/server/game/Handlers/ChatHandler.cpp
@@ -740,7 +740,7 @@ void WorldSession::HandleTextEmoteOpcode(WorldPacket & recv_data)
TypeContainerVisitor<Trinity::PlayerDistWorker<Trinity::LocalizedPacketDo<Trinity::EmoteChatBuilder> >, WorldTypeMapContainer> message(emote_worker);
cell.Visit(p, message, *GetPlayer()->GetMap(), *GetPlayer(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE));
- GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE, text_emote, 0, unit);
+ GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE, text_emote, 0, unit);
//Send scripted event call
if (unit && unit->GetTypeId() == TYPEID_UNIT && ((Creature*)unit)->AI())
diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp
index eadc0958518..626221e9696 100755
--- a/src/server/game/Handlers/GroupHandler.cpp
+++ b/src/server/game/Handlers/GroupHandler.cpp
@@ -476,10 +476,10 @@ void WorldSession::HandleLootRoll(WorldPacket& recvData)
switch (rollType)
{
case ROLL_NEED:
- GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED, 1);
+ GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED, 1);
break;
case ROLL_GREED:
- GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED, 1);
+ GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED, 1);
break;
}
}
diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp
index 5baa54a2779..1e29ea2621e 100755
--- a/src/server/game/Handlers/ItemHandler.cpp
+++ b/src/server/game/Handlers/ItemHandler.cpp
@@ -584,7 +584,7 @@ void WorldSession::HandleSellItemOpcode(WorldPacket & recv_data)
uint32 money = pProto->SellPrice * count;
_player->ModifyMoney(money);
- _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_VENDORS, money);
+ _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_VENDORS, money);
}
else
_player->SendSellError(SELL_ERR_CANT_SELL_ITEM, creature, itemguid, 0);
@@ -632,7 +632,7 @@ void WorldSession::HandleBuybackItem(WorldPacket & recv_data)
_player->ModifyMoney(-(int32)price);
_player->RemoveItemFromBuyBackSlot(slot, false);
_player->ItemAddedQuestCheck(pItem->GetEntry(), pItem->GetCount());
- _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM, pItem->GetEntry(), pItem->GetCount());
+ _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM, pItem->GetEntry(), pItem->GetCount());
_player->StoreItem(dest, pItem, true);
}
else
@@ -947,7 +947,7 @@ void WorldSession::HandleBuyBankSlotOpcode(WorldPacket& recvPacket)
data << uint32(ERR_BANKSLOT_OK);
SendPacket(&data);
- _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT);
+ _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT);
}
void WorldSession::HandleAutoBankItemOpcode(WorldPacket& recvPacket)
diff --git a/src/server/game/Handlers/LootHandler.cpp b/src/server/game/Handlers/LootHandler.cpp
index 339c7a44d9f..53e589e31fd 100755
--- a/src/server/game/Handlers/LootHandler.cpp
+++ b/src/server/game/Handlers/LootHandler.cpp
@@ -179,7 +179,7 @@ void WorldSession::HandleLootMoneyOpcode(WorldPacket & /*recv_data*/)
for (std::vector<Player*>::const_iterator i = playersNear.begin(); i != playersNear.end(); ++i)
{
(*i)->ModifyMoney(goldPerPlayer);
- (*i)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, goldPerPlayer);
+ (*i)->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, goldPerPlayer);
WorldPacket data(SMSG_LOOT_MONEY_NOTIFY, 4 + 1);
data << uint32(goldPerPlayer);
@@ -190,7 +190,7 @@ void WorldSession::HandleLootMoneyOpcode(WorldPacket & /*recv_data*/)
else
{
player->ModifyMoney(loot->gold);
- player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, loot->gold);
+ player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, loot->gold);
WorldPacket data(SMSG_LOOT_MONEY_NOTIFY, 4 + 1);
data << uint32(loot->gold);
@@ -496,9 +496,9 @@ void WorldSession::HandleLootMasterGiveOpcode(WorldPacket & recv_data)
// not move item from loot to target inventory
Item* newitem = target->StoreNewItem(dest, item.itemid, true, item.randomPropertyId, looters);
target->SendNewItem(newitem, uint32(item.count), false, false, true);
- target->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM, item.itemid, item.count);
- target->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE, loot->loot_type, item.count);
- target->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM, item.itemid, item.count);
+ target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM, item.itemid, item.count);
+ target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE, loot->loot_type, item.count);
+ target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM, item.itemid, item.count);
// mark as looted
item.count=0;
diff --git a/src/server/game/Handlers/MailHandler.cpp b/src/server/game/Handlers/MailHandler.cpp
index ce056d2729c..dd76c3a4c80 100755
--- a/src/server/game/Handlers/MailHandler.cpp
+++ b/src/server/game/Handlers/MailHandler.cpp
@@ -246,7 +246,7 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data)
player->SendMailResult(0, MAIL_SEND, MAIL_OK);
player->ModifyMoney(-int32(reqmoney));
- player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL, cost);
+ player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL, cost);
bool needItemDelay = false;
diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp
index 956179b9d26..1c02d2082b8 100755
--- a/src/server/game/Handlers/MiscHandler.cpp
+++ b/src/server/game/Handlers/MiscHandler.cpp
@@ -1691,7 +1691,16 @@ void WorldSession::HandleQueryInspectAchievements(WorldPacket & recv_data)
if (!player)
return;
- player->GetAchievementMgr().SendRespondInspectAchievements(_player);
+ player->GetAchievementMgr().SendAchievementInfo(_player);
+}
+
+void WorldSession::HandleGuildAchievementProgressQuery(WorldPacket& recvData)
+{
+ uint32 achievementId;
+ recvData >> achievementId;
+
+ if (Guild* guild = sGuildMgr->GetGuildById(_player->GetGuildId()))
+ guild->GetAchievementMgr().SendAchievementInfo(_player, achievementId);
}
void WorldSession::HandleWorldStateUITimerUpdate(WorldPacket& /*recv_data*/)
diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp
index 2998b8a1c75..62924c6ef36 100755
--- a/src/server/game/Handlers/QuestHandler.cpp
+++ b/src/server/game/Handlers/QuestHandler.cpp
@@ -440,7 +440,7 @@ void WorldSession::HandleQuestLogRemoveQuest(WorldPacket& recv_data)
_player->SetQuestSlot(slot, 0);
- _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_QUEST_ABANDONED, 1);
+ _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_QUEST_ABANDONED, 1);
}
}
diff --git a/src/server/game/Handlers/SpellHandler.cpp b/src/server/game/Handlers/SpellHandler.cpp
index 5823a38fb42..6aba8c82477 100755
--- a/src/server/game/Handlers/SpellHandler.cpp
+++ b/src/server/game/Handlers/SpellHandler.cpp
@@ -306,7 +306,7 @@ void WorldSession::HandleGameobjectReportUse(WorldPacket& recvPacket)
go->AI()->GossipHello(_player);
- _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT, go->GetEntry());
+ _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT, go->GetEntry());
}
void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
@@ -599,7 +599,7 @@ void WorldSession::HandleMirrorImageDataRequest(WorldPacket & recv_data)
data << uint8(player->GetByteValue(PLAYER_BYTES, 2)); // hair
data << uint8(player->GetByteValue(PLAYER_BYTES, 3)); // haircolor
data << uint8(player->GetByteValue(PLAYER_BYTES_2, 0)); // facialhair
- data << uint64(guild ? guild->GetGuid() : 0);
+ data << uint64(guild ? guild->GetGUID() : 0);
static EquipmentSlots const itemSlots[] =
{
diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h
index 6d526f23a94..5eb11416fdd 100755
--- a/src/server/game/Maps/Map.h
+++ b/src/server/game/Maps/Map.h
@@ -444,6 +444,7 @@ class Map : public GridRefManager<NGridType>
bool Contains(const GameObjectModel& mdl) const { return _dynamicTree.contains(mdl);}
bool getObjectHitPos(uint32 phasemask, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float &ry, float& rz, float modifyDist);
+ virtual uint32 GetOwnerGuildId(uint32 /*team*/ = TEAM_OTHER) const { return 0; }
/*
RESPAWN TIMES
*/
diff --git a/src/server/game/Reputation/ReputationMgr.cpp b/src/server/game/Reputation/ReputationMgr.cpp
index 94a6590cc4a..0ae16d72758 100755
--- a/src/server/game/Reputation/ReputationMgr.cpp
+++ b/src/server/game/Reputation/ReputationMgr.cpp
@@ -388,11 +388,11 @@ bool ReputationMgr::SetOneFactionReputation(FactionEntry const* factionEntry, in
UpdateRankCounters(old_rank, new_rank);
_player->ReputationChanged(factionEntry);
- _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KNOWN_FACTIONS, factionEntry->ID);
- _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION, factionEntry->ID);
- _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION, factionEntry->ID);
- _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_REVERED_REPUTATION, factionEntry->ID);
- _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_HONORED_REPUTATION, factionEntry->ID);
+ _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KNOWN_FACTIONS, factionEntry->ID);
+ _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION, factionEntry->ID);
+ _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION, factionEntry->ID);
+ _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_REVERED_REPUTATION, factionEntry->ID);
+ _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_HONORED_REPUTATION, factionEntry->ID);
return true;
}
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index 90245e8b109..ee28bd59618 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -320,6 +320,7 @@ void InitOpcodes()
//DEFINE_OPCODE_HANDLER(CMSG_GROUP_UNINVITE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupUninviteOpcode );
//DEFINE_OPCODE_HANDLER(CMSG_GROUP_UNINVITE_GUID, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupUninviteGuidOpcode );
//DEFINE_OPCODE_HANDLER(CMSG_GUILD_ACCEPT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildAcceptOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_ACHIEVEMENT_PROGRESS_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildAchievementProgressQuery);
//DEFINE_OPCODE_HANDLER(CMSG_GUILD_ADD_RANK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildAddRankOpcode );
//DEFINE_OPCODE_HANDLER(CMSG_GUILD_BANKER_ACTIVATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankerActivate );
//DEFINE_OPCODE_HANDLER(CMSG_GUILD_BANK_BUY_TAB, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankBuyTab );
@@ -779,7 +780,7 @@ void InitOpcodes()
//DEFINE_OPCODE_HANDLER(MSG_VIEW_PHASE_SHIFT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER(SMSG_ACCOUNT_DATA_TIMES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_ACHIEVEMENT_DELETED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- //DEFINE_OPCODE_HANDLER(SMSG_ACHIEVEMENT_EARNED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_ACHIEVEMENT_EARNED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_ACTION_BUTTONS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_ACTIVATETAXIREPLY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_ADDON_INFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
@@ -916,8 +917,8 @@ void InitOpcodes()
//DEFINE_OPCODE_HANDLER(SMSG_CORPSE_MAP_POSITION_QUERY_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_CORPSE_RECLAIM_DELAY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_CREATURE_QUERY_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- //DEFINE_OPCODE_HANDLER(SMSG_CRITERIA_DELETED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- //DEFINE_OPCODE_HANDLER(SMSG_CRITERIA_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CRITERIA_DELETED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CRITERIA_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_CROSSED_INEBRIATION_THRESHOLD, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_DAMAGE_CALC_LOG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_DANCE_QUERY_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
@@ -1001,8 +1002,13 @@ void InitOpcodes()
//DEFINE_OPCODE_HANDLER(SMSG_GROUP_LIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_GROUP_SET_LEADER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_GROUP_UNINVITE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_ACHIEVEMENT_DATA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_ACHIEVEMENT_DELETED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_ACHIEVEMENT_EARNED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_GUILD_BANK_LIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_GUILD_COMMAND_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_CRITERIA_DATA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_CRITERIA_DELETED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_GUILD_DECLINE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_GUILD_EVENT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_GUILD_INFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
@@ -1240,7 +1246,7 @@ void InitOpcodes()
//DEFINE_OPCODE_HANDLER(SMSG_SERVERTIME, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_SERVER_BUCK_DATA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_SERVER_BUCK_DATA_START, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- //DEFINE_OPCODE_HANDLER(SMSG_SERVER_FIRST_ACHIEVEMENT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SERVER_FIRST_ACHIEVEMENT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_SERVER_INFO_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_SERVER_MESSAGE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_SET_EXTRA_AURA_INFO_NEED_UPDATE_OBSOLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h
index f73f3af0446..26e3c65a1b7 100755
--- a/src/server/game/Server/Protocol/Opcodes.h
+++ b/src/server/game/Server/Protocol/Opcodes.h
@@ -200,6 +200,7 @@ enum Opcodes
CMSG_GROUP_UNINVITE_GUID = 0x0000,
CMSG_GUILDFINDER_JOIN = 0x0000,
CMSG_GUILD_ACCEPT = 0x2531,
+ CMSG_GUILD_ACHIEVEMENT_PROGRESS_QUERY = 0x3235,
CMSG_GUILD_BANKER_ACTIVATE = 0x2E37,
CMSG_GUILD_BANK_BUY_TAB = 0x0000,
CMSG_GUILD_BANK_DEPOSIT_MONEY = 0x0000,
@@ -543,7 +544,7 @@ enum Opcodes
MSG_TALENT_WIPE_CONFIRM = 0x0000,
MSG_VERIFY_CONNECTIVITY = 0x4F57,
SMSG_ACCOUNT_DATA_TIMES = 0x4B05,
- SMSG_ACHIEVEMENT_DELETED = 0x0000,
+ SMSG_ACHIEVEMENT_DELETED = 0x6A16,
SMSG_ACHIEVEMENT_EARNED = 0x4405,
SMSG_ACTION_BUTTONS = 0x38B5,
SMSG_ACTIVATETAXIREPLY = 0x0000,
@@ -672,7 +673,7 @@ enum Opcodes
SMSG_CORPSE_NOT_IN_INSTANCE = 0x0000,
SMSG_CORPSE_RECLAIM_DELAY = 0x0D34,
SMSG_CREATURE_QUERY_RESPONSE = 0x6024,
- SMSG_CRITERIA_DELETED = 0x0000,
+ SMSG_CRITERIA_DELETED = 0x2915,
SMSG_CRITERIA_UPDATE = 0x6E37,
SMSG_CROSSED_INEBRIATION_THRESHOLD = 0x0000,
SMSG_DAMAGE_CALC_LOG = 0x0000,
@@ -742,10 +743,14 @@ enum Opcodes
SMSG_GROUP_SET_LEADER = 0x0526,
SMSG_GROUP_UNINVITE = 0x0000,
SMSG_GUILDFINDER_SEARCH_RESULT = 0x0000,
- SMSG_GUILD_ACHIEVEMENT_DATA = 0x0000,
+ SMSG_GUILD_ACHIEVEMENT_DATA = 0x54B7,
+ SMSG_GUILD_ACHIEVEMENT_DELETED = 0x35A0,
+ SMSG_GUILD_ACHIEVEMENT_EARNED = 0x50B5,
SMSG_GUILD_BANK_LIST = 0x78A5,
SMSG_GUILD_CANCEL = 0x0000,
SMSG_GUILD_COMMAND_RESULT = 0x0000,
+ SMSG_GUILD_CRITERIA_DATA = 0x14B4,
+ SMSG_GUILD_CRITERIA_DELETED = 0x55B1,
SMSG_GUILD_DECLINE = 0x0000,
SMSG_GUILD_EVENT = 0x0705,
SMSG_GUILD_INFO = 0x0000,
@@ -977,7 +982,7 @@ enum Opcodes
SMSG_REQUEST_CEMETERY_LIST_RESPONSE = 0x0000,
SMSG_RESET_FAILED_NOTIFY = 0x0000,
SMSG_RESISTLOG = 0x0000,
- SMSG_RESPOND_INSPECT_ACHIEVEMENTS = 0x0000,
+ SMSG_RESPOND_INSPECT_ACHIEVEMENTS = 0x15B0,
SMSG_RESURRECT_REQUEST = 0x0000,
SMSG_RESYNC_RUNES = 0x0000,
SMSG_RWHOIS = 0x0000,
@@ -985,7 +990,7 @@ enum Opcodes
SMSG_SEND_MAIL_RESULT = 0x0000,
SMSG_SEND_UNLEARN_SPELLS = 0x4E25,
SMSG_SERVERTIME = 0x0000,
- SMSG_SERVER_FIRST_ACHIEVEMENT = 0x0000,
+ SMSG_SERVER_FIRST_ACHIEVEMENT = 0x6424,
SMSG_SERVER_MESSAGE = 0x6C04,
SMSG_SET_FACTION_ATWAR = 0x0000,
SMSG_SET_FACTION_STANDING = 0x0126,
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index 1d648fec6c9..7495a57f399 100755
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -921,6 +921,7 @@ class WorldSession
void HandleRemoveGlyph(WorldPacket& recv_data);
void HandleCharCustomize(WorldPacket& recv_data);
void HandleQueryInspectAchievements(WorldPacket& recv_data);
+ void HandleGuildAchievementProgressQuery(WorldPacket& recvData);
void HandleEquipmentSetSave(WorldPacket& recv_data);
void HandleEquipmentSetDelete(WorldPacket& recv_data);
void HandleEquipmentSetUse(WorldPacket& recv_data);
diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp
index a9c53f3a817..968a5b850e2 100755
--- a/src/server/game/Server/WorldSocket.cpp
+++ b/src/server/game/Server/WorldSocket.cpp
@@ -1028,7 +1028,7 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
// Sleep this Network thread for
uint32 sleepTime = sWorld->getIntConfig(CONFIG_SESSION_ADD_DELAY);
- ACE_OS::sleep(ACE_Time_Value (0, sleepTime));
+ ACE_OS::sleep(ACE_Time_Value(0, sleepTime));
sWorld->AddSession(m_Session);
return 0;
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 54b3ae310e2..76cae551bbd 100755
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -2602,14 +2602,14 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA
if (unit->GetTypeId() == TYPEID_PLAYER)
{
unit->ToPlayer()->GetAchievementMgr().StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET, m_spellInfo->Id);
- unit->ToPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, m_spellInfo->Id, 0, m_caster);
- unit->ToPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2, m_spellInfo->Id);
+ unit->ToPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, m_spellInfo->Id, 0, m_caster);
+ unit->ToPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2, m_spellInfo->Id);
}
if (m_caster->GetTypeId() == TYPEID_PLAYER)
{
m_caster->ToPlayer()->GetAchievementMgr().StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_SPELL_CASTER, m_spellInfo->Id);
- m_caster->ToPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2, m_spellInfo->Id, 0, unit);
+ m_caster->ToPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2, m_spellInfo->Id, 0, unit);
}
if (m_caster != unit)
@@ -3251,10 +3251,10 @@ void Spell::cast(bool skipCheck)
if (!(_triggeredCastFlags & TRIGGERED_IGNORE_CAST_ITEM) && m_CastItem)
{
m_caster->ToPlayer()->GetAchievementMgr().StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_ITEM, m_CastItem->GetEntry());
- m_caster->ToPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM, m_CastItem->GetEntry());
+ m_caster->ToPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM, m_CastItem->GetEntry());
}
- m_caster->ToPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL, m_spellInfo->Id);
+ m_caster->ToPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL, m_spellInfo->Id);
}
if (!(_triggeredCastFlags & TRIGGERED_IGNORE_POWER_AND_REAGENT_COST))
diff --git a/src/server/scripts/Commands/cs_reset.cpp b/src/server/scripts/Commands/cs_reset.cpp
index a8294dc9ddb..82c692ce39e 100644
--- a/src/server/scripts/Commands/cs_reset.cpp
+++ b/src/server/scripts/Commands/cs_reset.cpp
@@ -62,7 +62,7 @@ public:
if (target)
target->GetAchievementMgr().Reset();
else
- AchievementMgr::DeleteFromDB(GUID_LOPART(targetGuid));
+ AchievementMgr<Player>::DeleteFromDB(GUID_LOPART(targetGuid));
return true;
}
diff --git a/src/server/shared/DataStores/DBCStore.h b/src/server/shared/DataStores/DBCStore.h
index 589d331f22d..f8a983d22f3 100755
--- a/src/server/shared/DataStores/DBCStore.h
+++ b/src/server/shared/DataStores/DBCStore.h
@@ -41,7 +41,7 @@ struct SqlDbc
for (uint32 i = 0; i< sqlTableName.size(); ++i)
{
if (isalpha(sqlTableName[i]))
- sqlTableName[i] = tolower(sqlTableName[i]);
+ sqlTableName[i] = char(tolower(sqlTableName[i]));
else if (sqlTableName[i] == '.')
sqlTableName[i] = '_';
}
diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp
index 27bf92ad846..3bd398d040e 100755
--- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp
+++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp
@@ -228,6 +228,14 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PREPARE_STATEMENT(CHAR_UPD_GUILD_RANK_BANK_TIME4, "UPDATE guild_member SET BankResetTimeTab4 = 0 WHERE guildid = ? AND rank = ?", CONNECTION_ASYNC)
PREPARE_STATEMENT(CHAR_UPD_GUILD_RANK_BANK_TIME5, "UPDATE guild_member SET BankResetTimeTab5 = 0 WHERE guildid = ? AND rank = ?", CONNECTION_ASYNC)
PREPARE_STATEMENT(CHAR_SEL_CHAR_DATA_FOR_GUILD, "SELECT name, level, class, zone, account FROM characters WHERE guid = ?", CONNECTION_SYNCH)
+ PREPARE_STATEMENT(CHAR_DEL_GUILD_ACHIEVEMENT, "DELETE FROM guild_achievement WHERE guildId = ? AND achievement = ?", CONNECTION_SYNCH)
+ PREPARE_STATEMENT(CHAR_INS_GUILD_ACHIEVEMENT, "INSERT INTO guild_achievement (guildId, achievement, date, guids) VALUES (?, ?, ?, ?)", CONNECTION_SYNCH)
+ PREPARE_STATEMENT(CHAR_DEL_GUILD_ACHIEVEMENT_CRITERIA, "DELETE FROM guild_achievement_progress WHERE guildId = ? AND criteria = ?", CONNECTION_SYNCH)
+ PREPARE_STATEMENT(CHAR_INS_GUILD_ACHIEVEMENT_CRITERIA, "INSERT INTO guild_achievement_progress (guildId, criteria, counter, date, completedGuid) VALUES (?, ?, ?, ?, ?)", CONNECTION_SYNCH)
+ PREPARE_STATEMENT(CHAR_DEL_ALL_GUILD_ACHIEVEMENTS, "DELETE FROM guild_achievement WHERE guildId = ?", CONNECTION_SYNCH)
+ PREPARE_STATEMENT(CHAR_DEL_ALL_GUILD_ACHIEVEMENT_CRITERIA, "DELETE FROM guild_achievement_progress WHERE guildId = ?", CONNECTION_SYNCH)
+ PREPARE_STATEMENT(CHAR_SEL_GUILD_ACHIEVEMENT, "SELECT achievement, date, guids FROM guild_achievement WHERE guildId = ?", CONNECTION_SYNCH)
+ PREPARE_STATEMENT(CHAR_SEL_GUILD_ACHIEVEMENT_CRITERIA, "SELECT criteria, counter, date, completedGuid FROM guild_achievement_progress WHERE guildId = ?", CONNECTION_SYNCH)
// Chat channel handling
PREPARE_STATEMENT(CHAR_SEL_CHANNEL, "SELECT announce, ownership, password, bannedList FROM channels WHERE name = ? AND team = ?", CONNECTION_SYNCH)
diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.h b/src/server/shared/Database/Implementation/CharacterDatabase.h
index 08265c455d6..adaa4acf7c5 100755
--- a/src/server/shared/Database/Implementation/CharacterDatabase.h
+++ b/src/server/shared/Database/Implementation/CharacterDatabase.h
@@ -222,6 +222,14 @@ enum CharacterDatabaseStatements
CHAR_UPD_GUILD_RANK_BANK_TIME4,
CHAR_UPD_GUILD_RANK_BANK_TIME5,
CHAR_SEL_CHAR_DATA_FOR_GUILD,
+ CHAR_DEL_GUILD_ACHIEVEMENT,
+ CHAR_INS_GUILD_ACHIEVEMENT,
+ CHAR_DEL_GUILD_ACHIEVEMENT_CRITERIA,
+ CHAR_INS_GUILD_ACHIEVEMENT_CRITERIA,
+ CHAR_DEL_ALL_GUILD_ACHIEVEMENTS,
+ CHAR_DEL_ALL_GUILD_ACHIEVEMENT_CRITERIA,
+ CHAR_SEL_GUILD_ACHIEVEMENT,
+ CHAR_SEL_GUILD_ACHIEVEMENT_CRITERIA,
CHAR_SEL_CHANNEL,
CHAR_INS_CHANNEL,
diff --git a/src/server/shared/Packets/ByteBuffer.h b/src/server/shared/Packets/ByteBuffer.h
index 27d5e78bac5..b78d78c69f2 100755
--- a/src/server/shared/Packets/ByteBuffer.h
+++ b/src/server/shared/Packets/ByteBuffer.h
@@ -234,7 +234,7 @@ class ByteBuffer
if (!bit)
byte = 0;
else
- byte = ReadUInt8() ^ bit;
+ byte = uint8(ReadUInt8() ^ bit);
}
void WriteByteMask(uint8 b)