mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +00:00
feat: show area discovery toast with XP gain when exploring new zones
This commit is contained in:
parent
98ad71df0d
commit
77879769d3
4 changed files with 99 additions and 0 deletions
|
|
@ -1428,6 +1428,10 @@ public:
|
|||
using AchievementEarnedCallback = std::function<void(uint32_t achievementId, const std::string& name)>;
|
||||
void setAchievementEarnedCallback(AchievementEarnedCallback cb) { achievementEarnedCallback_ = std::move(cb); }
|
||||
const std::unordered_set<uint32_t>& getEarnedAchievements() const { return earnedAchievements_; }
|
||||
|
||||
// Area discovery callback — fires when SMSG_EXPLORATION_EXPERIENCE is received
|
||||
using AreaDiscoveryCallback = std::function<void(const std::string& areaName, uint32_t xpGained)>;
|
||||
void setAreaDiscoveryCallback(AreaDiscoveryCallback cb) { areaDiscoveryCallback_ = std::move(cb); }
|
||||
const std::unordered_map<uint32_t, uint64_t>& getCriteriaProgress() const { return criteriaProgress_; }
|
||||
/// Returns the WoW PackedTime earn date for an achievement, or 0 if unknown.
|
||||
uint32_t getAchievementDate(uint32_t id) const {
|
||||
|
|
@ -2749,6 +2753,7 @@ private:
|
|||
LevelUpCallback levelUpCallback_;
|
||||
OtherPlayerLevelUpCallback otherPlayerLevelUpCallback_;
|
||||
AchievementEarnedCallback achievementEarnedCallback_;
|
||||
AreaDiscoveryCallback areaDiscoveryCallback_;
|
||||
MountCallback mountCallback_;
|
||||
TaxiPrecacheCallback taxiPrecacheCallback_;
|
||||
TaxiOrientationCallback taxiOrientationCallback_;
|
||||
|
|
|
|||
|
|
@ -519,6 +519,14 @@ private:
|
|||
std::string achievementToastName_;
|
||||
void renderAchievementToast();
|
||||
|
||||
// Area discovery toast ("Discovered! <AreaName> +XP XP")
|
||||
static constexpr float DISCOVERY_TOAST_DURATION = 4.0f;
|
||||
float discoveryToastTimer_ = 0.0f;
|
||||
std::string discoveryToastName_;
|
||||
uint32_t discoveryToastXP_ = 0;
|
||||
bool areaDiscoveryCallbackSet_ = false;
|
||||
void renderDiscoveryToast();
|
||||
|
||||
// Zone discovery text ("Entering: <ZoneName>")
|
||||
static constexpr float ZONE_TEXT_DURATION = 5.0f;
|
||||
float zoneTextTimer_ = 0.0f;
|
||||
|
|
|
|||
|
|
@ -1767,6 +1767,8 @@ void GameHandler::handlePacket(network::Packet& packet) {
|
|||
}
|
||||
addSystemChatMessage(msg);
|
||||
// XP is updated via PLAYER_XP update fields from the server.
|
||||
if (areaDiscoveryCallback_)
|
||||
areaDiscoveryCallback_(areaName, xpGained);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -300,6 +300,16 @@ void GameScreen::render(game::GameHandler& gameHandler) {
|
|||
achievementCallbackSet_ = true;
|
||||
}
|
||||
|
||||
// Set up area discovery toast callback (once)
|
||||
if (!areaDiscoveryCallbackSet_) {
|
||||
gameHandler.setAreaDiscoveryCallback([this](const std::string& areaName, uint32_t xpGained) {
|
||||
discoveryToastName_ = areaName.empty() ? "New Area" : areaName;
|
||||
discoveryToastXP_ = xpGained;
|
||||
discoveryToastTimer_ = DISCOVERY_TOAST_DURATION;
|
||||
});
|
||||
areaDiscoveryCallbackSet_ = true;
|
||||
}
|
||||
|
||||
// Set up UI error frame callback (once)
|
||||
if (!uiErrorCallbackSet_) {
|
||||
gameHandler.setUIErrorCallback([this](const std::string& msg) {
|
||||
|
|
@ -628,6 +638,7 @@ void GameScreen::render(game::GameHandler& gameHandler) {
|
|||
renderSettingsWindow();
|
||||
renderDingEffect();
|
||||
renderAchievementToast();
|
||||
renderDiscoveryToast();
|
||||
renderZoneText();
|
||||
|
||||
// World map (M key toggle handled inside)
|
||||
|
|
@ -17927,6 +17938,79 @@ void GameScreen::renderAchievementToast() {
|
|||
IM_COL32(220, 200, 150, (int)(alpha * 255)), idBuf);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Area discovery toast — "Discovered: <AreaName>! (+XP XP)" centered on screen
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
void GameScreen::renderDiscoveryToast() {
|
||||
if (discoveryToastTimer_ <= 0.0f) return;
|
||||
|
||||
float dt = ImGui::GetIO().DeltaTime;
|
||||
discoveryToastTimer_ -= dt;
|
||||
if (discoveryToastTimer_ < 0.0f) discoveryToastTimer_ = 0.0f;
|
||||
|
||||
// Fade: ramp up in first 0.4s, hold, fade out in last 1.0s
|
||||
float alpha;
|
||||
if (discoveryToastTimer_ > DISCOVERY_TOAST_DURATION - 0.4f)
|
||||
alpha = 1.0f - (discoveryToastTimer_ - (DISCOVERY_TOAST_DURATION - 0.4f)) / 0.4f;
|
||||
else if (discoveryToastTimer_ < 1.0f)
|
||||
alpha = discoveryToastTimer_;
|
||||
else
|
||||
alpha = 1.0f;
|
||||
alpha = std::clamp(alpha, 0.0f, 1.0f);
|
||||
|
||||
auto* window = core::Application::getInstance().getWindow();
|
||||
float screenW = window ? static_cast<float>(window->getWidth()) : 1280.0f;
|
||||
float screenH = window ? static_cast<float>(window->getHeight()) : 720.0f;
|
||||
|
||||
ImFont* font = ImGui::GetFont();
|
||||
ImDrawList* draw = ImGui::GetForegroundDrawList();
|
||||
|
||||
const char* header = "Discovered!";
|
||||
float headerSize = 16.0f;
|
||||
float nameSize = 28.0f;
|
||||
float xpSize = 14.0f;
|
||||
|
||||
ImVec2 headerDim = font->CalcTextSizeA(headerSize, FLT_MAX, 0.0f, header);
|
||||
ImVec2 nameDim = font->CalcTextSizeA(nameSize, FLT_MAX, 0.0f, discoveryToastName_.c_str());
|
||||
|
||||
char xpBuf[48];
|
||||
if (discoveryToastXP_ > 0)
|
||||
snprintf(xpBuf, sizeof(xpBuf), "+%u XP", discoveryToastXP_);
|
||||
else
|
||||
xpBuf[0] = '\0';
|
||||
ImVec2 xpDim = font->CalcTextSizeA(xpSize, FLT_MAX, 0.0f, xpBuf);
|
||||
|
||||
// Position slightly below zone text (at 37% down screen)
|
||||
float centreY = screenH * 0.37f;
|
||||
float headerX = (screenW - headerDim.x) * 0.5f;
|
||||
float nameX = (screenW - nameDim.x) * 0.5f;
|
||||
float xpX = (screenW - xpDim.x) * 0.5f;
|
||||
float headerY = centreY;
|
||||
float nameY = centreY + headerDim.y + 4.0f;
|
||||
float xpY = nameY + nameDim.y + 4.0f;
|
||||
|
||||
// "Discovered!" in gold
|
||||
draw->AddText(font, headerSize, ImVec2(headerX + 1, headerY + 1),
|
||||
IM_COL32(0, 0, 0, (int)(alpha * 160)), header);
|
||||
draw->AddText(font, headerSize, ImVec2(headerX, headerY),
|
||||
IM_COL32(255, 215, 0, (int)(alpha * 255)), header);
|
||||
|
||||
// Area name in white
|
||||
draw->AddText(font, nameSize, ImVec2(nameX + 1, nameY + 1),
|
||||
IM_COL32(0, 0, 0, (int)(alpha * 160)), discoveryToastName_.c_str());
|
||||
draw->AddText(font, nameSize, ImVec2(nameX, nameY),
|
||||
IM_COL32(255, 255, 255, (int)(alpha * 255)), discoveryToastName_.c_str());
|
||||
|
||||
// XP gain in light green (if any)
|
||||
if (xpBuf[0] != '\0') {
|
||||
draw->AddText(font, xpSize, ImVec2(xpX + 1, xpY + 1),
|
||||
IM_COL32(0, 0, 0, (int)(alpha * 140)), xpBuf);
|
||||
draw->AddText(font, xpSize, ImVec2(xpX, xpY),
|
||||
IM_COL32(100, 220, 100, (int)(alpha * 230)), xpBuf);
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Zone discovery text — "Entering: <ZoneName>" fades in/out at screen centre
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue