From de1b62f6e6c2d5f1cb8368ece1a6178755bde632 Mon Sep 17 00:00:00 2001 From: avitasia Date: Mon, 8 Dec 2025 20:36:49 -0800 Subject: [PATCH] add new events for auras and unit death --- README.md | 48 +++++++++++++ UNIT_FIELDS.md | 6 +- nampower/CMakeLists.txt | 2 + nampower/auras.cpp | 148 +++++++++++++++++++++++++++++++++++++++ nampower/auras.hpp | 20 ++++++ nampower/dbc_fields.hpp | 9 ++- nampower/game.hpp | 18 ++++- nampower/main.cpp | 112 ++++++++++++++++++++++------- nampower/main.hpp | 5 +- nampower/offsets.hpp | 10 ++- nampower/scripts.cpp | 18 +++++ nampower/spellcast.cpp | 2 + nampower/spellevents.cpp | 3 + nampower/unit_fields.cpp | 4 +- 14 files changed, 364 insertions(+), 41 deletions(-) create mode 100644 nampower/auras.cpp create mode 100644 nampower/auras.hpp diff --git a/README.md b/README.md index 4429a13..3eeb78c 100644 --- a/README.md +++ b/README.md @@ -543,6 +543,54 @@ Cursive:RegisterEvent("SPELL_DAMAGE_EVENT_SELF", end); ``` +#### Buff/Debuff Events +New events fire whenever a buff or debuff is added or removed on you or any other unit that the client tracks. + +Events: +``` +BUFF_ADDED_SELF +BUFF_REMOVED_SELF +BUFF_ADDED_OTHER +BUFF_REMOVED_OTHER +DEBUFF_ADDED_SELF +DEBUFF_REMOVED_SELF +DEBUFF_ADDED_OTHER +DEBUFF_REMOVED_OTHER +``` + +All eight events pass the same parameters: +1. string guid - unit guid like "0xF5300000000000A5" +2. int slot - 1-based Lua slot index for the buff/debuff (skips empty slots to match UnitBuff/UnitDebuff ordering) +3. int spellId +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) + +Buff stack gains also fire the appropriate *_ADDED_* events. + +Example: +``` +local function onAuraEvent(eventName, guid, slot, spellId, stacks, auraLevel) + DEFAULT_CHAT_FRAME:AddMessage(string.format("[%s] %s slot=%d spell=%d stacks=%d level=%d", eventName, guid, slot, spellId, stacks, auraLevel)) +end + +for _, eventName in ipairs({"BUFF_ADDED_SELF", "BUFF_REMOVED_SELF", "DEBUFF_ADDED_OTHER", "DEBUFF_REMOVED_OTHER"}) do + frame:RegisterEvent(eventName, function(...) onAuraEvent(eventName, ...) end) +end +``` + +#### UNIT_DIED +Fires when a unit death is recorded in the combat log. + +Parameters: +1. string guid - guid of the unit that died + +Example: +``` +frame:RegisterEvent("UNIT_DIED", function(guid) + DEFAULT_CHAT_FRAME:AddMessage("Unit died: " .. guid) +end) +``` + ### Bug Reporting If you encounter any bugs please report them in the issues tab. Please include the nampower_debug.txt file in the same directory as your WoW.exe to help me diagnose the issue. If you are able to reproduce the bug please include the steps to reproduce it. In a future version once bugs are ironed out I'll make logging optional. diff --git a/UNIT_FIELDS.md b/UNIT_FIELDS.md index a55fc16..b741177 100644 --- a/UNIT_FIELDS.md +++ b/UNIT_FIELDS.md @@ -149,11 +149,9 @@ These fields return a Lua table with numeric indices (1-based). - **auraFlags** [6] - Bit flags for aura properties (positive, negative, cancelable, etc.) - Each UINT32 contains flags for 8 auras (4 bits per aura) -- **auraLevels** [12] - Aura caster levels - - Each UINT32 contains 4 aura levels (8 bits per level) +- **auraLevels** [48] - Aura caster levels (UINT8 per aura slot) -- **auraApplications** [12] - Aura stack counts - - Each UINT32 contains 4 aura stacks (8 bits per stack) +- **auraApplications** [48] - Aura stack counts (UINT8 per aura slot) ### Resistances (UINT32 arrays) - **resistances** [7] - Resistance values for all schools diff --git a/nampower/CMakeLists.txt b/nampower/CMakeLists.txt index 95736bb..0c013ee 100644 --- a/nampower/CMakeLists.txt +++ b/nampower/CMakeLists.txt @@ -30,6 +30,8 @@ set(SOURCE_FILES dbc_fields.cpp unit_fields.hpp unit_fields.cpp + auras.hpp + auras.cpp ) add_library(${DLL_NAME} SHARED ${SOURCE_FILES}) diff --git a/nampower/auras.cpp b/nampower/auras.cpp new file mode 100644 index 0000000..b8aadf2 --- /dev/null +++ b/nampower/auras.cpp @@ -0,0 +1,148 @@ +// +// Created by pmacc on 12/7/2025. +// + +#include "auras.hpp" +#include "offsets.hpp" +#include "logging.hpp" +#include "game.hpp" + +namespace Nampower { + // Helper function to trigger buff/debuff events + void TriggerAuraEvent(uintptr_t *unit, uint32_t slot, uint32_t spellId, bool wasAdded) { + // Determine if the unit is the active player (self) or another unit (other) + auto unitGuid = game::UnitGetGuid(unit); + auto playerGuid = game::ClntObjMgrGetActivePlayerGuid(); + bool isSelf = (unitGuid == playerGuid); + bool isBuff = slot < 32; // slots 0-31 are buffs + + // Trigger the appropriate event based on buff/debuff, add/remove, and self/other + game::Events eventToTrigger; + + int luaSlot = slot + 1; // lua uses 1-based indexing for slots + + auto *unitFields = *reinterpret_cast(unit + 68); + + auto auras = unitFields->aura; + auto auraLevels = unitFields->auraLevels; + auto auraStacks = unitFields->auraApplications; + + auto luaStacks = auraStacks[slot]; + + if (isBuff) { + // count empty buff slots before slot to adjust luaSlot for actual buff/debuff index + int emptyCount = 0; + for (uint32_t i = 0; i < slot; ++i) { + if (auras[i] == 0) { + emptyCount++; + } + } + luaSlot = luaSlot - emptyCount; + + if (wasAdded) { + luaStacks += 1; // count offset by 1 + + // Buff added + eventToTrigger = isSelf ? game::BUFF_ADDED_SELF : game::BUFF_ADDED_OTHER; + } else { + // Buff removed + eventToTrigger = isSelf ? game::BUFF_REMOVED_SELF : game::BUFF_REMOVED_OTHER; + } + } else { + luaSlot = luaSlot - 32; // adjust slot for debuffs + + // count empty debuff slots before slot to adjust luaSlot for actual buff/debuff index + int emptyCount = 0; + for (uint32_t i = 32; i < slot; ++i) { + if (auras[i] == 0) { + emptyCount++; + } + } + luaSlot = luaSlot - emptyCount; + + if (wasAdded) { + luaStacks += 1; // count offset by 1 + + // Debuff added + eventToTrigger = isSelf ? game::DEBUFF_ADDED_SELF : game::DEBUFF_ADDED_OTHER; + } else { + // Debuff removed + eventToTrigger = isSelf ? game::DEBUFF_REMOVED_SELF : game::DEBUFF_REMOVED_OTHER; + } + } + + char format[] = "%s%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(playerGuid)); + } else { + std::snprintf(guidStr, 21, "0x%016llX", static_cast(unitGuid)); + } + + // Trigger the event with spellId as parameter + ((int (__cdecl *)(int, char *, char *, uint32_t, uint32_t, uint32_t, uint32_t)) Offsets::SignalEventParam)( + eventToTrigger, + format, + guidStr, + luaSlot, + spellId, + luaStacks, + auraLevels[slot]); + + delete[] guidStr; + } + + void CGUnit_C_OnAuraRemovedHook(hadesmem::PatchDetourBase *detour, uintptr_t *unit, void *dummy_edx, uint32_t slot, + uint32_t spellId) { + auto const onAuraRemoved = detour->GetTrampolineT(); + + // Call the original function + onAuraRemoved(unit, dummy_edx, slot, spellId); + + TriggerAuraEvent(unit, slot, spellId, false); + } + + void CGUnit_C_OnAuraAddedHook(hadesmem::PatchDetourBase *detour, uintptr_t *unit, void *dummy_edx, uint32_t slot, + uint32_t spellId) { + auto const onAuraAdded = detour->GetTrampolineT(); + + // Call the original function + onAuraAdded(unit, dummy_edx, slot, spellId); + + TriggerAuraEvent(unit, slot, spellId, true); + } + + void CGUnit_C_OnAuraAddedStackHook(hadesmem::PatchDetourBase *detour, uintptr_t *unit, int slot) { + auto const unitAuraAddedStack = detour->GetTrampolineT(); + + // Call the original function + unitAuraAddedStack(unit, slot); + + // Get spell ID from the aura slot + auto *unitFields = *reinterpret_cast(unit + 68); + auto auras = unitFields->aura; + uint32_t spellId = auras[slot]; + + // Trigger the aura event for stack added + TriggerAuraEvent(unit, slot, spellId, true); + } + + void UnitCombatLogUnitDeadHook(hadesmem::PatchDetourBase *detour, uint64_t guid) { + auto const unitCombatLogUnitDead = detour->GetTrampolineT(); + + // Call the original function + unitCombatLogUnitDead(guid); + + // Trigger UNIT_DIED event + char format[] = "%s"; + char *guidStr = new char[21]; // 2 for 0x prefix, 18 for the number, and 1 for '\0' + std::snprintf(guidStr, 21, "0x%016llX", static_cast(guid)); + + ((int (__cdecl *)(int, char *, char *)) Offsets::SignalEventParam)( + game::UNIT_DIED, + format, + guidStr); + + delete[] guidStr; + } +} diff --git a/nampower/auras.hpp b/nampower/auras.hpp new file mode 100644 index 0000000..4c31b2a --- /dev/null +++ b/nampower/auras.hpp @@ -0,0 +1,20 @@ +// +// Created by pmacc on 12/7/2025. +// + +#pragma once + +#include +#include "main.hpp" + +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 UnitCombatLogUnitDeadT = void (__fastcall *)(uint64_t guid); + + 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 UnitCombatLogUnitDeadHook(hadesmem::PatchDetourBase *detour, uint64_t guid); +} diff --git a/nampower/dbc_fields.hpp b/nampower/dbc_fields.hpp index 675da27..9088da6 100644 --- a/nampower/dbc_fields.hpp +++ b/nampower/dbc_fields.hpp @@ -16,7 +16,8 @@ namespace Nampower { UINT32, FLOAT, STRING, - UINT64 + UINT64, + UINT8 }; // Field descriptor for simple fields @@ -88,6 +89,9 @@ namespace Nampower { case FieldType::UINT64: lua_pushnumber(luaState, static_cast(*reinterpret_cast(fieldPtr))); break; + case FieldType::UINT8: + lua_pushnumber(luaState, *reinterpret_cast(fieldPtr)); + break; case FieldType::STRING: { const char* str = *reinterpret_cast(fieldPtr); lua_pushstring(luaState, str ? const_cast(str) : const_cast("")); @@ -123,6 +127,9 @@ namespace Nampower { case FieldType::UINT64: lua_pushnumber(luaState, static_cast(reinterpret_cast(fieldPtr)[j])); break; + case FieldType::UINT8: + lua_pushnumber(luaState, reinterpret_cast(fieldPtr)[j]); + break; case FieldType::STRING: { const char* str = reinterpret_cast(fieldPtr)[j]; lua_pushstring(luaState, str ? const_cast(str) : const_cast("")); diff --git a/nampower/game.hpp b/nampower/game.hpp index fbeb776..9269f0b 100644 --- a/nampower/game.hpp +++ b/nampower/game.hpp @@ -1145,6 +1145,18 @@ namespace game { SPELL_CAST_EVENT = 540, SPELL_DAMAGE_EVENT_SELF = 549, SPELL_DAMAGE_EVENT_OTHER = 550, + + DEBUFF_ADDED_SELF = 551, + DEBUFF_REMOVED_SELF = 552, + DEBUFF_ADDED_OTHER = 553, + DEBUFF_REMOVED_OTHER = 554, + + BUFF_ADDED_SELF = 555, + BUFF_REMOVED_SELF = 556, + BUFF_ADDED_OTHER = 557, + BUFF_REMOVED_OTHER = 558, + + UNIT_DIED = 559, }; enum TypeMask { @@ -1293,8 +1305,8 @@ namespace game { uint32_t flags; // Size:1 uint32_t aura[48]; // Size:48 uint32_t auraFlags[6]; // Size:6 - uint32_t auraLevels[12]; // Size:12 - uint32_t auraApplications[12]; // Size:12 + uint8_t auraLevels[48]; // Size:48 + uint8_t auraApplications[48]; // Size:48 uint32_t auraState; // Size:1 uint32_t baseAttackTime; // Size:1 uint32_t offhandAttackTime; // Size:1 @@ -1370,4 +1382,4 @@ namespace game { bool UnitIsPvpFlagged(uintptr_t *unit); bool UnitIsInCombat(uintptr_t *unit); -} \ No newline at end of file +} diff --git a/nampower/main.cpp b/nampower/main.cpp index f22a219..4ef4f92 100644 --- a/nampower/main.cpp +++ b/nampower/main.cpp @@ -37,6 +37,7 @@ #include "spellchannel.hpp" #include "helper.hpp" #include "items.hpp" +#include "auras.hpp" #include #include @@ -86,6 +87,7 @@ namespace Nampower { std::unique_ptr> gSpellVisualsInitDetour; std::unique_ptr> gLoadScriptFunctionsDetour; std::unique_ptr> gCreateEventsDetour; + std::unique_ptr> gSetEventCountDetour; std::unique_ptr> gSetCVarDetour; std::unique_ptr> gCastDetour; @@ -121,6 +123,10 @@ namespace Nampower { std::unique_ptr> gSpellNonMeleeDmgLogHandlerDetour; std::unique_ptr> gCGPlayer_C_OnAttackIconPressedDetour; + std::unique_ptr> gCGUnit_C_OnAuraRemovedDetour; + std::unique_ptr> gCGUnit_C_OnAuraAddedDetour; + std::unique_ptr> gCGUnit_C_OnAuraAddedStackDetour; + std::unique_ptr> gUnitCombatLogUnitDeadDetour; std::unique_ptr> gInvalidFunctionPtrCheckDetour; @@ -1066,28 +1072,6 @@ namespace Nampower { gBufferTimeMs = gUserSettings.minBufferTimeMs; } - void initCustomEvents() { - auto strPtr = reinterpret_cast(Offsets::QueueEventStringPtr); - const char *SPELL_QUEUE_EVENT = "SPELL_QUEUE_EVENT"; - // Make 0x00BE175C which is the unused event string ptr point to SPELL_QUEUE_EVENT (369) - *strPtr = reinterpret_cast(SPELL_QUEUE_EVENT); - - strPtr = reinterpret_cast(Offsets::CastEventStringPtr); - const char *SPELL_CAST_EVENT = "SPELL_CAST_EVENT"; - // Make 0X00BE1A08 which is the unused event string ptr point to SPELL_CAST_EVENT (540) - *strPtr = reinterpret_cast(SPELL_CAST_EVENT); - - strPtr = reinterpret_cast(Offsets::SpellDamageEventSelfStringPtr); - const char *SPELL_DAMAGE_EVENT_SELF = "SPELL_DAMAGE_EVENT_SELF"; - // Make 0X00BE1A2C which is the unused event string ptr point to SPELL_DAMAGE_EVENT_SELF (549) - *strPtr = reinterpret_cast(SPELL_DAMAGE_EVENT_SELF); - - strPtr = reinterpret_cast(Offsets::SpellDamageEventOtherStringPtr); - const char *SPELL_DAMAGE_EVENT_OTHER = "SPELL_DAMAGE_EVENT_OTHER"; - // Make 0X00BE1A30 which is the unused event string ptr point to SPELL_DAMAGE_EVENT_OTHER (550) - *strPtr = reinterpret_cast(SPELL_DAMAGE_EVENT_OTHER); - } - // Template function to simplify hook initialization with specific storage template std::unique_ptr> @@ -1101,8 +1085,6 @@ namespace Nampower { void initHooks() { const hadesmem::Process process(::GetCurrentProcessId()); - initCustomEvents(); - gSetCVarDetour = createHook(process, Offsets::Script_SetCVar, &Script_SetCVarHook); gCastDetour = createHook(process, Offsets::Spell_C_CastSpell, &Spell_C_CastSpellHook); gSendCastDetour = createHook(process, Offsets::SendCast, &SendCastHook); @@ -1141,6 +1123,14 @@ namespace Nampower { &InvalidFunctionPtrCheckHook); gGetSpellSlotFromLuaDetour = createHook(process, Offsets::GetSpellSlotFromLua, &GetSpellSlotFromLuaHook); + gCGUnit_C_OnAuraRemovedDetour = createHook(process, Offsets::CGUnit_C_OnAuraRemoved, + &CGUnit_C_OnAuraRemovedHook); + gCGUnit_C_OnAuraAddedDetour = createHook(process, Offsets::CGUnit_C_OnAuraAdded, + &CGUnit_C_OnAuraAddedHook); + gCGUnit_C_OnAuraAddedStackDetour = createHook(process, Offsets::CGUnit_C_OnAuraAddedStack, + &CGUnit_C_OnAuraAddedStackHook); + gUnitCombatLogUnitDeadDetour = createHook(process, Offsets::UnitCombatLogUnitDead, + &UnitCombatLogUnitDeadHook); } void SpellVisualsInitializeHook(hadesmem::PatchDetourBase *detour) { @@ -1150,14 +1140,75 @@ namespace Nampower { initHooks(); } + void addCustomEvent(uint32_t code, char* name) { + char ** FrameScript_EventObject_Data = *reinterpret_cast(Offsets::Framescript_EventObject_Data); + + auto SStrDupA = reinterpret_cast(Offsets::SStrDupA); + FrameScript_EventObject_Data[code*4] = SStrDupA(name, name, 1308); + + DEBUG_LOG("Added custom event code:" << code << " " << name); + } + + + void initCustomEvents() { + char SPELL_QUEUE_EVENT[] = "SPELL_QUEUE_EVENT"; + addCustomEvent(game::SPELL_QUEUE_EVENT, SPELL_QUEUE_EVENT); + + char SPELL_CAST_EVENT[] = "SPELL_CAST_EVENT"; + addCustomEvent(game::SPELL_CAST_EVENT, SPELL_CAST_EVENT); + + char SPELL_DAMAGE_EVENT_SELF[] = "SPELL_DAMAGE_EVENT_SELF"; + addCustomEvent(game::SPELL_DAMAGE_EVENT_SELF, SPELL_DAMAGE_EVENT_SELF); + + char SPELL_DAMAGE_EVENT_OTHER[] = "SPELL_DAMAGE_EVENT_OTHER"; + addCustomEvent(game::SPELL_DAMAGE_EVENT_OTHER, SPELL_DAMAGE_EVENT_OTHER); + + char DEBUFF_ADDED_SELF[] = "DEBUFF_ADDED_SELF"; + addCustomEvent(game::DEBUFF_ADDED_SELF, DEBUFF_ADDED_SELF); + + char DEBUFF_REMOVED_SELF[] = "DEBUFF_REMOVED_SELF"; + addCustomEvent(game::DEBUFF_REMOVED_SELF, DEBUFF_REMOVED_SELF); + + char DEBUFF_ADDED_OTHER[] = "DEBUFF_ADDED_OTHER"; + addCustomEvent(game::DEBUFF_ADDED_OTHER, DEBUFF_ADDED_OTHER); + + char DEBUFF_REMOVED_OTHER[] = "DEBUFF_REMOVED_OTHER"; + addCustomEvent(game::DEBUFF_REMOVED_OTHER, DEBUFF_REMOVED_OTHER); + + char BUFF_ADDED_SELF[] = "BUFF_ADDED_SELF"; + addCustomEvent(game::BUFF_ADDED_SELF, BUFF_ADDED_SELF); + + char BUFF_REMOVED_SELF[] = "BUFF_REMOVED_SELF"; + addCustomEvent(game::BUFF_REMOVED_SELF, BUFF_REMOVED_SELF); + + char BUFF_ADDED_OTHER[] = "BUFF_ADDED_OTHER"; + addCustomEvent(game::BUFF_ADDED_OTHER, BUFF_ADDED_OTHER); + + char BUFF_REMOVED_OTHER[] = "BUFF_REMOVED_OTHER"; + addCustomEvent(game::BUFF_REMOVED_OTHER, BUFF_REMOVED_OTHER); + + char UNIT_DIED[] = "UNIT_DIED"; + addCustomEvent(game::UNIT_DIED, UNIT_DIED); + } + void FrameScript_CreateEventsHook(hadesmem::PatchDetourBase *detour, int param_1, uint32_t maxEventId) { auto const createEvents = detour->GetTrampolineT(); + createEvents(param_1, maxEventId); - if (maxEventId == 549) { - maxEventId = 551; // add two more events + if (maxEventId > 200) { + initCustomEvents(); + } + } + + void Framescript_SetEventCountHook(hadesmem::PatchDetourBase *detour, void *thisPtr, void *dummy_edx, uint32_t count) { + auto const setEventCount = detour->GetTrampolineT(); + + if (count > 200) { + DEBUG_LOG("Increasing event count from " << count << " to 700"); + count = 700; // extend to support additional custom events (this matches how superwow does it) } - createEvents(param_1, maxEventId); + setEventCount(thisPtr, dummy_edx, count); } void LoadScriptFunctionsHook(hadesmem::PatchDetourBase *detour) { @@ -1252,6 +1303,13 @@ namespace Nampower { createEventsOrig, &FrameScript_CreateEventsHook); gCreateEventsDetour->Apply(); + + auto const setEventCountOrig = hadesmem::detail::AliasCast( + Offsets::Framescript_SetEventCount); + gSetEventCountDetour = std::make_unique>(process, + setEventCountOrig, + &Framescript_SetEventCountHook); + gSetEventCountDetour->Apply(); } ); } diff --git a/nampower/main.hpp b/nampower/main.hpp index 9f5d0f8..b5962c3 100644 --- a/nampower/main.hpp +++ b/nampower/main.hpp @@ -30,8 +30,8 @@ namespace Nampower { constexpr uint32_t BUFFER_DECREASE_FREQUENCY = 10000; // time in ms between changes to lower buffer constexpr uint32_t MAJOR_VERSION = 2; - constexpr uint32_t MINOR_VERSION = 13; - constexpr uint32_t PATCH_VERSION = 1; + constexpr uint32_t MINOR_VERSION = 14; + constexpr uint32_t PATCH_VERSION = 0; constexpr int32_t LUA_REGISTRYINDEX = -10000; constexpr int32_t LUA_GLOBALSINDEX = -10001; @@ -111,6 +111,7 @@ namespace Nampower { using LoadScriptFunctionsT = void (__stdcall *)(); using FrameScript_RegisterFunctionT = void (__fastcall *)(char *name, uintptr_t *func); using FrameScript_CreateEventsT = void (__fastcall *)(int param_1, uint32_t maxEventId); + using FramescriptSetEventCountT = void (__fastcall *)(void *thisPtr, void *dummy_edx, uint32_t count); using LuaGetContextT = uintptr_t *(__fastcall *)(void); using LuaGetTableT = void (__fastcall *)(uintptr_t *luaState, int globalsIndex); diff --git a/nampower/offsets.hpp b/nampower/offsets.hpp index 4ab1c76..8caa37f 100644 --- a/nampower/offsets.hpp +++ b/nampower/offsets.hpp @@ -122,6 +122,8 @@ enum class Offsets : std::uint32_t { LoadScriptFunctions = 0x00490250, FrameScript_RegisterFunction = 0x00704120, FrameScript_CreateEvents = 0X00703D90, + Framescript_SetEventCount = 0X007053B0, + Framescript_EventObject_Data = 0x00CEEF68, // Existing script functions GetGUIDFromName = 0X00515970, @@ -131,6 +133,8 @@ enum class Offsets : std::uint32_t { Script_RunScript = 0x0048B980, Script_SpellStopCasting = 0x006E6E80, + SStrDupA = 0X0064A620, + lua_state_ptr = 0x7040D0, lua_isstring = 0x006F3510, @@ -166,13 +170,15 @@ enum class Offsets : std::uint32_t { QueueEventStringPtr = 0X00BE175C, // unused event 369 0x171 CastEventStringPtr = 0X00BE1A08, // unused event 540 0x21C - SpellDamageEventSelfStringPtr = 0X00BE1A2C, // unused event 549 0x225 - SpellDamageEventOtherStringPtr = 0X00BE1A30, // unused event 550 0x226 GetBuffByIndex = 0X004E4430, CGUnit_C_ClearCastingSpell = 0x0060d040, CGUnit_C_ClearSpellEffect = 0x00614150, + CGUnit_C_OnAuraRemoved = 0x00612320, + CGUnit_C_OnAuraAdded = 0x006123f0, + CGUnit_C_OnAuraAddedStack = 0x0062b800, + UnitCombatLogUnitDead = 0x0062c160, CGPlayer_C_OnAttackIconPressed = 0X006131A0, diff --git a/nampower/scripts.cpp b/nampower/scripts.cpp index 96e53a9..48a8cb3 100644 --- a/nampower/scripts.cpp +++ b/nampower/scripts.cpp @@ -573,6 +573,9 @@ namespace Nampower { case FieldType::UINT32: lua_pushnumber(luaState, *reinterpret_cast(fieldPtr)); return 1; + case FieldType::UINT8: + lua_pushnumber(luaState, *reinterpret_cast(fieldPtr)); + return 1; case FieldType::FLOAT: lua_pushnumber(luaState, *reinterpret_cast(fieldPtr)); return 1; @@ -605,6 +608,9 @@ namespace Nampower { case FieldType::UINT32: lua_pushnumber(luaState, reinterpret_cast(fieldPtr)[j]); break; + case FieldType::UINT8: + lua_pushnumber(luaState, reinterpret_cast(fieldPtr)[j]); + break; case FieldType::FLOAT: lua_pushnumber(luaState, reinterpret_cast(fieldPtr)[j]); break; @@ -667,6 +673,9 @@ namespace Nampower { case FieldType::UINT32: lua_pushnumber(luaState, *reinterpret_cast(fieldPtr)); return 1; + case FieldType::UINT8: + lua_pushnumber(luaState, *reinterpret_cast(fieldPtr)); + return 1; case FieldType::FLOAT: lua_pushnumber(luaState, *reinterpret_cast(fieldPtr)); return 1; @@ -700,6 +709,9 @@ namespace Nampower { case FieldType::UINT32: lua_pushnumber(luaState, reinterpret_cast(fieldPtr)[j]); break; + case FieldType::UINT8: + lua_pushnumber(luaState, reinterpret_cast(fieldPtr)[j]); + break; case FieldType::FLOAT: lua_pushnumber(luaState, reinterpret_cast(fieldPtr)[j]); break; @@ -836,6 +848,9 @@ namespace Nampower { case FieldType::UINT32: lua_pushnumber(luaState, *reinterpret_cast(fieldPtr)); return 1; + case FieldType::UINT8: + lua_pushnumber(luaState, *reinterpret_cast(fieldPtr)); + return 1; case FieldType::UINT64: lua_pushnumber(luaState, static_cast(*reinterpret_cast(fieldPtr))); return 1; @@ -863,6 +878,9 @@ namespace Nampower { case FieldType::UINT32: lua_pushnumber(luaState, reinterpret_cast(fieldPtr)[j]); break; + case FieldType::UINT8: + lua_pushnumber(luaState, reinterpret_cast(fieldPtr)[j]); + break; case FieldType::FLOAT: lua_pushnumber(luaState, reinterpret_cast(fieldPtr)[j]); break; diff --git a/nampower/spellcast.cpp b/nampower/spellcast.cpp index cec09ab..e17d407 100644 --- a/nampower/spellcast.cpp +++ b/nampower/spellcast.cpp @@ -333,6 +333,8 @@ namespace Nampower { castType, guidStr, itemId); + + delete[] guidStr; } void clearCastingSpell() { diff --git a/nampower/spellevents.cpp b/nampower/spellevents.cpp index e105a39..cd82264 100644 --- a/nampower/spellevents.cpp +++ b/nampower/spellevents.cpp @@ -562,6 +562,9 @@ namespace Nampower { hitInfo, spellSchool, effectsAuraTypeStream.str().c_str()); + + delete[] targetGuidStr; + delete[] casterGuidStr; } int PeriodicAuraLogHandlerHook(hadesmem::PatchDetourBase *detour, uint32_t unk, uint32_t opCode, uint32_t unk2, diff --git a/nampower/unit_fields.cpp b/nampower/unit_fields.cpp index 2c5ed93..d5de633 100644 --- a/nampower/unit_fields.cpp +++ b/nampower/unit_fields.cpp @@ -86,8 +86,8 @@ namespace Nampower { {"virtualItemInfo", offsetof(game::UnitFields, virtualItemInfo), FieldType::UINT32, 6}, {"aura", offsetof(game::UnitFields, aura), FieldType::UINT32, 48}, {"auraFlags", offsetof(game::UnitFields, auraFlags), FieldType::UINT32, 6}, - {"auraLevels", offsetof(game::UnitFields, auraLevels), FieldType::UINT32, 12}, - {"auraApplications", offsetof(game::UnitFields, auraApplications), FieldType::UINT32, 12}, + {"auraLevels", offsetof(game::UnitFields, auraLevels), FieldType::UINT8, 48}, + {"auraApplications", offsetof(game::UnitFields, auraApplications), FieldType::UINT8, 48}, {"resistances", offsetof(game::UnitFields, resistances), FieldType::UINT32, 7}, {"powerCostModifier", offsetof(game::UnitFields, powerCostModifier), FieldType::FLOAT, 7}, {"powerCostMultiplier", offsetof(game::UnitFields, powerCostMultiplier), FieldType::FLOAT, 7},