mirror of
https://github.com/brues-code/nampower.git
synced 2026-10-06 13:40:00 +00:00
fix stacks removed not triggering BUFF_REMOVED events and add additional state arg
This commit is contained in:
@@ -257,13 +257,19 @@ All eight events pass the same parameters:
|
||||
4. int stackCount - current stack count for the aura (1 for a new aura; 0 when fully removed)
|
||||
5. int auraLevel - caster level for the aura from UnitFields.auraLevels (uint8 per slot, 48 entries)
|
||||
6. int auraSlot - the raw 0-based aura slot index (0-31 for buffs, 32-47 for debuffs). This is the raw internal slot, not the Lua slot. Consistent with unit data fields, GetPlayerAuraDuration, and BUFF/DEBUFF_UPDATE_DURATION_SELF events.
|
||||
7. int state - indicates why the event fired: `0` = newly added, `1` = newly removed, `2` = modified (stack change). When state is `2`, the event type (*_ADDED_* or *_REMOVED_*) reflects whether stacks increased or decreased.
|
||||
|
||||
Buff stack gains also fire the appropriate *_ADDED_* events.
|
||||
Stack changes also fire the appropriate *_ADDED_* or *_REMOVED_* events (not just new applications). When stacks increase, the corresponding *_ADDED_* event fires; when stacks decrease, the corresponding *_REMOVED_* event fires.
|
||||
|
||||
Example:
|
||||
```
|
||||
local function onAuraEvent(eventName, guid, luaSlot, spellId, stacks, auraLevel, auraSlot)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(string.format("[%s] %s luaSlot=%d spell=%d stacks=%d level=%d auraSlot=%d", eventName, guid, luaSlot, spellId, stacks, auraLevel, auraSlot))
|
||||
local AURA_STATE_ADDED = 0
|
||||
local AURA_STATE_REMOVED = 1
|
||||
local AURA_STATE_MODIFIED = 2
|
||||
|
||||
local function onAuraEvent(eventName, guid, luaSlot, spellId, stacks, auraLevel, auraSlot, state)
|
||||
local stateNames = { [0] = "added", [1] = "removed", [2] = "modified" }
|
||||
DEFAULT_CHAT_FRAME:AddMessage(string.format("[%s] %s luaSlot=%d spell=%d stacks=%d level=%d auraSlot=%d state=%s", eventName, guid, luaSlot, spellId, stacks, auraLevel, auraSlot, stateNames[state] or "unknown"))
|
||||
end
|
||||
|
||||
for _, eventName in ipairs({"BUFF_ADDED_SELF", "BUFF_REMOVED_SELF", "DEBUFF_ADDED_OTHER", "DEBUFF_REMOVED_OTHER"}) do
|
||||
|
||||
+9975
-9975
File diff suppressed because it is too large
Load Diff
+20
-18
@@ -11,7 +11,8 @@ namespace Nampower {
|
||||
uint32_t gAuraExpirationTime[MAX_AURA_SLOTS] = {};
|
||||
|
||||
// Helper function to trigger buff/debuff events
|
||||
void TriggerAuraEvent(uintptr_t *unit, uint32_t slot, uint32_t spellId, bool wasAdded) {
|
||||
// state: 0 = newly added, 1 = newly removed, 2 = modified (stack change)
|
||||
void TriggerAuraEvent(uintptr_t *unit, uint32_t slot, uint32_t spellId, bool wasAdded, uint32_t state) {
|
||||
// Determine if the unit is the active player (self) or another unit (other)
|
||||
auto unitGuid = game::UnitGetGuid(unit);
|
||||
auto playerGuid = game::ClntObjMgrGetActivePlayerGuid();
|
||||
@@ -29,7 +30,7 @@ namespace Nampower {
|
||||
auto auraLevels = unitFields->auraLevels;
|
||||
auto auraStacks = unitFields->auraApplications;
|
||||
|
||||
auto luaStacks = auraStacks[slot];
|
||||
auto luaStacks = (state == 1) ? auraStacks[slot] : auraStacks[slot] + 1; // for some crazy reason the stack count is 0 indexed but also 0 instead of -1 when removed
|
||||
|
||||
if (isBuff) {
|
||||
// count empty buff slots before slot to adjust luaSlot for actual buff/debuff index
|
||||
@@ -42,8 +43,6 @@ namespace Nampower {
|
||||
luaUnitSlot = luaUnitSlot - emptyCount;
|
||||
|
||||
if (wasAdded) {
|
||||
luaStacks += 1; // count offset by 1
|
||||
|
||||
// Buff added
|
||||
eventToTrigger = isSelf ? game::BUFF_ADDED_SELF : game::BUFF_ADDED_OTHER;
|
||||
} else {
|
||||
@@ -63,8 +62,6 @@ namespace Nampower {
|
||||
luaUnitSlot = luaUnitSlot - emptyCount;
|
||||
|
||||
if (wasAdded) {
|
||||
luaStacks += 1; // count offset by 1
|
||||
|
||||
// Debuff added
|
||||
eventToTrigger = isSelf ? game::DEBUFF_ADDED_SELF : game::DEBUFF_ADDED_OTHER;
|
||||
} else {
|
||||
@@ -73,7 +70,7 @@ namespace Nampower {
|
||||
}
|
||||
}
|
||||
|
||||
static char format[] = "%s%d%d%d%d%d";
|
||||
static char format[] = "%s%d%d%d%d%d%d";
|
||||
char *guidStr = new char[21]; // 2 for 0x prefix, 18 for the number, and 1 for '\0'
|
||||
if (isSelf) {
|
||||
std::snprintf(guidStr, 21, "0x%016llX", static_cast<unsigned long long>(playerGuid));
|
||||
@@ -82,7 +79,7 @@ namespace Nampower {
|
||||
}
|
||||
|
||||
// Trigger the event with spellId as parameter
|
||||
((int (__cdecl *)(int, char *, char *, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t)) Offsets::SignalEventParam)(
|
||||
((int (__cdecl *)(int, char *, char *, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t)) Offsets::SignalEventParam)(
|
||||
eventToTrigger,
|
||||
format,
|
||||
guidStr,
|
||||
@@ -90,7 +87,8 @@ namespace Nampower {
|
||||
spellId,
|
||||
luaStacks,
|
||||
auraLevels[slot],
|
||||
slot);
|
||||
slot,
|
||||
state);
|
||||
|
||||
delete[] guidStr;
|
||||
}
|
||||
@@ -102,7 +100,7 @@ namespace Nampower {
|
||||
// Call the original function
|
||||
onAuraRemoved(unit, dummy_edx, slot, spellId);
|
||||
|
||||
TriggerAuraEvent(unit, slot, spellId, false);
|
||||
TriggerAuraEvent(unit, slot, spellId, false, 1);
|
||||
}
|
||||
|
||||
void CGUnit_C_OnAuraAddedHook(hadesmem::PatchDetourBase *detour, uintptr_t *unit, void *dummy_edx, uint32_t slot,
|
||||
@@ -112,22 +110,26 @@ namespace Nampower {
|
||||
// Call the original function
|
||||
onAuraAdded(unit, dummy_edx, slot, spellId);
|
||||
|
||||
TriggerAuraEvent(unit, slot, spellId, true);
|
||||
TriggerAuraEvent(unit, slot, spellId, true, 0);
|
||||
}
|
||||
|
||||
void CGUnit_C_OnAuraAddedStackHook(hadesmem::PatchDetourBase *detour, uintptr_t *unit, int slot) {
|
||||
auto const unitAuraAddedStack = detour->GetTrampolineT<CGUnit_C_OnAuraAddedStackT>();
|
||||
|
||||
// Call the original function
|
||||
unitAuraAddedStack(unit, slot);
|
||||
void CGUnit_C_OnAuraStacksChangedHook(hadesmem::PatchDetourBase *detour, uintptr_t *unit, void *dummy_edx, int slot, uint8_t stackCount) {
|
||||
auto const onAuraStacksChanged = detour->GetTrampolineT<CGUnit_C_OnAuraStacksChangedT>();
|
||||
|
||||
// Get spell ID from the aura slot
|
||||
auto *unitFields = *reinterpret_cast<game::UnitFields **>(unit + 68);
|
||||
auto auras = unitFields->aura;
|
||||
uint32_t spellId = auras[slot];
|
||||
|
||||
// Trigger the aura event for stack added
|
||||
TriggerAuraEvent(unit, slot, spellId, true);
|
||||
// Check if stacks increased or decreased (auraApplications is 0-indexed, convert to 1-indexed)
|
||||
uint8_t currentStacks = unitFields->auraApplications[slot];
|
||||
|
||||
// Call the original function
|
||||
onAuraStacksChanged(unit, dummy_edx, slot, stackCount);
|
||||
|
||||
bool wasAdded = stackCount < currentStacks;
|
||||
|
||||
TriggerAuraEvent(unit, slot, spellId, wasAdded, 2);
|
||||
}
|
||||
|
||||
void CGBuffBar_UpdateDurationHook(hadesmem::PatchDetourBase *detour, uint8_t auraSlot, int durationMs) {
|
||||
|
||||
+2
-2
@@ -14,13 +14,13 @@ namespace Nampower {
|
||||
|
||||
using CGUnit_C_OnAuraRemovedT = void (__fastcall *)(uintptr_t *unit, void *dummy_edx,uint32_t slot, uint32_t spellId);
|
||||
using CGUnit_C_OnAuraAddedT = void (__fastcall *)(uintptr_t *unit, void *dummy_edx,uint32_t slot, uint32_t spellId);
|
||||
using CGUnit_C_OnAuraAddedStackT = void (__fastcall *)(uintptr_t *unit, int slot);
|
||||
using CGUnit_C_OnAuraStacksChangedT = void (__fastcall *)(uintptr_t *unit, void *dummy_edx, int slot, uint8_t stackCount);
|
||||
using UnitCombatLogUnitDeadT = void (__fastcall *)(uint64_t guid);
|
||||
using CGBuffBar_UpdateDurationT = void (__fastcall *)(uint8_t auraSlot, int durationMs);
|
||||
|
||||
void CGUnit_C_OnAuraRemovedHook(hadesmem::PatchDetourBase *detour, uintptr_t *unit, void *dummy_edx, uint32_t slot, uint32_t spellId);
|
||||
void CGUnit_C_OnAuraAddedHook(hadesmem::PatchDetourBase *detour, uintptr_t *unit, void *dummy_edx, uint32_t slot, uint32_t spellId);
|
||||
void CGUnit_C_OnAuraAddedStackHook(hadesmem::PatchDetourBase *detour, uintptr_t *unit, int slot);
|
||||
void CGUnit_C_OnAuraStacksChangedHook(hadesmem::PatchDetourBase *detour, uintptr_t *unit, void *dummy_edx, int slot, uint8_t stackCount);
|
||||
void UnitCombatLogUnitDeadHook(hadesmem::PatchDetourBase *detour, uint64_t guid);
|
||||
void CGBuffBar_UpdateDurationHook(hadesmem::PatchDetourBase *detour, uint8_t auraSlot, int durationMs);
|
||||
}
|
||||
|
||||
+4
-4
@@ -146,7 +146,7 @@ namespace Nampower {
|
||||
std::unique_ptr<hadesmem::PatchDetour<CGActionBar_UseActionT> > gCGActionBar_UseActionDetour;
|
||||
std::unique_ptr<hadesmem::PatchDetour<CGUnit_C_OnAuraRemovedT> > gCGUnit_C_OnAuraRemovedDetour;
|
||||
std::unique_ptr<hadesmem::PatchDetour<CGUnit_C_OnAuraAddedT> > gCGUnit_C_OnAuraAddedDetour;
|
||||
std::unique_ptr<hadesmem::PatchDetour<CGUnit_C_OnAuraAddedStackT> > gCGUnit_C_OnAuraAddedStackDetour;
|
||||
std::unique_ptr<hadesmem::PatchDetour<CGUnit_C_OnAuraStacksChangedT> > gCGUnit_C_OnAuraStacksChangedDetour;
|
||||
std::unique_ptr<hadesmem::PatchDetour<UnitCombatLogUnitDeadT> > gUnitCombatLogUnitDeadDetour;
|
||||
std::unique_ptr<hadesmem::PatchDetour<CGBuffBar_UpdateDurationT> > gCGBuffBar_UpdateDurationDetour;
|
||||
|
||||
@@ -1390,9 +1390,9 @@ namespace Nampower {
|
||||
&CGUnit_C_OnAuraRemovedHook);
|
||||
gCGUnit_C_OnAuraAddedDetour = createHook<CGUnit_C_OnAuraAddedT>(process, Offsets::CGUnit_C_OnAuraAdded,
|
||||
&CGUnit_C_OnAuraAddedHook);
|
||||
gCGUnit_C_OnAuraAddedStackDetour = createHook<CGUnit_C_OnAuraAddedStackT>(
|
||||
process, Offsets::CGUnit_C_OnAuraAddedStack,
|
||||
&CGUnit_C_OnAuraAddedStackHook);
|
||||
gCGUnit_C_OnAuraStacksChangedDetour = createHook<CGUnit_C_OnAuraStacksChangedT>(
|
||||
process, Offsets::CGUnit_C_OnAuraStacksChanged,
|
||||
&CGUnit_C_OnAuraStacksChangedHook);
|
||||
gUnitCombatLogUnitDeadDetour = createHook<UnitCombatLogUnitDeadT>(process, Offsets::UnitCombatLogUnitDead,
|
||||
&UnitCombatLogUnitDeadHook);
|
||||
gCGBuffBar_UpdateDurationDetour = createHook<CGBuffBar_UpdateDurationT>(process, Offsets::CGBuffBar_UpdateDuration,
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ namespace Nampower {
|
||||
constexpr uint32_t DISENCHANT_QUALITY_PURPLE = 0x04; // Epic
|
||||
|
||||
constexpr uint32_t MAJOR_VERSION = 2;
|
||||
constexpr uint32_t MINOR_VERSION = 31;
|
||||
constexpr uint32_t MINOR_VERSION = 32;
|
||||
constexpr uint32_t PATCH_VERSION = 0;
|
||||
|
||||
constexpr int32_t LUA_REGISTRYINDEX = -10000;
|
||||
|
||||
@@ -205,7 +205,7 @@ enum class Offsets : std::uint32_t {
|
||||
CanInspectUnit = 0x004944a0,
|
||||
CGUnit_C_OnAuraRemoved = 0x00612320,
|
||||
CGUnit_C_OnAuraAdded = 0x006123f0,
|
||||
CGUnit_C_OnAuraAddedStack = 0x0062b800,
|
||||
CGUnit_C_OnAuraStacksChanged = 0x00612450,
|
||||
UnitCombatLogUnitDead = 0x0062c160,
|
||||
CGUnitGetUnitName = 0x00609210,
|
||||
CGUnitCanAttack = 0x00606980,
|
||||
|
||||
Reference in New Issue
Block a user