From 4bd237b654b2c59a9721b13ed97b8096ae50e608 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Fri, 20 Mar 2026 18:42:33 -0700 Subject: [PATCH] feat: add IsUsableSpell Lua API for spell usability checks Returns (usable, noMana) tuple. Checks if the spell is known and not on cooldown. Accepts spell ID or name. Used by action bar addons and WeakAuras for conditional spell display (greyed out when unusable). --- src/addons/lua_engine.cpp | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/addons/lua_engine.cpp b/src/addons/lua_engine.cpp index 2b1b4b03..157dd509 100644 --- a/src/addons/lua_engine.cpp +++ b/src/addons/lua_engine.cpp @@ -1194,6 +1194,41 @@ static int lua_UnitCreatureType(lua_State* L) { return 1; } +// IsUsableSpell(spellIdOrName) → usable, noMana +static int lua_IsUsableSpell(lua_State* L) { + auto* gh = getGameHandler(L); + if (!gh) { lua_pushboolean(L, 0); lua_pushboolean(L, 0); return 2; } + + uint32_t spellId = 0; + if (lua_isnumber(L, 1)) { + spellId = static_cast(lua_tonumber(L, 1)); + } else if (lua_isstring(L, 1)) { + const char* name = lua_tostring(L, 1); + if (!name || !*name) { lua_pushboolean(L, 0); lua_pushboolean(L, 0); return 2; } + std::string nameLow(name); + for (char& c : nameLow) c = static_cast(std::tolower(static_cast(c))); + for (uint32_t sid : gh->getKnownSpells()) { + std::string sn = gh->getSpellName(sid); + for (char& c : sn) c = static_cast(std::tolower(static_cast(c))); + if (sn == nameLow) { spellId = sid; break; } + } + } + + if (spellId == 0 || !gh->getKnownSpells().count(spellId)) { + lua_pushboolean(L, 0); + lua_pushboolean(L, 0); + return 2; + } + + // Check if on cooldown + float cd = gh->getSpellCooldown(spellId); + bool onCooldown = (cd > 0.1f); + + lua_pushboolean(L, onCooldown ? 0 : 1); // usable (not on cooldown) + lua_pushboolean(L, 0); // noMana (can't determine without spell cost data) + return 2; +} + // IsInInstance() → isInstance, instanceType static int lua_IsInInstance(lua_State* L) { auto* gh = getGameHandler(L); @@ -1622,6 +1657,7 @@ void LuaEngine::registerCoreAPI() { {"UnitIsEnemy", lua_UnitIsEnemy}, {"UnitCreatureType", lua_UnitCreatureType}, {"UnitClassification", lua_UnitClassification}, + {"IsUsableSpell", lua_IsUsableSpell}, {"IsInInstance", lua_IsInInstance}, {"GetInstanceInfo", lua_GetInstanceInfo}, {"GetInstanceDifficulty", lua_GetInstanceDifficulty},