mirror of
https://github.com/brues-code/nampower.git
synced 2026-09-21 23:26:54 +00:00
add new texture functions, fix tooltip/description missing on spellrec
This commit is contained in:
@@ -75,6 +75,7 @@ Related structs live in `nampower/game.hpp` (notably `SpellRec` and `ItemStats_C
|
|||||||
- `castingTimeIndex`
|
- `castingTimeIndex`
|
||||||
- `channelInterruptFlags`
|
- `channelInterruptFlags`
|
||||||
- `dispel`
|
- `dispel`
|
||||||
|
- `description` (string, defaults to current language)
|
||||||
- `dmgClass`
|
- `dmgClass`
|
||||||
- `durationIndex`
|
- `durationIndex`
|
||||||
- `equippedItemClass`
|
- `equippedItemClass`
|
||||||
@@ -87,6 +88,7 @@ Related structs live in `nampower/game.hpp` (notably `SpellRec` and `ItemStats_C
|
|||||||
- `manaCostPerlevel`
|
- `manaCostPerlevel`
|
||||||
- `manaPerSecond`
|
- `manaPerSecond`
|
||||||
- `manaPerSecondPerLevel`
|
- `manaPerSecondPerLevel`
|
||||||
|
- `name` (string, defaults to current language)
|
||||||
- `maxAffectedTargets`
|
- `maxAffectedTargets`
|
||||||
- `maxLevel`
|
- `maxLevel`
|
||||||
- `maxTargetLevel`
|
- `maxTargetLevel`
|
||||||
@@ -100,6 +102,7 @@ Related structs live in `nampower/game.hpp` (notably `SpellRec` and `ItemStats_C
|
|||||||
- `procCharges`
|
- `procCharges`
|
||||||
- `procFlags`
|
- `procFlags`
|
||||||
- `rangeIndex`
|
- `rangeIndex`
|
||||||
|
- `rank` (string, defaults to current language)
|
||||||
- `recoveryTime`
|
- `recoveryTime`
|
||||||
- `requiredAuraVision`
|
- `requiredAuraVision`
|
||||||
- `school`
|
- `school`
|
||||||
@@ -118,8 +121,10 @@ Related structs live in `nampower/game.hpp` (notably `SpellRec` and `ItemStats_C
|
|||||||
- `targetAuraState`
|
- `targetAuraState`
|
||||||
- `targetCreatureType`
|
- `targetCreatureType`
|
||||||
- `targets`
|
- `targets`
|
||||||
|
- `tooltip` (string, defaults to current language)
|
||||||
|
|
||||||
### SpellRec Array Fields (alphabetical)
|
### SpellRec Array Fields (alphabetical)
|
||||||
|
- `description` (char* x8, one per language)
|
||||||
- `dmgMultiplier`
|
- `dmgMultiplier`
|
||||||
- `effect`
|
- `effect`
|
||||||
- `effectAmplitude`
|
- `effectAmplitude`
|
||||||
@@ -139,6 +144,9 @@ Related structs live in `nampower/game.hpp` (notably `SpellRec` and `ItemStats_C
|
|||||||
- `effectRadiusIndex`
|
- `effectRadiusIndex`
|
||||||
- `effectRealPointsPerLevel`
|
- `effectRealPointsPerLevel`
|
||||||
- `effectTriggerSpell`
|
- `effectTriggerSpell`
|
||||||
|
- `name` (char* x8, one per language)
|
||||||
|
- `rank` (char* x8, one per language)
|
||||||
- `reagent`
|
- `reagent`
|
||||||
- `reagentCount`
|
- `reagentCount`
|
||||||
|
- `tooltip` (char* x8, one per language)
|
||||||
- `totem`
|
- `totem`
|
||||||
|
|||||||
+44
@@ -26,6 +26,8 @@ For installation, configuration, and general usage information, see the main [RE
|
|||||||
- [GetSpellSlotTypeIdForName](#getspellslottypeidfornamenspellname)
|
- [GetSpellSlotTypeIdForName](#getspellslottypeidfornamenspellname)
|
||||||
- [GetNampowerVersion](#getnampowerversion)
|
- [GetNampowerVersion](#getnampowerversion)
|
||||||
- [GetItemLevel](#getitemlevelitemid)
|
- [GetItemLevel](#getitemlevelitemid)
|
||||||
|
- [GetItemTexture](#getitemtexturedisplayinfoid)
|
||||||
|
- [GetSpellTexture](#getspelltexturespelliconid)
|
||||||
- [Spell Casting and Queuing](#spell-casting-and-queuing)
|
- [Spell Casting and Queuing](#spell-casting-and-queuing)
|
||||||
- [QueueSpellByName](#queuespellbynamespellname)
|
- [QueueSpellByName](#queuespellbynamespellname)
|
||||||
- [CastSpellByNameNoQueue](#castspellbynamenoqueuespellname)
|
- [CastSpellByNameNoQueue](#castspellbynamenoqueuespellname)
|
||||||
@@ -929,6 +931,48 @@ Examples:
|
|||||||
should print 90 for atiesh
|
should print 90 for atiesh
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### GetItemTexture(displayInfoId)
|
||||||
|
Returns the texture path for an item given its display info ID. Returns nil if the texture is not found or is the question mark placeholder texture.
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
- `displayInfoId` (number): The item's display info ID (can be obtained from `GetItemStatsField(itemId, "displayInfoID")`)
|
||||||
|
|
||||||
|
**Returns:**
|
||||||
|
- The texture path string (e.g., "Interface\\Icons\\INV_Sword_04"), or nil if not found
|
||||||
|
|
||||||
|
**Examples:**
|
||||||
|
```lua
|
||||||
|
-- Get texture for an item
|
||||||
|
local displayInfoId = GetItemStatsField(19019, "displayInfoID")
|
||||||
|
local texture = GetItemTexture(displayInfoId)
|
||||||
|
if texture then
|
||||||
|
print("Texture: " .. texture)
|
||||||
|
else
|
||||||
|
print("No texture found")
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
#### GetSpellTexture(spellIconId)
|
||||||
|
Returns the texture path for a spell given its spell icon ID. Returns nil if the texture is not found or is the question mark placeholder texture.
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
- `spellIconId` (number): The spell's icon ID (can be obtained from `GetSpellRecField(spellId, "spellIconID")`)
|
||||||
|
|
||||||
|
**Returns:**
|
||||||
|
- The texture path string with `Interface\Icons\` prefix (e.g., "Interface\\Icons\\Spell_Frost_FrostBolt02"), or nil if not found
|
||||||
|
|
||||||
|
**Examples:**
|
||||||
|
```lua
|
||||||
|
-- Get texture for Frostbolt
|
||||||
|
local spellIconId = GetSpellRecField(116, "spellIconID")
|
||||||
|
local texture = GetSpellTexture(spellIconId)
|
||||||
|
if texture then
|
||||||
|
print("Texture: " .. texture)
|
||||||
|
else
|
||||||
|
print("No texture found")
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
#### ChannelStopCastingNextTick()
|
#### ChannelStopCastingNextTick()
|
||||||
Will stop channeling early on the next tick if you have queue channeling spells enabled and try to cast a spell before the next tick (didn't know how to cancel channels without casting another spell). Uses your ChannelLatencyReductionPercentage to determine when to stop the channel.
|
Will stop channeling early on the next tick if you have queue channeling spells enabled and try to cast a spell before the next tick (didn't know how to cancel channels without casting another spell). Uses your ChannelLatencyReductionPercentage to determine when to stop the channel.
|
||||||
|
|
||||||
|
|||||||
+10923
-10863
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -124,7 +124,7 @@ namespace game {
|
|||||||
|
|
||||||
auto const language = *reinterpret_cast<std::uint32_t *>(Offsets::Language);
|
auto const language = *reinterpret_cast<std::uint32_t *>(Offsets::Language);
|
||||||
|
|
||||||
return spell->SpellName[language];
|
return spell->Name[language];
|
||||||
}
|
}
|
||||||
|
|
||||||
std::uint64_t ClntObjMgrGetActivePlayerGuid() {
|
std::uint64_t ClntObjMgrGetActivePlayerGuid() {
|
||||||
|
|||||||
+4
-4
@@ -192,13 +192,13 @@ namespace game {
|
|||||||
unsigned int SpellIconID;
|
unsigned int SpellIconID;
|
||||||
unsigned int activeIconID;
|
unsigned int activeIconID;
|
||||||
unsigned int spellPriority;
|
unsigned int spellPriority;
|
||||||
const char *SpellName[8];
|
const char *Name[8];
|
||||||
unsigned int SpellNameFlag;
|
unsigned int SpellNameFlag;
|
||||||
unsigned int Rank[8];
|
const char *Rank[8];
|
||||||
unsigned int RankFlags;
|
unsigned int RankFlags;
|
||||||
unsigned int Description[8];
|
const char *Description[8];
|
||||||
unsigned int DescriptionFlags;
|
unsigned int DescriptionFlags;
|
||||||
unsigned int ToolTip[8];
|
const char *ToolTip[8];
|
||||||
unsigned int ToolTipFlags;
|
unsigned int ToolTipFlags;
|
||||||
unsigned int ManaCostPercentage;
|
unsigned int ManaCostPercentage;
|
||||||
unsigned int StartRecoveryCategory;
|
unsigned int StartRecoveryCategory;
|
||||||
|
|||||||
+1
-1
@@ -74,7 +74,7 @@ namespace Nampower {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto const language = *reinterpret_cast<uint32_t *>(Offsets::Language);
|
auto const language = *reinterpret_cast<uint32_t *>(Offsets::Language);
|
||||||
auto const actualName = reinterpret_cast<const char *>(spell->SpellName[language]);
|
auto const actualName = reinterpret_cast<const char *>(spell->Name[language]);
|
||||||
if (!actualName) {
|
if (!actualName) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1646,6 +1646,12 @@ namespace Nampower {
|
|||||||
|
|
||||||
char disenchantAll[] = "DisenchantAll";
|
char disenchantAll[] = "DisenchantAll";
|
||||||
RegisterLuaFunction(disenchantAll, reinterpret_cast<uintptr_t *>(Script_DisenchantAll));
|
RegisterLuaFunction(disenchantAll, reinterpret_cast<uintptr_t *>(Script_DisenchantAll));
|
||||||
|
|
||||||
|
char getItemTexture[] = "GetItemTexture";
|
||||||
|
RegisterLuaFunction(getItemTexture, reinterpret_cast<uintptr_t *>(Script_GetItemTexture));
|
||||||
|
|
||||||
|
char getSpellTexture[] = "GetSpellTexture";
|
||||||
|
RegisterLuaFunction(getSpellTexture, reinterpret_cast<uintptr_t *>(Script_GetSpellTexture));
|
||||||
}
|
}
|
||||||
|
|
||||||
void load() {
|
void load() {
|
||||||
|
|||||||
+1
-1
@@ -35,7 +35,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 = 26;
|
constexpr uint32_t MINOR_VERSION = 27;
|
||||||
constexpr uint32_t PATCH_VERSION = 0;
|
constexpr uint32_t PATCH_VERSION = 0;
|
||||||
|
|
||||||
constexpr int32_t LUA_REGISTRYINDEX = -10000;
|
constexpr int32_t LUA_REGISTRYINDEX = -10000;
|
||||||
|
|||||||
@@ -660,9 +660,9 @@ namespace Nampower {
|
|||||||
// Display which item is being disenchanted
|
// Display which item is being disenchanted
|
||||||
char luaCode[256];
|
char luaCode[256];
|
||||||
snprintf(luaCode, sizeof(luaCode),
|
snprintf(luaCode, sizeof(luaCode),
|
||||||
"local itemLink = GetContainerItemLink(%d, %d); "
|
"local itemLink = GetContainerItemLink(%d, %d); "
|
||||||
"if itemLink then DEFAULT_CHAT_FRAME:AddMessage(\"Disenchanting \" .. itemLink .. \" move during cast to cancel.\") end",
|
"if itemLink then DEFAULT_CHAT_FRAME:AddMessage(\"Disenchanting \" .. itemLink .. \" move during cast to cancel.\") end",
|
||||||
itemSearchResult.bagIndex, itemSearchResult.slot + 1); // Lua slots are 1-indexed
|
itemSearchResult.bagIndex, itemSearchResult.slot + 1); // Lua slots are 1-indexed
|
||||||
LuaCall(luaCode);
|
LuaCall(luaCode);
|
||||||
|
|
||||||
// Set timer for next disenchant attempt (5 seconds to allow time for inventory to update)
|
// Set timer for next disenchant attempt (5 seconds to allow time for inventory to update)
|
||||||
@@ -785,4 +785,60 @@ namespace Nampower {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t Script_GetItemTexture(uintptr_t *luaState) {
|
||||||
|
luaState = GetLuaStatePtr(); // pcall leads to corrupted lua state pointer on added scripts, not sure why
|
||||||
|
|
||||||
|
if (!lua_isnumber(luaState, 1)) {
|
||||||
|
lua_error(luaState, "Usage: GetItemTexture(displayInfoId)");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t displayInfoId = static_cast<uint32_t>(lua_tonumber(luaState, 1));
|
||||||
|
|
||||||
|
auto const getInventoryArt = reinterpret_cast<GetInventoryArtT>(Offsets::CGItem_C_GetInventoryArt);
|
||||||
|
char *texturePath = getInventoryArt(displayInfoId);
|
||||||
|
|
||||||
|
if (texturePath && texturePath[0] != '\0' && !strstr(texturePath, "QuestionMark")) {
|
||||||
|
lua_pushstring(luaState, texturePath);
|
||||||
|
} else {
|
||||||
|
lua_pushnil(luaState);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Script_GetSpellTexture(uintptr_t *luaState) {
|
||||||
|
luaState = GetLuaStatePtr(); // pcall leads to corrupted lua state pointer on added scripts, not sure why
|
||||||
|
|
||||||
|
if (!lua_isnumber(luaState, 1)) {
|
||||||
|
lua_error(luaState, "Usage: GetSpellTexture(spellIconId)");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t iconId = static_cast<int32_t>(lua_tonumber(luaState, 1));
|
||||||
|
|
||||||
|
int32_t maxIconId = *reinterpret_cast<int32_t *>(Offsets::SpellIconDBMaxId);
|
||||||
|
uintptr_t *iconArray = *reinterpret_cast<uintptr_t **>(Offsets::SpellIconDBArray);
|
||||||
|
|
||||||
|
if (iconId < 0 || iconId > maxIconId) {
|
||||||
|
lua_pushnil(luaState);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uintptr_t iconEntry = reinterpret_cast<uintptr_t *>(iconArray)[iconId];
|
||||||
|
if (iconEntry == 0) {
|
||||||
|
lua_pushnil(luaState);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *texturePath = *reinterpret_cast<char **>(iconEntry + 4);
|
||||||
|
if (texturePath && texturePath[0] != '\0' && !strstr(texturePath, "QuestionMark")) {
|
||||||
|
lua_pushstring(luaState, texturePath);
|
||||||
|
} else {
|
||||||
|
lua_pushnil(luaState);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,5 +34,9 @@ namespace Nampower {
|
|||||||
|
|
||||||
uint32_t Script_DisenchantAll(uintptr_t *luaState);
|
uint32_t Script_DisenchantAll(uintptr_t *luaState);
|
||||||
|
|
||||||
|
uint32_t Script_GetItemTexture(uintptr_t *luaState);
|
||||||
|
|
||||||
|
uint32_t Script_GetSpellTexture(uintptr_t *luaState);
|
||||||
|
|
||||||
bool RunQueuedScript(int priority);
|
bool RunQueuedScript(int priority);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -215,6 +215,9 @@ enum class Offsets : std::uint32_t {
|
|||||||
CGItem_C_GetInventoryArt = 0x005D88B0,
|
CGItem_C_GetInventoryArt = 0x005D88B0,
|
||||||
CGItem_C_ItemIsQuestOrSoulbound = 0x005DA2C0,
|
CGItem_C_ItemIsQuestOrSoulbound = 0x005DA2C0,
|
||||||
|
|
||||||
|
SpellIconDBMaxId = 0x00c0d7f0,
|
||||||
|
SpellIconDBArray = 0x00c0d7ec,
|
||||||
|
|
||||||
DBCache_ItemCacheDBGetRow = 0x0055BA30,
|
DBCache_ItemCacheDBGetRow = 0x0055BA30,
|
||||||
|
|
||||||
InvalidFunctionPtrCheck = 0x0042A320,
|
InvalidFunctionPtrCheck = 0x0042A320,
|
||||||
|
|||||||
+27
-14
@@ -204,7 +204,7 @@ namespace Nampower {
|
|||||||
|
|
||||||
if (spell) {
|
if (spell) {
|
||||||
auto const language = *reinterpret_cast<std::uint32_t *>(Offsets::Language);
|
auto const language = *reinterpret_cast<std::uint32_t *>(Offsets::Language);
|
||||||
lua_pushstring(luaState, (char *) spell->SpellName[language]);
|
lua_pushstring(luaState, (char *) spell->Name[language]);
|
||||||
lua_pushstring(luaState, (char *) spell->Rank[language]);
|
lua_pushstring(luaState, (char *) spell->Rank[language]);
|
||||||
return 2;
|
return 2;
|
||||||
} else {
|
} else {
|
||||||
@@ -306,12 +306,17 @@ namespace Nampower {
|
|||||||
// Push string fields manually (require language)
|
// Push string fields manually (require language)
|
||||||
auto const language = *reinterpret_cast<uint32_t *>(Offsets::Language);
|
auto const language = *reinterpret_cast<uint32_t *>(Offsets::Language);
|
||||||
PushTableValue(luaState, const_cast<char *>("name"),
|
PushTableValue(luaState, const_cast<char *>("name"),
|
||||||
spell->SpellName[language] ? const_cast<char *>(spell->SpellName[language])
|
spell->Name[language] ? const_cast<char *>(spell->Name[language])
|
||||||
: const_cast<char *>(""));
|
: const_cast<char *>(""));
|
||||||
PushTableValue(luaState, const_cast<char *>("rank"),
|
PushTableValue(luaState, const_cast<char *>("rank"),
|
||||||
reinterpret_cast<const char *>(spell->Rank[language])
|
spell->Rank[language] ? const_cast<char *>(spell->Rank[language])
|
||||||
? const_cast<char *>(reinterpret_cast<const char *>(spell->Rank[language]))
|
: const_cast<char *>(""));
|
||||||
: const_cast<char *>(""));
|
PushTableValue(luaState, const_cast<char *>("description"),
|
||||||
|
spell->Description[language] ? const_cast<char *>(spell->Description[language])
|
||||||
|
: const_cast<char *>(""));
|
||||||
|
PushTableValue(luaState, const_cast<char *>("tooltip"),
|
||||||
|
spell->ToolTip[language] ? const_cast<char *>(spell->ToolTip[language])
|
||||||
|
: const_cast<char *>(""));
|
||||||
|
|
||||||
// Push all array fields using descriptors with or without references based on copy parameter
|
// Push all array fields using descriptors with or without references based on copy parameter
|
||||||
if (useCopy) {
|
if (useCopy) {
|
||||||
@@ -420,18 +425,26 @@ namespace Nampower {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for special string fields
|
// Check for special string fields (localized, need language index)
|
||||||
|
auto const language = *reinterpret_cast<uint32_t *>(Offsets::Language);
|
||||||
if (strcmp(fieldName, "name") == 0) {
|
if (strcmp(fieldName, "name") == 0) {
|
||||||
auto const language = *reinterpret_cast<uint32_t *>(Offsets::Language);
|
lua_pushstring(luaState, spell->Name[language] ? const_cast<char *>(spell->Name[language])
|
||||||
lua_pushstring(luaState, spell->SpellName[language] ? const_cast<char *>(spell->SpellName[language])
|
: const_cast<char *>(""));
|
||||||
: const_cast<char *>(""));
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (strcmp(fieldName, "rank") == 0) {
|
if (strcmp(fieldName, "rank") == 0) {
|
||||||
auto const language = *reinterpret_cast<uint32_t *>(Offsets::Language);
|
lua_pushstring(luaState, spell->Rank[language] ? const_cast<char *>(spell->Rank[language])
|
||||||
lua_pushstring(luaState, reinterpret_cast<const char *>(spell->Rank[language])
|
: const_cast<char *>(""));
|
||||||
? const_cast<char *>(reinterpret_cast<const char *>(spell->Rank[language]))
|
return 1;
|
||||||
: const_cast<char *>(""));
|
}
|
||||||
|
if (strcmp(fieldName, "description") == 0) {
|
||||||
|
lua_pushstring(luaState, spell->Description[language] ? const_cast<char *>(spell->Description[language])
|
||||||
|
: const_cast<char *>(""));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (strcmp(fieldName, "tooltip") == 0) {
|
||||||
|
lua_pushstring(luaState, spell->ToolTip[language] ? const_cast<char *>(spell->ToolTip[language])
|
||||||
|
: const_cast<char *>(""));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user