Handle SMSG_ACHIEVEMENT_EARNED with toast banner and chat notification

- Parse SMSG_ACHIEVEMENT_EARNED (guid + achievementId + PackedTime date)
  and fire AchievementEarnedCallback for self, chat notify for others
- Add renderAchievementToast() to GameScreen: slides in from right,
  gold-bordered panel with "Achievement Earned!" title + ID, 5s duration
  with 0.4s slide-in/out animation and fade at end
- Add triggerAchievementToast(uint32_t) public method on GameScreen
- Wire AchievementEarnedCallback in application.cpp
- Add playAchievementAlert() to UiSoundManager, loads
  Sound\Interface\AchievementSound.wav with level-up fallback
- SMSG_ALL_ACHIEVEMENT_DATA silently consumed (no tracker UI yet)
This commit is contained in:
Kelsi 2026-03-09 13:53:42 -07:00
parent 200a00d4f5
commit e4f53ce0c3
7 changed files with 159 additions and 0 deletions

View file

@ -67,6 +67,9 @@ public:
// Level up
void playLevelUp();
// Achievement
void playAchievementAlert();
// Error/feedback
void playError();
void playTargetSelect();
@ -114,6 +117,7 @@ private:
std::vector<UISample> drinkingSounds_;
std::vector<UISample> levelUpSounds_;
std::vector<UISample> achievementSounds_;
std::vector<UISample> errorSounds_;
std::vector<UISample> selectTargetSounds_;

View file

@ -834,6 +834,10 @@ public:
using OtherPlayerLevelUpCallback = std::function<void(uint64_t guid, uint32_t newLevel)>;
void setOtherPlayerLevelUpCallback(OtherPlayerLevelUpCallback cb) { otherPlayerLevelUpCallback_ = std::move(cb); }
// Achievement earned callback — fires when SMSG_ACHIEVEMENT_EARNED is received
using AchievementEarnedCallback = std::function<void(uint32_t achievementId)>;
void setAchievementEarnedCallback(AchievementEarnedCallback cb) { achievementEarnedCallback_ = std::move(cb); }
// Mount state
using MountCallback = std::function<void(uint32_t mountDisplayId)>; // 0 = dismount
void setMountCallback(MountCallback cb) { mountCallback_ = std::move(cb); }
@ -1166,6 +1170,7 @@ private:
void handleSpellGo(network::Packet& packet);
void handleSpellCooldown(network::Packet& packet);
void handleCooldownEvent(network::Packet& packet);
void handleAchievementEarned(network::Packet& packet);
void handleAuraUpdate(network::Packet& packet, bool isAll);
void handleLearnedSpell(network::Packet& packet);
void handleSupercededSpell(network::Packet& packet);
@ -1873,6 +1878,7 @@ private:
ChargeCallback chargeCallback_;
LevelUpCallback levelUpCallback_;
OtherPlayerLevelUpCallback otherPlayerLevelUpCallback_;
AchievementEarnedCallback achievementEarnedCallback_;
MountCallback mountCallback_;
TaxiPrecacheCallback taxiPrecacheCallback_;
TaxiOrientationCallback taxiOrientationCallback_;

View file

@ -326,8 +326,15 @@ private:
uint32_t dingLevel_ = 0;
void renderDingEffect();
// Achievement toast banner
static constexpr float ACHIEVEMENT_TOAST_DURATION = 5.0f;
float achievementToastTimer_ = 0.0f;
uint32_t achievementToastId_ = 0;
void renderAchievementToast();
public:
void triggerDing(uint32_t newLevel);
void triggerAchievementToast(uint32_t achievementId);
};
} // namespace ui