promotional bannermobile promotional banner

SmexyMats - Revived

ver looked at a stack of something in your bags and wondered whether anyone actually needs it? Is it worth keeping for your tailor, selling to a vendor, or sending to the guild bank? SmexyMats answers that the moment you hover the item.
Back to Files

SmexyMats-v1.14.1

File nameSmexyMats-SmexyMats-v1.14.1.zip
Uploader
PmptastyPmptasty
Uploaded
Sep 30, 2026
Downloads
19
Size
733.9 KB
Flavors
RetailMoP ClassicClassic TBCClassicForever
File ID
9015016
Type
R
Release
Supported game versions
  • 12.1.0
  • 12.0.7
  • 12.0.5
  • 5.5.4
  • 4.4.2
  • 3.4.5
  • 2.5.6
  • 1.60.1
  • 1.15.9

What's new

Changelog

[v1.14.1]

Fixed -- item tooltips errored on WoW Forever

Reported from WoW Forever: hovering an item in TOGProfessionMaster's crafting tab raised SmexyCore.lua:364: attempt to call a nil value from inside tt:GetItem(), 56 times in one session. On Forever GetItem is not the client's own method but GameTooltipDataMixin:GetItem, a shim over TooltipUtil.GetDisplayedItem (Blizzard_GameTooltip/Mainline/GameTooltip.lua:1031, Blizzard_SharedXMLGame/Tooltip/TooltipUtil.lua:9), and on that tooltip something it calls is nil. Which one was not confirmed in game. I called it unguarded.

The item post-call now reads the item from the tooltip data it is handed (data.hyperlink, else item:<data.id>) and passes it to ModifyItemTooltip, which uses it before asking the tooltip. GetItem itself is now called through pcall and a missing or throwing one counts as "no link", so the stored-link and title fallbacks still run. Tests/core_spec.lua covers all three paths.

Changed -- release docs for v1.14.1

README.md and docs/Curseforge_Description.html checked against the code. Two corrections: the "Where to get it" key binding is under Key Bindings > AddOns > SmexyMats (Bindings.xml declares category="ADDONS"), not Key Bindings > SmexyMats, and it is unbound by default; and on Retail and WoW Forever the lines also show on item tooltips other addons open, since the item post-call covers every item tooltip. The CurseForge page's VersionCheck-1.0 line now says what the README says (a guildmate has a newer SmexyMats). v1.14.1 Recent Updates added, grouped Fixed / Changed.

[v1.14.0]

The first release of the restored SmexyMats. It follows LunixiaLIVE's v1.13.2.

Changed -- release docs for v1.14.0

README.md rewritten player-first: the tooltip lines, the heading and [SM] prefix, where the lines show, the "Where to get it" window (columns, chance notes, faction button, the i help, remembered position, Questbook), slash commands, every option with its default (checked against Data/Options/Defaults.lua), per-version coverage, requirements, Discord for reports, and credits. docs/Curseforge_Description.html gains the same detail and fuller v1.14.0 notes. The comparison-tooltip claim is limited to Retail and WoW Forever, where the item post-call covers every tooltip; the Classic flavours hook GameTooltip and ItemRefTooltip only.

Fixed -- everyday vendor goods read PvP on TBC and Mists

Rebuilt Data/Flavour after ItemDB fixed its TBC and Mists location data (thread 60e304d7): ItemDB's source builder filed any item a battleground quartermaster stocks under that battleground only, so Refreshing Spring Water (159) read Source "PvP" on TBC. It now reads Quest, Vendor, and about 60 TBC and 70 Mists items are corrected the same way. Vanilla was unaffected. The rebuild's drift check flagged ItemDB's Tooltip.lua; its only change was a new _GetTooltipDefault helper, so COPIED_FROM moved to its new checksum with sourceLabels unchanged.

Changed -- the revived CurseForge project

SmexyMats now publishes to its own CurseForge project, smexymats-revived (project ID 1718084), taken over with LunixiaLIVE's permission. Every TOC's X-Curse-Project-ID moved from 270824 (LunixiaLIVE's original project) to 1718084, pinned by Tests/toc_spec.lua. The "Missing Data-Tables" load message, its locale key and all six translations now point at https://www.curseforge.com/wow/addons/smexymats-revived instead of the old project's mods.curse.com address. The CurseForge description is rewritten to the family's section layout and credits LunixiaLIVE as the original developer; the README gains a Credits section saying the same.

Fixed -- WoW Forever tooltips had no heading and no Source line

Found in game on WoW Forever (ItemDB disabled): Rough Stone showed Profession(s) and ItemID only. Two causes. Header defaulted to false; it is now true, matching ItemDB's header default (a profile saved while it was off keeps its saved value). And the per-flavour row can leave the sources or the expansion blank -- ItemDB's Forever row for 2835 is "||Blacksmithing,Engineering, Mining", and no Mists or Forever row carries an expansion -- so SearchDatabase now fills a blank source list or expansion from the Materials tables (the old lookup, now searchMaterials), keeping the flavour data's used-by list. Rough Stone on Forever now reads Drop, Mining and Classic.

Changed -- the copies of ItemDB's code and word list are pinned (audit 67e323f8 item 4)

Tests/data_spec.lua now reads every word the four generated flavours carry and asserts each draws as the Utilities.lua Profs entry of the same name (so SmexyCore.lua's WORD_PROF indices cannot drift from Profs), as one of ItemDB's three own icons (Quest, PvP, Reputation), or as text for the words ItemDB also leaves iconless because no icon was verified: "Crafted", "Poisons" and Mists' six cooking Ways. A new word fails by name. tools/build-itemdb-data.lua stamps the Adler-32 of ItemDB's Tooltip.lua and Where.lua (the files SmexyMats copies code from) into every Data/Flavour header and warns when either differs from COPIED_FROM, so a change in ItemDB surfaces at the next rebuild.

The Reset button's description still promised to "reset your alt database", a feature that never existed; it now says it restores every setting and reloads the UI. The deprecated-global sweep (audit item 1) found only GetItemInfo and GetItemIcon among SmexyMats' calls defined solely in the live tree's Blizzard_Deprecated* files (12.1.0), and both already go through C_Item first.

Fixed -- one Alt+Click opened two Where windows with ItemDB installed

ItemDB and SmexyMats each hooksecurefunc HandleModifiedItemClick, and both default the Where click to ALT-LeftButton, so with both installed one click opened both windows (audit 67e323f8 item 6). New SmexyMats:ItemDBOwnsWhereClick asks the loaded LibItemDB-1.0 whether its click is on (GetTooltipOption("altClick")) and bound, canonically, to the same click as SmexyMats' (GetTooltipOption("whereClick") through ParseClickBinding). When it is, WhereOnModifiedClick yields and the heading drops its click hint (ItemDB's heading already carries one), since ItemDB's window covers every item and SmexyMats' only materials and crafted items. Give the two addons different clicks and each opens its own. An ItemDB with no whereClick setting (older than LibItemDB MINOR 38) is never yielded to. /sm where and the key binding are unaffected.

Fixed -- Retail read item info through a deprecation fallback

GetItemProperties and the Where window called the bare GetItemInfo. On Retail that global is only a deprecation fallback (Blizzard_DeprecatedItemScript/Deprecated_ItemScript.lua: GetItemInfo = C_Item.GetItemInfo), loaded only with the loadDeprecationFallbacks CVar -- without it every item tooltip would have raised. New SmexyMats:ItemInfo resolves C_Item.GetItemInfo first, per call. Found by the session's self-audit.

Changed -- Retail and WoW Forever annotate every item tooltip

Only the live and forever trees' TooltipInfoDocumentation.lua define C_TooltipInfo.GetBagItem, ItemDB's test for its data-driven route -- the same two flavours HasScript("OnTooltipSetItem") already sends to the item post-call, so the route choice already matched. The post-call now annotates every item tooltip it is handed (the comparison tooltips beside GameTooltip included), as ItemDB's does, instead of GameTooltip and ItemRefTooltip only; OnTooltipCleared is hooked once per frame as each is first met, and a tooltip with no name reads no title instead of raising. The Classic flavours still hook GameTooltip and ItemRefTooltip only -- so does ItemDB.

Changed -- icon sizes are sliders; a malformed saved colour draws white

The << / >> buttons and the number line under them became two AceConfig range sliders: profession icons 8-64 (ItemDB's range) and the expansion logo 16-128 (SmexyMats' own, default 50), whole numbers, clamped, showing the default when the saved size is missing. The colour-blind colours now go through SmexyMats:ColorCode, which accepts exactly six hex digits (as ItemDB's setter does) and otherwise draws white -- a malformed escape would have swallowed the text after it.

Added -- the "Where to get it" window, ported from ItemDB

Where.lua (loaded right after SmexyCore.lua in every TOC) is ItemDB's Where.lua on the SmexyMats object: GetItemPlaces (the same packed format, unpacked the same way), GetWhereSources, BuildWhereRows (bosses, then drops, vendors, gathering nodes and chests with zone, chance and spawns, then quest / crafted / reputation / PvP), the faction filter, Questbook tracking with the stop icon, and the click binding (ParseClickBinding, ClickBindingText, IsWhereClick, one hooksecurefunc("HandleModifiedItemClick")). It opens on an item from the chosen click (default Alt+Left, a modifier always required), the unbound key binding in Bindings.xml, or /sm where [item]. The data rides in each Data/Flavour/<Flavour>.lua as a LoadWhereData call, written by tools/build-itemdb-data.lua from ItemDB's ItemPlaces.lua (Vanilla 395 items with places, TBC 825, Mists 1059; Forever ships sources but no places). On Wrath, Cata and Retail there is no Where data and nothing is hooked.

SCOPE, stated because the first write-up called this parity without it: the generator writes Where data only for the items the tooltip covers (reagents and profession-produced items), not for every item ItemDB has places for, so a boss-drop sword reads "No known source (materials and crafted items only)" in SmexyMats where ItemDB lists the drop (audit 67e323f8 #3). Extending it to every item would grow the data files several times over; the scope is said in the window and on the CurseForge page instead.

Two ItemDB features are deliberately not carried: the search strip, which searches ItemDB's item-name database that SmexyMats does not ship; and localised creature / vendor names (ItemDB's PlaceNames files) -- the names are English, while zone names still come from the client. New options: WhereClickEnabled, WhereClick (a select of every modifier combination with the left or right button, validated), WhereOwnFactionOnly; the heading gains the grey "(Alt+Click: where to get it)" hint while the click works on that flavour. LibAceGUIWidgets is an optional dependency in every TOC and a required one in .pkgmeta; without it the window says so in chat.

The generator's first build wrote the separator byte as \31, which Lua reads together with a following digit (\311) as one escape; escapes are now always three digits.

Added -- optional "SmexyMats" heading

New profile setting Header (default off, so the tooltip looks as it did) and its toggle in the options. When on, ProcessTooltip draws a blank line and "SmexyMats" (the wowtoken colour, or colour #1 in colour-blind mode) once, just above the first line it adds, and nothing when every line is switched off -- ItemDB's heading, minus its click hint, which waits for the Where window.

Added -- per-flavour tooltip data, generated from ItemDB

Data/Materials/Materials.lua is one Wowhead-derived table covering every expansion, so a Classic client read later-expansion answers (Deeprock Salt: Mining). ItemDB carries the same tooltip with per-flavour data built from each client's own DB2 tables. tools/build-itemdb-data.lua loads the installed ItemDB's LibItemDB-1.0 and one flavour's data offline, asks it what ItemDB's tooltip asks (GetReagentUses, the expansion tables, GetSources turned into words by a copy of ItemDB's sourceLabels), and writes Data/Flavour/<Flavour>.lua: one [id]="<exp>|<sources>|<used by>" row per item that is a reagent or that a profession produces. Vanilla 1571 items, TBC 2557, Mists 5918, Forever 2145. SmexyMats.toc, _TBC, _Mists and _Camelot load their file after SmexyLoadDB.xml; where one is loaded it is the whole answer, and Materials is not consulted. Wrath, Cata and Retail, for which ItemDB ships no data, keep Materials.

SmexyMats stays standalone: the data is copied into this repo at build time, and nothing reads ItemDB in the game. New source words Quest, PvP, Reputation and Crafted are in Locales/enUS.lua (other locales fall back to English); Quest/PvP/Reputation draw ItemDB's icons (file ids 134327, 132486, 134156), and a word with no icon or locale entry (Mists' "Way of the Wok") prints as it is, read with rawget so AceLocale does not report it missing. Source order is ItemDB's -- producing professions first -- so the sort moved out of FormatToolTipString into the Materials path of SearchDatabase. Tests/toc_spec.lua now allows exactly one Data\Flavour line per TOC, right after SmexyLoadDB.xml, and data_spec.lua checks every generated row's shape.

Added -- release and development tooling

SmexyMats had no packaging, docs or tests of any kind -- one TOC for Interface 20501 and the Lua source. This entry brings it up to the fleet's standard layout, with ItemDB as the reference.

  • Per-flavour TOCs. SmexyMats.toc (Classic Era, 11509), SmexyMats_TBC.toc (20506), SmexyMats_Wrath.toc (30405), SmexyMats_Cata.toc (40402), SmexyMats_Mists.toc (50504), SmexyMats_Camelot.toc (WoW Forever, 16001) and SmexyMats_Mainline.toc (Retail, 120005, 120007, 120100, the list VersionCheck-1.0's TOC declares). The Interface numbers come from the client versions in F:\Blizzard API Docs' per-flavour trees (1.15.9, 2.5.6, 5.5.4, 1.60.1, 12.1.0); Wrath and Cata have no live client and use the numbers ItemDB ships. Every TOC loads the same files as the old one did. ## Version: is now SmexyMats-v1.14.1 for the packager, and the author line credits the original author.
  • .pkgmeta (package as SmexyMats, manual changelog, Ace3 and VersionCheck as required dependencies; docs, Tests, *.ps1, *.code-workspace and CLAUDE.md ignored) and .github/workflows/release.yml (BigWigs packager on a pushed tag).
  • LICENSE (MIT), README.md, CLAUDE.md and docs/Curseforge_Description.html.
  • wow-version-replication.ps1 and .vscode/tasks.json: the dev watcher that copies the shippable files to the other installed flavours, _retail_ included. It differs from the fleet's copy in one respect: it waits on file-system change events (FileSystemWatcher + Register-ObjectEvent without -Action + Wait-Event) instead of polling the tree every two seconds, because writ refuses new timers. The fleet's copy polled because an -Action block runs in another runspace where the script's functions are not in scope; without -Action the events queue in the script's own session, so that reason does not apply. A watcher buffer overflow raises Error, which triggers a full resync.
  • Test harness. WoWAPITesting as a submodule at Tests/wowapi, the .busted shim, .luacheckrc, .luarc.json, .writ-suites.json, .markdownlint.json, and first specs: Tests/toc_spec.lua (every TOC's Interface number, file list and lockstep directives) and Tests/manifest_spec.lua (every shipped .lua is loaded by some manifest).

Fixed -- a clicked item link got no lines while GameTooltip was annotated

ModifyItemTooltip kept one "already annotated" flag for GameTooltip and ItemRefTooltip together, cleared by either tooltip's OnTooltipCleared. With GameTooltip showing an annotated item, a chat link opened in ItemRefTooltip was skipped. The flag is now per tooltip (a weak-keyed table), as ItemDB's tooltip does it. Found while comparing the two for feature parity.

Fixed -- no item annotations on Retail and WoW Forever

HookTooltips hooked OnTooltipSetItem on both tooltips unconditionally. In the Blizzard source that script is hooked only in the three Classic trees (Blizzard_PTRFeedback_Tooltips.lua in classic_era, classic and classic_anniversary); the live and forever trees name it nowhere but the UI schema and register TooltipDataProcessor.AddTooltipPostCall(Enum.TooltipDataType.Item, ...) instead. HookTooltips now asks each tooltip HasScript("OnTooltipSetItem"), hooks the script where it exists, and otherwise registers one item post-call that annotates GameTooltip and ItemRefTooltip only. Not verified in a Retail or Forever client yet; the offline specs drive both branches with a tooltip that refuses the script as the client would.

Removed -- SmexyEmbeds.xml

Every TOC loaded SmexyEmbeds.xml, which included ..\Ace3\*.xml from the Ace3 addon's own folder. Ace3 is a hard dependency in every TOC, so the client has loaded it before SmexyMats either way: if the client follows ..\ the file re-ran version-guarded libraries for nothing, and if it does not it was a load error. Which of the two the client does was not verified. The file is gone from all seven TOCs and the repo, and Tests/toc_spec.lua now fails any TOC or loaded XML that references a path outside the addon folder.

Changed -- test harness pinned to 1665785

WoWAPITesting fixed coverage.lua to compile targets the way the client does (a leading UTF-8 BOM skipped) and to print the compiler's error when a target will not load -- the request filed when Materials.lua's BOM stopped the coverage run. Pinned and re-run: 110 specs, 1076/1076 lines.

Fixed -- every flavour called itself "Classic"

The options panel registered as SmexyMats(Classic) and the load message printed Classic as the version, on Retail too. The panel is now SmexyMats, and the message prints the TOC's ## Version: (read through C_AddOns.GetAddOnMetadata or the bare global, whichever the client has -- the same helper now feeds the VersionCheck registration).

Fixed -- ItemRefTooltip read GameTooltip's title

The title fallback in ModifyItemTooltip and the uncached-item message in ProcessTooltip read GameTooltipTextLeft1 whichever tooltip they were processing, so a clicked item link was looked up by whatever GameTooltip last showed. Both now read <tooltip name>TextLeft1 of the tooltip in hand.

Added -- logic specs, 100% line coverage

Tests/env_smexy.lua loads SmexyMats the way its TOC does, against the installed Ace3 on the harness's widget layer (AceConfigDialog builds real frames when the options panel registers), with recording stand-ins for GameTooltip and ItemRefTooltip. Four spec files cover the logic: core_spec.lua (profile building, the hooks, /sm, the VersionCheck registration against the installed library, link parsing, the lookup, every tooltip line and toggle, the uncached-item message, the Classic profession-window path), utilities_spec.lua, options_spec.lua (every toggle, both colour pickers, the size steppers, Reset, the header list) and data_spec.lua (every Sources/Reagents cell the lookup indexes exists and holds item ids). 103 specs; Tests/wowapi/coverage.lua reports 1065/1065 lines across SmexyCore.lua, Utilities.lua, Options.lua, Defaults.lua, Materials.lua and Locales/enUS.lua. .writ-suites.json declares the coverage run and a whole-repo luacheck run, both at zero.

Fixed -- /sm raised an error on every flavour

ChatCommand called InterfaceOptionsFrame_OpenToCategory, which is defined nowhere in the Classic Era 1.15.9 or Retail FrameXML. It now calls Settings.OpenToCategory with the category ID that AceConfigDialog:AddToBlizOptions returns (its second return in the installed Ace3).

Fixed -- the profile WAS the defaults table, so Reset reset nothing

OnInitialize and the Reset button both assigned SmexyMats.defaults.profile itself to SmexyMatsDB.profile, so every setting a player changed was written into the defaults, and Reset handed the changed table back. New SmexyMats:FillProfile copies (deeply) every default the saved profile lacks, so a profile saved by an older version also gains settings added since; Reset builds a fresh copy.

Fixed -- smaller defects found while writing the specs

  • FormatToolTipString(nil) passed SearchDatabase's empty answer to table.sort and raised; it now answers empty strings. Found by the language server's type check.
  • Defaults.lua set ColorBlindPickedOne twice and ColorBlindPickedTwo never.
  • Options.lua used the key Section4 for both the "Commands" and the "Author" header, so the Commands header was silently replaced. The second is now Section6.
  • GetIDFromLink and the profession-window reads required a : after the item id, so a bare item:2589 string parsed as 0. The pattern is now item:(%d+).
  • InstallHook replaced GameTooltip.SetRecipeResultItem / SetRecipeReagentItem by assignment, which taints GameTooltip, and wrapped them even where the client has no such method (Classic), creating one that raises if called. It is gone. HookRecipeTooltips uses hooksecurefunc, only on methods the client has, and only when the data tables loaded. Because a secure hook runs after the client's method -- after the tooltip already asked for its item and found none -- the hook records the recipe's link and annotates the tooltip itself; ModifyItemTooltip now marks a tooltip done only once it found an item, so that second attempt is let through and a later OnTooltipSetItem cannot add the lines twice.
  • Data/Materials/Materials.lua began with a UTF-8 byte order mark, which plain loadfile rejects (the client and the harness loader both strip it). Removed, with trailing whitespace; line count and every number verified unchanged. The coverage tool's loadfile was reported to WoWAPITesting.

Changed -- Options.lua and Utilities.lua built from small constructors

The eleven identical toggle definitions, the two colour pickers, the four size steppers and their labels in Options.lua, and the 28 icon closures in Utilities.lua, are now produced by local builder functions. Output is unchanged, which the specs pin; the colour pickers' unused alpha hex and the dead "100" check went with it, as did Options.lua's unused locale handle.

Added -- guild version check (VersionCheck-1.0)

VersionCheck-1.0 is a hard dependency in all seven TOCs and in .pkgmeta's required-dependencies. SmexyMats:OnEnable (AceAddon fires it at login, after every dependency has loaded) registers the addon object with VC:RegisterCheck(self, <raw TOC Version>), falling back to VC:Enable(self) on a VersionCheck that predates RegisterCheck. The version is passed raw so an unsubstituted SmexyMats-v1.14.1 still marks a dev build. VersionCheck's own TOC declares every flavour SmexyMats ships for, Retail included, so the hard dependency does not stop SmexyMats loading anywhere. Tests/toc_spec.lua now asserts the dependency on every TOC.

Removed -- the "Report errors to chat" option and the code behind it

ProcessTooltip opened with a "cannot fetch item" chat block (with a LID de-duplication this session first "fixed") and a Classic TradeSkillFrame / GetMouseFocus lookup. Neither could run: the only caller, ModifyItemTooltip, calls ProcessTooltip only after ExamineObject has accepted an item with a real id, so the option never printed anything in game. The specs that drove the branch called ProcessTooltip directly, which is why 100% line coverage did not show it. Found in the session self-audit (inbox 67e323f8), confirmed by Peer Review. Removed the branch, the option and its ErrorReporting default, as ItemDB dropped chat error reporting; reversible if wanted.

Changed -- SmexyCore.lua made lint-clean

luacheck reported 138 warnings. Besides the fix above: the SetCurrencyToken hook was removed, because its post-hook named Hook_SetCurrencyToken, which is defined nowhere, so the hook wrapped the method and did nothing; JustTheTip and ExamineObject became file-local functions instead of globals; the doubled ExamineObject(obj) and ExamineObject(obj) tests became single calls; and unused locals, loop variables and trailing whitespace were dropped. C_AddOns and GetAddOnMetadata were added to .luacheckrc and .luarc.json.

Fixed -- the locale files were pulled in with the XML-file element

SmexyLocales.xml loaded all seven Locales/*.lua files with <Include file=...>, which is the element for an XML file; a Lua file is loaded with <Script file=...>. manifest_spec.lua caught it on its first run (all seven reported as loaded by no manifest). Whether the client tolerated the old form in game was not verified. The commented-out block of locales that do not exist (itIT, ptBR, zhCN, zhTW) was removed with it.

This mod has no additional files