mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +00:00
feat: add PvP honor credit toast on honorable kill
SMSG_PVP_CREDIT previously only wrote a system chat message. Now it also fires a new PvpHonorCallback, which game_screen.cpp uses to push a compact dark-red toast at the top-right of the screen showing "⚔ +N Honor" with a 3.5 s lifetime and smooth fade in/out.
This commit is contained in:
parent
59fc7cebaf
commit
129fa84fe3
4 changed files with 97 additions and 0 deletions
|
|
@ -1490,6 +1490,10 @@ public:
|
|||
using RepChangeCallback = std::function<void(const std::string& factionName, int32_t delta, int32_t standing)>;
|
||||
void setRepChangeCallback(RepChangeCallback cb) { repChangeCallback_ = std::move(cb); }
|
||||
|
||||
// PvP honor credit callback (honorable kill or BG reward)
|
||||
using PvpHonorCallback = std::function<void(uint32_t honorAmount, uint64_t victimGuid, uint32_t victimRank)>;
|
||||
void setPvpHonorCallback(PvpHonorCallback cb) { pvpHonorCallback_ = std::move(cb); }
|
||||
|
||||
// Quest turn-in completion callback
|
||||
using QuestCompleteCallback = std::function<void(uint32_t questId, const std::string& questTitle)>;
|
||||
void setQuestCompleteCallback(QuestCompleteCallback cb) { questCompleteCallback_ = std::move(cb); }
|
||||
|
|
@ -2831,6 +2835,9 @@ private:
|
|||
RepChangeCallback repChangeCallback_;
|
||||
uint32_t watchedFactionId_ = 0; // auto-set to most recently changed faction
|
||||
|
||||
// ---- PvP honor credit callback ----
|
||||
PvpHonorCallback pvpHonorCallback_;
|
||||
|
||||
// ---- Quest completion callback ----
|
||||
QuestCompleteCallback questCompleteCallback_;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -563,6 +563,17 @@ private:
|
|||
bool otherPlayerLevelUpCallbackSet_ = false;
|
||||
void renderPlayerLevelUpToasts(game::GameHandler& gameHandler);
|
||||
|
||||
// PvP honor credit toast ("+N Honor" shown when an honorable kill is credited)
|
||||
struct PvpHonorToastEntry {
|
||||
uint32_t honor = 0;
|
||||
uint32_t victimRank = 0; // 0 = unranked / not available
|
||||
float age = 0.0f;
|
||||
};
|
||||
static constexpr float PVP_HONOR_TOAST_DURATION = 3.5f;
|
||||
std::vector<PvpHonorToastEntry> pvpHonorToasts_;
|
||||
bool pvpHonorCallbackSet_ = false;
|
||||
void renderPvpHonorToasts();
|
||||
|
||||
// Zone discovery text ("Entering: <ZoneName>")
|
||||
static constexpr float ZONE_TEXT_DURATION = 5.0f;
|
||||
float zoneTextTimer_ = 0.0f;
|
||||
|
|
|
|||
|
|
@ -1882,6 +1882,9 @@ void GameHandler::handlePacket(network::Packet& packet) {
|
|||
std::dec, " rank=", rank);
|
||||
std::string msg = "You gain " + std::to_string(honor) + " honor points.";
|
||||
addSystemChatMessage(msg);
|
||||
if (pvpHonorCallback_) {
|
||||
pvpHonorCallback_(honor, victimGuid, rank);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -348,6 +348,17 @@ void GameScreen::render(game::GameHandler& gameHandler) {
|
|||
otherPlayerLevelUpCallbackSet_ = true;
|
||||
}
|
||||
|
||||
// Set up PvP honor credit toast callback (once)
|
||||
if (!pvpHonorCallbackSet_) {
|
||||
gameHandler.setPvpHonorCallback([this](uint32_t honor, uint64_t /*victimGuid*/, uint32_t rank) {
|
||||
if (honor == 0) return;
|
||||
pvpHonorToasts_.push_back({honor, rank, 0.0f});
|
||||
if (pvpHonorToasts_.size() > 4)
|
||||
pvpHonorToasts_.erase(pvpHonorToasts_.begin());
|
||||
});
|
||||
pvpHonorCallbackSet_ = true;
|
||||
}
|
||||
|
||||
// Set up UI error frame callback (once)
|
||||
if (!uiErrorCallbackSet_) {
|
||||
gameHandler.setUIErrorCallback([this](const std::string& msg) {
|
||||
|
|
@ -680,6 +691,7 @@ void GameScreen::render(game::GameHandler& gameHandler) {
|
|||
renderWhisperToasts();
|
||||
renderQuestProgressToasts();
|
||||
renderPlayerLevelUpToasts(gameHandler);
|
||||
renderPvpHonorToasts();
|
||||
renderZoneText();
|
||||
|
||||
// World map (M key toggle handled inside)
|
||||
|
|
@ -18214,6 +18226,70 @@ void GameScreen::renderQuestProgressToasts() {
|
|||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// PvP honor credit toasts — shown at screen top-right on honorable kill
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
void GameScreen::renderPvpHonorToasts() {
|
||||
if (pvpHonorToasts_.empty()) return;
|
||||
|
||||
float dt = ImGui::GetIO().DeltaTime;
|
||||
for (auto& t : pvpHonorToasts_) t.age += dt;
|
||||
pvpHonorToasts_.erase(
|
||||
std::remove_if(pvpHonorToasts_.begin(), pvpHonorToasts_.end(),
|
||||
[](const PvpHonorToastEntry& t) { return t.age >= PVP_HONOR_TOAST_DURATION; }),
|
||||
pvpHonorToasts_.end());
|
||||
if (pvpHonorToasts_.empty()) return;
|
||||
|
||||
ImVec2 displaySize = ImGui::GetIO().DisplaySize;
|
||||
float screenW = displaySize.x > 0.0f ? displaySize.x : 1280.0f;
|
||||
|
||||
// Stack toasts at top-right, below any minimap area
|
||||
constexpr float TOAST_W = 180.0f;
|
||||
constexpr float TOAST_H = 30.0f;
|
||||
constexpr float TOAST_GAP = 3.0f;
|
||||
constexpr float TOAST_TOP = 10.0f;
|
||||
float toastX = screenW - TOAST_W - 10.0f;
|
||||
|
||||
ImDrawList* bgDL = ImGui::GetBackgroundDrawList();
|
||||
const int count = static_cast<int>(pvpHonorToasts_.size());
|
||||
|
||||
for (int i = 0; i < count; ++i) {
|
||||
const auto& toast = pvpHonorToasts_[i];
|
||||
|
||||
float remaining = PVP_HONOR_TOAST_DURATION - toast.age;
|
||||
float alpha;
|
||||
if (toast.age < 0.15f)
|
||||
alpha = toast.age / 0.15f;
|
||||
else if (remaining < 0.8f)
|
||||
alpha = remaining / 0.8f;
|
||||
else
|
||||
alpha = 1.0f;
|
||||
alpha = std::clamp(alpha, 0.0f, 1.0f);
|
||||
|
||||
float ty = TOAST_TOP + i * (TOAST_H + TOAST_GAP);
|
||||
|
||||
uint8_t bgA = static_cast<uint8_t>(190 * alpha);
|
||||
uint8_t fgA = static_cast<uint8_t>(255 * alpha);
|
||||
|
||||
// Background: dark red (PvP theme)
|
||||
bgDL->AddRectFilled(ImVec2(toastX, ty), ImVec2(toastX + TOAST_W, ty + TOAST_H),
|
||||
IM_COL32(28, 5, 5, bgA), 4.0f);
|
||||
bgDL->AddRect(ImVec2(toastX, ty), ImVec2(toastX + TOAST_W, ty + TOAST_H),
|
||||
IM_COL32(200, 50, 50, static_cast<uint8_t>(160 * alpha)), 4.0f, 0, 1.2f);
|
||||
|
||||
// Sword ⚔ icon (U+2694, UTF-8: e2 9a 94)
|
||||
bgDL->AddText(ImVec2(toastX + 7.0f, ty + 7.0f),
|
||||
IM_COL32(220, 80, 80, fgA), "\xe2\x9a\x94");
|
||||
|
||||
// "+N Honor" text in gold
|
||||
char buf[40];
|
||||
snprintf(buf, sizeof(buf), "+%u Honor", toast.honor);
|
||||
bgDL->AddText(ImVec2(toastX + 24.0f, ty + 8.0f),
|
||||
IM_COL32(255, 210, 50, fgA), buf);
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Nearby player level-up toasts — shown at screen bottom-centre
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue