From f1d31643fc33c559b5a1f6ca16a0b875099d0479 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Mon, 9 Mar 2026 16:55:23 -0700 Subject: [PATCH] Implement SMSG_SPELLENERGIZELOG and fix missing combat text cases MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Parse SPELLENERGIZELOG (victim/caster packed GUIDs + spellId + powerType + amount) and emit ENERGIZE combat text for mana/energy gains. Add ENERGIZE to CombatTextEntry::Type enum (blue +N text). Also add explicit renderCombatText cases for BLOCK, PERIODIC_DAMAGE, PERIODIC_HEAL, and ENVIRONMENTAL — previously all fell through to the colourless default handler. --- include/game/spell_defines.hpp | 3 ++- src/game/game_handler.cpp | 19 ++++++++++++++++++- src/ui/game_screen.cpp | 23 +++++++++++++++++++++++ 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/include/game/spell_defines.hpp b/include/game/spell_defines.hpp index cf0e7ea9..dd563f9b 100644 --- a/include/game/spell_defines.hpp +++ b/include/game/spell_defines.hpp @@ -50,7 +50,8 @@ struct ActionBarSlot { struct CombatTextEntry { enum Type : uint8_t { MELEE_DAMAGE, SPELL_DAMAGE, HEAL, MISS, DODGE, PARRY, BLOCK, - CRIT_DAMAGE, CRIT_HEAL, PERIODIC_DAMAGE, PERIODIC_HEAL, ENVIRONMENTAL + CRIT_DAMAGE, CRIT_HEAL, PERIODIC_DAMAGE, PERIODIC_HEAL, ENVIRONMENTAL, + ENERGIZE }; Type type; int32_t amount = 0; diff --git a/src/game/game_handler.cpp b/src/game/game_handler.cpp index 71458a91..c8862538 100644 --- a/src/game/game_handler.cpp +++ b/src/game/game_handler.cpp @@ -3067,7 +3067,24 @@ void GameHandler::handlePacket(network::Packet& packet) { packet.setReadPos(packet.getSize()); break; } - case Opcode::SMSG_SPELLENERGIZELOG: + case Opcode::SMSG_SPELLENERGIZELOG: { + // packed victim GUID, packed caster GUID, uint32 spellId, uint8 powerType, int32 amount + size_t rem = packet.getSize() - packet.getReadPos(); + if (rem < 4) { packet.setReadPos(packet.getSize()); break; } + uint64_t victimGuid = UpdateObjectParser::readPackedGuid(packet); + uint64_t casterGuid = UpdateObjectParser::readPackedGuid(packet); + rem = packet.getSize() - packet.getReadPos(); + if (rem < 6) { packet.setReadPos(packet.getSize()); break; } + uint32_t spellId = packet.readUInt32(); + /*uint8_t powerType =*/ packet.readUInt8(); + int32_t amount = static_cast(packet.readUInt32()); + bool isPlayerVictim = (victimGuid == playerGuid); + bool isPlayerCaster = (casterGuid == playerGuid); + if ((isPlayerVictim || isPlayerCaster) && amount > 0) + addCombatText(CombatTextEntry::ENERGIZE, amount, spellId, isPlayerCaster); + packet.setReadPos(packet.getSize()); + break; + } case Opcode::SMSG_ENVIRONMENTAL_DAMAGE_LOG: case Opcode::SMSG_SET_PROFICIENCY: packet.setReadPos(packet.getSize()); diff --git a/src/ui/game_screen.cpp b/src/ui/game_screen.cpp index 14fc2324..04550cc7 100644 --- a/src/ui/game_screen.cpp +++ b/src/ui/game_screen.cpp @@ -4470,6 +4470,29 @@ void GameScreen::renderCombatText(game::GameHandler& gameHandler) { color = outgoing ? ImVec4(0.6f, 0.6f, 0.6f, alpha) : ImVec4(0.4f, 0.9f, 1.0f, alpha); break; + case game::CombatTextEntry::BLOCK: + snprintf(text, sizeof(text), outgoing ? "Block" : "You Block"); + color = outgoing ? ImVec4(0.6f, 0.6f, 0.6f, alpha) + : ImVec4(0.4f, 0.9f, 1.0f, alpha); + break; + case game::CombatTextEntry::PERIODIC_DAMAGE: + snprintf(text, sizeof(text), "-%d", entry.amount); + color = outgoing ? + ImVec4(1.0f, 0.9f, 0.3f, alpha) : // Outgoing DoT = pale yellow + ImVec4(1.0f, 0.4f, 0.4f, alpha); // Incoming DoT = pale red + break; + case game::CombatTextEntry::PERIODIC_HEAL: + snprintf(text, sizeof(text), "+%d", entry.amount); + color = ImVec4(0.4f, 1.0f, 0.5f, alpha); + break; + case game::CombatTextEntry::ENVIRONMENTAL: + snprintf(text, sizeof(text), "-%d", entry.amount); + color = ImVec4(0.9f, 0.5f, 0.2f, alpha); // Orange for environmental + break; + case game::CombatTextEntry::ENERGIZE: + snprintf(text, sizeof(text), "+%d", entry.amount); + color = ImVec4(0.3f, 0.6f, 1.0f, alpha); // Blue for mana/energy + break; default: snprintf(text, sizeof(text), "%d", entry.amount); color = ImVec4(1.0f, 1.0f, 1.0f, alpha);