mirror of
https://github.com/brues-code/nampower.git
synced 2026-10-10 07:30:01 +00:00
add new events for auras and unit death
This commit is contained in:
@@ -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.
|
||||
|
||||
|
||||
+2
-4
@@ -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
|
||||
|
||||
@@ -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})
|
||||
|
||||
@@ -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<game::UnitFields **>(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<unsigned long long>(playerGuid));
|
||||
} else {
|
||||
std::snprintf(guidStr, 21, "0x%016llX", static_cast<unsigned long long>(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<CGUnit_C_OnAuraRemovedT>();
|
||||
|
||||
// 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<CGUnit_C_OnAuraAddedT>();
|
||||
|
||||
// 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<CGUnit_C_OnAuraAddedStackT>();
|
||||
|
||||
// Call the original function
|
||||
unitAuraAddedStack(unit, slot);
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
void UnitCombatLogUnitDeadHook(hadesmem::PatchDetourBase *detour, uint64_t guid) {
|
||||
auto const unitCombatLogUnitDead = detour->GetTrampolineT<UnitCombatLogUnitDeadT>();
|
||||
|
||||
// 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<unsigned long long>(guid));
|
||||
|
||||
((int (__cdecl *)(int, char *, char *)) Offsets::SignalEventParam)(
|
||||
game::UNIT_DIED,
|
||||
format,
|
||||
guidStr);
|
||||
|
||||
delete[] guidStr;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
//
|
||||
// Created by pmacc on 12/7/2025.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Windows.h>
|
||||
#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);
|
||||
}
|
||||
@@ -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<double>(*reinterpret_cast<const uint64_t*>(fieldPtr)));
|
||||
break;
|
||||
case FieldType::UINT8:
|
||||
lua_pushnumber(luaState, *reinterpret_cast<const uint8_t*>(fieldPtr));
|
||||
break;
|
||||
case FieldType::STRING: {
|
||||
const char* str = *reinterpret_cast<const char* const*>(fieldPtr);
|
||||
lua_pushstring(luaState, str ? const_cast<char*>(str) : const_cast<char*>(""));
|
||||
@@ -123,6 +127,9 @@ namespace Nampower {
|
||||
case FieldType::UINT64:
|
||||
lua_pushnumber(luaState, static_cast<double>(reinterpret_cast<const uint64_t*>(fieldPtr)[j]));
|
||||
break;
|
||||
case FieldType::UINT8:
|
||||
lua_pushnumber(luaState, reinterpret_cast<const uint8_t*>(fieldPtr)[j]);
|
||||
break;
|
||||
case FieldType::STRING: {
|
||||
const char* str = reinterpret_cast<const char* const*>(fieldPtr)[j];
|
||||
lua_pushstring(luaState, str ? const_cast<char*>(str) : const_cast<char*>(""));
|
||||
|
||||
+15
-3
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
+85
-27
@@ -37,6 +37,7 @@
|
||||
#include "spellchannel.hpp"
|
||||
#include "helper.hpp"
|
||||
#include "items.hpp"
|
||||
#include "auras.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
@@ -86,6 +87,7 @@ namespace Nampower {
|
||||
std::unique_ptr<hadesmem::PatchDetour<SpellVisualsInitializeT >> gSpellVisualsInitDetour;
|
||||
std::unique_ptr<hadesmem::PatchDetour<LoadScriptFunctionsT >> gLoadScriptFunctionsDetour;
|
||||
std::unique_ptr<hadesmem::PatchDetour<FrameScript_CreateEventsT >> gCreateEventsDetour;
|
||||
std::unique_ptr<hadesmem::PatchDetour<FramescriptSetEventCountT >> gSetEventCountDetour;
|
||||
|
||||
std::unique_ptr<hadesmem::PatchDetour<SetCVarT>> gSetCVarDetour;
|
||||
std::unique_ptr<hadesmem::PatchDetour<CastSpellT>> gCastDetour;
|
||||
@@ -121,6 +123,10 @@ namespace Nampower {
|
||||
std::unique_ptr<hadesmem::PatchDetour<FastCallPacketHandlerT>> gSpellNonMeleeDmgLogHandlerDetour;
|
||||
|
||||
std::unique_ptr<hadesmem::PatchDetour<CGPlayer_C_OnAttackIconPressedT>> gCGPlayer_C_OnAttackIconPressedDetour;
|
||||
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<UnitCombatLogUnitDeadT>> gUnitCombatLogUnitDeadDetour;
|
||||
|
||||
std::unique_ptr<hadesmem::PatchDetour<InvalidFunctionPtrCheckT>> gInvalidFunctionPtrCheckDetour;
|
||||
|
||||
@@ -1066,28 +1072,6 @@ namespace Nampower {
|
||||
gBufferTimeMs = gUserSettings.minBufferTimeMs;
|
||||
}
|
||||
|
||||
void initCustomEvents() {
|
||||
auto strPtr = reinterpret_cast<uintptr_t *>(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<uintptr_t>(SPELL_QUEUE_EVENT);
|
||||
|
||||
strPtr = reinterpret_cast<uintptr_t *>(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<uintptr_t>(SPELL_CAST_EVENT);
|
||||
|
||||
strPtr = reinterpret_cast<uintptr_t *>(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<uintptr_t>(SPELL_DAMAGE_EVENT_SELF);
|
||||
|
||||
strPtr = reinterpret_cast<uintptr_t *>(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<uintptr_t>(SPELL_DAMAGE_EVENT_OTHER);
|
||||
}
|
||||
|
||||
// Template function to simplify hook initialization with specific storage
|
||||
template<typename FuncT, typename HookT>
|
||||
std::unique_ptr<hadesmem::PatchDetour<FuncT>>
|
||||
@@ -1101,8 +1085,6 @@ namespace Nampower {
|
||||
void initHooks() {
|
||||
const hadesmem::Process process(::GetCurrentProcessId());
|
||||
|
||||
initCustomEvents();
|
||||
|
||||
gSetCVarDetour = createHook<SetCVarT>(process, Offsets::Script_SetCVar, &Script_SetCVarHook);
|
||||
gCastDetour = createHook<CastSpellT>(process, Offsets::Spell_C_CastSpell, &Spell_C_CastSpellHook);
|
||||
gSendCastDetour = createHook<SendCastT>(process, Offsets::SendCast, &SendCastHook);
|
||||
@@ -1141,6 +1123,14 @@ namespace Nampower {
|
||||
&InvalidFunctionPtrCheckHook);
|
||||
gGetSpellSlotFromLuaDetour = createHook<GetSpellSlotFromLuaT>(process, Offsets::GetSpellSlotFromLua,
|
||||
&GetSpellSlotFromLuaHook);
|
||||
gCGUnit_C_OnAuraRemovedDetour = createHook<CGUnit_C_OnAuraRemovedT>(process, Offsets::CGUnit_C_OnAuraRemoved,
|
||||
&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);
|
||||
gUnitCombatLogUnitDeadDetour = createHook<UnitCombatLogUnitDeadT>(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<char ***>(Offsets::Framescript_EventObject_Data);
|
||||
|
||||
auto SStrDupA = reinterpret_cast<char* (__stdcall *)(char*, char*, int)>(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<FrameScript_CreateEventsT>();
|
||||
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<FramescriptSetEventCountT>();
|
||||
|
||||
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<FramescriptSetEventCountT>(
|
||||
Offsets::Framescript_SetEventCount);
|
||||
gSetEventCountDetour = std::make_unique<hadesmem::PatchDetour<FramescriptSetEventCountT >>(process,
|
||||
setEventCountOrig,
|
||||
&Framescript_SetEventCountHook);
|
||||
gSetEventCountDetour->Apply();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
+3
-2
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
|
||||
@@ -573,6 +573,9 @@ namespace Nampower {
|
||||
case FieldType::UINT32:
|
||||
lua_pushnumber(luaState, *reinterpret_cast<const uint32_t *>(fieldPtr));
|
||||
return 1;
|
||||
case FieldType::UINT8:
|
||||
lua_pushnumber(luaState, *reinterpret_cast<const uint8_t *>(fieldPtr));
|
||||
return 1;
|
||||
case FieldType::FLOAT:
|
||||
lua_pushnumber(luaState, *reinterpret_cast<const float *>(fieldPtr));
|
||||
return 1;
|
||||
@@ -605,6 +608,9 @@ namespace Nampower {
|
||||
case FieldType::UINT32:
|
||||
lua_pushnumber(luaState, reinterpret_cast<const uint32_t *>(fieldPtr)[j]);
|
||||
break;
|
||||
case FieldType::UINT8:
|
||||
lua_pushnumber(luaState, reinterpret_cast<const uint8_t *>(fieldPtr)[j]);
|
||||
break;
|
||||
case FieldType::FLOAT:
|
||||
lua_pushnumber(luaState, reinterpret_cast<const float *>(fieldPtr)[j]);
|
||||
break;
|
||||
@@ -667,6 +673,9 @@ namespace Nampower {
|
||||
case FieldType::UINT32:
|
||||
lua_pushnumber(luaState, *reinterpret_cast<const uint32_t *>(fieldPtr));
|
||||
return 1;
|
||||
case FieldType::UINT8:
|
||||
lua_pushnumber(luaState, *reinterpret_cast<const uint8_t *>(fieldPtr));
|
||||
return 1;
|
||||
case FieldType::FLOAT:
|
||||
lua_pushnumber(luaState, *reinterpret_cast<const float *>(fieldPtr));
|
||||
return 1;
|
||||
@@ -700,6 +709,9 @@ namespace Nampower {
|
||||
case FieldType::UINT32:
|
||||
lua_pushnumber(luaState, reinterpret_cast<const uint32_t *>(fieldPtr)[j]);
|
||||
break;
|
||||
case FieldType::UINT8:
|
||||
lua_pushnumber(luaState, reinterpret_cast<const uint8_t *>(fieldPtr)[j]);
|
||||
break;
|
||||
case FieldType::FLOAT:
|
||||
lua_pushnumber(luaState, reinterpret_cast<const float *>(fieldPtr)[j]);
|
||||
break;
|
||||
@@ -836,6 +848,9 @@ namespace Nampower {
|
||||
case FieldType::UINT32:
|
||||
lua_pushnumber(luaState, *reinterpret_cast<const uint32_t *>(fieldPtr));
|
||||
return 1;
|
||||
case FieldType::UINT8:
|
||||
lua_pushnumber(luaState, *reinterpret_cast<const uint8_t *>(fieldPtr));
|
||||
return 1;
|
||||
case FieldType::UINT64:
|
||||
lua_pushnumber(luaState, static_cast<double>(*reinterpret_cast<const uint64_t *>(fieldPtr)));
|
||||
return 1;
|
||||
@@ -863,6 +878,9 @@ namespace Nampower {
|
||||
case FieldType::UINT32:
|
||||
lua_pushnumber(luaState, reinterpret_cast<const uint32_t *>(fieldPtr)[j]);
|
||||
break;
|
||||
case FieldType::UINT8:
|
||||
lua_pushnumber(luaState, reinterpret_cast<const uint8_t *>(fieldPtr)[j]);
|
||||
break;
|
||||
case FieldType::FLOAT:
|
||||
lua_pushnumber(luaState, reinterpret_cast<const float *>(fieldPtr)[j]);
|
||||
break;
|
||||
|
||||
@@ -333,6 +333,8 @@ namespace Nampower {
|
||||
castType,
|
||||
guidStr,
|
||||
itemId);
|
||||
|
||||
delete[] guidStr;
|
||||
}
|
||||
|
||||
void clearCastingSpell() {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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},
|
||||
|
||||
Reference in New Issue
Block a user