mirror of
https://github.com/brues-code/nampower.git
synced 2026-10-20 20:00:48 +00:00
add ability to pass unitstr to CastSpellByName 2nd param, add SetMouseoverUnit
This commit is contained in:
@@ -120,14 +120,14 @@ Name and spellId lookups are cached internally and validated against current spe
|
||||
|
||||
See examples below for differences in how BOOKTYPE works.
|
||||
|
||||
Functions: `GetSpellIconTexture`, `GetSpellName`, `GetSpellCooldown`, `GetSpellAutocast`, `ToggleSpellAutocast`, `PickupSpell`, `CastSpell`, `IsCurrentCast`, `IsSpellPassive`.
|
||||
Functions: `GetSpellTexture`, `GetSpellName`, `GetSpellCooldown`, `GetSpellAutocast`, `ToggleSpellAutocast`, `PickupSpell`, `CastSpell`, `IsCurrentCast`, `IsSpellPassive`.
|
||||
|
||||
Examples:
|
||||
```
|
||||
/run print(GetSpellIconTexture(1, "spell")) -- booktype required
|
||||
/run print(GetSpellIconTexture("spellId:25978")) -- defaults to BOOKTYPE_SPELL
|
||||
/run print(GetSpellIconTexture("spellId:6268", "pet")) -- "pet" needed for pet spells
|
||||
/run print(GetSpellIconTexture("Fireball")) -- name search
|
||||
/run print(GetSpellTexture(1, "spell")) -- booktype required
|
||||
/run print(GetSpellTexture("spellId:25978")) -- defaults to BOOKTYPE_SPELL
|
||||
/run print(GetSpellTexture("spellId:6268", "pet")) -- "pet" needed for pet spells
|
||||
/run print(GetSpellTexture("Fireball")) -- name search
|
||||
```
|
||||
|
||||
|
||||
|
||||
+5
-2
@@ -689,8 +689,11 @@ For example can make a macro with
|
||||
```
|
||||
to cast 2 frostbolts in a row. Currently, can only queue 1 GCD spell at a time and 5 non gcd spells. This means you can't do 3 frostbolts in a row with one macro.
|
||||
|
||||
#### CastSpellByNameNoQueue(spellName)
|
||||
Will force a spell cast to never queue even if your settings would normally queue. Can be used to fix addons that don't work with queued spells.
|
||||
#### CastSpellByName(spellName, [onSelfOrUnit])
|
||||
The vanilla `CastSpellByName` is enhanced to accept a unit token string (e.g. "mouseover", "party1", "focus", etc.) or a GUID string as the second parameter to cast on that unit. The original behavior of passing `1` to cast on self is preserved.
|
||||
|
||||
#### CastSpellByNameNoQueue(spellName, [onSelfOrUnit])
|
||||
Will force a spell cast to never queue even if your settings would normally queue. Can be used to fix addons that don't work with queued spells. Supports the same unit string parameter as `CastSpellByName`.
|
||||
|
||||
#### QueueScript(script, [priority])
|
||||
Queues any arbitrary script using the same logic as a regular spell using NP_SpellQueueWindowMs as the window. If no spell is being cast and you are not on the gcd the script will be run immediately.
|
||||
|
||||
+11346
-11333
File diff suppressed because it is too large
Load Diff
+4
-4
@@ -34,9 +34,9 @@ namespace Nampower {
|
||||
luaL_unrefT luaL_unref = reinterpret_cast<luaL_unrefT>(Offsets::luaL_unref);
|
||||
|
||||
|
||||
uint32_t GetSpellSlotAndTypeForName(const char *spellName, uint32_t *spellType) {
|
||||
int32_t GetSpellSlotAndTypeForName(const char *spellName, uint32_t *spellType) {
|
||||
struct CachedEntry {
|
||||
uint32_t slot;
|
||||
int32_t slot;
|
||||
uint32_t type;
|
||||
std::string cachedNameLower;
|
||||
};
|
||||
@@ -109,10 +109,10 @@ namespace Nampower {
|
||||
|
||||
uint32_t GetSpellIdFromSpellName(const char *spellName) {
|
||||
uint32_t bookType;
|
||||
uint32_t spellSlot = GetSpellSlotAndTypeForName(spellName, &bookType);
|
||||
int32_t spellSlot = GetSpellSlotAndTypeForName(spellName, &bookType);
|
||||
|
||||
uint32_t spellId = 0;
|
||||
if (spellSlot < 1024) {
|
||||
if (spellSlot >= 0 && spellSlot < 1024) {
|
||||
if (bookType == 0) {
|
||||
spellId = *reinterpret_cast<uint32_t *>(static_cast<uint32_t>(Offsets::CGSpellBook_mKnownSpells) +
|
||||
spellSlot * 4);
|
||||
|
||||
+1
-1
@@ -42,7 +42,7 @@ namespace Nampower {
|
||||
return lua_type(luaState, idx) == LUA_TTABLE;
|
||||
}
|
||||
|
||||
uint32_t GetSpellSlotAndTypeForName(const char *spellName, uint32_t *spellType);
|
||||
int32_t GetSpellSlotAndTypeForName(const char *spellName, uint32_t *spellType);
|
||||
|
||||
uint32_t GetSpellIdFromSpellName(const char *spellName);
|
||||
|
||||
|
||||
+7
-1
@@ -156,6 +156,7 @@ namespace Nampower {
|
||||
std::unique_ptr<hadesmem::PatchDetour<GetSpellSlotFromLuaT> > gGetSpellSlotFromLuaDetour;
|
||||
|
||||
std::unique_ptr<hadesmem::PatchDetour<LuaScriptT> > gCSimpleFrame_GetNameDetour;
|
||||
std::unique_ptr<hadesmem::PatchDetour<LuaScriptT> > gCastSpellByNameDetour;
|
||||
|
||||
// Flags for one-time initialization
|
||||
std::once_flag loadFlag;
|
||||
@@ -561,7 +562,7 @@ namespace Nampower {
|
||||
gQueuesProcessed = true;
|
||||
|
||||
// Process item export if active (low priority, runs when nothing else is queued)
|
||||
// ProcessItemExport()
|
||||
// ProcessItemExport();
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -1368,6 +1369,8 @@ namespace Nampower {
|
||||
&Spell_C_SpellFailedHook);
|
||||
gSpellGoDetour = createHook<SpellGoT>(process, Offsets::SpellGo, &SpellGoHook);
|
||||
gSpellDelayedDetour = createHook<PacketHandlerT>(process, Offsets::SpellDelayed, &SpellDelayedHook);
|
||||
gCastSpellByNameDetour = createHook<LuaScriptT>(process, Offsets::Script_CastSpellByName,
|
||||
&Script_CastSpellByNameHook);
|
||||
gSpellTargetUnitDetour = createHook<LuaScriptT>(process, Offsets::Script_SpellTargetUnit,
|
||||
&Script_SpellTargetUnitHook);
|
||||
gSpellStopCastingDetour = createHook<LuaScriptT>(process, Offsets::Script_SpellStopCasting,
|
||||
@@ -1711,6 +1714,9 @@ namespace Nampower {
|
||||
char playerIsSwimming[] = "PlayerIsSwimming";
|
||||
RegisterLuaFunction(playerIsSwimming, reinterpret_cast<uintptr_t *>(Script_PlayerIsSwimming));
|
||||
|
||||
char setMouseoverUnit[] = "SetMouseoverUnit";
|
||||
RegisterLuaFunction(setMouseoverUnit, reinterpret_cast<uintptr_t *>(Script_SetMouseoverUnit));
|
||||
|
||||
}
|
||||
|
||||
void load() {
|
||||
|
||||
+3
-2
@@ -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 = 36;
|
||||
constexpr uint32_t MINOR_VERSION = 37;
|
||||
constexpr uint32_t PATCH_VERSION = 0;
|
||||
|
||||
constexpr int32_t LUA_REGISTRYINDEX = -10000;
|
||||
@@ -82,6 +82,7 @@ namespace Nampower {
|
||||
using EndSceneT = int (__fastcall *)(uintptr_t *unk);
|
||||
using OnSpriteRightClickT = int (__fastcall *)(uint64_t objectGUID);
|
||||
using CGGameUI_TargetT = void (__stdcall *)(uint64_t objectGUID);
|
||||
using CGGameUI_HandleObjectTrackChangeT = void (__stdcall *)(uint64_t guid, uint32_t param3, uint32_t param4);
|
||||
using Spell_C_SpellFailedT = void (__fastcall *)(uint32_t, game::SpellCastResult, int, int, bool);
|
||||
using Spell_C_GetAutoRepeatingSpellT = int (__cdecl *)();
|
||||
using SpellGoT = void (__fastcall *)(uint64_t *, uint64_t *, uint32_t, CDataStore *);
|
||||
@@ -105,7 +106,7 @@ namespace Nampower {
|
||||
using CGActionBar_UseActionT = void (__fastcall *)(uint32_t param_1, int param_2, int param_3);
|
||||
using CGCharacterInfo_UseItemT = void (__fastcall *)(uintptr_t *this_ptr, void *dummy_edx, uint32_t itemSlot, uint64_t *targetGuid);
|
||||
|
||||
using GetSpellSlotAndTypeT = uint32_t (__fastcall *)(const char *, uint32_t *);
|
||||
using GetSpellSlotAndTypeT = int32_t (__fastcall *)(const char *, uint32_t *);
|
||||
using GetSpellSlotFromLuaT = uint32_t (__fastcall *)(int param_1, uint32_t *slot, uint32_t *type);
|
||||
using GetTimeMsT = uint64_t (__stdcall *)();
|
||||
|
||||
|
||||
@@ -1097,6 +1097,32 @@ namespace Nampower {
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32_t Script_SetMouseoverUnit(uintptr_t *luaState) {
|
||||
luaState = GetLuaStatePtr();
|
||||
|
||||
uint64_t guid = 0;
|
||||
if (lua_isstring(luaState, 1)) {
|
||||
const char *unitToken = lua_tostring(luaState, 1);
|
||||
auto const getGUIDFromName = reinterpret_cast<GetGUIDFromNameT>(Offsets::GetGUIDFromName);
|
||||
guid = getGUIDFromName(unitToken);
|
||||
}
|
||||
|
||||
auto const handleObjectTrackChange = reinterpret_cast<CGGameUI_HandleObjectTrackChangeT>(
|
||||
Offsets::CGGameUI_HandleObjectTrackChange);
|
||||
handleObjectTrackChange(guid, 0, 0);
|
||||
|
||||
auto const mouseoverLow = *reinterpret_cast<uint32_t *>(Offsets::MouseoverGuidLow);
|
||||
auto const mouseoverHigh = *reinterpret_cast<uint32_t *>(Offsets::MouseoverGuidHigh);
|
||||
|
||||
if (mouseoverLow != 0 || mouseoverHigh != 0) {
|
||||
lua_pushnumber(luaState, 1);
|
||||
} else {
|
||||
lua_pushnil(luaState);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32_t CSimpleFrame_GetNameHook(hadesmem::PatchDetourBase *detour, uintptr_t *luaState) {
|
||||
luaState = GetLuaStatePtr();
|
||||
|
||||
|
||||
@@ -45,5 +45,7 @@ namespace Nampower {
|
||||
uint32_t Script_CancelPlayerAuraSlot(uintptr_t *luaState);
|
||||
uint32_t Script_CancelPlayerAuraSpellId(uintptr_t *luaState);
|
||||
|
||||
uint32_t Script_SetMouseoverUnit(uintptr_t *luaState);
|
||||
|
||||
uint32_t CSimpleFrame_GetNameHook(hadesmem::PatchDetourBase *detour, uintptr_t *luaState);
|
||||
}
|
||||
|
||||
@@ -87,9 +87,13 @@ enum class Offsets : std::uint32_t {
|
||||
|
||||
LockedTargetGuid = 0x00B4E2D8,
|
||||
OnSpriteRightClick = 0x00492820,
|
||||
CGGameUI_HandleObjectTrackChange = 0x00492890,
|
||||
CGGameUI_Target = 0X00493540,
|
||||
ScriptTargetUnit = 0X00489A40,
|
||||
|
||||
MouseoverGuidLow = 0x00B4E2C8,
|
||||
MouseoverGuidHigh = 0x00B4E2CC,
|
||||
|
||||
SpellVisualsHandleCastStart = 0X006EC220,
|
||||
PlaySpellVisualHandler = 0X006E98D0,
|
||||
PlaySpellVisual = 0X0060EDF0,
|
||||
|
||||
@@ -32,6 +32,38 @@ namespace Nampower {
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t Script_CastSpellByNameHook(hadesmem::PatchDetourBase *detour, uintptr_t *luaState) {
|
||||
luaState = GetLuaStatePtr();
|
||||
|
||||
if (!lua_isstring(luaState, 1)) {
|
||||
lua_error(luaState, "Usage: CastSpellByName(name [, onSelfOrUnit])");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Check if 2nd param is strictly a string (type 4), not a number that lua_isstring would also match
|
||||
if (lua_type(luaState, 2) == 4) {
|
||||
auto const unitToken = lua_tostring(luaState, 2);
|
||||
auto const unitGuid = GetUnitGuidFromString(unitToken);
|
||||
|
||||
if (unitGuid != 0) {
|
||||
auto const spellName = lua_tostring(luaState, 1);
|
||||
uint32_t bookType = 0;
|
||||
auto spellSlot = GetSpellSlotAndTypeForName(spellName, &bookType);
|
||||
|
||||
if (spellSlot >= 0 && spellSlot < 100000) {
|
||||
auto const castSpell = reinterpret_cast<CGSpellBook_CastSpellT>(Offsets::CGSpellBook_CastSpell);
|
||||
castSpell(spellSlot, bookType, unitGuid);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Fall through to original for normal calls (no 2nd param, or number "on self" flag)
|
||||
auto const castSpellByName = detour->GetTrampolineT<LuaScriptT>();
|
||||
return castSpellByName(luaState);
|
||||
}
|
||||
|
||||
uint32_t Script_QueueSpellByName(uintptr_t *luaState) {
|
||||
luaState = GetLuaStatePtr(); // pcall leads to corrupted lua state pointer on added scripts, not sure why
|
||||
|
||||
@@ -226,8 +258,8 @@ namespace Nampower {
|
||||
uint32_t bookType;
|
||||
auto spellSlot = GetSpellSlotAndTypeForName(spellName, &bookType);
|
||||
|
||||
// returns large number if spell not found
|
||||
if (spellSlot > 100000) {
|
||||
// returns -1 or large number if spell not found
|
||||
if (spellSlot < 0 || spellSlot > 100000) {
|
||||
lua_pushnumber(luaState, 0);
|
||||
spellSlot = 0;
|
||||
bookType = 999;
|
||||
@@ -548,8 +580,8 @@ namespace Nampower {
|
||||
} else {
|
||||
uint32_t bookType;
|
||||
auto spellSlot = GetSpellSlotAndTypeForName(spellStr, &bookType);
|
||||
// returns large number if spell not found
|
||||
if (spellSlot == 0 || spellSlot > 100000) {
|
||||
// returns -1 or large number if spell not found
|
||||
if (spellSlot < 0 || spellSlot > 100000) {
|
||||
lua_error(luaState, "Unable to find spell slot for spell name.");
|
||||
return 0;
|
||||
} else {
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
namespace Nampower {
|
||||
uint32_t Script_CastSpellByNameNoQueue(uintptr_t *luaState);
|
||||
|
||||
uint32_t Script_CastSpellByNameHook(hadesmem::PatchDetourBase *detour, uintptr_t *luaState);
|
||||
|
||||
uint32_t Script_QueueSpellByName(uintptr_t *luaState);
|
||||
|
||||
uint32_t Script_IsSpellInRange(uintptr_t *luaState);
|
||||
|
||||
Reference in New Issue
Block a user