mirror of
https://github.com/brues-code/nampower.git
synced 2026-09-21 23:26:54 +00:00
show cooldown, proc chance, and ICD info in item tooltips
This commit is contained in:
@@ -111,6 +111,8 @@ SET NP_TargetingQueueWindowMs "1000"
|
||||
|
||||
- `NP_EnableSpellEnergizeEvents` - Whether to enable SPELL_ENERGIZE_BY_SELF, SPELL_ENERGIZE_BY_OTHER, and SPELL_ENERGIZE_ON_SELF events. 0 to disable, 1 to enable. Default is 0.
|
||||
|
||||
- `NP_EnableEnhancedTooltips` - Whether to enable nampower's tooltip additions such as spell proc chance, ICD, and item cooldown text. 0 to disable, 1 to enable. Default is 1.
|
||||
|
||||
- `NP_EnableUnitEventsPet` - Whether to fire unit state events for the `pet` and `partypet1`–`partypet4` unit tokens. 0 to disable, 1 to enable. Default is 1.
|
||||
|
||||
- `NP_EnableUnitEventsParty` - Whether to fire unit state events for the `party1`–`party4` unit tokens. 0 to disable, 1 to enable. Default is 1.
|
||||
|
||||
+15035
-14713
File diff suppressed because it is too large
Load Diff
@@ -55,6 +55,8 @@ set(SOURCE_FILES
|
||||
pet.cpp
|
||||
unit.hpp
|
||||
unit.cpp
|
||||
tooltip.hpp
|
||||
tooltip.cpp
|
||||
)
|
||||
|
||||
add_library(${DLL_NAME} SHARED ${SOURCE_FILES})
|
||||
|
||||
@@ -33,5 +33,6 @@ namespace Nampower {
|
||||
bool isOnGcdCategoryCooldown = false;
|
||||
};
|
||||
|
||||
CooldownDetail GetItemSpellCooldownDetail(uint32_t itemId, uint32_t spellId);
|
||||
CooldownDetail GetItemCooldownDetail(uint32_t itemId);
|
||||
}
|
||||
|
||||
@@ -14,6 +14,10 @@ namespace Nampower {
|
||||
// Reusable table reference to reduce memory allocations
|
||||
static int cooldownDetailTableRef = LUA_REFNIL;
|
||||
|
||||
static uint32_t GetNonNegativeItemCooldownMs(int32_t durationMs) {
|
||||
return durationMs > 0 ? static_cast<uint32_t>(durationMs) : 0;
|
||||
}
|
||||
|
||||
game::SpellHistoryEntry *GetSpellHistoryHead() {
|
||||
auto const spellHistoryAddr = static_cast<uintptr_t>(Offsets::SpellHistories);
|
||||
|
||||
@@ -127,11 +131,13 @@ namespace Nampower {
|
||||
auto *itemStats = GetItemStats(itemId);
|
||||
if (itemStats) {
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
if (itemStats->m_spellCooldown[i] > 0 || itemStats->m_spellCategoryCooldown[i] > 0) {
|
||||
auto const spellCooldownMs = GetNonNegativeItemCooldownMs(itemStats->m_spellCooldown[i]);
|
||||
auto const spellCategoryCooldownMs = GetNonNegativeItemCooldownMs(itemStats->m_spellCategoryCooldown[i]);
|
||||
if (spellCooldownMs > 0 || spellCategoryCooldownMs > 0) {
|
||||
detail.itemHasActiveSpell = true;
|
||||
detail.itemActiveSpellId = itemStats->m_spellID[i];
|
||||
detail.individualDurationMs = itemStats->m_spellCooldown[i];
|
||||
detail.categoryDurationMs = itemStats->m_spellCategoryCooldown[i];
|
||||
detail.individualDurationMs = spellCooldownMs;
|
||||
detail.categoryDurationMs = spellCategoryCooldownMs;
|
||||
return detail;
|
||||
}
|
||||
}
|
||||
@@ -199,6 +205,40 @@ namespace Nampower {
|
||||
PushTableValue(luaState, isOnGcdCategoryCooldownKey, detail.isOnGcdCategoryCooldown ? 1 : 0);
|
||||
}
|
||||
|
||||
CooldownDetail GetItemSpellCooldownDetail(uint32_t itemId, uint32_t spellId) {
|
||||
auto *itemStats = GetItemStats(itemId);
|
||||
|
||||
if (!itemStats || spellId == 0) {
|
||||
return CooldownDetail{};
|
||||
}
|
||||
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
if (itemStats->m_spellID[i] != spellId) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto const categoryOverride = static_cast<uint32_t>(itemStats->m_spellCategory[i]);
|
||||
auto detail = GetCooldownFromSpellHistory(spellId, itemId, categoryOverride);
|
||||
auto const spellCooldownMs = GetNonNegativeItemCooldownMs(itemStats->m_spellCooldown[i]);
|
||||
auto const spellCategoryCooldownMs = GetNonNegativeItemCooldownMs(itemStats->m_spellCategoryCooldown[i]);
|
||||
|
||||
if (spellCooldownMs > 0 || spellCategoryCooldownMs > 0) {
|
||||
detail.itemHasActiveSpell = true;
|
||||
detail.itemActiveSpellId = spellId;
|
||||
detail.individualDurationMs = spellCooldownMs;
|
||||
detail.categoryDurationMs = spellCategoryCooldownMs;
|
||||
} else {
|
||||
// Passive/on-equip effects can share a spell record but don't expose an item-use cooldown.
|
||||
detail.gcdCategoryDurationMs = 0;
|
||||
detail.gcdCategoryId = 0;
|
||||
}
|
||||
|
||||
return detail;
|
||||
}
|
||||
|
||||
return CooldownDetail{};
|
||||
}
|
||||
|
||||
CooldownDetail GetItemCooldownDetail(uint32_t itemId) {
|
||||
auto *itemStats = GetItemStats(itemId);
|
||||
|
||||
@@ -212,8 +252,7 @@ namespace Nampower {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto const categoryOverride = static_cast<uint32_t>(itemStats->m_spellCategory[i]);
|
||||
auto const detail = GetCooldownFromSpellHistory(spellId, itemId, categoryOverride);
|
||||
auto const detail = GetItemSpellCooldownDetail(itemId, spellId);
|
||||
|
||||
if (detail.cooldownRemainingMs >= longestCooldownMs) {
|
||||
activeCooldownDetail = detail;
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace Nampower {
|
||||
{"maxDamage", offsetof(game::ItemStats_C, m_maxDamage), FieldType::FLOAT, 5},
|
||||
{"damageType", offsetof(game::ItemStats_C, m_damageType), FieldType::INT32, 5},
|
||||
{"resistances", offsetof(game::ItemStats_C, m_resistances), FieldType::INT32, 7},
|
||||
{"spellID", offsetof(game::ItemStats_C, m_spellID), FieldType::INT32, 5},
|
||||
{"spellID", offsetof(game::ItemStats_C, m_spellID), FieldType::UINT32, 5},
|
||||
{"spellTrigger", offsetof(game::ItemStats_C, m_spellTrigger), FieldType::INT32, 5},
|
||||
{"spellCharges", offsetof(game::ItemStats_C, m_spellCharges), FieldType::INT32, 5},
|
||||
{"spellCooldown", offsetof(game::ItemStats_C, m_spellCooldown), FieldType::INT32, 5},
|
||||
|
||||
+16
-1
@@ -497,7 +497,7 @@ namespace game {
|
||||
int m_delay;
|
||||
int m_ammoType;
|
||||
int m_rangedModRange;
|
||||
int m_spellID[5];
|
||||
uint32_t m_spellID[5];
|
||||
int m_spellTrigger[5];
|
||||
int m_spellCharges[5];
|
||||
int m_spellCooldown[5];
|
||||
@@ -1013,6 +1013,21 @@ namespace game {
|
||||
// Each caster has his own aura slot, instead of replacing others
|
||||
};
|
||||
|
||||
enum ItemSpelltriggerType
|
||||
{
|
||||
ITEM_SPELLTRIGGER_ON_USE = 0, // use after equip cooldown
|
||||
ITEM_SPELLTRIGGER_ON_EQUIP = 1,
|
||||
ITEM_SPELLTRIGGER_CHANCE_ON_HIT = 2,
|
||||
ITEM_SPELLTRIGGER_SOULSTONE = 4,
|
||||
/*
|
||||
* ItemSpelltriggerType 5 might have changed on 2.4.3/3.0.3: Such auras
|
||||
* will be applied on item pickup and removed on item loss - maybe on the
|
||||
* other hand the item is destroyed if the aura is removed ("removed on
|
||||
* death" of spell 57348 makes me think so)
|
||||
*/
|
||||
ITEM_SPELLTRIGGER_ON_NO_DELAY_USE = 5, // no equip cooldown
|
||||
};
|
||||
|
||||
enum SpellTarget {
|
||||
TARGET_NONE = 0,
|
||||
TARGET_UNIT_CASTER = 1,
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "autoattack.hpp"
|
||||
#include "unit.hpp"
|
||||
#include "pet.hpp"
|
||||
#include "tooltip.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
@@ -175,6 +176,8 @@ namespace Nampower {
|
||||
std::unique_ptr<hadesmem::PatchDetour<CGUnit_C_HandleEnvironmentDamageT> > gCGUnit_C_HandleEnvironmentDamageDetour;
|
||||
std::unique_ptr<hadesmem::PatchDetour<UnitCombatLogDamageShieldT> > gUnitCombatLogDamageShieldDetour;
|
||||
std::unique_ptr<hadesmem::PatchDetour<LoadScriptFunctionsT> > gGlueLoadScriptFunctionsDetour;
|
||||
std::unique_ptr<hadesmem::PatchDetour<CGTooltip_SetItemT> > gCGTooltip_SetItemDetour;
|
||||
std::unique_ptr<hadesmem::PatchDetour<SpellParserParseTextT> > gSpellParserParseTextDetour;
|
||||
|
||||
// Flags for one-time initialization
|
||||
std::once_flag loadFlag;
|
||||
@@ -743,6 +746,9 @@ namespace Nampower {
|
||||
} else if (strcmp(cvar, "NP_PreventMountingWhenBuffCapped") == 0) {
|
||||
gUserSettings.preventMountingWhenBuffCapped = atoi(value) != 0;
|
||||
DEBUG_LOG("Set NP_PreventMountingWhenBuffCapped to " << gUserSettings.preventMountingWhenBuffCapped);
|
||||
} else if (strcmp(cvar, "NP_EnableEnhancedTooltips") == 0) {
|
||||
gUserSettings.enableEnhancedTooltips = atoi(value) != 0;
|
||||
DEBUG_LOG("Set NP_EnableEnhancedTooltips to " << gUserSettings.enableEnhancedTooltips);
|
||||
} else if (strcmp(cvar, "NP_MinBufferTimeMs") == 0) {
|
||||
gUserSettings.minBufferTimeMs = atoi(value);
|
||||
DEBUG_LOG("Set NP_MinBufferTimeMs and current buffer to " << gUserSettings.minBufferTimeMs);
|
||||
@@ -1164,6 +1170,16 @@ namespace Nampower {
|
||||
0, // unk2
|
||||
0); // unk3
|
||||
|
||||
char NP_EnableEnhancedTooltips[] = "NP_EnableEnhancedTooltips";
|
||||
CVarRegister(NP_EnableEnhancedTooltips, // name
|
||||
nullptr, // help
|
||||
0, // unk1
|
||||
gUserSettings.enableEnhancedTooltips ? defaultTrue : defaultFalse, // default value address
|
||||
nullptr, // callback
|
||||
1, // category
|
||||
0, // unk2
|
||||
0); // unk3
|
||||
|
||||
char NP_OnSwingBufferCooldownMs[] = "NP_OnSwingBufferCooldownMs";
|
||||
CVarRegister(NP_OnSwingBufferCooldownMs, // name
|
||||
nullptr, // help
|
||||
@@ -1385,6 +1401,7 @@ namespace Nampower {
|
||||
loadUserVar("NP_EnableSpellHealEvents");
|
||||
loadUserVar("NP_EnableSpellEnergizeEvents");
|
||||
loadUserVar("NP_PreventMountingWhenBuffCapped");
|
||||
loadUserVar("NP_EnableEnhancedTooltips");
|
||||
|
||||
loadUserVar("NP_MinBufferTimeMs");
|
||||
loadUserVar("NP_NonGcdBufferTimeMs");
|
||||
@@ -1602,6 +1619,10 @@ namespace Nampower {
|
||||
process, Offsets::CGUnit_C_HandleEnvironmentDamage, &CGUnit_C_HandleEnvironmentDamageHook);
|
||||
gUnitCombatLogDamageShieldDetour = createHook<UnitCombatLogDamageShieldT>(
|
||||
process, Offsets::UnitCombatLogDamageShield, &UnitCombatLogDamageShieldHook);
|
||||
gCGTooltip_SetItemDetour = createHook<CGTooltip_SetItemT>(
|
||||
process, Offsets::CGTooltip_SetItem, &CGTooltip_SetItemHook);
|
||||
gSpellParserParseTextDetour = createHook<SpellParserParseTextT>(
|
||||
process, Offsets::SpellParserParseText, &SpellParserParseTextHook);
|
||||
gLoadScriptFunctionsDetour = createHook<LoadScriptFunctionsT>(process, Offsets::Player_LoadScriptFunctions,
|
||||
&Player_LoadScriptFunctionsHook);
|
||||
gGlueLoadScriptFunctionsDetour = createHook<LoadScriptFunctionsT>(process, Offsets::Glue_LoadScriptFunctions,
|
||||
|
||||
+2
-2
@@ -26,8 +26,8 @@ namespace Nampower {
|
||||
constexpr uint32_t DISENCHANT_QUALITY_PURPLE = 0x04; // Epic
|
||||
|
||||
constexpr uint32_t MAJOR_VERSION = 4;
|
||||
constexpr uint32_t MINOR_VERSION = 2;
|
||||
constexpr uint32_t PATCH_VERSION = 2;
|
||||
constexpr uint32_t MINOR_VERSION = 3;
|
||||
constexpr uint32_t PATCH_VERSION = 0;
|
||||
|
||||
constexpr int32_t LUA_REGISTRYINDEX = -10000;
|
||||
constexpr int32_t LUA_GLOBALSINDEX = -10001;
|
||||
|
||||
@@ -289,6 +289,8 @@ enum class Offsets : std::uint32_t {
|
||||
TogglePetSlotAutocast = 0x004bcbb0,
|
||||
CGPetInfo_GetPetSpellAction = 0x004bd190,
|
||||
CGPetInfo_SendPetAction = 0x004bd1d0,
|
||||
CGTooltip_SetItem = 0x0052B650,
|
||||
SpellParserParseText = 0x005075F0,
|
||||
PetActionBarSlots = 0x00b71438,
|
||||
PetReactionMode = 0x00b71468,
|
||||
ActivePetGuid = 0x00b714a0,
|
||||
|
||||
@@ -0,0 +1,187 @@
|
||||
#include "tooltip.hpp"
|
||||
|
||||
#include "cooldown.hpp"
|
||||
#include "items.hpp"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace Nampower {
|
||||
static const std::unordered_map<uint32_t, uint32_t> gKnownSpellIcdSeconds = {
|
||||
{12322, 3}, // Unbridled Wrath
|
||||
{18137, 3}, // Shadowguard
|
||||
{28780, 1}, // The Eye of the Dead
|
||||
{44096, 2}, // Ancient Accord Passive
|
||||
{48003, 1}, // Burning Hatred
|
||||
{51061, 18}, // Uncontained Magic Passive
|
||||
{51272, 3}, // Wisdom of the Mak'aru Passive
|
||||
{52864, 1}, // Midnight Comet
|
||||
{52987, 8}, // Command Whelp Passive
|
||||
{52998, 5}, // Decayed Heart Passive
|
||||
|
||||
};
|
||||
uint32_t gActiveTooltipItemId = 0;
|
||||
|
||||
static bool ItemHasOnUseSpellId(uint32_t itemId, uint32_t spellId) {
|
||||
auto const *itemStats = GetItemStats(itemId);
|
||||
if (!itemStats || spellId == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
auto const spellCooldownMs = itemStats->m_spellCooldown[i] > 0 ? itemStats->m_spellCooldown[i] : 0;
|
||||
auto const spellCategoryCooldownMs = itemStats->m_spellCategoryCooldown[i] > 0
|
||||
? itemStats->m_spellCategoryCooldown[i]
|
||||
: 0;
|
||||
auto const spellTrigger = itemStats->m_spellTrigger[i];
|
||||
if (static_cast<uint32_t>(itemStats->m_spellID[i]) == spellId &&
|
||||
spellTrigger != game::ITEM_SPELLTRIGGER_ON_EQUIP &&
|
||||
spellTrigger != game::ITEM_SPELLTRIGGER_CHANCE_ON_HIT &&
|
||||
(spellCooldownMs > 0 || spellCategoryCooldownMs > 0)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int CGTooltip_SetItemHook(hadesmem::PatchDetourBase *detour,
|
||||
void *thisptr,
|
||||
void *dummy_edx,
|
||||
uint32_t itemId,
|
||||
int **param_2,
|
||||
int **param_3,
|
||||
int param_4,
|
||||
int param_5,
|
||||
int param_6,
|
||||
int param_7,
|
||||
uint32_t param_8,
|
||||
int ****param_9) {
|
||||
auto const cgTooltipSetItem = detour->GetTrampolineT<CGTooltip_SetItemT>();
|
||||
gActiveTooltipItemId = itemId;
|
||||
|
||||
auto const result = cgTooltipSetItem(thisptr, dummy_edx, itemId, param_2, param_3, param_4, param_5, param_6,
|
||||
param_7, param_8, param_9);
|
||||
|
||||
gActiveTooltipItemId = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
static uint32_t GetTooltipItemCooldownDurationMs(uint32_t itemId, uint32_t spellId) {
|
||||
auto const detail = GetItemSpellCooldownDetail(itemId, spellId);
|
||||
auto durationMs = detail.individualDurationMs;
|
||||
if (detail.categoryDurationMs > durationMs) {
|
||||
durationMs = detail.categoryDurationMs;
|
||||
}
|
||||
return durationMs;
|
||||
}
|
||||
|
||||
static uint32_t GetKnownSpellIcdDurationMs(uint32_t spellId) {
|
||||
auto const it = gKnownSpellIcdSeconds.find(spellId);
|
||||
if (it == gKnownSpellIcdSeconds.end()) {
|
||||
return 0;
|
||||
}
|
||||
return it->second * 1000;
|
||||
}
|
||||
|
||||
static bool AppendTooltipText(char *buffer, size_t bufferSize, const char *text) {
|
||||
if (!buffer || !text || bufferSize == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto const currentLength = std::strlen(buffer);
|
||||
auto const textLength = std::strlen(text);
|
||||
auto const maxLength = bufferSize - 1;
|
||||
|
||||
if (currentLength >= maxLength || textLength > (maxLength - currentLength)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::strncat(buffer, text, textLength);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool AppendTooltipDurationText(char *buffer,
|
||||
size_t bufferSize,
|
||||
const char *label,
|
||||
uint32_t durationMs) {
|
||||
if (durationMs == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
char text[32] = "";
|
||||
if (durationMs >= 60000) {
|
||||
std::snprintf(text, sizeof(text), " %s: %.1f min", label, durationMs / 60000.0f);
|
||||
} else {
|
||||
std::snprintf(text, sizeof(text), " %s: %u sec", label, static_cast<uint32_t>((durationMs + 500) / 1000));
|
||||
}
|
||||
|
||||
return AppendTooltipText(buffer, bufferSize, text);
|
||||
}
|
||||
|
||||
static bool AppendTooltipIcdText(char *buffer, size_t bufferSize, uint32_t durationMs) {
|
||||
if (durationMs == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
char text[24] = "";
|
||||
if (durationMs >= 60000) {
|
||||
std::snprintf(text, sizeof(text), " ICD: %.1fm", durationMs / 60000.0f);
|
||||
} else {
|
||||
std::snprintf(text, sizeof(text), " ICD: %us", static_cast<uint32_t>((durationMs + 500) / 1000));
|
||||
}
|
||||
|
||||
return AppendTooltipText(buffer, bufferSize, text);
|
||||
}
|
||||
|
||||
static bool AppendTooltipProcChanceText(char *buffer, size_t bufferSize, uint32_t procChance) {
|
||||
if (!buffer || procChance == 0 || procChance >= 100) {
|
||||
return false;
|
||||
}
|
||||
|
||||
char procChanceText[16] = "";
|
||||
int procChanceTextLength = std::snprintf(procChanceText, sizeof(procChanceText), "%u%%", procChance);
|
||||
if (procChanceTextLength <= 0 || std::strstr(buffer, procChanceText) != nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
char chanceText[24] = "";
|
||||
std::snprintf(chanceText, sizeof(chanceText), " Chance: %u%%", procChance);
|
||||
return AppendTooltipText(buffer, bufferSize, chanceText);
|
||||
}
|
||||
|
||||
bool SpellParserParseTextHook(hadesmem::PatchDetourBase *detour,
|
||||
game::SpellRec *spellRec,
|
||||
char *buffer,
|
||||
int bufferSize,
|
||||
float param_4,
|
||||
float param_5,
|
||||
float param_6,
|
||||
float param_7,
|
||||
float param_8) {
|
||||
auto const spellParserParseText = detour->GetTrampolineT<SpellParserParseTextT>();
|
||||
auto const result = spellParserParseText(spellRec, buffer, bufferSize, param_4, param_5, param_6, param_7,
|
||||
param_8);
|
||||
|
||||
if (!result || !gUserSettings.enableEnhancedTooltips || !spellRec || !buffer || bufferSize <= 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Add item cooldown if on use spell
|
||||
if (gActiveTooltipItemId != 0 && ItemHasOnUseSpellId(gActiveTooltipItemId, spellRec->Id)) {
|
||||
AppendTooltipDurationText(buffer,
|
||||
static_cast<size_t>(bufferSize),
|
||||
"CD",
|
||||
GetTooltipItemCooldownDurationMs(gActiveTooltipItemId, spellRec->Id));
|
||||
}
|
||||
|
||||
// Add ICD if available
|
||||
AppendTooltipIcdText(buffer, static_cast<size_t>(bufferSize), GetKnownSpellIcdDurationMs(spellRec->Id));
|
||||
|
||||
// Add proc chance from dbc if available
|
||||
AppendTooltipProcChanceText(buffer, static_cast<size_t>(bufferSize), spellRec->procChance);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
|
||||
#include "main.hpp"
|
||||
|
||||
namespace Nampower {
|
||||
extern uint32_t gActiveTooltipItemId;
|
||||
|
||||
using SpellParserParseTextT = bool (__fastcall *)(game::SpellRec *spellRec,
|
||||
char *buffer,
|
||||
int bufferSize,
|
||||
float param_4,
|
||||
float param_5,
|
||||
float param_6,
|
||||
float param_7,
|
||||
float param_8);
|
||||
|
||||
bool SpellParserParseTextHook(hadesmem::PatchDetourBase *detour,
|
||||
game::SpellRec *spellRec,
|
||||
char *buffer,
|
||||
int bufferSize,
|
||||
float param_4,
|
||||
float param_5,
|
||||
float param_6,
|
||||
float param_7,
|
||||
float param_8);
|
||||
|
||||
using CGTooltip_SetItemT = int (__fastcall *)(void *thisptr,
|
||||
void *dummy_edx,
|
||||
uint32_t itemId,
|
||||
int **param_2,
|
||||
int **param_3,
|
||||
int param_4,
|
||||
int param_5,
|
||||
int param_6,
|
||||
int param_7,
|
||||
uint32_t param_8,
|
||||
int ****param_9);
|
||||
|
||||
int CGTooltip_SetItemHook(hadesmem::PatchDetourBase *detour,
|
||||
void *thisptr,
|
||||
void *dummy_edx,
|
||||
uint32_t itemId,
|
||||
int **param_2,
|
||||
int **param_3,
|
||||
int param_4,
|
||||
int param_5,
|
||||
int param_6,
|
||||
int param_7,
|
||||
uint32_t param_8,
|
||||
int ****param_9);
|
||||
}
|
||||
@@ -44,6 +44,7 @@ struct UserSettings {
|
||||
bool enableSpellHealEvents = false;
|
||||
bool enableSpellEnergizeEvents = false;
|
||||
bool preventMountingWhenBuffCapped = true;
|
||||
bool enableEnhancedTooltips = true;
|
||||
|
||||
uint32_t spellQueueWindowMs = 500;
|
||||
uint32_t onSwingBufferCooldownMs = 500;
|
||||
|
||||
Reference in New Issue
Block a user