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`
|
||||
- `channelInterruptFlags`
|
||||
- `dispel`
|
||||
- `description` (string, defaults to current language)
|
||||
- `dmgClass`
|
||||
- `durationIndex`
|
||||
- `equippedItemClass`
|
||||
@@ -87,6 +88,7 @@ Related structs live in `nampower/game.hpp` (notably `SpellRec` and `ItemStats_C
|
||||
- `manaCostPerlevel`
|
||||
- `manaPerSecond`
|
||||
- `manaPerSecondPerLevel`
|
||||
- `name` (string, defaults to current language)
|
||||
- `maxAffectedTargets`
|
||||
- `maxLevel`
|
||||
- `maxTargetLevel`
|
||||
@@ -100,6 +102,7 @@ Related structs live in `nampower/game.hpp` (notably `SpellRec` and `ItemStats_C
|
||||
- `procCharges`
|
||||
- `procFlags`
|
||||
- `rangeIndex`
|
||||
- `rank` (string, defaults to current language)
|
||||
- `recoveryTime`
|
||||
- `requiredAuraVision`
|
||||
- `school`
|
||||
@@ -118,8 +121,10 @@ Related structs live in `nampower/game.hpp` (notably `SpellRec` and `ItemStats_C
|
||||
- `targetAuraState`
|
||||
- `targetCreatureType`
|
||||
- `targets`
|
||||
- `tooltip` (string, defaults to current language)
|
||||
|
||||
### SpellRec Array Fields (alphabetical)
|
||||
- `description` (char* x8, one per language)
|
||||
- `dmgMultiplier`
|
||||
- `effect`
|
||||
- `effectAmplitude`
|
||||
@@ -139,6 +144,9 @@ Related structs live in `nampower/game.hpp` (notably `SpellRec` and `ItemStats_C
|
||||
- `effectRadiusIndex`
|
||||
- `effectRealPointsPerLevel`
|
||||
- `effectTriggerSpell`
|
||||
- `name` (char* x8, one per language)
|
||||
- `rank` (char* x8, one per language)
|
||||
- `reagent`
|
||||
- `reagentCount`
|
||||
- `tooltip` (char* x8, one per language)
|
||||
- `totem`
|
||||
|
||||
+44
@@ -26,6 +26,8 @@ For installation, configuration, and general usage information, see the main [RE
|
||||
- [GetSpellSlotTypeIdForName](#getspellslottypeidfornamenspellname)
|
||||
- [GetNampowerVersion](#getnampowerversion)
|
||||
- [GetItemLevel](#getitemlevelitemid)
|
||||
- [GetItemTexture](#getitemtexturedisplayinfoid)
|
||||
- [GetSpellTexture](#getspelltexturespelliconid)
|
||||
- [Spell Casting and Queuing](#spell-casting-and-queuing)
|
||||
- [QueueSpellByName](#queuespellbynamespellname)
|
||||
- [CastSpellByNameNoQueue](#castspellbynamenoqueuespellname)
|
||||
@@ -929,6 +931,48 @@ Examples:
|
||||
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()
|
||||
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);
|
||||
|
||||
return spell->SpellName[language];
|
||||
return spell->Name[language];
|
||||
}
|
||||
|
||||
std::uint64_t ClntObjMgrGetActivePlayerGuid() {
|
||||
|
||||
+4
-4
@@ -192,13 +192,13 @@ namespace game {
|
||||
unsigned int SpellIconID;
|
||||
unsigned int activeIconID;
|
||||
unsigned int spellPriority;
|
||||
const char *SpellName[8];
|
||||
const char *Name[8];
|
||||
unsigned int SpellNameFlag;
|
||||
unsigned int Rank[8];
|
||||
const char *Rank[8];
|
||||
unsigned int RankFlags;
|
||||
unsigned int Description[8];
|
||||
const char *Description[8];
|
||||
unsigned int DescriptionFlags;
|
||||
unsigned int ToolTip[8];
|
||||
const char *ToolTip[8];
|
||||
unsigned int ToolTipFlags;
|
||||
unsigned int ManaCostPercentage;
|
||||
unsigned int StartRecoveryCategory;
|
||||
|
||||
+1
-1
@@ -74,7 +74,7 @@ namespace Nampower {
|
||||
}
|
||||
|
||||
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) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1646,6 +1646,12 @@ namespace Nampower {
|
||||
|
||||
char disenchantAll[] = "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() {
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ namespace Nampower {
|
||||
constexpr uint32_t DISENCHANT_QUALITY_PURPLE = 0x04; // Epic
|
||||
|
||||
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 int32_t LUA_REGISTRYINDEX = -10000;
|
||||
|
||||
@@ -660,9 +660,9 @@ namespace Nampower {
|
||||
// Display which item is being disenchanted
|
||||
char luaCode[256];
|
||||
snprintf(luaCode, sizeof(luaCode),
|
||||
"local itemLink = GetContainerItemLink(%d, %d); "
|
||||
"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
|
||||
"local itemLink = GetContainerItemLink(%d, %d); "
|
||||
"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
|
||||
LuaCall(luaCode);
|
||||
|
||||
// Set timer for next disenchant attempt (5 seconds to allow time for inventory to update)
|
||||
@@ -785,4 +785,60 @@ namespace Nampower {
|
||||
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_GetItemTexture(uintptr_t *luaState);
|
||||
|
||||
uint32_t Script_GetSpellTexture(uintptr_t *luaState);
|
||||
|
||||
bool RunQueuedScript(int priority);
|
||||
}
|
||||
|
||||
@@ -215,6 +215,9 @@ enum class Offsets : std::uint32_t {
|
||||
CGItem_C_GetInventoryArt = 0x005D88B0,
|
||||
CGItem_C_ItemIsQuestOrSoulbound = 0x005DA2C0,
|
||||
|
||||
SpellIconDBMaxId = 0x00c0d7f0,
|
||||
SpellIconDBArray = 0x00c0d7ec,
|
||||
|
||||
DBCache_ItemCacheDBGetRow = 0x0055BA30,
|
||||
|
||||
InvalidFunctionPtrCheck = 0x0042A320,
|
||||
|
||||
+27
-14
@@ -204,7 +204,7 @@ namespace Nampower {
|
||||
|
||||
if (spell) {
|
||||
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]);
|
||||
return 2;
|
||||
} else {
|
||||
@@ -306,12 +306,17 @@ namespace Nampower {
|
||||
// Push string fields manually (require language)
|
||||
auto const language = *reinterpret_cast<uint32_t *>(Offsets::Language);
|
||||
PushTableValue(luaState, const_cast<char *>("name"),
|
||||
spell->SpellName[language] ? const_cast<char *>(spell->SpellName[language])
|
||||
: const_cast<char *>(""));
|
||||
spell->Name[language] ? const_cast<char *>(spell->Name[language])
|
||||
: const_cast<char *>(""));
|
||||
PushTableValue(luaState, const_cast<char *>("rank"),
|
||||
reinterpret_cast<const char *>(spell->Rank[language])
|
||||
? const_cast<char *>(reinterpret_cast<const char *>(spell->Rank[language]))
|
||||
: const_cast<char *>(""));
|
||||
spell->Rank[language] ? const_cast<char *>(spell->Rank[language])
|
||||
: 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
|
||||
if (useCopy) {
|
||||
@@ -420,18 +425,26 @@ namespace Nampower {
|
||||
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) {
|
||||
auto const language = *reinterpret_cast<uint32_t *>(Offsets::Language);
|
||||
lua_pushstring(luaState, spell->SpellName[language] ? const_cast<char *>(spell->SpellName[language])
|
||||
: const_cast<char *>(""));
|
||||
lua_pushstring(luaState, spell->Name[language] ? const_cast<char *>(spell->Name[language])
|
||||
: const_cast<char *>(""));
|
||||
return 1;
|
||||
}
|
||||
if (strcmp(fieldName, "rank") == 0) {
|
||||
auto const language = *reinterpret_cast<uint32_t *>(Offsets::Language);
|
||||
lua_pushstring(luaState, reinterpret_cast<const char *>(spell->Rank[language])
|
||||
? const_cast<char *>(reinterpret_cast<const char *>(spell->Rank[language]))
|
||||
: const_cast<char *>(""));
|
||||
lua_pushstring(luaState, spell->Rank[language] ? const_cast<char *>(spell->Rank[language])
|
||||
: const_cast<char *>(""));
|
||||
return 1;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user