add CancelPlayerAuraSpellId/CancelPlayerAuraSlot

This commit is contained in:
avitasia
2026-02-12 09:10:14 -08:00
parent a7d2cd4fa6
commit c094fdd5e8
10 changed files with 11003 additions and 10895 deletions
+3 -1
View File
@@ -152,9 +152,11 @@ This includes functions for:
- Cast information (GetCastInfo, GetCurrentCastingInfo) - Cast information (GetCastInfo, GetCurrentCastingInfo)
- Cooldown tracking (GetSpellIdCooldown, GetItemIdCooldown), including item metadata on cooldown detail tables - Cooldown tracking (GetSpellIdCooldown, GetItemIdCooldown), including item metadata on cooldown detail tables
- Inventory helpers (GetTrinketCooldown, GetTrinkets, GetAmmo) - Inventory helpers (GetTrinketCooldown, GetTrinkets, GetAmmo)
- Aura duration tracking (GetPlayerAuraDuration) - Aura duration tracking and cancel helpers (GetPlayerAuraDuration, CancelPlayerAuraSlot, CancelPlayerAuraSpellId)
- Spell lookups and utilities - Spell lookups and utilities
`CancelPlayerAuraSpellId(spellId, [ignoreMissing])` supports an optional second parameter where `1` skips the aura-slot presence check (useful for buff-capped cases) and `0`/omitted keeps the default check.
Cooldown detail tables now also expose `itemId`, `itemHasActiveSpell`, and `itemActiveSpellId` alongside the existing per-category timing data. Cooldown detail tables now also expose `itemId`, `itemHasActiveSpell`, and `itemActiveSpellId` alongside the existing per-category timing data.
Use `GetTrinkets([copy])` to enumerate equipped trinkets and bagged trinkets (backpack/bags 1-4) with `itemId`, `trinketName`, `texture`, `itemLevel`, `bagIndex` (nil when equipped), and 1-based `slotIndex`. It reuses cached tables by default; pass `1` (or any truthy value) to force a fresh copy. Use `GetTrinkets([copy])` to enumerate equipped trinkets and bagged trinkets (backpack/bags 1-4) with `itemId`, `trinketName`, `texture`, `itemLevel`, `bagIndex` (nil when equipped), and 1-based `slotIndex`. It reuses cached tables by default; pass `1` (or any truthy value) to force a fresh copy.
+10891 -10884
View File
File diff suppressed because it is too large Load Diff
+2 -3
View File
@@ -147,10 +147,9 @@ namespace Nampower {
bool isBuff = auraSlot < 32; bool isBuff = auraSlot < 32;
game::Events eventToTrigger = isBuff ? game::BUFF_UPDATE_DURATION_SELF : game::DEBUFF_UPDATE_DURATION_SELF; game::Events eventToTrigger = isBuff ? game::BUFF_UPDATE_DURATION_SELF : game::DEBUFF_UPDATE_DURATION_SELF;
auto playerUnit = game::GetObjectPtr(game::ClntObjMgrGetActivePlayerGuid());
uint32_t spellId = 0; uint32_t spellId = 0;
if (playerUnit) { auto *unitFields = game::GetActivePlayerUnitFields();
auto *unitFields = *reinterpret_cast<game::UnitFields **>(playerUnit + 68); if (unitFields) {
spellId = unitFields->aura[auraSlot]; spellId = unitFields->aura[auraSlot];
} }
+11 -1
View File
@@ -134,6 +134,16 @@ namespace game {
return getActivePlayer(); return getActivePlayer();
} }
UnitFields *GetActivePlayerUnitFields() {
auto const playerGuid = ClntObjMgrGetActivePlayerGuid();
auto *playerUnit = GetObjectPtr(playerGuid);
if (!playerUnit) {
return nullptr;
}
return *reinterpret_cast<UnitFields **>(playerUnit + 68);
}
std::uint64_t GetCurrentTargetGuid() { std::uint64_t GetCurrentTargetGuid() {
return *reinterpret_cast<uint64_t *>(Offsets::LockedTargetGuid); return *reinterpret_cast<uint64_t *>(Offsets::LockedTargetGuid);
} }
@@ -267,4 +277,4 @@ namespace game {
return unitFields->mountDisplayId; return unitFields->mountDisplayId;
} }
} }
+1
View File
@@ -1786,6 +1786,7 @@ namespace game {
const char *GetSpellName(uint32_t spellId); const char *GetSpellName(uint32_t spellId);
std::uint64_t ClntObjMgrGetActivePlayerGuid(); std::uint64_t ClntObjMgrGetActivePlayerGuid();
UnitFields *GetActivePlayerUnitFields();
std::uint64_t GetCurrentTargetGuid(); std::uint64_t GetCurrentTargetGuid();
+6
View File
@@ -1689,6 +1689,12 @@ namespace Nampower {
char getPlayerAuraDuration[] = "GetPlayerAuraDuration"; char getPlayerAuraDuration[] = "GetPlayerAuraDuration";
RegisterLuaFunction(getPlayerAuraDuration, reinterpret_cast<uintptr_t *>(Script_GetPlayerAuraDuration)); RegisterLuaFunction(getPlayerAuraDuration, reinterpret_cast<uintptr_t *>(Script_GetPlayerAuraDuration));
char cancelPlayerAuraSlot[] = "CancelPlayerAuraSlot";
RegisterLuaFunction(cancelPlayerAuraSlot, reinterpret_cast<uintptr_t *>(Script_CancelPlayerAuraSlot));
char cancelPlayerAuraSpellId[] = "CancelPlayerAuraSpellId";
RegisterLuaFunction(cancelPlayerAuraSpellId, reinterpret_cast<uintptr_t *>(Script_CancelPlayerAuraSpellId));
char getSpellPower[] = "GetSpellPower"; char getSpellPower[] = "GetSpellPower";
RegisterLuaFunction(getSpellPower, reinterpret_cast<uintptr_t *>(Script_GetSpellPower)); RegisterLuaFunction(getSpellPower, reinterpret_cast<uintptr_t *>(Script_GetSpellPower));
+1 -1
View File
@@ -25,7 +25,7 @@ namespace Nampower {
constexpr uint32_t DISENCHANT_QUALITY_PURPLE = 0x04; // Epic constexpr uint32_t DISENCHANT_QUALITY_PURPLE = 0x04; // Epic
constexpr uint32_t MAJOR_VERSION = 2; constexpr uint32_t MAJOR_VERSION = 2;
constexpr uint32_t MINOR_VERSION = 33; constexpr uint32_t MINOR_VERSION = 34;
constexpr uint32_t PATCH_VERSION = 0; constexpr uint32_t PATCH_VERSION = 0;
constexpr int32_t LUA_REGISTRYINDEX = -10000; constexpr int32_t LUA_REGISTRYINDEX = -10000;
+85 -5
View File
@@ -857,14 +857,11 @@ namespace Nampower {
} }
// Get spellId from player unit fields // Get spellId from player unit fields
auto playerGuid = game::ClntObjMgrGetActivePlayerGuid(); auto *unitFields = game::GetActivePlayerUnitFields();
auto *playerUnit = game::GetObjectPtr(playerGuid); if (!unitFields) {
if (!playerUnit) {
lua_pushnil(luaState); lua_pushnil(luaState);
return 1; return 1;
} }
auto *unitFields = *reinterpret_cast<game::UnitFields **>(playerUnit + 68);
uint32_t spellId = unitFields->aura[auraSlot]; uint32_t spellId = unitFields->aura[auraSlot];
uint32_t expirationTime = gAuraExpirationTime[auraSlot]; uint32_t expirationTime = gAuraExpirationTime[auraSlot];
@@ -877,6 +874,89 @@ namespace Nampower {
return 3; return 3;
} }
uint32_t Script_CancelPlayerAuraSlot(uintptr_t *luaState) {
constexpr uint32_t kMaxCancelAuraSlots = 32;
luaState = GetLuaStatePtr();
if (!lua_isnumber(luaState, 1)) {
lua_error(luaState, "Usage: CancelPlayerAuraSlot(auraSlot)");
return 0;
}
auto auraSlot = static_cast<uint32_t>(lua_tonumber(luaState, 1));
if (auraSlot >= kMaxCancelAuraSlots) {
lua_pushnumber(luaState, 0);
return 1;
}
auto *unitFields = game::GetActivePlayerUnitFields();
if (!unitFields) {
lua_pushnumber(luaState, 0);
return 1;
}
auto spellId = static_cast<int>(unitFields->aura[auraSlot]);
if (spellId == 0) {
lua_pushnumber(luaState, 0);
return 1;
}
auto const cancelAura = reinterpret_cast<void(__fastcall *)(int)>(Offsets::Spell_C_CancelAura);
cancelAura(spellId);
lua_pushnumber(luaState, 1);
return 1;
}
uint32_t Script_CancelPlayerAuraSpellId(uintptr_t *luaState) {
constexpr uint32_t kMaxCancelAuraSlots = 32;
luaState = GetLuaStatePtr();
if (!lua_isnumber(luaState, 1)) {
lua_error(luaState, "Usage: CancelPlayerAuraSpellId(spellId, [ignoreMissing])");
return 0;
}
auto spellId = static_cast<uint32_t>(lua_tonumber(luaState, 1));
if (spellId == 0) {
lua_pushnumber(luaState, 0);
return 1;
}
// Optional arg2: 1 skips aura-presence check, 0/missing keeps default behavior.
bool ignoreMissing = false;
if (lua_isnumber(luaState, 2)) {
ignoreMissing = (static_cast<int>(lua_tonumber(luaState, 2)) == 1);
}
if (!ignoreMissing) {
auto *unitFields = game::GetActivePlayerUnitFields();
if (!unitFields) {
lua_pushnumber(luaState, 0);
return 1;
}
bool foundSpell = false;
for (uint32_t auraSlot = 0; auraSlot < kMaxCancelAuraSlots; ++auraSlot) {
if (unitFields->aura[auraSlot] == spellId) {
foundSpell = true;
break;
}
}
if (!foundSpell) {
lua_pushnumber(luaState, 0);
return 1;
}
}
auto const cancelAura = reinterpret_cast<void(__fastcall *)(uint32_t)>(Offsets::Spell_C_CancelAura);
cancelAura(spellId);
lua_pushnumber(luaState, 1);
return 1;
}
uint32_t CSimpleFrame_GetNameHook(hadesmem::PatchDetourBase *detour, uintptr_t *luaState) { uint32_t CSimpleFrame_GetNameHook(hadesmem::PatchDetourBase *detour, uintptr_t *luaState) {
luaState = GetLuaStatePtr(); luaState = GetLuaStatePtr();
+2
View File
@@ -41,6 +41,8 @@ namespace Nampower {
bool RunQueuedScript(int priority); bool RunQueuedScript(int priority);
uint32_t Script_GetPlayerAuraDuration(uintptr_t *luaState); uint32_t Script_GetPlayerAuraDuration(uintptr_t *luaState);
uint32_t Script_CancelPlayerAuraSlot(uintptr_t *luaState);
uint32_t Script_CancelPlayerAuraSpellId(uintptr_t *luaState);
uint32_t CSimpleFrame_GetNameHook(hadesmem::PatchDetourBase *detour, uintptr_t *luaState); uint32_t CSimpleFrame_GetNameHook(hadesmem::PatchDetourBase *detour, uintptr_t *luaState);
} }
+1
View File
@@ -117,6 +117,7 @@ enum class Offsets : std::uint32_t {
Spell_C_GetAutoRepeatingSpell = 0x006E9FD0, Spell_C_GetAutoRepeatingSpell = 0x006E9FD0,
Spell_C_HandleSpriteClick = 0x006E5B10, Spell_C_HandleSpriteClick = 0x006E5B10,
Spell_C_HandleTerrainClick = 0x006E60F0, Spell_C_HandleTerrainClick = 0x006E60F0,
Spell_C_CancelAura = 0x006E7040,
CGWorldFrame_OnLayerTrackTerrain = 0x004820F0, CGWorldFrame_OnLayerTrackTerrain = 0x004820F0,
Spell_C_TargetSpell = 0x006E5250, Spell_C_TargetSpell = 0x006E5250,
Spell_C_GetSpellCooldown = 0X006E2EA0, Spell_C_GetSpellCooldown = 0X006E2EA0,