From 269d9e2d4070a2c1769bed7ad167f7ff7a151d78 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Fri, 20 Mar 2026 11:51:46 -0700 Subject: [PATCH] feat: fire PLAYER_TARGET_CHANGED and PLAYER_LEVEL_UP addon events MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a generic AddonEventCallback to GameHandler for firing named events with string arguments directly from game logic. Wire it to the addon system in Application. New events fired: - PLAYER_TARGET_CHANGED — when target is set or cleared - PLAYER_LEVEL_UP(newLevel) — on level up The generic callback pattern makes it easy to add more events from game_handler.cpp without touching Application/AddonManager code. Total addon events: 16 (2 world + 12 chat + 2 gameplay). --- include/game/game_handler.hpp | 5 +++++ src/core/application.cpp | 6 ++++++ src/game/game_handler.cpp | 3 +++ 3 files changed, 14 insertions(+) diff --git a/include/game/game_handler.hpp b/include/game/game_handler.hpp index 70510727..7270e365 100644 --- a/include/game/game_handler.hpp +++ b/include/game/game_handler.hpp @@ -283,6 +283,10 @@ public: using AddonChatCallback = std::function; void setAddonChatCallback(AddonChatCallback cb) { addonChatCallback_ = std::move(cb); } + // Generic addon event callback: fires named events with string args + using AddonEventCallback = std::function&)>; + void setAddonEventCallback(AddonEventCallback cb) { addonEventCallback_ = std::move(cb); } + // Emote animation callback: (entityGuid, animationId) using EmoteAnimCallback = std::function; void setEmoteAnimCallback(EmoteAnimCallback cb) { emoteAnimCallback_ = std::move(cb); } @@ -2639,6 +2643,7 @@ private: std::vector joinedChannels_; // Active channel memberships ChatBubbleCallback chatBubbleCallback_; AddonChatCallback addonChatCallback_; + AddonEventCallback addonEventCallback_; EmoteAnimCallback emoteAnimCallback_; // Targeting diff --git a/src/core/application.cpp b/src/core/application.cpp index 38f0b2a2..33b92f25 100644 --- a/src/core/application.cpp +++ b/src/core/application.cpp @@ -360,6 +360,12 @@ bool Application::initialize() { addonManager_->fireEvent(eventName, {msg.message, msg.senderName}); } }); + // Wire generic game events to addon dispatch + gameHandler->setAddonEventCallback([this](const std::string& event, const std::vector& args) { + if (addonManager_ && addonsLoaded_) { + addonManager_->fireEvent(event, args); + } + }); LOG_INFO("Addon system initialized, found ", addonManager_->getAddons().size(), " addon(s)"); } else { LOG_WARNING("Failed to initialize addon system"); diff --git a/src/game/game_handler.cpp b/src/game/game_handler.cpp index 6b95a64c..7710d80f 100644 --- a/src/game/game_handler.cpp +++ b/src/game/game_handler.cpp @@ -4557,6 +4557,7 @@ void GameHandler::handlePacket(network::Packet& packet) { sfx->playLevelUp(); } if (levelUpCallback_) levelUpCallback_(newLevel); + if (addonEventCallback_) addonEventCallback_("PLAYER_LEVEL_UP", {std::to_string(newLevel)}); } } } @@ -13332,11 +13333,13 @@ void GameHandler::setTarget(uint64_t guid) { if (guid != 0) { LOG_INFO("Target set: 0x", std::hex, guid, std::dec); } + if (addonEventCallback_) addonEventCallback_("PLAYER_TARGET_CHANGED", {}); } void GameHandler::clearTarget() { if (targetGuid != 0) { LOG_INFO("Target cleared"); + if (addonEventCallback_) addonEventCallback_("PLAYER_TARGET_CHANGED", {}); } targetGuid = 0; tabCycleIndex = -1;