mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +00:00
feat: add party/raid unit IDs and game events for Lua addon system
Extend resolveUnit() to support party1-4, raid1-40, and use resolveUnitGuid for UnitGUID/UnitIsPlayer/UnitBuff/UnitDebuff (including unitAurasCache for party member auras). Fire UNIT_HEALTH, UNIT_POWER, UNIT_AURA, UNIT_SPELLCAST_START, UNIT_SPELLCAST_SUCCEEDED, GROUP_ROSTER_UPDATE, and PARTY_MEMBERS_CHANGED events to Lua addons from the corresponding packet handlers.
This commit is contained in:
parent
22b0cc8a3c
commit
4c10974553
2 changed files with 96 additions and 18 deletions
|
|
@ -68,20 +68,46 @@ static game::Unit* getPlayerUnit(lua_State* L) {
|
|||
return dynamic_cast<game::Unit*>(entity.get());
|
||||
}
|
||||
|
||||
// Helper: resolve "player", "target", "focus", "pet" unit IDs to entity
|
||||
// Helper: resolve WoW unit IDs to GUID
|
||||
static uint64_t resolveUnitGuid(game::GameHandler* gh, const std::string& uid) {
|
||||
if (uid == "player") return gh->getPlayerGuid();
|
||||
if (uid == "target") return gh->getTargetGuid();
|
||||
if (uid == "focus") return gh->getFocusGuid();
|
||||
if (uid == "pet") return gh->getPetGuid();
|
||||
// party1-party4, raid1-raid40
|
||||
if (uid.rfind("party", 0) == 0 && uid.size() > 5) {
|
||||
int idx = 0;
|
||||
try { idx = std::stoi(uid.substr(5)); } catch (...) { return 0; }
|
||||
if (idx < 1 || idx > 4) return 0;
|
||||
const auto& pd = gh->getPartyData();
|
||||
// party members exclude self; index 1-based
|
||||
int found = 0;
|
||||
for (const auto& m : pd.members) {
|
||||
if (m.guid == gh->getPlayerGuid()) continue;
|
||||
if (++found == idx) return m.guid;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (uid.rfind("raid", 0) == 0 && uid.size() > 4 && uid[4] != 'p') {
|
||||
int idx = 0;
|
||||
try { idx = std::stoi(uid.substr(4)); } catch (...) { return 0; }
|
||||
if (idx < 1 || idx > 40) return 0;
|
||||
const auto& pd = gh->getPartyData();
|
||||
if (idx <= static_cast<int>(pd.members.size()))
|
||||
return pd.members[idx - 1].guid;
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Helper: resolve "player", "target", "focus", "pet", "partyN", "raidN" unit IDs to entity
|
||||
static game::Unit* resolveUnit(lua_State* L, const char* unitId) {
|
||||
auto* gh = getGameHandler(L);
|
||||
if (!gh || !unitId) return nullptr;
|
||||
std::string uid(unitId);
|
||||
for (char& c : uid) c = static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
|
||||
|
||||
uint64_t guid = 0;
|
||||
if (uid == "player") guid = gh->getPlayerGuid();
|
||||
else if (uid == "target") guid = gh->getTargetGuid();
|
||||
else if (uid == "focus") guid = gh->getFocusGuid();
|
||||
else if (uid == "pet") guid = gh->getPetGuid();
|
||||
else return nullptr;
|
||||
|
||||
uint64_t guid = resolveUnitGuid(gh, uid);
|
||||
if (guid == 0) return nullptr;
|
||||
auto entity = gh->getEntityManager().getEntity(guid);
|
||||
if (!entity) return nullptr;
|
||||
|
|
@ -250,11 +276,7 @@ static int lua_UnitGUID(lua_State* L) {
|
|||
if (!gh) { lua_pushnil(L); return 1; }
|
||||
std::string uidStr(uid);
|
||||
for (char& c : uidStr) c = static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
|
||||
uint64_t guid = 0;
|
||||
if (uidStr == "player") guid = gh->getPlayerGuid();
|
||||
else if (uidStr == "target") guid = gh->getTargetGuid();
|
||||
else if (uidStr == "focus") guid = gh->getFocusGuid();
|
||||
else if (uidStr == "pet") guid = gh->getPetGuid();
|
||||
uint64_t guid = resolveUnitGuid(gh, uidStr);
|
||||
if (guid == 0) { lua_pushnil(L); return 1; }
|
||||
char buf[32];
|
||||
snprintf(buf, sizeof(buf), "0x%016llX", (unsigned long long)guid);
|
||||
|
|
@ -268,10 +290,7 @@ static int lua_UnitIsPlayer(lua_State* L) {
|
|||
if (!gh) { lua_pushboolean(L, 0); return 1; }
|
||||
std::string uidStr(uid);
|
||||
for (char& c : uidStr) c = static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
|
||||
uint64_t guid = 0;
|
||||
if (uidStr == "player") guid = gh->getPlayerGuid();
|
||||
else if (uidStr == "target") guid = gh->getTargetGuid();
|
||||
else if (uidStr == "focus") guid = gh->getFocusGuid();
|
||||
uint64_t guid = resolveUnitGuid(gh, uidStr);
|
||||
auto entity = guid ? gh->getEntityManager().getEntity(guid) : nullptr;
|
||||
lua_pushboolean(L, entity && entity->getType() == game::ObjectType::PLAYER);
|
||||
return 1;
|
||||
|
|
@ -346,6 +365,11 @@ static int lua_UnitAura(lua_State* L, bool wantBuff) {
|
|||
const std::vector<game::AuraSlot>* auras = nullptr;
|
||||
if (uidStr == "player") auras = &gh->getPlayerAuras();
|
||||
else if (uidStr == "target") auras = &gh->getTargetAuras();
|
||||
else {
|
||||
// Try party/raid/focus via GUID lookup in unitAurasCache
|
||||
uint64_t guid = resolveUnitGuid(gh, uidStr);
|
||||
if (guid != 0) auras = gh->getUnitAuras(guid);
|
||||
}
|
||||
if (!auras) { lua_pushnil(L); return 1; }
|
||||
|
||||
// Filter to buffs or debuffs and find the Nth one
|
||||
|
|
|
|||
|
|
@ -12120,6 +12120,8 @@ void GameHandler::applyUpdateObjectBlock(const UpdateBlock& block, bool& newItem
|
|||
bool displayIdChanged = false;
|
||||
bool npcDeathNotified = false;
|
||||
bool npcRespawnNotified = false;
|
||||
bool healthChanged = false;
|
||||
bool powerChanged = false;
|
||||
const uint16_t ufHealth = fieldIndex(UF::UNIT_FIELD_HEALTH);
|
||||
const uint16_t ufPowerBase = fieldIndex(UF::UNIT_FIELD_POWER1);
|
||||
const uint16_t ufMaxHealth = fieldIndex(UF::UNIT_FIELD_MAXHEALTH);
|
||||
|
|
@ -12136,6 +12138,7 @@ void GameHandler::applyUpdateObjectBlock(const UpdateBlock& block, bool& newItem
|
|||
if (key == ufHealth) {
|
||||
uint32_t oldHealth = unit->getHealth();
|
||||
unit->setHealth(val);
|
||||
healthChanged = true;
|
||||
if (val == 0) {
|
||||
if (block.guid == autoAttackTarget) {
|
||||
stopAutoAttack();
|
||||
|
|
@ -12178,7 +12181,7 @@ void GameHandler::applyUpdateObjectBlock(const UpdateBlock& block, bool& newItem
|
|||
}
|
||||
// Specific fields checked BEFORE power/maxpower range checks
|
||||
// (Classic packs maxHealth/level/faction adjacent to power indices)
|
||||
} else if (key == ufMaxHealth) { unit->setMaxHealth(val); }
|
||||
} else if (key == ufMaxHealth) { unit->setMaxHealth(val); healthChanged = true; }
|
||||
else if (key == ufBytes0) {
|
||||
unit->setPowerType(static_cast<uint8_t>((val >> 24) & 0xFF));
|
||||
} else if (key == ufFlags) { unit->setUnitFlags(val); }
|
||||
|
|
@ -12272,8 +12275,23 @@ void GameHandler::applyUpdateObjectBlock(const UpdateBlock& block, bool& newItem
|
|||
// Power/maxpower range checks AFTER all specific fields
|
||||
else if (key >= ufPowerBase && key < ufPowerBase + 7) {
|
||||
unit->setPowerByType(static_cast<uint8_t>(key - ufPowerBase), val);
|
||||
powerChanged = true;
|
||||
} else if (key >= ufMaxPowerBase && key < ufMaxPowerBase + 7) {
|
||||
unit->setMaxPowerByType(static_cast<uint8_t>(key - ufMaxPowerBase), val);
|
||||
powerChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Fire UNIT_HEALTH / UNIT_POWER events for Lua addons
|
||||
if (addonEventCallback_ && (healthChanged || powerChanged)) {
|
||||
std::string unitId;
|
||||
if (block.guid == playerGuid) unitId = "player";
|
||||
else if (block.guid == targetGuid) unitId = "target";
|
||||
else if (block.guid == focusGuid) unitId = "focus";
|
||||
else if (block.guid == petGuid_) unitId = "pet";
|
||||
if (!unitId.empty()) {
|
||||
if (healthChanged) addonEventCallback_("UNIT_HEALTH", {unitId});
|
||||
if (powerChanged) addonEventCallback_("UNIT_POWER", {unitId});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -18948,6 +18966,16 @@ void GameHandler::handleSpellStart(network::Packet& packet) {
|
|||
hearthstonePreloadCallback_(homeBindMapId_, homeBindPos_.x, homeBindPos_.y, homeBindPos_.z);
|
||||
}
|
||||
}
|
||||
|
||||
// Fire UNIT_SPELLCAST_START for Lua addons
|
||||
if (addonEventCallback_) {
|
||||
std::string unitId;
|
||||
if (data.casterUnit == playerGuid) unitId = "player";
|
||||
else if (data.casterUnit == targetGuid) unitId = "target";
|
||||
else if (data.casterUnit == focusGuid) unitId = "focus";
|
||||
if (!unitId.empty())
|
||||
addonEventCallback_("UNIT_SPELLCAST_START", {unitId, std::to_string(data.spellId)});
|
||||
}
|
||||
}
|
||||
|
||||
void GameHandler::handleSpellGo(network::Packet& packet) {
|
||||
|
|
@ -19084,6 +19112,16 @@ void GameHandler::handleSpellGo(network::Packet& packet) {
|
|||
if (tgt == playerGuid) { playerIsHit = true; }
|
||||
if (data.casterUnit == playerGuid && tgt != playerGuid && tgt != 0) { playerHitEnemy = true; }
|
||||
}
|
||||
// Fire UNIT_SPELLCAST_SUCCEEDED for Lua addons
|
||||
if (addonEventCallback_) {
|
||||
std::string unitId;
|
||||
if (data.casterUnit == playerGuid) unitId = "player";
|
||||
else if (data.casterUnit == targetGuid) unitId = "target";
|
||||
else if (data.casterUnit == focusGuid) unitId = "focus";
|
||||
if (!unitId.empty())
|
||||
addonEventCallback_("UNIT_SPELLCAST_SUCCEEDED", {unitId, std::to_string(data.spellId)});
|
||||
}
|
||||
|
||||
if (playerIsHit || playerHitEnemy) {
|
||||
if (auto* renderer = core::Application::getInstance().getRenderer()) {
|
||||
if (auto* ssm = renderer->getSpellSoundManager()) {
|
||||
|
|
@ -19202,6 +19240,17 @@ void GameHandler::handleAuraUpdate(network::Packet& packet, bool isAll) {
|
|||
(*auraList)[slot] = aura;
|
||||
}
|
||||
|
||||
// Fire UNIT_AURA event for Lua addons
|
||||
if (addonEventCallback_) {
|
||||
std::string unitId;
|
||||
if (data.guid == playerGuid) unitId = "player";
|
||||
else if (data.guid == targetGuid) unitId = "target";
|
||||
else if (data.guid == focusGuid) unitId = "focus";
|
||||
else if (data.guid == petGuid_) unitId = "pet";
|
||||
if (!unitId.empty())
|
||||
addonEventCallback_("UNIT_AURA", {unitId});
|
||||
}
|
||||
|
||||
// If player is mounted but we haven't identified the mount aura yet,
|
||||
// check newly added auras (aura update may arrive after mountDisplayId)
|
||||
if (data.guid == playerGuid && currentMountDisplayId_ != 0 && mountAuraSpellId_ == 0) {
|
||||
|
|
@ -19597,6 +19646,11 @@ void GameHandler::handleGroupList(network::Packet& packet) {
|
|||
} else if (nowInGroup && partyData.memberCount != prevCount) {
|
||||
LOG_INFO("Group updated: ", partyData.memberCount, " members");
|
||||
}
|
||||
// Fire GROUP_ROSTER_UPDATE / PARTY_MEMBERS_CHANGED for Lua addons
|
||||
if (addonEventCallback_) {
|
||||
addonEventCallback_("GROUP_ROSTER_UPDATE", {});
|
||||
addonEventCallback_("PARTY_MEMBERS_CHANGED", {});
|
||||
}
|
||||
}
|
||||
|
||||
void GameHandler::handleGroupUninvite(network::Packet& packet) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue