diff --git a/src/world/Actor/Player.cpp b/src/world/Actor/Player.cpp index 6f71c033..103b5bb6 100644 --- a/src/world/Actor/Player.cpp +++ b/src/world/Actor/Player.cpp @@ -1323,6 +1323,11 @@ Player::AchievementDataList& Player::getAchievementDataList() return m_achievementData; } +Player::AchievementHistory& Player::getAchievementHistory() +{ + return m_achievementHistory; +} + void Player::setMaxGearSets( uint8_t amount ) { if( amount == 1 ) diff --git a/src/world/Actor/Player.h b/src/world/Actor/Player.h index ed0228a8..dcc0db7c 100644 --- a/src/world/Actor/Player.h +++ b/src/world/Actor/Player.h @@ -27,6 +27,7 @@ namespace Sapphire::Entity public: using AchievementDataList = std::map< uint32_t, uint32_t >; using AchievementList = std::array< uint8_t, 2048 / 8 >; // up to 2048 achievements + using AchievementHistory = std::array< uint16_t, 5 >; using TitleList = std::array< uint8_t, 48 >; using HowToList = std::array< uint8_t, 34 >; using MinionList = std::array< uint8_t, 40 >; @@ -373,6 +374,9 @@ namespace Sapphire::Entity /*! get player's achievement data list */ AchievementDataList& getAchievementDataList(); + /*! get player's achievement data history */ + AchievementHistory& getAchievementHistory(); + /*! set number of gear sets */ void setMaxGearSets( uint8_t amount ); @@ -870,6 +874,7 @@ namespace Sapphire::Entity AchievementList m_achievementList{}; AchievementDataList m_achievementData{}; + AchievementHistory m_achievementHistory{}; uint16_t m_activeTitle{}; TitleList m_titleList{}; HowToList m_howTo{}; diff --git a/src/world/Manager/AchievementMgr.cpp b/src/world/Manager/AchievementMgr.cpp index 495b2012..633ba67c 100644 --- a/src/world/Manager/AchievementMgr.cpp +++ b/src/world/Manager/AchievementMgr.cpp @@ -57,6 +57,13 @@ void AchievementMgr::unlockAchievement( Entity::Player& player, uint32_t achieve player.getAchievementList()[ index ] |= value; + // handle player achievement history + // todo: verify retail behavior due to client copying the last achievement unlocked + /* auto& achvHistory = player.getAchievementHistory(); + + std::rotate( achvHistory.rbegin(), achvHistory.rbegin() + 1, achvHistory.rend() ); + achvHistory[ 0 ] = achievementId;*/ + // fire packets Common::Service< World::Manager::PlayerMgr >::ref().onUnlockAchievement( player, achievementId ); diff --git a/src/world/Manager/PlayerMgr.cpp b/src/world/Manager/PlayerMgr.cpp index 16439b7b..a6d894e9 100644 --- a/src/world/Manager/PlayerMgr.cpp +++ b/src/world/Manager/PlayerMgr.cpp @@ -79,7 +79,8 @@ void PlayerMgr::onSendAchievementList( Entity::Player& player ) auto& server = Common::Service< World::WorldServer >::ref(); auto achvPacket = makeZonePacket< FFXIVIpcAchievement >( player.getId() ); - std::memcpy( &achvPacket->data().complete[ 0 ], &player.getAchievementList()[ 0 ], sizeof( &achvPacket->data().complete ) ); + std::memcpy( &achvPacket->data().complete[ 0 ], &player.getAchievementList()[ 0 ], sizeof( achvPacket->data().complete ) ); + std::memcpy( &achvPacket->data().history[ 0 ], &player.getAchievementHistory()[ 0 ], sizeof( achvPacket->data().history ) ); server.queueForPlayer( player.getCharacterId(), achvPacket ); }