Restore static Vendor Values API boundary

This commit is contained in:
2026-08-24 10:06:19 +02:00
parent d1e0498738
commit 47aa0897e3
-135
View File
@@ -28,9 +28,6 @@ API.spellinfo = type(_G.GetSpellInfo) == "function"
API.inventory = type(_G.C_Container) == "table"
and type(_G.C_Container.GetContainerNumFreeSlots) == "function"
API.itemprice = type(_G.C_Item) == "table"
and type(_G.C_Item.GetItemSellPriceByID) == "function"
API.merchant = type(_G.C_MerchantFrame) == "table"
and type(_G.C_MerchantFrame.GetNumJunkItems) == "function"
and type(_G.C_MerchantFrame.SellAllJunkItems) == "function"
@@ -144,138 +141,6 @@ API.GetContainerNumFreeSlots = function(bag)
return 0, 0
end
-- Returns the live vendor sell price in copper when the client has the item
-- cached. ClassicAPI warms uncached item data itself and returns nil until the
-- cache fill completes.
API.GetItemSellPriceByID = function(itemID)
if API.itemprice and itemID then
return _G.C_Item.GetItemSellPriceByID(itemID)
end
end
local function GetVendorPriceCache()
ShaguTweaks_cache = ShaguTweaks_cache or {}
ShaguTweaks_cache["vendor_prices"] = ShaguTweaks_cache["vendor_prices"] or {}
return ShaguTweaks_cache["vendor_prices"]
end
-- Store only prices that add something to the original static database:
-- new Turtle/custom items or prices changed by Turtle WoW. This keeps the
-- per-character SavedVariables cache very small.
local function StoreVendorPrice(itemID, price)
if type(itemID) ~= "number" or type(price) ~= "number" or price <= 0 then return end
local learned = GetVendorPriceCache()
local legacy = ShaguTweaks.SellValueLegacyDB or ShaguTweaks.SellValueDB
local legacyPrice = legacy and legacy[itemID]
if not legacyPrice or legacyPrice ~= price then
learned[itemID] = price
else
-- Drop a now-redundant learned value if the bundled database caught up.
learned[itemID] = nil
end
-- If the ClassicAPI proxy is already active, make this confirmed value
-- immediately available without another lookup during the current session.
if ShaguTweaks.SellValueLegacyDB and ShaguTweaks.SellValueDB then
rawset(ShaguTweaks.SellValueDB, itemID, price)
end
return price
end
API.StoreVendorPrice = StoreVendorPrice
API.RememberVendorPrice = function(itemID)
if not API.itemprice or type(itemID) ~= "number" then return end
local price = API.GetItemSellPriceByID(itemID)
if price and price > 0 then
return StoreVendorPrice(itemID, price)
end
end
-- Vendor Values keeps its original static database as the final fallback.
-- Resolution order is: current ClassicAPI value -> learned persistent value ->
-- bundled ShaguTweaks database.
API.PrepareVendorValues = function()
if not API.itemprice or not ShaguTweaks.SellValueDB or ShaguTweaks.SellValueLegacyDB then
return
end
local legacy = ShaguTweaks.SellValueDB
local learned = GetVendorPriceCache()
local live = {}
setmetatable(live, {
__index = function(tab, itemID)
if type(itemID) ~= "number" then
return legacy[itemID]
end
local price = API.GetItemSellPriceByID(itemID)
if price and price > 0 then
if not legacy[itemID] or legacy[itemID] ~= price then
learned[itemID] = price
else
learned[itemID] = nil
end
rawset(tab, itemID, price)
return price
end
local remembered = learned[itemID]
if remembered and remembered > 0 then
return remembered
end
return legacy[itemID]
end
})
ShaguTweaks.SellValueLegacyDB = legacy
ShaguTweaks.SellValueDB = live
-- Vendor Values intentionally suppresses its own price while a merchant is
-- open because vanilla already displays the real sell value there. If
-- ClassicAPI's item record still lacks a new Turtle item's sell price, read
-- the native money frame *after* SetBagItem built the merchant tooltip and
-- persist that value. The merchant tooltip reports the current stack value,
-- so convert it back to the per-item price used by SellValueDB.
if not API.vendorprice_tooltip_hooks then
API.vendorprice_tooltip_hooks = true
ShaguTweaks.hooksecurefunc(GameTooltip, "SetBagItem", function(tooltip, container, slot)
if not MerchantFrame or not MerchantFrame:IsShown() then return end
local link = GetContainerItemLink(container, slot)
local itemID = link and ShaguTweaks.GetItemIDFromLink(link)
if not itemID then return end
-- Prefer ClassicAPI whenever it has a direct item-record price.
if API.RememberVendorPrice(itemID) then return end
local _, count = GetContainerItemInfo(container, slot)
count = tonumber(count) or 1
if count < 1 then count = 1 end
local tooltipName = tooltip and tooltip:GetName()
local moneyFrame = tooltipName and _G[tooltipName .. "MoneyFrame1"]
local stackPrice = moneyFrame and moneyFrame:IsShown() and tonumber(moneyFrame.staticMoney)
if not stackPrice or stackPrice <= 0 then return end
local unitPrice = floor(stackPrice / count)
-- A vendor stack value must be an exact multiple of its per-item value.
-- Refuse ambiguous values rather than persist a potentially wrong price.
if unitPrice > 0 and unitPrice * count == stackPrice then
StoreVendorPrice(itemID, unitPrice)
end
end)
end
end
API.GetNumJunkItems = function()
if API.merchant then
return _G.C_MerchantFrame.GetNumJunkItems()