From e9470f65b92f0e7fe4d749c105019ff2cf4100a5 Mon Sep 17 00:00:00 2001 From: arrai Date: Tue, 28 Oct 2008 22:15:41 +0100 Subject: [PATCH] Fixed several achievement related packets --- src/game/AchievementMgr.cpp | 112 ++++++++++++++++++++++++++++++++++++-------- src/game/AchievementMgr.h | 11 +++-- src/game/Player.cpp | 7 +-- 3 files changed, 104 insertions(+), 26 deletions(-) diff --git a/src/game/AchievementMgr.cpp b/src/game/AchievementMgr.cpp index c490c9dd8..67c1932ef 100644 --- a/src/game/AchievementMgr.cpp +++ b/src/game/AchievementMgr.cpp @@ -22,6 +22,7 @@ #include "WorldPacket.h" #include "Database/DBCEnums.h" #include "ObjectMgr.h" +#include "Guild.h" AchievementMgr::AchievementMgr(Player *player) { @@ -41,23 +42,40 @@ void AchievementMgr::LoadFromDB() void AchievementMgr::SendAchievementEarned(uint32 achievementId) { sLog.outString("AchievementMgr::SendAchievementEarned(%u)", achievementId); + WorldPacket data(SMSG_MESSAGECHAT, 200); data << uint8(CHAT_MSG_ACHIEVEMENT); data << uint32(LANG_UNIVERSAL); data << uint64(GetPlayer()->GetGUID()); - data << uint32(0); + data << uint32(5); data << uint64(GetPlayer()->GetGUID()); const char *msg = "|Hplayer:$N|h[$N]|h has earned the achievement $a!"; - data << uint32(strlen(msg)); + data << uint32(strlen(msg)+1); data << msg; data << uint8(0); data << uint32(achievementId); GetPlayer()->SendMessageToSet(&data, true); + if(Guild* guild = objmgr.GetGuildById(GetPlayer()->GetGuildId())) + { + data.Initialize(SMSG_MESSAGECHAT, 200); + data << uint8(CHAT_MSG_GUILD_ACHIEVEMENT); + data << uint32(LANG_UNIVERSAL); + data << uint64(GetPlayer()->GetGUID()); + data << uint32(5); + data << uint64(GetPlayer()->GetGUID()); + data << uint32(strlen(msg)+1); + data << msg; + data << uint8(0); + data << uint32(achievementId); + guild->BroadcastPacket(&data); + } + data.Initialize(SMSG_ACHIEVEMENT_EARNED, 8+4+8); data.append(GetPlayer()->GetPackGUID()); data << uint32(achievementId); - data << uint64(0x0000000); // magic number? same as in SMSG_CRITERIA_UPDATE. static for every player? + data << uint32(secsToTimeBitFields(time(NULL))); + data << uint32(0); GetPlayer()->SendMessageToSet(&data, true); } @@ -71,19 +89,24 @@ void AchievementMgr::SendCriteriaUpdate(uint32 criteriaId, uint32 counter) data.appendPackGUID(counter); data.append(GetPlayer()->GetPackGUID()); - /* - data << uint32(counter); - data << uint32(counter+1);//timer1 - data << uint32(counter+2);//timer2 - */ - data << uint32(0); - data << uint32(0); - data << uint32(0); data << uint32(0); + data << uint32(secsToTimeBitFields(time(NULL))); + data << uint32(0); // timer 1 + data << uint32(0); // timer 2 GetPlayer()->SendMessageToSet(&data, true); } /** + * called at player login. The player might have fulfilled some achievements when the achievement system wasn't working yet + */ +void AchievementMgr::CheckAllAchievementCriteria() +{ + // suppress sending packets + for(uint32 i=0; igetLevel()); + break; case ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT: - SetCriteriaProgress(achievementCriteria, miscvalue1); - break; + SetCriteriaProgress(achievementCriteria, GetPlayer()->GetByteValue(PLAYER_BYTES_2, 2)+1); + break; default: return; } @@ -136,24 +161,29 @@ void AchievementMgr::CompletedCriteria(AchievementCriteriaEntry const* criteria) if(achievement->flags & ACHIEVEMENT_FLAG_COUNTER) return; - if(criteria->completionFlag & ACHIEVEMENT_CRITERIA_COMPLETE_FLAG_ALL) + if(criteria->completionFlag & ACHIEVEMENT_CRITERIA_COMPLETE_FLAG_ALL || IsCompletedAchievement(achievement)) { CompletedAchievement(achievement); - return; } +} - // Check if there are also other critiera which have to be fulfilled for that achievement +bool AchievementMgr::IsCompletedAchievement(AchievementEntry const* achievement) +{ + bool foundOutstanding = false; for (uint32 entryId = 0; entryIdreferredAchievement!= achievement->ID) continue; - // found an outstanding criteria, return + if(IsCompletedCriteria(criteria) && criteria->completionFlag & ACHIEVEMENT_CRITERIA_COMPLETE_FLAG_ALL) + return true; + + // found an umcompleted criteria, but DONT return false - there might be a completed criteria with ACHIEVEMENT_CRITERIA_COMPLETE_FLAG_ALL if(!IsCompletedCriteria(criteria)) - return; + foundOutstanding = true; } - CompletedAchievement(achievement); + return !foundOutstanding; } void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint32 newValue) @@ -170,7 +200,49 @@ void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement) return; SendAchievementEarned(achievement->ID); - m_completedAchievements.insert(achievement->ID); + m_completedAchievements[achievement->ID] = time(NULL); // TODO: reward titles and items } +void AchievementMgr::SendAllAchievementData() +{ + // since we don't know the exact size of the packed GUIDs this is just an approximation + WorldPacket data(SMSG_ALL_ACHIEVEMENT_DATA,4*2+m_completedAchievements.size()*4*2+m_completedAchievements.size()*7*4); + BuildAllDataPacket(&data); + GetPlayer()->GetSession()->SendPacket(&data); +} + +void AchievementMgr::SendRespondInspectAchievements(Player* player) +{ + // since we don't know the exact size of the packed GUIDs this is just an approximation + WorldPacket data(SMSG_ALL_ACHIEVEMENT_DATA,4+4*2+m_completedAchievements.size()*4*2+m_completedAchievements.size()*7*4); + data.append(GetPlayer()->GetPackGUID()); + BuildAllDataPacket(&data); + player->GetSession()->SendPacket(&data); +} + +/** + * used by both SMSG_ALL_ACHIEVEMENT_DATA and SMSG_RESPOND_INSPECT_ACHIEVEMENT + */ +void AchievementMgr::BuildAllDataPacket(WorldPacket *data) +{ + for(CompletedAchievementMap::iterator iter = m_completedAchievements.begin(); iter!=m_completedAchievements.end(); ++iter) + { + *data << uint32(iter->first); + *data << uint32(secsToTimeBitFields(iter->second)); + } + *data << int32(-1); + for(CriteriaProgressMap::iterator iter = m_criteriaProgress.begin(); iter!=m_criteriaProgress.end(); ++iter) + { + *data << uint32(iter->first); + data->appendPackGUID(iter->second); + data->append(GetPlayer()->GetPackGUID()); + *data << uint32(0); + *data << uint32(secsToTimeBitFields(time(NULL))); + *data << uint32(0); + *data << uint32(0); + } + *data << int32(-1); + +} + diff --git a/src/game/AchievementMgr.h b/src/game/AchievementMgr.h index a374b7d7c..9dfb03bcc 100644 --- a/src/game/AchievementMgr.h +++ b/src/game/AchievementMgr.h @@ -23,9 +23,10 @@ #include "Database/DBCStores.h" typedef HM_NAMESPACE::hash_map CriteriaProgressMap; -typedef std::set CompletedAchievementSet; +typedef HM_NAMESPACE::hash_map CompletedAchievementMap; class Player; +class WorldPacket; class AchievementMgr { @@ -35,6 +36,9 @@ class AchievementMgr void LoadFromDB(); void SaveToDB(); void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscvalue1=0, uint32 miscvalue2=0, uint32 time=0); + void CheckAllAchievementCriteria(); + void SendAllAchievementData(); + void SendRespondInspectAchievements(Player* player); Player* GetPlayer() { return m_player;} @@ -45,11 +49,12 @@ class AchievementMgr void CompletedCriteria(AchievementCriteriaEntry const* entry); void CompletedAchievement(AchievementEntry const* entry); bool IsCompletedCriteria(AchievementCriteriaEntry const* entry); + bool IsCompletedAchievement(AchievementEntry const* entry); + void BuildAllDataPacket(WorldPacket *data); Player* m_player; CriteriaProgressMap m_criteriaProgress; - CompletedAchievementSet m_completedAchievements; - + CompletedAchievementMap m_completedAchievements; }; diff --git a/src/game/Player.cpp b/src/game/Player.cpp index d17f47657..b4053002c 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -2142,7 +2142,7 @@ void Player::GiveLevel(uint32 level) Pet* pet = GetPet(); if(pet && pet->getPetType()==SUMMON_PET) pet->GivePetLevel(level); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL, level); + GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL); } void Player::InitTalentForLevel() @@ -13971,8 +13971,6 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder ) m_social = sSocialMgr.LoadFromDB(holder->GetResult(PLAYER_LOGIN_QUERY_LOADSOCIALLIST), GetGUIDLow()); - m_achievementMgr.LoadFromDB(); - if(!_LoadHomeBind(holder->GetResult(PLAYER_LOGIN_QUERY_LOADHOMEBIND))) return false; @@ -14090,6 +14088,8 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder ) _LoadDeclinedNames(holder->GetResult(PLAYER_LOGIN_QUERY_LOADDECLINEDNAMES)); + m_achievementMgr.LoadFromDB(); + m_achievementMgr.CheckAllAchievementCriteria(); return true; } @@ -17459,6 +17459,7 @@ void Player::SendInitialPacketsBeforeAddToMap() SendInitialActionButtons(); SendInitialReputations(); + m_achievementMgr.SendAllAchievementData(); UpdateZone(GetZoneId()); SendInitWorldStates(); -- 2.11.4.GIT