feat: fire PLAYER_TARGET_CHANGED and PLAYER_LEVEL_UP addon events

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).
This commit is contained in:
Kelsi 2026-03-20 11:51:46 -07:00
parent c284a971c2
commit 269d9e2d40
3 changed files with 14 additions and 0 deletions

View file

@ -283,6 +283,10 @@ public:
using AddonChatCallback = std::function<void(const MessageChatData&)>;
void setAddonChatCallback(AddonChatCallback cb) { addonChatCallback_ = std::move(cb); }
// Generic addon event callback: fires named events with string args
using AddonEventCallback = std::function<void(const std::string&, const std::vector<std::string>&)>;
void setAddonEventCallback(AddonEventCallback cb) { addonEventCallback_ = std::move(cb); }
// Emote animation callback: (entityGuid, animationId)
using EmoteAnimCallback = std::function<void(uint64_t, uint32_t)>;
void setEmoteAnimCallback(EmoteAnimCallback cb) { emoteAnimCallback_ = std::move(cb); }
@ -2639,6 +2643,7 @@ private:
std::vector<std::string> joinedChannels_; // Active channel memberships
ChatBubbleCallback chatBubbleCallback_;
AddonChatCallback addonChatCallback_;
AddonEventCallback addonEventCallback_;
EmoteAnimCallback emoteAnimCallback_;
// Targeting

View file

@ -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<std::string>& 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");

View file

@ -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;