You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

魔兽世界插件开发求助:无法在Tooltip显示物品升级成本

魔兽世界插件开发问题:物品Tooltip升级成本不显示排查

我正在开发一款魔兽世界(WoW)插件,目标是在物品Tooltip中显示其升级成本,但目前Tooltip上无任何相关内容显示。经排查,推测问题出在ItemLocation对象以及C_ItemUpgrade.GetItemUpgradeItemInfo(ItemLocation)函数上。目前调试还差2-3步就能获取所有相关信息,后续显示逻辑难度不大,现寻求WoW插件或Lua专家指点错误所在。

相关代码

-- 创建用于处理事件的框架
local frame = CreateFrame("Frame")

-- 处理物品Tooltip显示及升级成本的函数
local function OnTooltipSetItem(tooltip)
    local name, link = tooltip:GetItem()
    if not link then return end

    -- 打印物品链接用于调试
    print("物品链接:", link)

    -- 提取并打印物品ID
    local itemID = tonumber(string.match(link, "item:(%d+)"))
    if not itemID then
        print("提取ItemID失败")
        return
    end
    print("物品ID:", itemID)

-- 尝试通过背包和槽位信息创建ItemLocation对象
local itemLocation
for bag = 0, NUM_BAG_SLOTS do
    for slot = 1, C_Container.GetContainerNumSlots(bag) do
        local slotItemID = C_Container.GetContainerItemID(bag, slot)
        if slotItemID == itemID then
            itemLocation = ItemLocation:CreateFromBagAndSlot(bag, slot)
            break
        end
    end
    if itemLocation then break end
end

if itemLocation then
    if itemLocation:IsValid() then
        print("ItemLocation有效")
        local bag, slot = itemLocation:GetBagAndSlot()
        print("背包:", bag, "槽位:", slot)
    else
        print("ItemLocation无效")
    end
else
    print("ItemLocation对象为nil")
end


-- 已装备物品的调试输出
if itemLocation and itemLocation:IsValid() then
    if itemLocation:GetType() == "BAG" then
        local bag, slot = itemLocation:GetBagAndSlot()
        print("背包:", bag, "槽位:", slot)
    elseif itemLocation:GetType() == "EQUIPMENT" then
        local equipmentSlot = itemLocation:GetEquipmentSlot()
        print("装备槽位:", equipmentSlot)
    end
end


-- 如果背包中未找到,检查已装备物品
if not itemLocation then
    for slot = 1, 19 do -- 19个装备槽位
        local slotItemID = GetInventoryItemID("player", slot)
        if slotItemID == itemID then
            itemLocation = ItemLocation:CreateFromEquipmentSlot(slot)
            break
        end
    end
end

if not itemLocation then
    print("创建ItemLocation失败")
    return
end

-- ItemLocation的调试输出
print("ItemLocation状态:", itemLocation and itemLocation:IsValid() and "有效" or "无效")
print("背包:", itemLocation and itemLocation:GetBagAndSlot() or "N/A")
print("槽位:", itemLocation and itemLocation:GetBagAndSlot() or "N/A")

-- 检查物品是否可升级
local isValid = C_ItemUpgrade.CanUpgradeItem(itemLocation)
print("可升级:", isValid)
if not isValid then
    return
end

-- 获取物品升级信息
local itemUpgradeInfo = C_ItemUpgrade.GetItemUpgradeItemInfo(itemLocation)
if not itemUpgradeInfo then
    print("获取物品ID为", itemID, "的升级信息失败")
    print("ItemLocation状态:", itemLocation and itemLocation:IsValid() and "有效" or "无效")
    return
end
print("物品升级信息:", itemUpgradeInfo)


    -- 检查当前升级等级和最大升级等级
    local currentUpgradeLevel = C_ItemUpgrade.GetItemUpgradeCurrentLevel(itemLocation)
    local maxUpgradeLevel = C_ItemUpgrade.GetItemUpgradeMaxLevel(itemLocation)
    print("当前升级等级:", currentUpgradeLevel)
    print("最大升级等级:", maxUpgradeLevel)

    -- 获取当前赛季
    local currentSeason = C_ItemUpgrade.GetCurrentItemUpgradeSeason()
    print("当前赛季:", currentSeason)

    -- 获取赛季索引
    local seasonIndex = itemUpgradeInfo.upgradeCostTypesForSeasonIndex and itemUpgradeInfo.upgradeCostTypesForSeasonIndex[currentSeason]
    print("赛季索引:", seasonIndex)

    -- 获取当前赛季的升级成本(如果有)
    local cost = itemUpgradeInfo.upgradeCostTypesForSeason and itemUpgradeInfo.upgradeCostTypesForSeason[seasonIndex]
    if cost then
        print("升级成本:", cost)
        tooltip:AddDoubleLine("升级成本:", GetCoinTextureString(cost), 1, 1, 1)
    else
        print("当前赛季无可用升级成本")
    end
end

-- 处理ADDON_LOADED事件的函数
local function OnAddonLoaded(self, event, addon)
    if addon == "UpgradeLion" then
        -- 注册Tooltip钩子
        if TooltipDataProcessor then
            -- 适用于巨龙时代及以后版本
            TooltipDataProcessor.AddTooltipPostCall(Enum.TooltipDataType.Item, OnTooltipSetItem)
        else
            -- 适用于更早版本
            GameTooltip:HookScript("OnTooltipSetItem", OnTooltipSetItem)
            ItemRefTooltip:HookScript("OnTooltipSetItem", OnTooltipSetItem)
        end

        -- 注销ADDON_LOADED事件
        self:UnregisterEvent("ADDON_LOADED")
    end
end

-- 注册ADDON_LOADED事件
frame:RegisterEvent("ADDON_LOADED")
frame:SetScript("OnEvent", OnAddonLoaded)

问题排查与修复建议

1. ItemLocation创建顺序逻辑错误

你现在的代码在遍历背包后,先做了一轮有效性检查和输出,然后才去检查装备栏,但在背包遍历后如果没找到ItemLocation,后续的if not itemLocation then return会直接终止函数,导致装备栏的ItemLocation创建逻辑根本不会执行。

修复: 调整顺序,先完成背包+装备栏的ItemLocation创建,再统一做有效性判断:

-- 先遍历背包创建ItemLocation
local itemLocation
for bag = 0, NUM_BAG_SLOTS do
    for slot = 1, C_Container.GetContainerNumSlots(bag) do
        local slotItemID = C_Container.GetContainerItemID(bag, slot)
        if slotItemID == itemID then
            itemLocation = ItemLocation:CreateFromBagAndSlot(bag, slot)
            break
        end
    end
    if itemLocation then break end
end

-- 背包没找到,再遍历装备栏
if not itemLocation then
    -- 用枚举代替硬编码1-19,适配不同版本
    for slot = Enum.InventorySlot.HeadSlot, Enum.InventorySlot.BackSlot do
        local slotItemID = GetInventoryItemID("player", slot)
        if slotItemID == itemID then
            itemLocation = ItemLocation:CreateFromEquipmentSlot(slot)
            break
        end
    end
end

-- 最后统一判断是否创建成功
if not itemLocation or not itemLocation:IsValid() then
    print("创建有效ItemLocation失败")
    return
end

2. 新版本Tooltip钩子参数错误

巨龙时代及以后版本使用TooltipDataProcessor时,回调函数的参数是tooltip, data,而不是直接通过tooltip:GetItem()获取链接,这会导致新版本中无法正确拿到物品信息。

修复: 适配新版本的钩子逻辑:

if TooltipDataProcessor then
    TooltipDataProcessor.AddTooltipPostCall(Enum.TooltipDataType.Item, function(tooltip, data)
        local link = data and data.hyperlink
        if not link then return end
        -- 把原来OnTooltipSetItem里的逻辑移到这里,用link代替tooltip:GetItem()的返回值
        local itemID = tonumber(string.match(link, "item:(%d+)"))
        -- ...后续逻辑...
    end)
else
    -- 旧版本钩子保持不变
    GameTooltip:HookScript("OnTooltipSetItem", OnTooltipSetItem)
    ItemRefTooltip:HookScript("OnTooltipSetItem", OnTooltipSetItem)
end

3. 升级成本获取路径错误

你当前从itemUpgradeInfo中获取成本的逻辑不对,upgradeCostTypesForSeason和upgradeCostTypesForSeasonIndex的结构并非直接通过索引取值。建议用DevTools_Dump(itemUpgradeInfo)打印完整结构,确认正确的字段路径。通常升级成本是按等级存储的,比如itemUpgradeInfo.upgradeCostsByLevel[currentUpgradeLevel + 1](如果要升级到下一级)。

4. 冗余代码清理

代码中有多处重复的ItemLocation有效性检查和打印,建议合并成一次检查,避免逻辑混乱,减少不必要的调试输出。

内容的提问来源于stack exchange,提问作者Lazy Loafs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 06:05:53