Merge pull request #73 from vatichild/feat/localization

feat: localization, pick lock, auto clam open
This commit is contained in:
Vati
2026-04-09 16:38:34 +04:00
committed by GitHub
22 changed files with 2488 additions and 248 deletions
+47
View File
@@ -0,0 +1,47 @@
-- Guda AutoLoot
-- TurtleWoW with SuperWoW removes the hardcoded shift-autoloot and exposes:
-- * SetAutoloot(0|1) — global client autoloot toggle
-- * LootSlot(slot, forceloot) — forceloot=1 is REQUIRED to actually loot
-- We prefer SetAutoloot when present (lets the client handle everything),
-- and also fall back to a LOOT_OPENED handler that calls LootSlot(slot, 1)
-- so this works on clients without SuperWoW too.
local addon = Guda
local AutoLoot = {}
addon.Modules.AutoLoot = AutoLoot
local function ApplyClientSetting()
local enabled = Guda.Modules.DB and Guda.Modules.DB:GetSetting("autoLoot")
if SetAutoloot then
SetAutoloot(enabled and 1 or 0)
elseif SetAutoLootDefault then
SetAutoLootDefault(enabled and true or false)
end
end
local function OnLootOpened()
if not (Guda.Modules.DB and Guda.Modules.DB:GetSetting("autoLoot")) then
return
end
-- If SuperWoW's SetAutoloot is present and enabled, the client has
-- already looted everything before LOOT_OPENED reaches us — this loop
-- is a no-op safety net for normal clients and any leftovers (BoP
-- confirms, etc.).
local n = GetNumLootItems()
if not n or n == 0 then return end
for slot = n, 1, -1 do
LootSlot(slot, 1) -- forceloot=1 for SuperWoW compatibility
if ConfirmLootSlot then ConfirmLootSlot(slot) end
end
end
function AutoLoot:Initialize()
addon.Modules.Events:Register("LOOT_OPENED", OnLootOpened, "AutoLoot")
ApplyClientSetting()
end
-- Called by the settings checkbox so the client toggle flips immediately.
function AutoLoot:Apply()
ApplyClientSetting()
end
+61
View File
@@ -0,0 +1,61 @@
-- Guda CacheWarmer
-- Pre-warms ItemDetection's tooltip-scan cache and BagScanner's bag-data
-- cache shortly after PLAYER_LOGIN, in the background, so the FIRST time the
-- user opens the bag frame they don't pay for ~80 synchronous tooltip scans.
--
-- Reuses Utils:QueueWork (Core/Utils.lua) for frame-budgeted background
-- processing — no new scheduler.
local addon = Guda
local CacheWarmer = {}
addon.Modules.CacheWarmer = CacheWarmer
-- Walk player bags 0-4 and warm BagScanner per-bag cache. Cheap, runs inline.
function CacheWarmer:WarmBagScanner()
local BagScanner = Guda.Modules.BagScanner
if not BagScanner or not BagScanner.ScanBag then return end
-- ScanBag populates the per-bag cache used by GetBagData later.
for bagID = 0, 4 do
local ok = pcall(function() BagScanner:ScanBag(bagID) end)
if not ok then break end
end
end
-- Walk player bags 0-4 and queue one ItemDetection:GetItemProperties per
-- occupied slot. The work queue spreads them across frames within the
-- existing 100ms-per-frame budget.
function CacheWarmer:WarmItemDetectionCache()
local Utils = Guda.Modules.Utils
local ItemDetection = Guda.Modules.ItemDetection
if not (Utils and Utils.QueueWork) then return end
if not (ItemDetection and ItemDetection.GetItemProperties) then return end
for bagID = 0, 4 do
local numSlots = GetContainerNumSlots(bagID)
if numSlots and numSlots > 0 then
for slotID = 1, numSlots do
local link = GetContainerItemLink(bagID, slotID)
if link then
-- Capture upvalues so the closure has stable bag/slot/link.
local b, s, l = bagID, slotID, link
Utils:QueueWork(function()
-- Minimal itemData — GetItemProperties only needs
-- .link to compute the cache key; bagID/slotID feed
-- the tooltip scan.
ItemDetection:GetItemProperties({ link = l }, b, s)
end, "CacheWarmer.itemDetection")
end
end
end
end
end
function CacheWarmer:Initialize()
-- Defer ~0.5s so we don't compete with the busy login frame. The user
-- typically opens bags several seconds later, so the cache will be hot.
Guda_ScheduleTimer(0.5, function()
CacheWarmer:WarmBagScanner()
CacheWarmer:WarmItemDetectionCache()
end)
end
+155
View File
@@ -0,0 +1,155 @@
-- Guda ClamOpener
-- Walks the player's bags and uses each clam in turn until none remain.
-- Triggered by /guda openclams. Stops on UI_ERROR_MESSAGE so a full inventory
-- (or any other error from UseContainerItem) cleanly aborts the run.
local addon = Guda
local L = Guda_L
local ClamOpener = {}
addon.Modules.ClamOpener = ClamOpener
-- Hardcoded vanilla clam item IDs
local CLAM_IDS = {
[5523] = true, -- Small Barnacled Clam
[5524] = true, -- Thick-shelled Clam
[7973] = true, -- Big-mouth Clam
[15874] = true, -- Soft-shelled Clam
}
local OPEN_DELAY = 0.3 -- seconds between opens; lets loot/bag updates settle
local running = false
local silentRun = false
-- Find the next clam in player bags. Returns bagID, slotID, itemLink or nil.
local function FindNextClam()
for bagID = 0, 4 do
local numSlots = GetContainerNumSlots(bagID)
if numSlots and numSlots > 0 then
for slotID = 1, numSlots do
local link = GetContainerItemLink(bagID, slotID)
if link then
local _, _, idStr = string.find(link, "item:(%d+)")
local itemID = idStr and tonumber(idStr)
if itemID and CLAM_IDS[itemID] then
return bagID, slotID
end
end
end
end
end
return nil
end
local function StopRun(reason)
if not running then return end
running = false
-- Don't unregister BAG_UPDATE — it's the auto-trigger. Only drop the
-- per-run UI_ERROR_MESSAGE listener.
addon.Modules.Events:UnregisterOwner("ClamOpener_Run")
if reason and not silentRun then
addon:Print(reason)
end
silentRun = false
end
local function OpenNext()
if not running then return end
if CursorHasItem() then
-- Cursor is busy with something else; try again shortly.
Guda_ScheduleTimer(OPEN_DELAY, OpenNext)
return
end
local bagID, slotID = FindNextClam()
if not bagID then
StopRun(L["No more clams to open."])
return
end
UseContainerItem(bagID, slotID)
Guda_ScheduleTimer(OPEN_DELAY, OpenNext)
end
-- Stop on UI_ERROR_MESSAGE (e.g. inventory full). UseContainerItem fires this
-- the same frame on failure, so any error after we start counts as an abort.
local function OnUIError()
if not running then return end
local msg = arg1
StopRun(string.format(L["Clam opener stopped: %s"], tostring(msg or "error")))
end
-- silent: true to suppress chat messages (used by auto-trigger).
function ClamOpener:Open(silent)
if running then
if not silent then
addon:Print(L["Clam opener is already running."])
end
return
end
-- Quick sanity check so we don't print "stopped" without ever starting.
if not FindNextClam() then
if not silent then
addon:Print(L["No clams found in your bags."])
end
return
end
running = true
silentRun = silent and true or false
addon.Modules.Events:Register("UI_ERROR_MESSAGE", OnUIError, "ClamOpener_Run")
if not silent then
addon:Print(L["Opening clams..."])
end
OpenNext()
end
-- Returns true if any blocking window (loot/mail/trade/merchant/bank/auction)
-- is currently open. We don't want to UseContainerItem while these are active —
-- it can race the open window or get queued and lost.
local function IsBlockingWindowOpen()
local frames = {
"LootFrame", "MailFrame", "TradeFrame", "MerchantFrame",
"BankFrame", "AuctionFrame",
-- Guda's own bank/mail frames too
"Guda_BankFrame", "Guda_MailboxFrame",
}
for _, name in ipairs(frames) do
local f = getglobal(name)
if f and f.IsShown and f:IsShown() then
return true
end
end
return false
end
-- Initialize auto-open. Triggers:
-- * BAG_UPDATE — catches clams that arrived without a blocking window.
-- * LOOT_CLOSED — the common case: clam looted from a corpse.
-- * MAIL_CLOSED — clam received via mail.
-- * TRADE_CLOSED — clam received via trade.
-- * BANKFRAME_CLOSED — clam withdrawn from bank.
-- Each trigger defers ~0.15s and then attempts a silent Open(); the running
-- guard, the FindNextClam check, and the IsBlockingWindowOpen guard absorb
-- the noise of multiple events firing in quick succession.
function ClamOpener:Initialize()
local function tryAutoOpen()
if running then return end
if not (Guda.Modules.DB and Guda.Modules.DB:GetSetting("autoOpenClams")) then
return
end
Guda_ScheduleTimer(0.15, function()
if running then return end
if IsBlockingWindowOpen() then return end
ClamOpener:Open(true)
end)
end
addon.Modules.Events:Register("BAG_UPDATE", tryAutoOpen, "ClamOpener")
addon.Modules.Events:Register("LOOT_CLOSED", tryAutoOpen, "ClamOpener")
addon.Modules.Events:Register("MAIL_CLOSED", tryAutoOpen, "ClamOpener")
addon.Modules.Events:Register("TRADE_CLOSED", tryAutoOpen, "ClamOpener")
addon.Modules.Events:Register("BANKFRAME_CLOSED", tryAutoOpen, "ClamOpener")
end
+6
View File
@@ -147,6 +147,12 @@ function DB:Initialize()
if Guda_CharDB.settings.autoLockSetItems == nil then
Guda_CharDB.settings.autoLockSetItems = true
end
if Guda_CharDB.settings.autoLoot == nil then
Guda_CharDB.settings.autoLoot = false
end
if Guda_CharDB.settings.autoOpenClams == nil then
Guda_CharDB.settings.autoOpenClams = false
end
-- Auto-detect pfUI on first load (theme not yet set)
if Guda_CharDB.settings.theme == nil then
+50 -28
View File
@@ -2,6 +2,7 @@
-- Sets up all modules and auto-save system
local addon = Guda
local L = Guda_L
local Main = {}
addon.Modules.Main = Main
@@ -10,7 +11,7 @@ addon.Modules.Main = Main
function Main:Initialize()
-- Wait for PLAYER_LOGIN to ensure saved variables are loaded
addon.Modules.Events:OnPlayerLogin(function()
addon:Print("Initializing...")
addon:Print(L["Initializing..."])
-- Initialize database
addon.Modules.DB:Initialize()
@@ -38,7 +39,7 @@ function Main:Initialize()
end
-- Initialize UI
addon:Print("Initializing UI...")
addon:Print(L["Initializing UI..."])
addon.Modules.BagFrame:Initialize()
addon.Modules.BankFrame:Initialize()
addon.Modules.MailboxFrame:Initialize()
@@ -81,6 +82,22 @@ function Main:Initialize()
addon:Error("Tooltip module not loaded!")
end
-- Initialize auto-loot handler (LOOT_OPENED listener)
if addon.Modules.AutoLoot and addon.Modules.AutoLoot.Initialize then
addon.Modules.AutoLoot:Initialize()
end
-- Initialize clam opener (registers BAG_UPDATE for auto-open)
if addon.Modules.ClamOpener and addon.Modules.ClamOpener.Initialize then
addon.Modules.ClamOpener:Initialize()
end
-- Pre-warm ItemDetection / BagScanner caches in the background so the
-- first bag-frame open after login doesn't freeze on tooltip scans.
if addon.Modules.CacheWarmer and addon.Modules.CacheWarmer.Initialize then
addon.Modules.CacheWarmer:Initialize()
end
-- Setup slash commands
Main:SetupSlashCommands()
@@ -100,7 +117,7 @@ function Main:Initialize()
end
addon:Debug("Initialization complete")
addon:Print("Ready! Type /guda to open bags")
addon:Print(L["Ready! Type /guda to open bags"])
end, "Main")
end
@@ -132,27 +149,31 @@ function Main:SetupSlashCommands()
-- Sort bank
addon.Modules.SortEngine:SortBank()
elseif msg == "openclams" or msg == "clams" then
-- Open all clams in bags
addon.Modules.ClamOpener:Open()
elseif msg == "debug" then
-- Toggle debug
addon.DEBUG = not addon.DEBUG
addon:Print("Debug mode: %s", addon.DEBUG and "ON" or "OFF")
addon:Print(L["Debug mode: %s"], addon.DEBUG and L["ON"] or L["OFF"])
elseif msg == "debugsort" then
-- Toggle debug sort (verbose sorting output)
addon.DEBUG_SORT = not addon.DEBUG_SORT
addon:Print("Debug sort mode: %s", addon.DEBUG_SORT and "ON" or "OFF")
addon:Print(L["Debug sort mode: %s"], addon.DEBUG_SORT and L["ON"] or L["OFF"])
elseif msg == "debugcat" then
-- Toggle debug category view (for troubleshooting layout issues)
addon.DEBUG_CATEGORY = not addon.DEBUG_CATEGORY
addon:Print("Debug category mode: %s", addon.DEBUG_CATEGORY and "ON" or "OFF")
addon:Print(L["Debug category mode: %s"], addon.DEBUG_CATEGORY and L["ON"] or L["OFF"])
elseif msg == "quest" then
-- Toggle quest bar
local show = not addon.Modules.DB:GetSetting("showQuestBar")
addon.Modules.DB:SetSetting("showQuestBar", show)
addon.Modules.QuestItemBar:Update()
addon:Print("Quest bar: %s", show and "ON" or "OFF")
addon:Print(L["Quest bar: %s"], show and L["ON"] or L["OFF"])
elseif msg == "track" then
-- Toggle tracked items bar visibility
@@ -172,7 +193,7 @@ function Main:SetupSlashCommands()
elseif addon.Modules.SettingsPopup and addon.Modules.SettingsPopup.Toggle then
addon.Modules.SettingsPopup:Toggle()
else
addon:Print("Settings window not available")
addon:Print(L["Settings window not available"])
end
elseif msg == "cleanup" then
@@ -184,7 +205,7 @@ function Main:SetupSlashCommands()
if addon.Modules.Utils and addon.Modules.Utils.PrintPerformanceStats then
addon.Modules.Utils:PrintPerformanceStats()
else
addon:Print("Performance stats not available")
addon:Print(L["Performance stats not available"])
end
-- Also show category cache stats
if addon.Modules.CategoryManager and addon.Modules.CategoryManager.GetCacheStats then
@@ -215,7 +236,7 @@ function Main:SetupSlashCommands()
-- Reset performance statistics
if addon.Modules.Utils and addon.Modules.Utils.ResetPerformanceStats then
addon.Modules.Utils:ResetPerformanceStats()
addon:Print("Performance stats reset")
addon:Print(L["Performance stats reset"])
end
-- Also clear category cache
if addon.Modules.CategoryManager and addon.Modules.CategoryManager.ClearCache then
@@ -235,35 +256,36 @@ function Main:SetupSlashCommands()
local bagFrame = getglobal("Guda_BagFrame")
local bankFrame = getglobal("Guda_BankFrame")
if (bagFrame and bagFrame:IsShown()) or (bankFrame and bankFrame:IsShown()) then
addon:Print("Cannot reset pool while bag/bank frames are open. Close them first.")
addon:Print(L["Cannot reset pool while bag/bank frames are open. Close them first."])
else
if Guda_ResetButtonPool then
Guda_ResetButtonPool()
addon:Print("Button pool reset. Pool is now empty.")
addon:Print(L["Button pool reset. Pool is now empty."])
else
addon:Print("Button pool reset function not available.")
addon:Print(L["Button pool reset function not available."])
end
end
elseif msg == "help" then
-- Show help
addon:Print("Commands:")
addon:Print("/guda - Toggle bags")
addon:Print("/guda bank - Toggle bank")
addon:Print("/guda mail - Toggle mailbox")
addon:Print("/guda settings - Open settings")
addon:Print("/guda sort - Sort bags")
addon:Print("/guda sortbank - Sort bank")
addon:Print("/guda track - Toggle item tracking")
addon:Print("/guda debug - Toggle debug mode")
addon:Print("/guda debugsort - Toggle sort debug output")
addon:Print("/guda cleanup - Remove old characters")
addon:Print("/guda perf - Show performance stats")
addon:Print("/guda perfreset - Reset performance stats")
addon:Print("/guda poolreset - Reset button pool (debug)")
addon:Print(L["Commands:"])
addon:Print(L["/guda - Toggle bags"])
addon:Print(L["/guda bank - Toggle bank"])
addon:Print(L["/guda mail - Toggle mailbox"])
addon:Print(L["/guda settings - Open settings"])
addon:Print(L["/guda sort - Sort bags"])
addon:Print(L["/guda sortbank - Sort bank"])
addon:Print(L["/guda openclams - Open all clams in bags"])
addon:Print(L["/guda track - Toggle item tracking"])
addon:Print(L["/guda debug - Toggle debug mode"])
addon:Print(L["/guda debugsort - Toggle sort debug output"])
addon:Print(L["/guda cleanup - Remove old characters"])
addon:Print(L["/guda perf - Show performance stats"])
addon:Print(L["/guda perfreset - Reset performance stats"])
addon:Print(L["/guda poolreset - Reset button pool (debug)"])
else
addon:Print("Unknown command. Type /guda help for commands")
addon:Print(L["Unknown command. Type /guda help for commands"])
end
end
+1 -1
View File
@@ -100,7 +100,7 @@ function SharedData:Initialize()
end
if importCount > 0 then
addon:Print("Imported " .. importCount .. " character(s) from other accounts")
addon:Print(format(Guda_L["Imported %d character(s) from other accounts"], importCount))
end
-- Clean up the global to free memory
+11 -11
View File
@@ -325,16 +325,16 @@ function Tooltip:AddInventoryInfo(tooltip, link)
tooltip:AddLine(" ")
-- Inventory label in exact bag frame title color
tooltip:AddLine("|cFFFFD200Inventory|r")
tooltip:AddLine("|cFFFFD200" .. Guda_L["Inventory"] .. "|r")
-- Total line with cyan label and white count (reuse module-level table)
local totalText = "|cFF00FFFFTotal|r: |cFFFFFFFF" .. totalCount .. "|r"
local totalText = "|cFF00FFFF" .. Guda_L["Total"] .. "|r: |cFFFFFFFF" .. totalCount .. "|r"
local breakdownParts = _breakdownParts
local bpIndex = 0
if totalBags > 0 then bpIndex = bpIndex + 1; breakdownParts[bpIndex] = "|cFF00FFFFBags|r: |cFFFFFFFF" .. totalBags .. "|r" end
if totalBank > 0 then bpIndex = bpIndex + 1; breakdownParts[bpIndex] = "|cFF00FFFFBank|r: |cFFFFFFFF" .. totalBank .. "|r" end
if totalMail > 0 then bpIndex = bpIndex + 1; breakdownParts[bpIndex] = "|cFF00FFFFMail|r: |cFFFFFFFF" .. totalMail .. "|r" end
if totalEquipped > 0 then bpIndex = bpIndex + 1; breakdownParts[bpIndex] = "|cFF00FFFFEquipped|r: |cFFFFFFFF" .. totalEquipped .. "|r" end
if totalBags > 0 then bpIndex = bpIndex + 1; breakdownParts[bpIndex] = "|cFF00FFFF" .. Guda_L["Bags"] .. "|r: |cFFFFFFFF" .. totalBags .. "|r" end
if totalBank > 0 then bpIndex = bpIndex + 1; breakdownParts[bpIndex] = "|cFF00FFFF" .. Guda_L["Bank"] .. "|r: |cFFFFFFFF" .. totalBank .. "|r" end
if totalMail > 0 then bpIndex = bpIndex + 1; breakdownParts[bpIndex] = "|cFF00FFFF" .. Guda_L["Mail"] .. "|r: |cFFFFFFFF" .. totalMail .. "|r" end
if totalEquipped > 0 then bpIndex = bpIndex + 1; breakdownParts[bpIndex] = "|cFF00FFFF" .. Guda_L["Equipped"] .. "|r: |cFFFFFFFF" .. totalEquipped .. "|r" end
for i = bpIndex + 1, table.getn(breakdownParts) do breakdownParts[i] = nil end
local breakdownText = ""
@@ -356,23 +356,23 @@ function Tooltip:AddInventoryInfo(tooltip, link)
local sharedSeparatorShown = false
for _, charInfo in ipairs(characterCounts) do
if charInfo.isShared and not sharedSeparatorShown then
tooltip:AddLine("|cFF80C0FFOther Accounts|r")
tooltip:AddLine("|cFF80C0FF" .. Guda_L["Other Accounts"] .. "|r")
sharedSeparatorShown = true
end
local r, g, b = GetClassColor(charInfo.classToken)
local pIndex = 0
if charInfo.bagCount > 0 then
pIndex = pIndex + 1; parts[pIndex] = "|cFF00FFFFBags|r: |cFFFFFFFF" .. charInfo.bagCount .. "|r"
pIndex = pIndex + 1; parts[pIndex] = "|cFF00FFFF" .. Guda_L["Bags"] .. "|r: |cFFFFFFFF" .. charInfo.bagCount .. "|r"
end
if charInfo.bankCount > 0 then
pIndex = pIndex + 1; parts[pIndex] = "|cFF00FFFFBank|r: |cFFFFFFFF" .. charInfo.bankCount .. "|r"
pIndex = pIndex + 1; parts[pIndex] = "|cFF00FFFF" .. Guda_L["Bank"] .. "|r: |cFFFFFFFF" .. charInfo.bankCount .. "|r"
end
if charInfo.mailCount > 0 then
pIndex = pIndex + 1; parts[pIndex] = "|cFF00FFFFMail|r: |cFFFFFFFF" .. charInfo.mailCount .. "|r"
pIndex = pIndex + 1; parts[pIndex] = "|cFF00FFFF" .. Guda_L["Mail"] .. "|r: |cFFFFFFFF" .. charInfo.mailCount .. "|r"
end
if charInfo.equippedCount > 0 then
pIndex = pIndex + 1; parts[pIndex] = "|cFF00FFFFEquipped|r: |cFFFFFFFF" .. charInfo.equippedCount .. "|r"
pIndex = pIndex + 1; parts[pIndex] = "|cFF00FFFF" .. Guda_L["Equipped"] .. "|r: |cFFFFFFFF" .. charInfo.equippedCount .. "|r"
end
for i = pIndex + 1, table.getn(parts) do parts[i] = nil end
+77 -31
View File
@@ -291,12 +291,12 @@ end
-- Print current performance statistics (for debugging)
function Utils:PrintPerformanceStats()
local stats = self:GetPerformanceStats()
addon:Print("=== Guda Performance Stats ===")
addon:Print("Frame Budget: %.0fms", stats.frameBudget * 1000)
addon:Print("Last Update: %.1fms", stats.lastUpdateDuration * 1000)
addon:Print(Guda_L["=== Guda Performance Stats ==="])
addon:Print(Guda_L["Frame Budget: %.0fms"], stats.frameBudget * 1000)
addon:Print(Guda_L["Last Update: %.1fms"], stats.lastUpdateDuration * 1000)
addon:Print("Avg Update: %.1fms", stats.averageUpdateDuration * 1000)
addon:Print("Total Updates: %d", stats.totalUpdates)
addon:Print("Budget Exceeded: %d times", stats.budgetExceededCount)
addon:Print(Guda_L["Total Updates: %d"], stats.totalUpdates)
addon:Print(Guda_L["Budget Exceeded: %d times"], stats.budgetExceededCount)
addon:Print("Work Queue: %d items", stats.workQueueSize)
end
@@ -987,6 +987,44 @@ end
-- Returns: "soul", "herb", "enchant", "quiver", "ammo", or nil
-- This is the consolidated bag type detection function with tooltip fallback
-- =============================================================================
-- Locale-independent type resolution
-- =============================================================================
-- WoW's GetItemInfo returns LOCALIZED type/subtype strings ("Quiver" on enUS,
-- "箭袋" on zhCN, etc.). We resolve the local-client strings at runtime by
-- querying a few reference itemIDs that exist in every WoW 1.12 client, so
-- the rest of the code can match against the local language without hardcoding.
local localizedBagTypes = {} -- lowercased localized subType -> "quiver"/"ammo"/...
local localizedProjectiles = {} -- localized subType (any case) -> "arrow"/"bullet"
local localizedTypesResolved = false
-- Locale-specific subType strings live in Localization.lua (Guda_LSubtypes).
-- Avoids GetItemInfo cache cold-start: lookups are pure table reads, populated
-- once on first use from the current client locale (with enUS as a fallback).
local function ResolveLocalizedTypes()
if localizedTypesResolved then return end
if not Guda_LSubtypes then return end
local clientLocale = (GetLocale and GetLocale()) or "enUS"
local map = Guda_LSubtypes[clientLocale] or Guda_LSubtypes.enUS
local en = Guda_LSubtypes.enUS or {}
-- Merge enUS first (so English clients on a partial locale still work),
-- then the active locale on top.
local sources = { en, map }
for i = 1, 2 do
local src = sources[i]
if src then
if src.quiver then localizedBagTypes[string.lower(src.quiver)] = "quiver" end
if src.ammo then localizedBagTypes[string.lower(src.ammo)] = "ammo" end
if src.soul then localizedBagTypes[string.lower(src.soul)] = "soul" end
if src.herb then localizedBagTypes[string.lower(src.herb)] = "herb" end
if src.enchant then localizedBagTypes[string.lower(src.enchant)] = "enchant" end
if src.arrow then localizedProjectiles[src.arrow] = "arrow" end
if src.bullet then localizedProjectiles[src.bullet] = "bullet" end
end
end
localizedTypesResolved = true
end
function Utils:GetSpecializedBagType(bagID)
-- Skip backpack, bank, and keyring
if bagID == 0 or bagID == -1 or bagID == -2 then
@@ -1012,6 +1050,12 @@ function Utils:GetSpecializedBagType(bagID)
if itemType then
local typeLower = string.lower(itemType)
-- Locale-independent: match against resolved local-client strings
ResolveLocalizedTypes()
if localizedBagTypes[typeLower] then
return localizedBagTypes[typeLower]
end
if string.find(typeLower, "soul bag") or string.find(typeLower, "soul pouch") then
return "soul"
end
@@ -1176,17 +1220,28 @@ function Utils:GetConsumableRestoreTag(bagID, slotID, itemLink)
return tag
end
-- Check if item is Arrow or Bullet (for Quiver routing)
-- Check if item is Arrow or Bullet (for Quiver routing).
-- Locale-independent: also matches against the local client's translated
-- subtype strings, resolved from reference vanilla items at runtime.
function Utils:IsArrowOrBullet(itemType)
if not itemType then return false end
-- Exact matching only
return itemType == "Arrow" or itemType == "Bullet"
if itemType == "Arrow" or itemType == "Bullet" then return true end
ResolveLocalizedTypes()
return localizedProjectiles[itemType] ~= nil
end
-- Check if item is Ammo (any type - for Ammo Pouch)
function Utils:IsAmmo(itemType)
if not itemType then return false end
return itemType == "Arrow" or itemType == "Bullet"
return self:IsArrowOrBullet(itemType)
end
-- Returns "arrow", "bullet", or nil for the given item subtype string.
function Utils:GetProjectileKind(itemType)
if not itemType then return nil end
if itemType == "Arrow" then return "arrow" end
if itemType == "Bullet" then return "bullet" end
ResolveLocalizedTypes()
return localizedProjectiles[itemType]
end
-- Get preferred container type for an item
@@ -1206,13 +1261,14 @@ function Utils:GetItemPreferredContainer(itemLink)
local itemName, _, itemRarity, itemLevel, itemCategory, itemType, itemStackCount, itemSubType, itemTexture = self:GetItemInfoSafe(itemID)
if not itemType then return nil end
-- Only route PROJECTILE category items that are specifically arrows or bullets
if itemCategory == "Projectile" then
if itemType == "Arrow" then
return "quiver"
elseif itemType == "Bullet" then
return "ammo"
end
-- Locale-independent projectile routing. Don't gate on itemCategory string
-- (it's localized); the projectile kind lookup already covers both English
-- and the local client's strings via runtime-resolved reference items.
local projectileKind = self:GetProjectileKind(itemType)
if projectileKind == "arrow" then
return "quiver"
elseif projectileKind == "bullet" then
return "ammo"
end
-- Route herbs to herb bags (robust: category/subtype OR texture pattern fallback)
@@ -1387,15 +1443,12 @@ function Utils:IsHerbItem(itemLink)
local name, _, quality, iLevel, itemCategory, itemType, itemStackCount, itemSubType, itemTexture = self:GetItemInfoSafe(itemID)
if itemCategory ~= "Trade Goods" then
return false
end
if not itemTexture then
return false
end
-- Normalize and check texture name
-- Texture path is locale-independent (English in every WoW client),
-- so we don't need to gate on the localized "Trade Goods" category.
local tex = string.lower(itemTexture)
tex = string.gsub(tex, "^interface\\\\icons\\\\", "")
@@ -1418,14 +1471,7 @@ function Utils:IsEnchantingItem(itemLink)
local name, _, quality, iLevel, itemCategory, itemType, itemStackCount, itemSubType, itemTexture = self:GetItemInfoSafe(itemID)
if itemCategory ~= "Trade Goods" then
-- Some private servers may report Enchanting directly as type
if itemType ~= "Enchanting" and itemSubType ~= "Enchanting" then
return false
end
end
-- If explicit Enchanting subtype/type, accept immediately
-- Explicit English subtype (rare but possible on some servers)
if itemType == "Enchanting" or itemSubType == "Enchanting" then
return true
end
@@ -1434,7 +1480,7 @@ function Utils:IsEnchantingItem(itemLink)
return false
end
-- Normalize and check texture name
-- Texture path is locale-independent — primary signal for non-English clients.
local tex = string.lower(itemTexture)
tex = string.gsub(tex, "^interface\\\\icons\\\\", "")
+2 -2
View File
@@ -89,12 +89,12 @@ function EquipmentScanner:Initialize()
-- Player logged in - save equipment data
addon.Modules.Events:OnPlayerLogin(function()
playerLoggedIn = true
addon:Print("Scanning equipped items...")
addon:Print(Guda_L["Scanning equipped items..."])
-- Delay scan to ensure character is fully loaded (uses pooled timer)
Guda_ScheduleTimer(2.0, function()
EquipmentScanner:SaveToDatabase()
addon:Print("Equipped items scanned and saved!")
addon:Print(Guda_L["Equipped items scanned and saved!"])
end)
end, "EquipmentScanner")
+4 -1
View File
@@ -2,7 +2,7 @@
## Title: Guda
## Notes: All-in-one bag and bank addon for World of Warcraft 1.12.1 (Turtle WoW)
## Author: Vati
## Version: 2.2.4
## Version: 2.2.5
## SavedVariables: Guda_DB
## SavedVariablesPerCharacter: Guda_CharDB
## OptionalDeps: pfUI
@@ -21,6 +21,9 @@ Core\Utils.lua
Core\ItemDetection.lua
Core\CategoryManager.lua
Core\Tooltip.lua
Core\ClamOpener.lua
Core\AutoLoot.lua
Core\CacheWarmer.lua
Data\BagScanner.lua
Data\BankScanner.lua
+1628 -3
View File
File diff suppressed because it is too large Load Diff
+4 -4
View File
@@ -299,7 +299,7 @@ local function FinalizeReplacement()
waitingForLocks = false
onLocksCleared = nil
BagReplacer.inProgress = false
addon:Print("Bag replaced successfully!")
addon:Print(Guda_L["Bag replaced successfully!"])
-- Invalidate bag scanner cache BEFORE update so it does a full rescan
-- (bag slot count changed, incremental update can't handle that)
@@ -479,7 +479,7 @@ function BagReplacer:Execute(targetBagID, invSlot)
-- Guard: already in progress
if self.inProgress then
addon:DebugSort("[BagReplacer] Blocked: replacement already in progress")
addon:Print("Cannot replace bag: another replacement is in progress.")
addon:Print(Guda_L["Cannot replace bag: another replacement is in progress."])
return
end
@@ -487,14 +487,14 @@ function BagReplacer:Execute(targetBagID, invSlot)
local SortEngine = addon.Modules.SortEngine
if SortEngine and SortEngine.sortingInProgress then
addon:DebugSort("[BagReplacer] Blocked: sorting in progress")
addon:Print("Cannot replace bag while sorting is in progress.")
addon:Print(Guda_L["Cannot replace bag while sorting is in progress."])
return
end
-- Guard: combat
if UnitAffectingCombat("player") then
addon:DebugSort("[BagReplacer] Blocked: in combat")
addon:Print("Cannot replace bag during combat.")
addon:Print(Guda_L["Cannot replace bag during combat."])
return
end
+3 -3
View File
@@ -1779,7 +1779,7 @@ function SortEngine:SortBankPass()
propertyCache = {}
if not addon.Modules.BankScanner:IsBankOpen() then
addon:Print("Bank must be open to sort!")
addon:Print(Guda_L["Bank must be open to sort!"])
return 0
end
@@ -1849,7 +1849,7 @@ end
function SortEngine:SortBank()
if not addon.Modules.BankScanner:IsBankOpen() then
addon:Print("Bank must be open to sort!")
addon:Print(Guda_L["Bank must be open to sort!"])
return 0
end
@@ -1935,7 +1935,7 @@ end
function SortEngine:ExecuteSort(sortFunction, analyzeFunction, updateFrame, sortType)
-- Check if sorting is already in progress
if self.sortingInProgress then
addon:Print("Sorting already in progress, please wait...")
addon:Print(Guda_L["Sorting already in progress, please wait..."])
return false, "sorting in progress"
end
+183 -25
View File
@@ -156,7 +156,7 @@ function Guda_BagFrame_OnLoad(self)
-- Set up search box placeholder
local searchBox = getglobal(self:GetName().."_SearchBar_SearchBox")
if searchBox then
searchBox:SetText("Search, try ~equipment")
searchBox:SetText(Guda_L["Search, try ~equipment"])
searchBox:SetTextColor(0.5, 0.5, 0.5, 1)
end
@@ -636,6 +636,7 @@ function BagFrame:UpdateBaglineLayout()
local info = getglobal("Guda_BagFrame_Toolbar_BagSlotsInfo")
local hearthstone = getglobal("Guda_BagFrame_HearthstoneFrame")
local disenchant = getglobal("Guda_BagFrame_DisenchantFrame")
local lockpick = getglobal("Guda_BagFrame_LockpickFrame")
-- Determine last visible special button for info anchor
local lastButton = keyring
@@ -690,6 +691,14 @@ function BagFrame:UpdateBaglineLayout()
local anchor = hearthstone or info
disenchant:SetPoint("LEFT", anchor, "RIGHT", 6, 0)
end
-- Anchor lockpick next to disenchant (or hearthstone if no disenchant)
if lockpick and lockpick:IsShown() then
lockpick:ClearAllPoints()
local anchor = (disenchant and disenchant:IsShown()) and disenchant
or hearthstone or info
lockpick:SetPoint("LEFT", anchor, "RIGHT", 6, 0)
end
else
-- Standard horizontal layout - all bags visible
if bag1 then
@@ -741,6 +750,14 @@ function BagFrame:UpdateBaglineLayout()
disenchant:SetPoint("LEFT", anchor, "RIGHT", 6, 0)
end
-- Anchor lockpick next to disenchant (or hearthstone if no disenchant)
if lockpick and lockpick:IsShown() then
lockpick:ClearAllPoints()
local anchor = (disenchant and disenchant:IsShown()) and disenchant
or hearthstone or info
lockpick:SetPoint("LEFT", anchor, "RIGHT", 6, 0)
end
-- Hide flyout when switching to full bagline
self:HideBagFlyout()
end
@@ -859,7 +876,7 @@ function BagFrame:Update()
end
if titleFont and displayName then
titleFont:SetText(string.format("%s's Bags", displayName))
titleFont:SetText(string.format(Guda_L["%s's Bags"], displayName))
end
-- Display items
@@ -911,6 +928,9 @@ function BagFrame:Update()
-- Update disenchant button
self:UpdateDisenchant()
-- Update lockpick button
self:UpdateLockpick()
-- Update bag slots info
self:UpdateBagSlotsInfo(bagData, isOtherChar)
@@ -1604,7 +1624,7 @@ end
-- Check if search is currently active
function BagFrame:IsSearchActive()
return searchText and searchText ~= "" and searchText ~= "Search, try ~equipment"
return searchText and searchText ~= "" and searchText ~= Guda_L["Search, try ~equipment"]
end
-- Check if item passes search filter (pfUI style)
@@ -1729,11 +1749,11 @@ function BagFrame:UpdateBagSlotsInfo(bagData, isOtherChar)
infoFrame:EnableMouse(true)
infoFrame:SetScript("OnEnter", function()
GameTooltip:SetOwner(this, "ANCHOR_TOP")
GameTooltip:AddLine("Bag Slots", 1, 1, 1)
GameTooltip:AddLine(Guda_L["Bag Slots"], 1, 1, 1)
GameTooltip:AddLine(" ")
-- Regular bags
if this.regularTotal then
GameTooltip:AddDoubleLine("Regular Bags:", string.format("%d / %d", this.regularUsed, this.regularTotal), 1, 1, 1, 0.8, 0.8, 0.8)
GameTooltip:AddDoubleLine(Guda_L["Regular Bags:"], string.format("%d / %d", this.regularUsed, this.regularTotal), 1, 1, 1, 0.8, 0.8, 0.8)
end
-- Special bags
if this.specialBags then
@@ -1956,6 +1976,141 @@ function BagFrame:CreateDisenchantFrame()
addon:Debug("DisenchantFrame created")
end
-- ============================================================================
-- Lockpick button (Rogue: Pick Lock)
-- ============================================================================
-- Check if player is a Rogue with Pick Lock learned. Class check is
-- locale-independent; spell match falls back to English name + icon path
-- candidates so this works on most locales without a translation table.
-- Thieves' Tools (item 5060) presence — required to actually use Pick Lock.
function BagFrame:HasThievesTools()
for bagID = 0, 4 do
local numSlots = GetContainerNumSlots(bagID)
if numSlots and numSlots > 0 then
for slotID = 1, numSlots do
local link = GetContainerItemLink(bagID, slotID)
if link then
local _, _, idStr = string.find(link, "item:(%d+)")
if idStr and tonumber(idStr) == 5060 then
return true
end
end
end
end
end
return false
end
function BagFrame:HasLockpick()
local i = 1
while true do
local name = GetSpellName(i, BOOKTYPE_SPELL)
if not name then break end
if name == "Pick Lock" then
self._lockpickSpellIndex = i
return true
end
local tex = GetSpellTexture(i, BOOKTYPE_SPELL)
if tex then
local tl = string.lower(tex)
-- Known/likely Pick Lock icon paths in 1.12 / TurtleWoW.
if string.find(tl, "spell_nature_slow", 1, true)
or string.find(tl, "ability_rogue_pickpocket", 1, true)
or string.find(tl, "inv_misc_key_03", 1, true) then
self._lockpickSpellIndex = i
return true
end
end
i = i + 1
end
self._lockpickSpellIndex = nil
return false
end
function BagFrame:CreateLockpickFrame()
local frameName = "Guda_BagFrame_LockpickFrame"
if getglobal(frameName) then return end
local toolbar = getglobal("Guda_BagFrame_Toolbar") or Guda_BagFrame
local frame = CreateFrame("Button", frameName, toolbar)
frame:SetWidth(20)
frame:SetHeight(20)
-- Default anchor; will be repositioned by UpdateBaglineLayout
local de = getglobal("Guda_BagFrame_DisenchantFrame")
local hs = getglobal("Guda_BagFrame_HearthstoneFrame")
local anchorTo = (de and de:IsShown()) and de or hs
if anchorTo then
frame:SetPoint("LEFT", anchorTo, "RIGHT", 6, 0)
else
frame:SetPoint("LEFT", toolbar, "LEFT", 0, 0)
end
frame:SetFrameLevel((toolbar:GetFrameLevel() or 5) + 5)
local icon = frame:CreateTexture(frameName .. "_Icon", "ARTWORK")
icon:SetAllPoints(frame)
icon:SetTexture("Interface\\Icons\\Spell_Nature_Slow")
frame:EnableMouse(true)
frame:RegisterForClicks("LeftButtonUp")
frame:SetScript("OnEnter", function()
GameTooltip:SetOwner(this, "ANCHOR_TOP")
GameTooltip:ClearLines()
GameTooltip:AddLine(Guda_L["Lockpicking"], 1, 1, 1)
if BagFrame:HasThievesTools() then
GameTooltip:AddLine(Guda_L["Click to cast Pick Lock"], 0.7, 0.7, 0.7)
else
GameTooltip:AddLine(Guda_L["Requires Thieves' Tools"], 1, 0.3, 0.3)
end
GameTooltip:Show()
end)
frame:SetScript("OnLeave", function()
GameTooltip:Hide()
end)
frame:SetScript("OnClick", function()
-- Block click when no Thieves' Tools — the spell would just error.
if not BagFrame:HasThievesTools() then return end
-- Re-resolve in case spellbook changed since last update
if not BagFrame._lockpickSpellIndex then
BagFrame:HasLockpick()
end
if BagFrame._lockpickSpellIndex then
CastSpell(BagFrame._lockpickSpellIndex, BOOKTYPE_SPELL)
end
end)
addon:Debug("LockpickFrame created")
end
function BagFrame:UpdateLockpick()
local hideFooter = addon.Modules.DB:GetSetting("hideFooter")
local frame = getglobal("Guda_BagFrame_LockpickFrame")
if hideFooter or not self:HasLockpick() then
if frame then frame:Hide() end
return
end
if not frame then
self:CreateLockpickFrame()
frame = getglobal("Guda_BagFrame_LockpickFrame")
end
if frame then
frame:Show()
-- Dim the icon when Thieves' Tools are missing
local icon = getglobal(frame:GetName() .. "_Icon")
if icon then
if self:HasThievesTools() then
icon:SetVertexColor(1, 1, 1)
else
icon:SetVertexColor(0.4, 0.4, 0.4)
end
end
end
end
-- Update disenchant button visibility
function BagFrame:UpdateDisenchant()
local hideFooter = addon.Modules.DB:GetSetting("hideFooter")
@@ -2209,7 +2364,7 @@ local function CreateMoneyTooltip()
-- Header label
f.header = f:CreateFontString(nil, "OVERLAY", "GameFontNormal")
f.header:SetPoint("TOPLEFT", f, "TOPLEFT", 10, -10)
f.header:SetText("Current realm gold")
f.header:SetText(Guda_L["Current realm gold"])
f.header:SetTextColor(1, 0.82, 0)
-- Header money frame (total) — anchored to right edge, same row as header
@@ -2219,7 +2374,7 @@ local function CreateMoneyTooltip()
-- Hint text at bottom
f.hint = f:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
f.hint:SetText("Right-click to manage characters")
f.hint:SetText(Guda_L["Right-click to manage characters"])
f.hint:SetTextColor(0.5, 0.5, 0.5)
return f
@@ -2286,7 +2441,7 @@ function Guda_MoneyTooltip_Show(anchor)
end
-- Update header money
moneyTooltip.header:SetText("Total gold")
moneyTooltip.header:SetText(Guda_L["Total gold"])
MoneyFrame_Update("Guda_MoneyTooltip_Total", totalMoney)
FormatMoneyFrameWithCommas("Guda_MoneyTooltip_Total")
@@ -2778,7 +2933,7 @@ end
function Guda_BagFrame_ClearSearch()
local searchBox = getglobal("Guda_BagFrame_SearchBar_SearchBox")
if searchBox then
searchBox:SetText("Search, try ~equipment")
searchBox:SetText(Guda_L["Search, try ~equipment"])
searchBox:SetTextColor(0.5, 0.5, 0.5, 1)
searchBox:ClearFocus()
end
@@ -2797,7 +2952,7 @@ end
function Guda_BagFrame_OnSearchChanged(self)
local text = self:GetText()
-- Ignore placeholder text
if text == "Search, try ~equipment" then
if text == Guda_L["Search, try ~equipment"] then
text = ""
end
if text ~= searchText then
@@ -2884,7 +3039,7 @@ end
function Guda_BagFrame_Sort()
if currentViewChar then
addon:Print("Cannot sort another character's bags!")
addon:Print(Guda_L["Cannot sort another character's bags!"])
return
end
@@ -2903,7 +3058,7 @@ function Guda_BagFrame_Sort()
)
if not success and message == "already sorted" then
addon:Print("Bags are already sorted!")
addon:Print(Guda_L["Bags are already sorted!"])
end
end
@@ -2917,7 +3072,7 @@ function Guda_BagFrame_MergeStacks()
-- Check if sorting is already in progress
if addon.Modules.SortEngine.sortingInProgress then
addon:Print("Sorting already in progress, please wait...")
addon:Print(Guda_L["Sorting already in progress, please wait..."])
return
end
@@ -3042,7 +3197,7 @@ function Guda_BagFrame_MergeStacks()
end
-- Refresh the view
BagFrame:Update()
addon:Print("Restacked " .. totalMoves .. " stack(s)")
addon:Print(format(Guda_L["Restacked %d stack(s)"], totalMoves))
return
end
@@ -3465,12 +3620,14 @@ function BagFrame:UpdateFooterVisibility()
local moneyFrame = getglobal("Guda_BagFrame_MoneyFrame")
local hearthstoneFrame = getglobal("Guda_BagFrame_HearthstoneFrame")
local disenchantFrame = getglobal("Guda_BagFrame_DisenchantFrame")
local lockpickFrame = getglobal("Guda_BagFrame_LockpickFrame")
if hideFooter then
if toolbar then toolbar:Hide() end
if moneyFrame then moneyFrame:Hide() end
if hearthstoneFrame then hearthstoneFrame:Hide() end
if disenchantFrame then disenchantFrame:Hide() end
if lockpickFrame then lockpickFrame:Hide() end
else
if toolbar then toolbar:Show() end
if moneyFrame then moneyFrame:Show() end
@@ -3481,6 +3638,7 @@ function BagFrame:UpdateFooterVisibility()
self:UpdateMoney()
self:UpdateHearthstone()
self:UpdateDisenchant()
self:UpdateLockpick()
end
end
@@ -3739,24 +3897,24 @@ function Guda_BagSlot_OnEnter(button, bagID)
if bagID == 0 then
-- Backpack tooltip
GameTooltip:SetText("Backpack", 1.0, 1.0, 1.0)
GameTooltip:SetText(Guda_L["Backpack"], 1.0, 1.0, 1.0)
local numSlots = GetContainerNumSlots(0)
GameTooltip:AddLine(string.format("%d Slots", numSlots), 0.8, 0.8, 0.8)
GameTooltip:AddLine(string.format(Guda_L["%d Slots"], numSlots), 0.8, 0.8, 0.8)
if hiddenBags[bagID] then
GameTooltip:AddLine("(Hidden - Right-Click to show)", 0.8, 0.5, 0.5)
else
GameTooltip:AddLine("(Right-Click to hide)", 0.5, 0.8, 0.5)
GameTooltip:AddLine(Guda_L["(Right-Click to hide)"], 0.5, 0.8, 0.5)
end
Guda_BagFrame_HighlightBagSlots(0)
elseif bagID == -2 then
-- Keyring tooltip
GameTooltip:SetText("Keyring", 1.0, 1.0, 1.0)
GameTooltip:SetText(Guda_L["Keyring"], 1.0, 1.0, 1.0)
local numSlots = GetContainerNumSlots(-2) or 0
GameTooltip:AddLine(string.format("%d Slots", numSlots), 0.8, 0.8, 0.8)
GameTooltip:AddLine(string.format(Guda_L["%d Slots"], numSlots), 0.8, 0.8, 0.8)
if hiddenBags[bagID] then
GameTooltip:AddLine("(Hidden - Right-Click to show)", 0.8, 0.5, 0.5)
else
GameTooltip:AddLine("(Right-Click to hide)", 0.5, 0.8, 0.5)
GameTooltip:AddLine(Guda_L["(Right-Click to hide)"], 0.5, 0.8, 0.5)
end
Guda_BagFrame_HighlightBagSlots(-2)
else
@@ -3770,17 +3928,17 @@ function Guda_BagSlot_OnEnter(button, bagID)
if hiddenBags[bagID] then
GameTooltip:AddLine("(Hidden - Right-Click to show)", 0.8, 0.5, 0.5)
else
GameTooltip:AddLine("(Right-Click to hide)", 0.5, 0.8, 0.5)
GameTooltip:AddLine(Guda_L["(Right-Click to hide)"], 0.5, 0.8, 0.5)
end
Guda_BagFrame_HighlightBagSlots(bagID)
else
-- Empty slot
GameTooltip:SetText(string.format("Bag %d", bagID), 1.0, 1.0, 1.0)
GameTooltip:SetText(string.format(Guda_L["Bag %d"], bagID), 1.0, 1.0, 1.0)
GameTooltip:AddLine("Empty", 0.5, 0.5, 0.5)
if hiddenBags[bagID] then
GameTooltip:AddLine("(Hidden - Right-Click to show)", 0.8, 0.5, 0.5)
else
GameTooltip:AddLine("(Right-Click to hide)", 0.5, 0.8, 0.5)
GameTooltip:AddLine(Guda_L["(Right-Click to hide)"], 0.5, 0.8, 0.5)
end
Guda_BagFrame_HighlightBagSlots(bagID)
end
@@ -4134,7 +4292,7 @@ function BagFrame:Initialize()
if not isMerchantOpen then
this:SetScript("OnUpdate", nil)
if soldCount > 0 then
addon:Print("Sold " .. soldCount .. " junk item(s).")
addon:Print(format(Guda_L["Sold %d junk item(s)"], soldCount))
end
return
end
@@ -4149,7 +4307,7 @@ function BagFrame:Initialize()
else
this:SetScript("OnUpdate", nil)
if soldCount > 0 then
addon:Print("Sold " .. soldCount .. " junk item(s).")
addon:Print(format(Guda_L["Sold %d junk item(s)"], soldCount))
end
end
end)
+5 -5
View File
@@ -85,7 +85,7 @@
</OnClick>
<OnEnter>
GameTooltip:SetOwner(this, "ANCHOR_TOP")
GameTooltip:SetText("Settings")
GameTooltip:SetText(Guda_L["Settings"])
GameTooltip:Show()
</OnEnter>
<OnLeave>
@@ -137,7 +137,7 @@
GameTooltip:SetText("Restack and Clean")
GameTooltip:AddLine("Merges split stacks and refreshes the view", 0.7, 0.7, 0.7)
else
GameTooltip:SetText("Sort Bags")
GameTooltip:SetText(Guda_L["Sort Bags"])
end
GameTooltip:Show()
</OnEnter>
@@ -185,7 +185,7 @@
</OnClick>
<OnEnter>
GameTooltip:SetOwner(this, "ANCHOR_TOP")
GameTooltip:SetText("My Characters")
GameTooltip:SetText(Guda_L["My Characters"])
GameTooltip:Show()
</OnEnter>
<OnLeave>
@@ -232,7 +232,7 @@
</OnClick>
<OnEnter>
GameTooltip:SetOwner(this, "ANCHOR_TOP")
GameTooltip:SetText("View Bank")
GameTooltip:SetText(Guda_L["View Bank"])
GameTooltip:Show()
</OnEnter>
<OnLeave>
@@ -278,7 +278,7 @@
</OnClick>
<OnEnter>
GameTooltip:SetOwner(this, "ANCHOR_TOP")
GameTooltip:SetText("View Mailbox")
GameTooltip:SetText(Guda_L["View Mailbox"])
GameTooltip:Show()
</OnEnter>
<OnLeave>
+20 -20
View File
@@ -135,7 +135,7 @@ function Guda_BankFrame_OnLoad(self)
-- Set up search box placeholder
local searchBox = getglobal(self:GetName().."_SearchBar_SearchBox")
if searchBox then
searchBox:SetText("Search bank...")
searchBox:SetText(Guda_L["Search bank..."])
searchBox:SetTextColor(0.5, 0.5, 0.5, 1)
end
@@ -641,7 +641,7 @@ function BankFrame:Update()
bankData = addon.Modules.DB:GetCharacterBank(currentViewChar)
isOtherChar = true
charName = currentViewChar
getglobal("Guda_BankFrame_Title"):SetText(currentViewChar .. "'s Bank")
getglobal("Guda_BankFrame_Title"):SetText(format(Guda_L["%s's Bank"], currentViewChar))
else
-- Viewing current character's bank
-- Use live data if bank is officially open OR if we can access bank data
@@ -660,11 +660,11 @@ function BankFrame:Update()
if useLiveData then
-- Bank is accessible - use live data
bankData = addon.Modules.BankScanner:GetBankData()
getglobal("Guda_BankFrame_Title"):SetText(playerName .. "'s Bank")
getglobal("Guda_BankFrame_Title"):SetText(format(Guda_L["%s's Bank"], playerName))
else
-- Bank is truly closed - use saved data (read-only mode)
bankData = addon.Modules.DB:GetCharacterBank(playerName)
getglobal("Guda_BankFrame_Title"):SetText(playerName .. "'s Bank")
getglobal("Guda_BankFrame_Title"):SetText(format(Guda_L["%s's Bank"], playerName))
end
end
@@ -1579,7 +1579,7 @@ end
-- Check if search is currently active
function BankFrame:IsSearchActive()
return searchText and searchText ~= "" and searchText ~= "Search bank..."
return searchText and searchText ~= "" and searchText ~= Guda_L["Search bank..."]
end
-- Check if item passes search filter (pfUI style)
@@ -1592,7 +1592,7 @@ end
function Guda_BankFrame_OnSearchChanged(self)
local text = self:GetText()
-- Ignore placeholder text
if text == "Search bank..." then
if text == Guda_L["Search bank..."] then
text = ""
end
if text ~= searchText then
@@ -1605,7 +1605,7 @@ end
function Guda_BankFrame_ClearSearch()
local searchBox = getglobal("Guda_BankFrame_SearchBar_SearchBox")
if searchBox then
searchBox:SetText("Search bank...")
searchBox:SetText(Guda_L["Search bank..."])
searchBox:SetTextColor(0.5, 0.5, 0.5, 1)
if searchBox.ClearFocus then searchBox:ClearFocus() end
end
@@ -1625,12 +1625,12 @@ end
-- Bank button handler
function Guda_BankFrame_Sort()
if isReadOnlyMode or currentViewChar then
addon:Print("Cannot sort in read-only mode!")
addon:Print(Guda_L["Cannot sort in read-only mode!"])
return
end
if not addon.Modules.BankScanner:IsBankOpen() then
addon:Print("Bank must be open to sort!")
addon:Print(Guda_L["Bank must be open to sort!"])
return
end
@@ -1649,7 +1649,7 @@ function Guda_BankFrame_Sort()
)
if not success and message == "already sorted" then
addon:Print("Bank is already sorted!")
addon:Print(Guda_L["Bank is already sorted!"])
end
end
@@ -1668,7 +1668,7 @@ function Guda_BankFrame_MergeStacks()
-- Check if sorting is already in progress
if addon.Modules.SortEngine.sortingInProgress then
addon:Print("Sorting already in progress, please wait...")
addon:Print(Guda_L["Sorting already in progress, please wait..."])
return
end
@@ -1795,7 +1795,7 @@ function Guda_BankFrame_MergeStacks()
addon.Modules.ItemDetection:ClearCache()
end
BankFrame:Update()
addon:Print("Restacked " .. totalMoves .. " stack(s)")
addon:Print(format(Guda_L["Restacked %d stack(s)"], totalMoves))
return
end
@@ -1884,7 +1884,7 @@ function Guda_BankFrame_SwitchToGudaUI()
-- Update the custom bank frame in interactive mode
BankFrame:ShowCurrentCharacter()
addon:Print("Switched to Guda bank UI")
addon:Print(Guda_L["Switched to Guda bank UI"])
end
-- Create button on Blizzard BankFrame to switch to Guda UI
@@ -1927,7 +1927,7 @@ function BankFrame:CreateGudaButtonOnBlizzardUI()
gudaButton:SetScript("OnEnter", function()
GameTooltip:SetOwner(this, "ANCHOR_LEFT")
GameTooltip:SetText("Use Guda Bank UI")
GameTooltip:SetText(Guda_L["Use Guda Bank UI"])
GameTooltip:Show()
end)
@@ -2658,13 +2658,13 @@ function Guda_BankBagSlot_OnEnter(button, bagID)
if bagID == -1 then
-- Main bank bag tooltip
GameTooltip:SetText("Bank", 1.0, 1.0, 1.0)
GameTooltip:SetText(Guda_L["Bank"], 1.0, 1.0, 1.0)
local numSlots = 24
GameTooltip:AddLine(string.format("%d Slots", numSlots), 0.8, 0.8, 0.8)
GameTooltip:AddLine(string.format(Guda_L["%d Slots"], numSlots), 0.8, 0.8, 0.8)
if hiddenBankBags[bagID] then
GameTooltip:AddLine("(Hidden - Right-Click to show)", 0.8, 0.5, 0.5)
else
GameTooltip:AddLine("(Right-Click to hide)", 0.5, 0.8, 0.5)
GameTooltip:AddLine(Guda_L["(Right-Click to hide)"], 0.5, 0.8, 0.5)
end
else
local invSlot, bankButtonID = BankFrame:GetBankInvSlotForBagID(bagID)
@@ -2678,19 +2678,19 @@ function Guda_BankBagSlot_OnEnter(button, bagID)
if hiddenBankBags[bagID] then
GameTooltip:AddLine("(Hidden - Right-Click to show)", 0.8, 0.5, 0.5)
else
GameTooltip:AddLine("(Right-Click to hide)", 0.5, 0.8, 0.5)
GameTooltip:AddLine(Guda_L["(Right-Click to hide)"], 0.5, 0.8, 0.5)
end
-- Reset cursor for purchased slots with items
ResetCursor()
elseif isPurchased then
-- Empty purchased slot (no hide/show text, no purchase cursor)
GameTooltip:SetText(string.format("Bank Bag Slot %d", bankButtonID or -1), 1.0, 1.0, 1.0)
GameTooltip:SetText(string.format(Guda_L["Bank Bag Slot %d"], bankButtonID or -1), 1.0, 1.0, 1.0)
GameTooltip:AddLine("Empty", 0.8, 0.8, 0.8)
-- Reset cursor for empty purchased slots
ResetCursor()
else
-- Unpurchased slot (no hide/show text, show purchase cursor)
GameTooltip:SetText(string.format("Bank Bag Slot %d", bankButtonID or -1), 1.0, 1.0, 1.0)
GameTooltip:SetText(string.format(Guda_L["Bank Bag Slot %d"], bankButtonID or -1), 1.0, 1.0, 1.0)
local cost = GetBankSlotCost(numSlots)
GameTooltip:AddLine(addon.Modules.Utils:FormatMoney(cost, false, true), 1, 1, 1)
-- Show purchase cursor (coin icon)
+4 -4
View File
@@ -90,7 +90,7 @@
GameTooltip:SetText("Restack and Clean")
GameTooltip:AddLine("Merges split stacks and refreshes the view", 0.7, 0.7, 0.7)
else
GameTooltip:SetText("Sort Bank")
GameTooltip:SetText(Guda_L["Sort Bank"])
end
GameTooltip:Show()
</OnEnter>
@@ -138,7 +138,7 @@
</OnClick>
<OnEnter>
GameTooltip:SetOwner(this, "ANCHOR_TOP")
GameTooltip:SetText("Settings")
GameTooltip:SetText(Guda_L["Settings"])
GameTooltip:Show()
</OnEnter>
<OnLeave>
@@ -185,7 +185,7 @@
</OnClick>
<OnEnter>
GameTooltip:SetOwner(this, "ANCHOR_TOP")
GameTooltip:SetText("Use Blizzard Bank UI")
GameTooltip:SetText(Guda_L["Use Blizzard Bank UI"])
GameTooltip:Show()
</OnEnter>
<OnLeave>
@@ -232,7 +232,7 @@
</OnClick>
<OnEnter>
GameTooltip:SetOwner(this, "ANCHOR_TOP")
GameTooltip:SetText("View Bank")
GameTooltip:SetText(Guda_L["View Bank"])
GameTooltip:Show()
</OnEnter>
<OnLeave>
+10 -10
View File
@@ -695,13 +695,13 @@ UseContainerItem = function(bag, slot, ...)
if itemID and DB:IsItemProtected(itemID) then
-- Block selling at merchant
if MerchantFrame and MerchantFrame:IsVisible() then
addon:Print("Cannot sell " .. link .. " — item is protected")
addon:Print(format(Guda_L["Cannot sell %s — item is protected"], link))
return
end
-- Block disenchant/milling/prospecting (spell targeting an item)
if SpellIsTargeting and SpellIsTargeting() then
SpellStopTargeting()
addon:Print("Cannot disenchant " .. link .. " — item is protected")
addon:Print(format(Guda_L["Cannot disenchant %s — item is protected"], link))
return
end
end
@@ -739,7 +739,7 @@ local function HookDeletePopup(dialogName)
local originalOnShow = StaticPopupDialogs[dialogName].OnShow
StaticPopupDialogs[dialogName].OnShow = function()
if cursorProtectedLink then
addon:Print("Cannot delete " .. cursorProtectedLink .. " — item is protected")
addon:Print(format(Guda_L["Cannot delete %s — item is protected"], cursorProtectedLink))
ClearCursor()
cursorProtectedLink = nil
this:Hide()
@@ -1092,9 +1092,9 @@ function Guda_ItemButton_OnLoad(self)
if EquipSets and EquipSets.IsInSet and EquipSets:IsInSet(itemID) then
local isNowExcepted = addon.Modules.DB:ToggleSetProtectionException(itemID)
if isNowExcepted then
addon:Print(link .. " set protection removed")
addon:Print(format(Guda_L["%s set protection removed"], link))
else
addon:Print(link .. " set protection restored")
addon:Print(format(Guda_L["%s set protection restored"], link))
end
-- Refresh bag/bank frames
if addon.Modules.BagFrame and addon.Modules.BagFrame.Update then
@@ -1108,9 +1108,9 @@ function Guda_ItemButton_OnLoad(self)
end
local isNowLocked = addon.Modules.DB:ToggleItemLock(itemID)
if isNowLocked then
addon:Print(link .. " locked")
addon:Print(format(Guda_L["%s locked"], link))
else
addon:Print(link .. " unlocked")
addon:Print(format(Guda_L["%s unlocked"], link))
end
-- Refresh bag/bank frames
if addon.Modules.BagFrame and addon.Modules.BagFrame.Update then
@@ -1133,9 +1133,9 @@ function Guda_ItemButton_OnLoad(self)
itemName = " " .. this.itemData.link
end
if isNowPinned then
addon:Print("Slot pinned" .. itemName .. " (skipped during sort)")
addon:Print(format(Guda_L["Slot pinned %s (skipped during sort)"], itemName))
else
addon:Print("Slot unpinned" .. itemName)
addon:Print(format(Guda_L["Slot unpinned %s"], itemName))
end
-- Refresh to show/hide pin icon
if addon.Modules.BagFrame and addon.Modules.BagFrame.Update then
@@ -1204,7 +1204,7 @@ function Guda_ItemButton_OnLoad(self)
local itemID = addon.Modules.Utils:ExtractItemID(link)
if itemID and addon.Modules.DB:IsItemProtected(itemID) then
SpellStopTargeting()
addon:Print("Cannot disenchant " .. link .. " — item is protected")
addon:Print(format(Guda_L["Cannot disenchant %s — item is protected"], link))
return
end
end
+5 -5
View File
@@ -30,7 +30,7 @@ function Guda_MailboxFrame_OnLoad(self)
-- Set up search box placeholder
local searchBox = getglobal(self:GetName().."_SearchBar_SearchBox")
if searchBox then
searchBox:SetText("Search mailbox...")
searchBox:SetText(Guda_L["Search mailbox..."])
searchBox:SetTextColor(0.5, 0.5, 0.5, 1)
end
@@ -148,7 +148,7 @@ function MailboxFrame:Update()
charName = string.sub(charFullName, 1, dashPos - 1)
end
getglobal("Guda_MailboxFrame_Title"):SetText(charName .. "'s Mailbox")
getglobal("Guda_MailboxFrame_Title"):SetText(format(Guda_L["%s's Mailbox"], charName))
-- Filter items based on search text
local filteredItems = {}
@@ -175,7 +175,7 @@ function MailboxFrame:Update()
local emptyMessage = getglobal("Guda_MailboxFrame_EmptyMessage")
if emptyMessage then
if totalItems == 0 then
emptyMessage:SetText("No mailbox data found for this character.\n\nVisit a mailbox in-game to save your mail data.")
emptyMessage:SetText(Guda_L["No mailbox data found for this character.\n\nVisit a mailbox in-game to save your mail data."])
emptyMessage:Show()
else
emptyMessage:Hide()
@@ -333,7 +333,7 @@ function MailboxFrame:DisplayItems(items, charFullName, totalMails)
local paginationText = getglobal("Guda_MailboxFrame_Pagination_Text")
if paginationText then
if totalMails == 0 then
paginationText:SetText("No Mail")
paginationText:SetText(Guda_L["No Mail"])
else
paginationText:SetText(string.format("%d/%d (items: %d)", currentPage, totalPages, totalMails or 0))
end
@@ -344,7 +344,7 @@ end
function Guda_MailboxFrame_OnSearchTextChanged()
local searchBox = getglobal("Guda_MailboxFrame_SearchBar_SearchBox")
local text = searchBox:GetText()
if text == "Search mailbox..." then
if text == Guda_L["Search mailbox..."] then
searchText = ""
else
searchText = string.lower(text)
+2 -2
View File
@@ -272,7 +272,7 @@ function QuestItemBar:Update()
button:SetScript("OnClick", function()
if this.fromDB then
addon:Print("Item is not currently in your bags (loading from database).")
addon:Print(Guda_L["Item is not currently in your bags (loading from database)."])
return
end
@@ -613,7 +613,7 @@ function QuestItemBar:UpdateFlyout(parent)
btn:SetScript("OnClick", function()
if this.fromDB then
addon:Print("Item is not currently in your bags (loading from database).")
addon:Print(Guda_L["Item is not currently in your bags (loading from database)."])
return
end
+184 -93
View File
@@ -10,7 +10,7 @@ addon.Modules.SettingsPopup = SettingsPopup
local function CreateSectionHeader(parent, text, yOffset)
local label = parent:CreateFontString(nil, "OVERLAY", "GameFontNormal")
label:SetPoint("TOPLEFT", parent, "TOPLEFT", 5, yOffset)
label:SetText(text)
label:SetText(Guda_L[text] or text)
label:SetTextColor(1, 0.82, 0, 1)
-- Separator line extending from label to the right edge
@@ -39,35 +39,33 @@ function Guda_SettingsPopup_OnLoad(self)
Guda:ApplyBackdrop(self, "DEFAULT_FRAME")
local title = getglobal(self:GetName().."_Title")
title:SetText("Guda Settings")
title:SetText(Guda_L["Guda Settings"])
-- Increase title font size
local titleFont, _, titleFlags = title:GetFont()
if titleFont then
title:SetFont(titleFont, 16, titleFlags)
end
-- Set How to Use text
-- Localize the XML-defined tab button labels at runtime
local function localizeTabBtn(btnName, key)
local fs = getglobal(btnName .. "_Text")
if fs then fs:SetText(Guda_L[key]) end
end
localizeTabBtn("Guda_SettingsPopup_GeneralTabButton", "General")
localizeTabBtn("Guda_SettingsPopup_LayoutTabButton", "Layout")
localizeTabBtn("Guda_SettingsPopup_IconsTabButton", "Icons")
localizeTabBtn("Guda_SettingsPopup_BarTabButton", "Bar")
localizeTabBtn("Guda_SettingsPopup_CategoriesTabButton", "Categories")
localizeTabBtn("Guda_SettingsPopup_GuideTabButton", "Guide")
-- Localize Categories tab header (set in XML)
local catHeader = getglobal("Guda_SettingsPopup_CategoriesTab_Header")
if catHeader then catHeader:SetText(Guda_L["Manage item categories and their display order:"]) end
-- Set How to Use text (localized)
local instructions = getglobal("Guda_SettingsPopup_GuideTab_Instructions")
if instructions then
local text = "|cffffd100Tracking Items:|r\n" ..
"Alt + Left Click on any item in your bags to track it.\n" ..
"Tracked items will appear in the Tracked Item Bar.\n" ..
"Left Click on an item in the bar to use it.\n" ..
"Alt + Left Click on an item in the bar to untrack it.\n\n" ..
"|cffffd100Locked Items:|r\n" ..
"Ctrl + Right Click on any item to lock/unlock it.\n" ..
"Locked items cannot be sold at vendors, deleted, or disenchanted.\n" ..
"Equipment set items are automatically protected.\n" ..
"Ctrl + Right Click a set item to toggle its protection.\n" ..
"A lock icon appears on the bottom-right corner.\n\n" ..
"|cffffd100Pin Slot:|r\n" ..
"Alt + Right Click on any bag slot to pin/unpin it.\n" ..
"Pinned slots are skipped during sorting.\n" ..
"The pin stays on the slot, not the item.\n" ..
"A pin icon appears on the top-left corner.\n\n" ..
"|cffffd100Moving Bars:|r\n" ..
"Shift + Left Click and drag any item on the Quest Item Bar or Tracked Item Bar to move the bar.\n"
instructions:SetText(text)
instructions:SetText(Guda_L["GUIDE_TEXT"])
end
-- Create section headers for each tab
@@ -343,6 +341,20 @@ function Guda_SettingsPopup_OnShow(self)
whiteItemsJunkCheckbox:SetChecked(whiteItemsJunk and 1 or 0)
end
-- Auto Loot checkbox
local autoLootCheckbox = getglobal("Guda_SettingsPopup_AutoLootCheckbox")
if autoLootCheckbox then
local autoLoot = Guda.Modules.DB:GetSetting("autoLoot") and true or false
autoLootCheckbox:SetChecked(autoLoot and 1 or 0)
end
-- Auto Open Clams checkbox
local autoOpenClamsCheckbox = getglobal("Guda_SettingsPopup_AutoOpenClamsCheckbox")
if autoOpenClamsCheckbox then
local autoOpenClams = Guda.Modules.DB:GetSetting("autoOpenClams") and true or false
autoOpenClamsCheckbox:SetChecked(autoOpenClams and 1 or 0)
end
if bagViewDropdown then
UIDropDownMenu_SetSelectedValue(bagViewDropdown, bagViewType)
UIDropDownMenu_SetText(bagViewType == "single" and "Single" or "Category", bagViewDropdown)
@@ -405,7 +417,7 @@ function Guda_SettingsPopup_BagColumnsSlider_OnLoad(self)
getglobal(self:GetName().."High"):SetText("20")
local text = getglobal(self:GetName().."Text")
text:SetText("Bag columns")
text:SetText(Guda_L["Bag columns"])
-- Increase font size
local font, _, flags = text:GetFont()
@@ -425,7 +437,7 @@ function Guda_SettingsPopup_BagColumnsSlider_OnValueChanged(self)
local value = self:GetValue()
-- Update display text
getglobal(self:GetName().."Text"):SetText("Bag columns: " .. value)
getglobal(self:GetName().."Text"):SetText(format(Guda_L["Bag columns: %d"], value))
-- Save setting
Guda.Modules.DB:SetSetting("bagColumns", value)
@@ -443,7 +455,7 @@ function Guda_SettingsPopup_BankColumnsSlider_OnLoad(self)
getglobal(self:GetName().."High"):SetText("20")
local text = getglobal(self:GetName().."Text")
text:SetText("Bank columns")
text:SetText(Guda_L["Bank columns"])
-- Increase font size
local font, _, flags = text:GetFont()
@@ -463,7 +475,7 @@ function Guda_SettingsPopup_BankColumnsSlider_OnValueChanged(self)
local value = self:GetValue()
-- Update display text
getglobal(self:GetName().."Text"):SetText("Bank columns: " .. value)
getglobal(self:GetName().."Text"):SetText(format(Guda_L["Bank columns: %d"], value))
-- Save setting
Guda.Modules.DB:SetSetting("bankColumns", value)
@@ -481,7 +493,7 @@ function Guda_SettingsPopup_BgTransparencySlider_OnLoad(self)
getglobal(self:GetName().."High"):SetText("100%")
local text = getglobal(self:GetName().."Text")
text:SetText("Background Transparency")
text:SetText(Guda_L["Background Transparency"])
-- Increase font size
local font, _, flags = text:GetFont()
@@ -503,7 +515,7 @@ function Guda_SettingsPopup_BgTransparencySlider_OnValueChanged(self)
value = math.floor(value * 100 + 0.5) / 100
-- Update display text
getglobal(self:GetName().."Text"):SetText("Background Transparency: " .. math.floor(value * 100) .. "%")
getglobal(self:GetName().."Text"):SetText(format(Guda_L["Background Transparency: %d%%"], math.floor(value * 100)))
-- Save setting
Guda.Modules.DB:SetSetting("bgTransparency", value)
@@ -540,7 +552,7 @@ function Guda_SettingsPopup_IconSizeSlider_OnLoad(self)
getglobal(self:GetName().."High"):SetText("64px")
local text = getglobal(self:GetName().."Text")
text:SetText("Icon size")
text:SetText(Guda_L["Icon size"])
-- Increase font size
local font, _, flags = text:GetFont()
@@ -559,7 +571,7 @@ end
function Guda_SettingsPopup_IconSizeSlider_OnValueChanged(self)
local value = math.floor(self:GetValue() + 0.5)
getglobal(self:GetName().."Text"):SetText("Icon size: " .. value .. "px")
getglobal(self:GetName().."Text"):SetText(format(Guda_L["Icon size: %dpx"], value))
Guda.Modules.DB:SetSetting("iconSize", value)
@@ -580,7 +592,7 @@ function Guda_SettingsPopup_IconFontSizeSlider_OnLoad(self)
getglobal(self:GetName().."High"):SetText("20px")
local text = getglobal(self:GetName().."Text")
text:SetText("Icon font size")
text:SetText(Guda_L["Icon font size"])
-- Increase font size
local font, _, flags = text:GetFont()
@@ -599,7 +611,7 @@ end
function Guda_SettingsPopup_IconFontSizeSlider_OnValueChanged(self)
local value = math.floor(self:GetValue() + 0.5)
getglobal(self:GetName().."Text"):SetText("Icon font size: " .. value .. "px")
getglobal(self:GetName().."Text"):SetText(format(Guda_L["Icon font size: %dpx"], value))
Guda.Modules.DB:SetSetting("iconFontSize", value)
@@ -620,7 +632,7 @@ function Guda_SettingsPopup_IconSpacingSlider_OnLoad(self)
getglobal(self:GetName().."High"):SetText("20px")
local text = getglobal(self:GetName().."Text")
text:SetText("Icon spacing")
text:SetText(Guda_L["Icon spacing"])
-- Increase font size
local font, _, flags = text:GetFont()
@@ -639,7 +651,7 @@ end
function Guda_SettingsPopup_IconSpacingSlider_OnValueChanged(self)
local value = math.floor(self:GetValue() + 0.5)
local displayValue = value >= 0 and value .. "px" or value .. "px"
getglobal(self:GetName().."Text"):SetText("Icon spacing: " .. displayValue)
getglobal(self:GetName().."Text"):SetText(format(Guda_L["Icon spacing: %s"], tostring(displayValue)))
-- Save setting
Guda.Modules.DB:SetSetting("iconSpacing", value)
@@ -666,7 +678,7 @@ function Guda_SettingsPopup_QuestBarSizeSlider_OnLoad(self)
getglobal(self:GetName().."High"):SetText("64px")
local text = getglobal(self:GetName().."Text")
text:SetText("Quest bar size")
text:SetText(Guda_L["Quest bar size"])
-- Increase font size
local font, _, flags = text:GetFont()
@@ -685,7 +697,7 @@ end
function Guda_SettingsPopup_QuestBarSizeSlider_OnValueChanged(self)
local value = math.floor(self:GetValue() + 0.5)
getglobal(self:GetName().."Text"):SetText("Quest bar size: " .. value .. "px")
getglobal(self:GetName().."Text"):SetText(format(Guda_L["Quest bar size: %dpx"], value))
Guda.Modules.DB:SetSetting("questBarSize", value)
@@ -701,7 +713,7 @@ function Guda_SettingsPopup_TrackedBarSizeSlider_OnLoad(self)
getglobal(self:GetName().."High"):SetText("64px")
local text = getglobal(self:GetName().."Text")
text:SetText("Tracked bar size")
text:SetText(Guda_L["Tracked bar size"])
-- Increase font size
local font, _, flags = text:GetFont()
@@ -720,7 +732,7 @@ end
function Guda_SettingsPopup_TrackedBarSizeSlider_OnValueChanged(self)
local value = math.floor(self:GetValue() + 0.5)
getglobal(self:GetName().."Text"):SetText("Tracked bar size: " .. value .. "px")
getglobal(self:GetName().."Text"):SetText(format(Guda_L["Tracked bar size: %dpx"], value))
Guda.Modules.DB:SetSetting("trackedBarSize", value)
@@ -734,7 +746,7 @@ end
function Guda_SettingsPopup_LockBagsCheckbox_OnLoad(self)
local text = getglobal(self:GetName().."Text")
if text then
text:SetText("Lock Window")
text:SetText(Guda_L["Lock Window"])
-- Increase font size
local font, _, flags = text:GetFont()
@@ -781,7 +793,7 @@ end
function Guda_SettingsPopup_HideBordersCheckbox_OnLoad(self)
local text = getglobal(self:GetName().."Text")
if text then
text:SetText("Hide Frame Borders")
text:SetText(Guda_L["Hide Frame Borders"])
-- Increase font size
local font, _, flags = text:GetFont()
@@ -840,7 +852,7 @@ end
function Guda_SettingsPopup_QualityBorderEquipmentCheckbox_OnLoad(self)
local text = getglobal(self:GetName().."Text")
if text then
text:SetText("Equipment Borders")
text:SetText(Guda_L["Equipment Borders"])
-- Increase font size
local font, _, flags = text:GetFont()
@@ -888,7 +900,7 @@ end
function Guda_SettingsPopup_QualityBorderOtherCheckbox_OnLoad(self)
local text = getglobal(self:GetName().."Text")
if text then
text:SetText("Other Item Borders")
text:SetText(Guda_L["Other Item Borders"])
-- Increase font size
local font, _, flags = text:GetFont()
@@ -936,7 +948,7 @@ end
function Guda_SettingsPopup_ShowSearchBarCheckbox_OnLoad(self)
local text = getglobal(self:GetName().."Text")
if text then
text:SetText("Show Search Bar")
text:SetText(Guda_L["Show Search Bar"])
-- Increase font size
local font, _, flags = text:GetFont()
@@ -993,7 +1005,7 @@ end
function Guda_SettingsPopup_ShowQuestBarCheckbox_OnLoad(self)
local text = getglobal(self:GetName().."Text")
if text then
text:SetText("Show Quest Bar")
text:SetText(Guda_L["Show Quest Bar"])
-- Increase font size
local font, _, flags = text:GetFont()
@@ -1035,7 +1047,7 @@ end
function Guda_SettingsPopup_HoverBaglineCheckbox_OnLoad(self)
local text = getglobal(self:GetName().."Text")
if text then
text:SetText("Show All Bags")
text:SetText(Guda_L["Show All Bags"])
-- Increase font size
local font, _, flags = text:GetFont()
@@ -1087,7 +1099,7 @@ end
function Guda_SettingsPopup_HideFooterCheckbox_OnLoad(self)
local text = getglobal(self:GetName().."Text")
if text then
text:SetText("Hide Footer")
text:SetText(Guda_L["Hide Footer"])
-- Increase font size
local font, _, flags = text:GetFont()
@@ -1142,7 +1154,7 @@ end
function Guda_SettingsPopup_ShowTooltipCountsCheckbox_OnLoad(self)
local text = getglobal(self:GetName().."Text")
if text then
text:SetText(L_SHOW_TOOLTIP_COUNTS or "Show Item Counts in Tooltip")
text:SetText(Guda_L["Tooltip Extension"])
-- Increase font size
local font, _, flags = text:GetFont()
@@ -1152,7 +1164,7 @@ function Guda_SettingsPopup_ShowTooltipCountsCheckbox_OnLoad(self)
end
-- Tooltip
self.tooltipText = L_SHOW_TOOLTIP_COUNTS_TT or "Show how many of this item you have across all your characters in the item tooltip."
self.tooltipText = Guda_L["Show how many of this item you have across all your characters in the item tooltip."]
local showTooltipCounts = true
if Guda and Guda.Modules and Guda.Modules.DB then
@@ -1181,7 +1193,7 @@ function Guda_SettingsPopup_JunkOpacitySlider_OnLoad(self)
getglobal(self:GetName().."High"):SetText("100%")
local text = getglobal(self:GetName().."Text")
text:SetText("Junk item opacity")
text:SetText(Guda_L["Junk item opacity"])
-- Increase font size
local font, _, flags = text:GetFont()
@@ -1203,7 +1215,7 @@ function Guda_SettingsPopup_JunkOpacitySlider_OnValueChanged(self)
value = math.floor(value * 100 + 0.5) / 100
-- Update display text
getglobal(self:GetName().."Text"):SetText("Junk item opacity: " .. math.floor(value * 100) .. "%")
getglobal(self:GetName().."Text"):SetText(format(Guda_L["Junk item opacity: %d%%"], math.floor(value * 100)))
-- Save setting
Guda.Modules.DB:SetSetting("junkOpacity", value)
@@ -1225,7 +1237,7 @@ end
function Guda_SettingsPopup_MarkUnusableCheckbox_OnLoad(self)
local text = getglobal(self:GetName().."Text")
if text then
text:SetText("Mark Unusable Items")
text:SetText(Guda_L["Mark Unusable Items"])
-- Increase font size
local font, _, flags = text:GetFont()
@@ -1235,7 +1247,7 @@ function Guda_SettingsPopup_MarkUnusableCheckbox_OnLoad(self)
end
-- Tooltip
self.tooltipText = "Show a red tint on items that your character cannot use (wrong class, level, etc.)."
self.tooltipText = Guda_L["Show a red tint on items that your character cannot use (wrong class, level, etc.)."]
local markUnusable = true
if Guda and Guda.Modules and Guda.Modules.DB then
@@ -1273,7 +1285,7 @@ end
function Guda_SettingsPopup_ShowEquipSetCategoriesCheckbox_OnLoad(self)
local text = getglobal(self:GetName().."Text")
if text then
text:SetText("Equip Set Categories")
text:SetText(Guda_L["Equip Set Categories"])
local font, _, flags = text:GetFont()
if font then
@@ -1281,7 +1293,7 @@ function Guda_SettingsPopup_ShowEquipSetCategoriesCheckbox_OnLoad(self)
end
end
self.tooltipText = "Show equipment set categories in category view."
self.tooltipText = Guda_L["Show equipment set categories in category view."]
local enabled = true
if Guda and Guda.Modules and Guda.Modules.DB then
@@ -1315,7 +1327,7 @@ end
function Guda_SettingsPopup_MarkEquipmentSetsCheckbox_OnLoad(self)
local text = getglobal(self:GetName().."Text")
if text then
text:SetText("Mark Equipment Sets")
text:SetText(Guda_L["Mark Equipment Sets"])
local font, _, flags = text:GetFont()
if font then
@@ -1323,7 +1335,7 @@ function Guda_SettingsPopup_MarkEquipmentSetsCheckbox_OnLoad(self)
end
end
self.tooltipText = "Show a special icon on items that belong to an equipment set."
self.tooltipText = Guda_L["Show a special icon on items that belong to an equipment set."]
local enabled = true
if Guda and Guda.Modules and Guda.Modules.DB then
@@ -1357,7 +1369,7 @@ end
function Guda_SettingsPopup_AutoLockSetItemsCheckbox_OnLoad(self)
local text = getglobal(self:GetName().."Text")
if text then
text:SetText("Auto Lock Set Items")
text:SetText(Guda_L["Auto Lock Set Items"])
local font, _, flags = text:GetFont()
if font then
@@ -1365,7 +1377,7 @@ function Guda_SettingsPopup_AutoLockSetItemsCheckbox_OnLoad(self)
end
end
self.tooltipText = "Prevent selling and deleting items saved in equipment sets."
self.tooltipText = Guda_L["Prevent selling and deleting items saved in equipment sets."]
local enabled = true
if Guda and Guda.Modules and Guda.Modules.DB then
@@ -1389,7 +1401,7 @@ end
function Guda_SettingsPopup_ShowCategoryCountCheckbox_OnLoad(self)
local text = getglobal(self:GetName().."Text")
if text then
text:SetText("Show Category Count")
text:SetText(Guda_L["Show Category Count"])
local font, _, flags = text:GetFont()
if font then
@@ -1397,7 +1409,7 @@ function Guda_SettingsPopup_ShowCategoryCountCheckbox_OnLoad(self)
end
end
self.tooltipText = "Show the item count next to each category header in category view."
self.tooltipText = Guda_L["Show the item count next to each category header in category view."]
local enabled = true
if Guda and Guda.Modules and Guda.Modules.DB then
@@ -1427,11 +1439,90 @@ function Guda_SettingsPopup_ShowCategoryCountCheckbox_OnClick(self)
end
end
-- Auto Loot Checkbox OnLoad
function Guda_SettingsPopup_AutoLootCheckbox_OnLoad(self)
local text = getglobal(self:GetName().."Text")
if text then
text:SetText(Guda_L["Auto Loot"])
local font, _, flags = text:GetFont()
if font then text:SetFont(font, 13, flags) end
end
-- TurtleWoW requires SuperWoW for any addon-driven autoloot to work
-- (both SetAutoloot and LootSlot are gated). If it's not present, soft-
-- disable: keep mouse enabled so the tooltip still shows on hover, but
-- mark the button so OnClick is a no-op and dim the label.
local hasSuperWoW = SetAutoloot ~= nil
self._gudaSoftDisabled = not hasSuperWoW
if hasSuperWoW then
self.tooltipText = Guda_L["Automatically loot all items when looting a corpse or container."]
if text then text:SetTextColor(1, 1, 1) end
else
self.tooltipText = Guda_L["Auto Loot requires the SuperWoW client mod. Install SuperWoW to enable this option."]
if text then text:SetTextColor(0.5, 0.5, 0.5) end
end
local enabled = false
if Guda and Guda.Modules and Guda.Modules.DB then
enabled = Guda.Modules.DB:GetSetting("autoLoot") and true or false
end
self:SetChecked(enabled and 1 or 0)
end
-- Auto Loot Checkbox OnClick
function Guda_SettingsPopup_AutoLootCheckbox_OnClick(self)
-- Soft-disable: revert the click and bail when SuperWoW is missing.
if self._gudaSoftDisabled then
local enabled = Guda.Modules.DB:GetSetting("autoLoot") and true or false
self:SetChecked(enabled and 1 or 0)
return
end
local isChecked = self:GetChecked() == 1
if Guda and Guda.Modules and Guda.Modules.DB then
Guda.Modules.DB:SetSetting("autoLoot", isChecked)
end
-- Apply immediately to the client (SuperWoW's SetAutoloot or vanilla
-- SetAutoLootDefault) so the toggle takes effect on the next loot.
if Guda.Modules.AutoLoot and Guda.Modules.AutoLoot.Apply then
Guda.Modules.AutoLoot:Apply()
end
end
-- Auto Open Clams Checkbox OnLoad
function Guda_SettingsPopup_AutoOpenClamsCheckbox_OnLoad(self)
local text = getglobal(self:GetName().."Text")
if text then
text:SetText(Guda_L["Auto Open Clams"])
local font, _, flags = text:GetFont()
if font then text:SetFont(font, 13, flags) end
end
self.tooltipText = Guda_L["Automatically open clams in your bags when you loot one."]
local enabled = false
if Guda and Guda.Modules and Guda.Modules.DB then
enabled = Guda.Modules.DB:GetSetting("autoOpenClams") and true or false
end
self:SetChecked(enabled and 1 or 0)
end
-- Auto Open Clams Checkbox OnClick
function Guda_SettingsPopup_AutoOpenClamsCheckbox_OnClick(self)
local isChecked = self:GetChecked() == 1
if Guda and Guda.Modules and Guda.Modules.DB then
Guda.Modules.DB:SetSetting("autoOpenClams", isChecked)
end
-- If enabling, kick off an immediate run for any clams already in bags.
if isChecked and Guda.Modules.ClamOpener then
Guda.Modules.ClamOpener:Open(true)
end
end
-- Auto Vendor Junk Checkbox OnLoad
function Guda_SettingsPopup_AutoVendorJunkCheckbox_OnLoad(self)
local text = getglobal(self:GetName().."Text")
if text then
text:SetText("Auto Sell Junk")
text:SetText(Guda_L["Auto Sell Junk"])
local font, _, flags = text:GetFont()
if font then
@@ -1439,7 +1530,7 @@ function Guda_SettingsPopup_AutoVendorJunkCheckbox_OnLoad(self)
end
end
self.tooltipText = "Automatically sell gray (junk) items when you visit a vendor."
self.tooltipText = Guda_L["Automatically sell gray (junk) items when you visit a vendor."]
local enabled = true
if Guda and Guda.Modules and Guda.Modules.DB then
@@ -1463,7 +1554,7 @@ end
function Guda_SettingsPopup_AutoOpenBagsCheckbox_OnLoad(self)
local text = getglobal(self:GetName().."Text")
if text then
text:SetText("Auto Open Bags")
text:SetText(Guda_L["Auto Open Bags"])
local font, _, flags = text:GetFont()
if font then
@@ -1471,7 +1562,7 @@ function Guda_SettingsPopup_AutoOpenBagsCheckbox_OnLoad(self)
end
end
self.tooltipText = "Automatically open bags when interacting with bank, auction house, mail, or trade."
self.tooltipText = Guda_L["Automatically open bags when interacting with bank, auction house, mail, or trade."]
local enabled = true
if Guda and Guda.Modules and Guda.Modules.DB then
@@ -1495,7 +1586,7 @@ end
function Guda_SettingsPopup_AutoCloseBagsCheckbox_OnLoad(self)
local text = getglobal(self:GetName().."Text")
if text then
text:SetText("Auto Close Bags")
text:SetText(Guda_L["Auto Close Bags"])
local font, _, flags = text:GetFont()
if font then
@@ -1503,7 +1594,7 @@ function Guda_SettingsPopup_AutoCloseBagsCheckbox_OnLoad(self)
end
end
self.tooltipText = "Automatically close bags when closing bank, auction house, mail, trade, or vendor."
self.tooltipText = Guda_L["Automatically close bags when closing bank, auction house, mail, trade, or vendor."]
local enabled = false
if Guda and Guda.Modules and Guda.Modules.DB then
@@ -1527,7 +1618,7 @@ end
function Guda_SettingsPopup_WhiteItemsJunkCheckbox_OnLoad(self)
local text = getglobal(self:GetName().."Text")
if text then
text:SetText("White Items as Junk")
text:SetText(Guda_L["White Items as Junk"])
local font, _, flags = text:GetFont()
if font then
@@ -1535,7 +1626,7 @@ function Guda_SettingsPopup_WhiteItemsJunkCheckbox_OnLoad(self)
end
end
self.tooltipText = "Treat white (common) equippable items as junk. They will be dimmed and auto-sold if auto-sell is enabled."
self.tooltipText = Guda_L["Treat white (common) equippable items as junk. They will be dimmed and auto-sold if auto-sell is enabled."]
local enabled = false
if Guda and Guda.Modules and Guda.Modules.DB then
@@ -1582,13 +1673,13 @@ local themeOptions = {
function Guda_SettingsPopup_UsePfUITransparencyCheckbox_OnLoad(self)
local text = getglobal(self:GetName().."Text")
if text then
text:SetText("pfUI Transparency")
text:SetText(Guda_L["pfUI Transparency"])
local font, _, flags = text:GetFont()
if font then
text:SetFont(font, 13, flags)
end
end
self.tooltipText = "When enabled, uses pfUI's background transparency instead of the slider below."
self.tooltipText = Guda_L["When enabled, uses pfUI's background transparency instead of the slider below."]
local val = true
if Guda and Guda.Modules and Guda.Modules.DB then
@@ -1643,7 +1734,7 @@ function Guda_SettingsPopup_ThemeDropdown_OnLoad(self)
-- Add label above dropdown
local label = self:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
label:SetPoint("BOTTOMLEFT", self, "TOPLEFT", 20, 2)
label:SetText("Theme")
label:SetText(Guda_L["Theme"])
label:SetTextColor(1, 0.82, 0, 1)
end
@@ -1761,7 +1852,7 @@ function Guda_SettingsPopup_BagViewDropdown_OnLoad(self)
local label = self:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
label:SetPoint("BOTTOMLEFT", self, "TOPLEFT", 20, 2)
label:SetText("Bag View")
label:SetText(Guda_L["Bag View"])
label:SetTextColor(1, 0.82, 0, 1)
end
@@ -1800,7 +1891,7 @@ function Guda_SettingsPopup_BankViewDropdown_OnLoad(self)
local label = self:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
label:SetPoint("BOTTOMLEFT", self, "TOPLEFT", 20, 2)
label:SetText("Bank View")
label:SetText(Guda_L["Bank View"])
label:SetTextColor(1, 0.82, 0, 1)
end
@@ -1808,7 +1899,7 @@ end
function Guda_SettingsPopup_ReverseStackSortCheckbox_OnLoad(self)
local text = getglobal(self:GetName().."Text")
if text then
text:SetText("Reverse Stack Sort")
text:SetText(Guda_L["Reverse Stack Sort"])
-- Increase font size
local font, _, flags = text:GetFont()
@@ -1818,7 +1909,7 @@ function Guda_SettingsPopup_ReverseStackSortCheckbox_OnLoad(self)
end
-- Tooltip
self.tooltipText = "When enabled, smaller stacks of the same item will be sorted before larger stacks (e.g., stack of 16 before stack of 20)."
self.tooltipText = Guda_L["When enabled, smaller stacks of the same item will be sorted before larger stacks (e.g., stack of 16 before stack of 20)."]
local reverseStackSort = false
if Guda and Guda.Modules and Guda.Modules.DB then
@@ -1901,7 +1992,7 @@ local function GetCategoryRowFrame(index)
editBtn:SetWidth(40)
editBtn:SetHeight(18)
editBtn:SetPoint("LEFT", nameText, "RIGHT", 5, 0)
editBtn:SetText("Edit")
editBtn:SetText(Guda_L["Edit"])
editBtn:SetScript("OnClick", function()
local catId = this:GetParent().categoryId
if catId then
@@ -1967,7 +2058,7 @@ local function GetCategoryRowFrame(index)
-- Built-in indicator
local builtInText = row:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
builtInText:SetPoint("LEFT", deleteBtn, "RIGHT", 5, 0)
builtInText:SetText("(Built-in)")
builtInText:SetText(Guda_L["(Built-in)"])
builtInText:SetTextColor(0.5, 0.5, 0.5)
row.builtInText = builtInText
@@ -1991,7 +2082,7 @@ local function GetCategoryRowFrame(index)
end)
local mergeLabel = row:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
mergeLabel:SetPoint("RIGHT", mergeCheckbox, "LEFT", -2, 0)
mergeLabel:SetText("Merge")
mergeLabel:SetText(Guda_L["Merge"])
mergeLabel:SetTextColor(0.8, 0.8, 0.8)
row.mergeCheckbox = mergeCheckbox
row.mergeLabel = mergeLabel
@@ -2141,12 +2232,12 @@ function Guda_SettingsPopup_CategoriesTab_Update()
-- Set button texts
local addBtn = getglobal("Guda_SettingsPopup_AddCategoryButton")
if addBtn then
addBtn:SetText("+ Add Category")
addBtn:SetText(Guda_L["+ Add Category"])
end
local resetBtn = getglobal("Guda_SettingsPopup_ResetCategoriesButton")
if resetBtn then
resetBtn:SetText("Reset Defaults")
resetBtn:SetText(Guda_L["Reset Defaults"])
end
end
@@ -2262,13 +2353,13 @@ function Guda_CategoryEditor_OnLoad(self)
-- Set button texts
local addBtn = getglobal("Guda_CategoryEditor_AddRuleButton")
if addBtn then addBtn:SetText("+ Add Rule") end
if addBtn then addBtn:SetText(Guda_L["+ Add Rule"]) end
local saveBtn = getglobal("Guda_CategoryEditor_SaveButton")
if saveBtn then saveBtn:SetText("Save") end
if saveBtn then saveBtn:SetText(Guda_L["Save"]) end
local cancelBtn = getglobal("Guda_CategoryEditor_CancelButton")
if cancelBtn then cancelBtn:SetText("Cancel") end
if cancelBtn then cancelBtn:SetText(Guda_L["Cancel"]) end
-- Create group EditBox if it doesn't exist
if not getglobal("Guda_CategoryEditor_GroupEditBox") then
@@ -2277,7 +2368,7 @@ function Guda_CategoryEditor_OnLoad(self)
-- Label
local groupLabel = self:CreateFontString("Guda_CategoryEditor_GroupLabel", "OVERLAY", "GameFontNormalSmall")
groupLabel:SetPoint("LEFT", nameBox, "RIGHT", 14, 0)
groupLabel:SetText("Group:")
groupLabel:SetText(Guda_L["Group:"])
groupLabel:SetTextColor(0.7, 0.7, 0.7)
-- EditBox
@@ -2299,7 +2390,7 @@ function Guda_CategoryEditor_OnLoad(self)
local markLabel = self:CreateFontString("Guda_CategoryEditor_MarkLabel", "OVERLAY", "GameFontNormalSmall")
markLabel:SetPoint("TOPLEFT", self, "TOPLEFT", 20, -78)
markLabel:SetText("Mark:")
markLabel:SetText(Guda_L["Mark:"])
markLabel:SetTextColor(0.7, 0.7, 0.7)
-- "None" button (first)
@@ -2360,14 +2451,14 @@ function Guda_CategoryEditor_OnLoad(self)
if anyRadio then
local label = anyRadio:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
label:SetPoint("LEFT", anyRadio, "RIGHT", 2, 0)
label:SetText("Any rule")
label:SetText(Guda_L["Any rule"])
end
local allRadio = getglobal("Guda_CategoryEditor_MatchAll")
if allRadio then
local label = allRadio:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
label:SetPoint("LEFT", allRadio, "RIGHT", 2, 0)
label:SetText("All rules")
label:SetText(Guda_L["All rules"])
end
end
@@ -2413,9 +2504,9 @@ function Guda_CategoryEditor_Open(categoryId)
local title = getglobal("Guda_CategoryEditor_Title")
if title then
if categoryDef.isBuiltIn then
title:SetText("Edit Category (Built-in)")
title:SetText(Guda_L["Edit Category (Built-in)"])
else
title:SetText("Edit Category")
title:SetText(Guda_L["Edit Category"])
end
end
@@ -2498,7 +2589,7 @@ local function GetRuleRowFrame(index)
typeBtn:SetWidth(120)
typeBtn:SetHeight(22)
typeBtn:SetPoint("LEFT", row, "LEFT", 0, 0)
typeBtn:SetText("Select Type")
typeBtn:SetText(Guda_L["Select Type"])
typeBtn.ruleIndex = index
typeBtn:SetScript("OnClick", function()
Guda_CategoryEditor_ShowTypeDropdown(this, this.ruleIndex)
@@ -2527,7 +2618,7 @@ local function GetRuleRowFrame(index)
valueBtn:SetWidth(140)
valueBtn:SetHeight(22)
valueBtn:SetPoint("LEFT", typeBtn, "RIGHT", 5, 0)
valueBtn:SetText("Select Value")
valueBtn:SetText(Guda_L["Select Value"])
valueBtn.ruleIndex = index
valueBtn:SetScript("OnClick", function()
Guda_CategoryEditor_ShowValueDropdown(this, this.ruleIndex)
@@ -2567,7 +2658,7 @@ local function GetRuleRowFrame(index)
-- "(Drop Item)" label
local dzLabel = dropZone:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
dzLabel:SetPoint("LEFT", dropZone, "RIGHT", 4, 0)
dzLabel:SetText("(Drop Item)")
dzLabel:SetText(Guda_L["(Drop Item)"])
dzLabel:SetTextColor(0.5, 0.5, 0.5)
dropZone.label = dzLabel
@@ -2672,7 +2763,7 @@ function Guda_CategoryEditor_UpdateRulesDisplay()
-- Update rules count label
local rulesLabel = getglobal("Guda_CategoryEditor_RulesLabel")
if rulesLabel then
rulesLabel:SetText("Rules (" .. numRules .. "/" .. MAX_RULES .. "):")
rulesLabel:SetText(format(Guda_L["Rules (%d/%d):"], numRules, MAX_RULES))
end
-- Update scroll frame
+26
View File
@@ -342,6 +342,32 @@
<OnClick>Guda_SettingsPopup_AutoVendorJunkCheckbox_OnClick(this)</OnClick>
</Scripts>
</CheckButton>
<!-- Auto Loot Checkbox -->
<CheckButton name="Guda_SettingsPopup_AutoLootCheckbox" inherits="OptionsCheckButtonTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativePoint="BOTTOMLEFT" relativeTo="Guda_SettingsPopup_AutoVendorJunkCheckbox">
<Offset><AbsDimension x="0" y="-8"/></Offset>
</Anchor>
</Anchors>
<Scripts>
<OnLoad>Guda_SettingsPopup_AutoLootCheckbox_OnLoad(this)</OnLoad>
<OnClick>Guda_SettingsPopup_AutoLootCheckbox_OnClick(this)</OnClick>
</Scripts>
</CheckButton>
<!-- Auto Open Clams Checkbox -->
<CheckButton name="Guda_SettingsPopup_AutoOpenClamsCheckbox" inherits="OptionsCheckButtonTemplate">
<Anchors>
<Anchor point="LEFT" relativePoint="RIGHT" relativeTo="Guda_SettingsPopup_AutoVendorJunkCheckbox">
<Offset><AbsDimension x="200" y="0"/></Offset>
</Anchor>
</Anchors>
<Scripts>
<OnLoad>Guda_SettingsPopup_AutoOpenClamsCheckbox_OnLoad(this)</OnLoad>
<OnClick>Guda_SettingsPopup_AutoOpenClamsCheckbox_OnClick(this)</OnClick>
</Scripts>
</CheckButton>
</Frames>
</Frame>