328 lines
9.6 KiB
Lua
328 lines
9.6 KiB
Lua
local _G = ShaguTweaks.GetGlobalEnv()
|
|
|
|
-- Central capability layer for ClassicAPI / SuperWoW integration.
|
|
-- Keep feature checks here so individual modules don't scatter DLL-specific
|
|
-- detection logic all over the codebase.
|
|
ShaguTweaks.API = ShaguTweaks.API or {}
|
|
local API = ShaguTweaks.API
|
|
|
|
API.classicapi_version = tonumber(_G.CLASSIC_API_VERSION) or 0
|
|
API.classicapi = type(_G.C_NamePlate) == "table"
|
|
or type(_G.C_Spell) == "table"
|
|
or type(_G.C_UnitAuras) == "table"
|
|
or type(_G.UnitGUID) == "function"
|
|
|
|
API.nameplates = type(_G.C_NamePlate) == "table"
|
|
and type(_G.C_NamePlate.GetNamePlateForUnit) == "function"
|
|
|
|
API.casts = type(_G.C_Spell) == "table"
|
|
and type(_G.C_Spell.UnitCastingInfo) == "function"
|
|
and type(_G.C_Spell.UnitChannelInfo) == "function"
|
|
|
|
API.spellrange = type(_G.C_Spell) == "table"
|
|
and type(_G.C_Spell.IsSpellInRange) == "function"
|
|
|
|
API.auras = type(_G.C_UnitAuras) == "table"
|
|
and type(_G.C_UnitAuras.GetAuraDataByIndex) == "function"
|
|
and type(_G.C_UnitAuras.GetDebuffDataByIndex) == "function"
|
|
|
|
API.aurapositional = type(_G.C_UnitAuras) == "table"
|
|
and type(_G.C_UnitAuras.UnitDebuff) == "function"
|
|
|
|
API.spellinfo = type(_G.GetSpellInfo) == "function"
|
|
API.actioninfo = type(_G.GetActionInfo) == "function"
|
|
API.macrospell = type(_G.GetMacroSpell) == "function"
|
|
|
|
API.inventory = type(_G.C_Container) == "table"
|
|
and type(_G.C_Container.GetContainerNumFreeSlots) == "function"
|
|
|
|
API.containeritems = type(_G.C_Container) == "table"
|
|
and type(_G.C_Container.GetContainerItemID) == "function"
|
|
|
|
API.items = type(_G.C_Item) == "table"
|
|
API.iteminfo = API.items and type(_G.C_Item.GetItemInfo) == "function"
|
|
API.itemname = API.items and type(_G.C_Item.GetItemNameByID) == "function"
|
|
API.itemquality = API.items and type(_G.C_Item.GetItemQualityByID) == "function"
|
|
API.itemprice = API.items and type(_G.C_Item.GetItemSellPriceByID) == "function"
|
|
API.iteminventorytype = API.items and type(_G.C_Item.GetItemInventoryTypeByID) == "function"
|
|
API.iteminventoryslotkey = API.items and type(_G.C_Item.GetItemInventorySlotKey) == "function"
|
|
API.itemrange = API.items and type(_G.C_Item.IsItemInRange) == "function"
|
|
|
|
API.eventutils = type(_G.C_EventUtils) == "table"
|
|
and type(_G.C_EventUtils.IsEventValid) == "function"
|
|
API.modifierkeys = type(_G.IsLeftShiftKeyDown) == "function"
|
|
and type(_G.IsRightShiftKeyDown) == "function"
|
|
API.modifierstate = API.eventutils and API.modifierkeys
|
|
and _G.C_EventUtils.IsEventValid("MODIFIER_STATE_CHANGED")
|
|
|
|
API.merchant = type(_G.C_MerchantFrame) == "table"
|
|
and type(_G.C_MerchantFrame.GetNumJunkItems) == "function"
|
|
and type(_G.C_MerchantFrame.SellAllJunkItems) == "function"
|
|
|
|
API.playerstate = type(_G.IsMounted) == "function"
|
|
and type(_G.Dismount) == "function"
|
|
and type(_G.GetShapeshiftFormID) == "function"
|
|
and type(_G.CancelShapeshiftForm) == "function"
|
|
|
|
API.unitguid = type(_G.UnitGUID) == "function"
|
|
|
|
API.chatidentity = type(_G.GetCurrentChatGUID) == "function"
|
|
and type(_G.GetPlayerInfoByGUID) == "function"
|
|
|
|
API.playercache = type(_G.C_PlayerCache) == "table"
|
|
and type(_G.C_PlayerCache.GetPlayerInfoByName) == "function"
|
|
|
|
-- SuperWoW remains optional. It can still provide useful extra cast/GUID
|
|
-- information, but ClassicAPI is the primary compatibility layer.
|
|
API.superwow = type(_G.SpellInfo) == "function"
|
|
and type(_G.CombatLogAdd) == "function"
|
|
|
|
API.GetNamePlateForUnit = function(unit)
|
|
if API.nameplates then
|
|
return _G.C_NamePlate.GetNamePlateForUnit(unit)
|
|
end
|
|
end
|
|
|
|
API.UnitCastingInfo = function(unit)
|
|
if API.casts then
|
|
return _G.C_Spell.UnitCastingInfo(unit)
|
|
end
|
|
end
|
|
|
|
API.UnitChannelInfo = function(unit)
|
|
if API.casts then
|
|
return _G.C_Spell.UnitChannelInfo(unit)
|
|
end
|
|
end
|
|
|
|
-- ShaguTweaks' castbar modules use the old 1.12-compatible seven-value shape.
|
|
-- Keep that public shape while sourcing the data from ClassicAPI first.
|
|
API.GetCastInfo = function(unit)
|
|
if not API.casts then return end
|
|
|
|
local name, displayName, texture, startTime, endTime, isTradeSkill,
|
|
castID, notInterruptible, spellID = _G.C_Spell.UnitCastingInfo(unit)
|
|
|
|
-- Remote channels seen after they started can have metadata but no timing.
|
|
-- Castbars require start/end times, so only expose complete timing data here.
|
|
if not name or not startTime or not endTime then return end
|
|
|
|
return name, "", displayName or "", texture, startTime, endTime,
|
|
isTradeSkill, castID, notInterruptible, spellID
|
|
end
|
|
|
|
API.GetChannelInfo = function(unit)
|
|
if not API.casts then return end
|
|
|
|
local name, displayName, texture, startTime, endTime, isTradeSkill,
|
|
notInterruptible, spellID = _G.C_Spell.UnitChannelInfo(unit)
|
|
|
|
if not name or not startTime or not endTime then return end
|
|
|
|
return name, "", displayName or "", texture, startTime, endTime,
|
|
isTradeSkill, notInterruptible, spellID
|
|
end
|
|
|
|
API.IsSpellInRange = function(spell, unit)
|
|
if API.spellrange then
|
|
return _G.C_Spell.IsSpellInRange(spell, unit)
|
|
end
|
|
end
|
|
|
|
API.GetActionInfo = function(slot)
|
|
if API.actioninfo then
|
|
return _G.GetActionInfo(slot)
|
|
end
|
|
end
|
|
|
|
API.GetMacroSpell = function(slot)
|
|
if API.macrospell then
|
|
return _G.GetMacroSpell(slot)
|
|
end
|
|
end
|
|
|
|
API.GetAuraDataByIndex = function(unit, index, filter)
|
|
if API.auras then
|
|
return _G.C_UnitAuras.GetAuraDataByIndex(unit, index, filter)
|
|
end
|
|
end
|
|
|
|
API.GetDebuffDataByIndex = function(unit, index)
|
|
if API.auras then
|
|
return _G.C_UnitAuras.GetDebuffDataByIndex(unit, index)
|
|
end
|
|
end
|
|
|
|
-- ClassicAPI's positional UnitDebuff mirrors the Classic-Era 15-value shape
|
|
-- without allocating an AuraData table. Prefer it in hot UI refresh paths.
|
|
API.UnitDebuff = function(unit, index, filter)
|
|
if API.aurapositional then
|
|
return _G.C_UnitAuras.UnitDebuff(unit, index, filter)
|
|
end
|
|
end
|
|
|
|
API.GetCurrentChatGUID = function()
|
|
if API.chatidentity then
|
|
return _G.GetCurrentChatGUID()
|
|
end
|
|
end
|
|
|
|
API.GetPlayerInfoByGUID = function(guid)
|
|
if API.chatidentity and guid then
|
|
return _G.GetPlayerInfoByGUID(guid)
|
|
end
|
|
end
|
|
|
|
-- Read-only bridge to ClassicAPI's optional persistent player cache.
|
|
-- ShaguTweaks never enables that cache or its visible-object scanner itself.
|
|
API.GetCachedPlayerInfoByName = function(name)
|
|
if API.playercache and name then
|
|
return _G.C_PlayerCache.GetPlayerInfoByName(name)
|
|
end
|
|
end
|
|
|
|
API.GetSpellInfo = function(spell, bookType)
|
|
if API.spellinfo then
|
|
return _G.GetSpellInfo(spell, bookType)
|
|
end
|
|
end
|
|
|
|
API.GetContainerNumFreeSlots = function(bag)
|
|
if API.inventory then
|
|
return _G.C_Container.GetContainerNumFreeSlots(bag)
|
|
end
|
|
return 0, 0
|
|
end
|
|
|
|
-- ClassicAPI updates its own left/right modifier bitmap before firing
|
|
-- MODIFIER_STATE_CHANGED. Prefer that state over vanilla IsShiftKeyDown(),
|
|
-- whose merged Win32 key state can still be stale inside the event callback.
|
|
API.IsShiftKeyDown = function()
|
|
if API.modifierkeys then
|
|
return (_G.IsLeftShiftKeyDown() or _G.IsRightShiftKeyDown()) and true or false
|
|
end
|
|
|
|
if type(_G.IsShiftKeyDown) == "function" then
|
|
return _G.IsShiftKeyDown() and true or false
|
|
end
|
|
|
|
return false
|
|
end
|
|
|
|
-- Direct item IDs avoid a class of Turtle WoW custom-item failures caused by
|
|
-- relying exclusively on legacy item-link parsing.
|
|
local function GetItemIDFromLink(link)
|
|
if not link then return end
|
|
local _, _, itemID = string.find(link, "item:(%d+)")
|
|
return itemID and tonumber(itemID) or nil
|
|
end
|
|
|
|
API.GetItemIDFromLink = GetItemIDFromLink
|
|
|
|
API.GetContainerItemID = function(bag, slot)
|
|
if API.containeritems then
|
|
local itemID = _G.C_Container.GetContainerItemID(bag, slot)
|
|
if itemID then return itemID end
|
|
end
|
|
|
|
return GetItemIDFromLink(_G.GetContainerItemLink(bag, slot))
|
|
end
|
|
|
|
API.GetInventoryItemID = function(unit, slot)
|
|
if type(_G.GetInventoryItemID) == "function" then
|
|
local itemID = _G.GetInventoryItemID(unit, slot)
|
|
if itemID then return itemID end
|
|
end
|
|
|
|
return GetItemIDFromLink(_G.GetInventoryItemLink(unit, slot))
|
|
end
|
|
|
|
API.GetItemInfo = function(item)
|
|
if API.iteminfo then
|
|
return _G.C_Item.GetItemInfo(item)
|
|
end
|
|
return _G.GetItemInfo(item)
|
|
end
|
|
|
|
API.GetItemNameByID = function(itemID)
|
|
if not itemID then return end
|
|
if API.itemname then
|
|
return _G.C_Item.GetItemNameByID(itemID)
|
|
end
|
|
|
|
local name = _G.GetItemInfo(itemID)
|
|
return name
|
|
end
|
|
|
|
API.GetItemQualityByID = function(itemID)
|
|
if not itemID then return end
|
|
if API.itemquality then
|
|
return _G.C_Item.GetItemQualityByID(itemID)
|
|
end
|
|
|
|
local _, _, quality = _G.GetItemInfo(itemID)
|
|
return quality
|
|
end
|
|
|
|
API.GetItemSellPriceByID = function(itemID)
|
|
if not itemID then return end
|
|
if API.itemprice then
|
|
return _G.C_Item.GetItemSellPriceByID(itemID)
|
|
end
|
|
end
|
|
|
|
API.GetItemInventoryTypeByID = function(itemID)
|
|
if not itemID then return end
|
|
if API.iteminventorytype then
|
|
return _G.C_Item.GetItemInventoryTypeByID(itemID)
|
|
end
|
|
end
|
|
|
|
API.GetItemInventorySlotKey = function(inventoryType)
|
|
if inventoryType == nil then return end
|
|
if API.iteminventoryslotkey then
|
|
return _G.C_Item.GetItemInventorySlotKey(inventoryType)
|
|
end
|
|
end
|
|
|
|
API.IsItemInRange = function(item, unit)
|
|
if API.itemrange then
|
|
return _G.C_Item.IsItemInRange(item, unit)
|
|
end
|
|
end
|
|
|
|
API.GetNumJunkItems = function()
|
|
if API.merchant then
|
|
return _G.C_MerchantFrame.GetNumJunkItems()
|
|
end
|
|
return 0
|
|
end
|
|
|
|
API.SellAllJunkItems = function()
|
|
if API.merchant then
|
|
return _G.C_MerchantFrame.SellAllJunkItems()
|
|
end
|
|
end
|
|
|
|
API.IsMounted = function()
|
|
return API.playerstate and _G.IsMounted() or false
|
|
end
|
|
|
|
API.Dismount = function()
|
|
if API.playerstate then return _G.Dismount() end
|
|
end
|
|
|
|
API.GetShapeshiftFormID = function()
|
|
if API.playerstate then return _G.GetShapeshiftFormID() end
|
|
return 0
|
|
end
|
|
|
|
API.CancelShapeshiftForm = function()
|
|
if API.playerstate then return _G.CancelShapeshiftForm() end
|
|
end
|
|
|
|
API.UnitGUID = function(unit)
|
|
if API.unitguid then
|
|
return _G.UnitGUID(unit)
|
|
end
|
|
end |