first commit
This commit is contained in:
@@ -0,0 +1,201 @@
|
||||
-- Guda Database Module
|
||||
-- Handles saving and loading character data
|
||||
|
||||
local addon = Guda
|
||||
|
||||
local DB = {}
|
||||
addon.Modules.DB = DB
|
||||
|
||||
-- Current player info
|
||||
local playerName, playerRealm, playerFaction
|
||||
|
||||
-- Initialize database
|
||||
function DB:Initialize()
|
||||
-- Get player info
|
||||
playerName = UnitName("player")
|
||||
playerRealm = GetRealmName()
|
||||
playerFaction = UnitFactionGroup("player")
|
||||
|
||||
local fullName = playerName .. "-" .. playerRealm
|
||||
|
||||
-- Initialize global DB
|
||||
if not Guda_DB then
|
||||
Guda_DB = {
|
||||
version = addon.VERSION,
|
||||
characters = {},
|
||||
}
|
||||
end
|
||||
|
||||
-- Initialize character DB
|
||||
if not Guda_CharDB then
|
||||
Guda_CharDB = {
|
||||
settings = {
|
||||
showBankInBags = true,
|
||||
showOtherChars = true,
|
||||
bagColumns = 10,
|
||||
bankColumns = 15,
|
||||
sortMethod = "quality", -- quality, name, type
|
||||
iconSize = addon.Constants and addon.Constants.BUTTON_SIZE or 37,
|
||||
iconFontSize = 12,
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
-- Ensure new settings exist for existing installations
|
||||
if not Guda_CharDB.settings.bagColumns then
|
||||
Guda_CharDB.settings.bagColumns = 10
|
||||
end
|
||||
if not Guda_CharDB.settings.bankColumns then
|
||||
Guda_CharDB.settings.bankColumns = 15
|
||||
end
|
||||
if not Guda_CharDB.settings.iconSize then
|
||||
Guda_CharDB.settings.iconSize = addon.Constants and addon.Constants.BUTTON_SIZE or 37
|
||||
end
|
||||
if not Guda_CharDB.settings.iconFontSize then
|
||||
Guda_CharDB.settings.iconFontSize = 12
|
||||
end
|
||||
|
||||
-- Initialize this character's data
|
||||
if not Guda_DB.characters[fullName] then
|
||||
Guda_DB.characters[fullName] = {
|
||||
name = playerName,
|
||||
realm = playerRealm,
|
||||
faction = playerFaction,
|
||||
class = UnitClass("player"),
|
||||
level = UnitLevel("player"),
|
||||
money = 0,
|
||||
bags = {},
|
||||
bank = {},
|
||||
lastUpdate = time(),
|
||||
}
|
||||
end
|
||||
|
||||
addon:Debug("Database initialized for %s", fullName)
|
||||
end
|
||||
|
||||
-- Get current player's full name
|
||||
function DB:GetPlayerFullName()
|
||||
return playerName .. "-" .. playerRealm
|
||||
end
|
||||
|
||||
-- Get current character data
|
||||
function DB:GetCurrentCharacter()
|
||||
local fullName = self:GetPlayerFullName()
|
||||
return Guda_DB.characters[fullName]
|
||||
end
|
||||
|
||||
-- Save bag data
|
||||
function DB:SaveBags(bagData)
|
||||
local char = self:GetCurrentCharacter()
|
||||
if char then
|
||||
char.bags = bagData
|
||||
char.lastUpdate = time()
|
||||
addon:Debug("Saved bag data")
|
||||
end
|
||||
end
|
||||
|
||||
-- Save bank data
|
||||
function DB:SaveBank(bankData)
|
||||
local char = self:GetCurrentCharacter()
|
||||
if char then
|
||||
char.bank = bankData
|
||||
char.lastUpdate = time()
|
||||
addon:Debug("Saved bank data")
|
||||
end
|
||||
end
|
||||
|
||||
-- Save money
|
||||
function DB:SaveMoney(copper)
|
||||
local char = self:GetCurrentCharacter()
|
||||
if char then
|
||||
char.money = copper
|
||||
char.level = UnitLevel("player")
|
||||
addon:Debug("Saved money: %d copper", copper)
|
||||
end
|
||||
end
|
||||
|
||||
-- Get all characters (optionally filter by faction)
|
||||
function DB:GetAllCharacters(sameFactionOnly)
|
||||
local chars = {}
|
||||
for fullName, data in pairs(Guda_DB.characters) do
|
||||
if not sameFactionOnly or data.faction == playerFaction then
|
||||
table.insert(chars, {
|
||||
fullName = fullName,
|
||||
name = data.name,
|
||||
realm = data.realm,
|
||||
class = data.class,
|
||||
level = data.level,
|
||||
faction = data.faction,
|
||||
money = data.money,
|
||||
lastUpdate = data.lastUpdate,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
-- Sort by name
|
||||
table.sort(chars, function(a, b)
|
||||
return a.name < b.name
|
||||
end)
|
||||
|
||||
return chars
|
||||
end
|
||||
|
||||
-- Get character's bags
|
||||
function DB:GetCharacterBags(fullName)
|
||||
local char = Guda_DB.characters[fullName]
|
||||
return char and char.bags or {}
|
||||
end
|
||||
|
||||
-- Get character's bank
|
||||
function DB:GetCharacterBank(fullName)
|
||||
local char = Guda_DB.characters[fullName]
|
||||
return char and char.bank or {}
|
||||
end
|
||||
|
||||
-- Get total money across all characters
|
||||
function DB:GetTotalMoney(sameFactionOnly)
|
||||
local total = 0
|
||||
for fullName, data in pairs(Guda_DB.characters) do
|
||||
if not sameFactionOnly or data.faction == playerFaction then
|
||||
total = total + (data.money or 0)
|
||||
end
|
||||
end
|
||||
return total
|
||||
end
|
||||
|
||||
-- Get character setting
|
||||
function DB:GetSetting(key)
|
||||
-- SavedVariables may not be initialized yet when some UI OnLoad scripts run
|
||||
if not Guda_CharDB or not Guda_CharDB.settings then
|
||||
return nil
|
||||
end
|
||||
return Guda_CharDB.settings[key]
|
||||
end
|
||||
|
||||
-- Set character setting
|
||||
function DB:SetSetting(key, value)
|
||||
-- Ensure tables exist even if called early
|
||||
if not Guda_CharDB then
|
||||
Guda_CharDB = { settings = {} }
|
||||
elseif not Guda_CharDB.settings then
|
||||
Guda_CharDB.settings = {}
|
||||
end
|
||||
Guda_CharDB.settings[key] = value
|
||||
end
|
||||
|
||||
-- Cleanup old characters (not updated in 90 days)
|
||||
function DB:CleanupOldCharacters()
|
||||
local cutoff = time() - (90 * 24 * 60 * 60) -- 90 days
|
||||
local removed = 0
|
||||
|
||||
for fullName, data in pairs(Guda_DB.characters) do
|
||||
if data.lastUpdate and data.lastUpdate < cutoff then
|
||||
Guda_DB.characters[fullName] = nil
|
||||
removed = removed + 1
|
||||
end
|
||||
end
|
||||
|
||||
if removed > 0 then
|
||||
addon:Print("Cleaned up %d old character(s)", removed)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,83 @@
|
||||
-- Guda Events Module
|
||||
-- Handles game event registration and callbacks
|
||||
|
||||
local addon = Guda
|
||||
|
||||
local Events = {}
|
||||
addon.Modules.Events = Events
|
||||
|
||||
-- Event frame
|
||||
local eventFrame = CreateFrame("Frame")
|
||||
Events.frame = eventFrame
|
||||
|
||||
-- Registered callbacks
|
||||
local callbacks = {}
|
||||
|
||||
-- Register an event with callback
|
||||
function Events:Register(event, callback, owner)
|
||||
if not callbacks[event] then
|
||||
callbacks[event] = {}
|
||||
eventFrame:RegisterEvent(event)
|
||||
addon:Debug("Registered event: %s", event)
|
||||
end
|
||||
|
||||
table.insert(callbacks[event], {
|
||||
callback = callback,
|
||||
owner = owner or "addon",
|
||||
})
|
||||
end
|
||||
|
||||
-- Unregister all callbacks for an owner
|
||||
function Events:UnregisterOwner(owner)
|
||||
for event, cbs in pairs(callbacks) do
|
||||
for i = table.getn(cbs), 1, -1 do
|
||||
if cbs[i].owner == owner then
|
||||
table.remove(cbs, i)
|
||||
end
|
||||
end
|
||||
|
||||
-- Unregister event if no callbacks left
|
||||
if table.getn(cbs) == 0 then
|
||||
eventFrame:UnregisterEvent(event)
|
||||
callbacks[event] = nil
|
||||
addon:Debug("Unregistered event: %s", event)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Event dispatcher
|
||||
eventFrame:SetScript("OnEvent", function()
|
||||
if callbacks[event] then
|
||||
for _, entry in ipairs(callbacks[event]) do
|
||||
local success, err = pcall(entry.callback, event, arg1, arg2, arg3, arg4, arg5)
|
||||
if not success then
|
||||
addon:Error("Event callback error [%s]: %s", event, err)
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- Convenience functions for common events
|
||||
function Events:OnBagUpdate(callback, owner)
|
||||
self:Register("BAG_UPDATE", callback, owner)
|
||||
end
|
||||
|
||||
function Events:OnBankOpen(callback, owner)
|
||||
self:Register("BANKFRAME_OPENED", callback, owner)
|
||||
end
|
||||
|
||||
function Events:OnBankClose(callback, owner)
|
||||
self:Register("BANKFRAME_CLOSED", callback, owner)
|
||||
end
|
||||
|
||||
function Events:OnMoneyChanged(callback, owner)
|
||||
self:Register("PLAYER_MONEY", callback, owner)
|
||||
end
|
||||
|
||||
function Events:OnPlayerLogin(callback, owner)
|
||||
self:Register("PLAYER_LOGIN", callback, owner)
|
||||
end
|
||||
|
||||
function Events:OnPlayerLogout(callback, owner)
|
||||
self:Register("PLAYER_LOGOUT", callback, owner)
|
||||
end
|
||||
@@ -0,0 +1,78 @@
|
||||
-- Guda - Turtle WoW Bag Addon
|
||||
-- Core initialization
|
||||
|
||||
-- Create addon namespace
|
||||
Guda = {}
|
||||
local addon = Guda
|
||||
|
||||
-- Version info
|
||||
addon.VERSION = "1.0.0"
|
||||
addon.BUILD = "TurtleWoW-1.12.1"
|
||||
|
||||
-- Debug flag
|
||||
addon.DEBUG = false
|
||||
|
||||
-- Constants
|
||||
addon.Constants = {
|
||||
-- Bag IDs
|
||||
BACKPACK = 0,
|
||||
BAG_1 = 1,
|
||||
BAG_2 = 2,
|
||||
BAG_3 = 3,
|
||||
BAG_4 = 4,
|
||||
BANK = -1,
|
||||
BANK_BAG_1 = 5,
|
||||
BANK_BAG_2 = 6,
|
||||
BANK_BAG_3 = 7,
|
||||
BANK_BAG_4 = 8,
|
||||
BANK_BAG_5 = 9,
|
||||
BANK_BAG_6 = 10,
|
||||
|
||||
-- All bag IDs for easy iteration
|
||||
BAGS = {0, 1, 2, 3, 4},
|
||||
BANK_BAGS = {-1, 5, 6, 7, 8, 9, 10},
|
||||
ALL_BAGS = {0, 1, 2, 3, 4, -1, 5, 6, 7, 8, 9, 10},
|
||||
|
||||
-- Item qualities (colors)
|
||||
QUALITY_COLORS = {
|
||||
[0] = {r = 0.62, g = 0.62, b = 0.62}, -- Poor (Gray)
|
||||
[1] = {r = 1.00, g = 1.00, b = 1.00}, -- Common (White)
|
||||
[2] = {r = 0.12, g = 1.00, b = 0.00}, -- Uncommon (Green)
|
||||
[3] = {r = 0.00, g = 0.44, b = 0.87}, -- Rare (Blue)
|
||||
[4] = {r = 0.64, g = 0.21, b = 0.93}, -- Epic (Purple)
|
||||
[5] = {r = 1.00, g = 0.50, b = 0.00}, -- Legendary (Orange)
|
||||
},
|
||||
|
||||
-- Save intervals
|
||||
SAVE_INTERVAL = 1800, -- 30 minutes in seconds
|
||||
|
||||
-- UI Constants
|
||||
BUTTON_SIZE = 37,
|
||||
BUTTON_SPACING = 4,
|
||||
BUTTONS_PER_ROW = 8,
|
||||
}
|
||||
|
||||
-- Initialize modules storage
|
||||
addon.Modules = {}
|
||||
|
||||
-- Print function with addon prefix
|
||||
function addon:Print(msg, a1, a2, a3, a4, a5)
|
||||
local text = string.format(msg, a1, a2, a3, a4, a5)
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cFF00FF96Guda:|r " .. text)
|
||||
end
|
||||
|
||||
-- Debug print
|
||||
function addon:Debug(msg, a1, a2, a3, a4, a5)
|
||||
if self.DEBUG then
|
||||
local text = string.format(msg, a1, a2, a3, a4, a5)
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cFFFFFF00[Debug]|r |cFF00FF96Guda:|r " .. text)
|
||||
end
|
||||
end
|
||||
|
||||
-- Error handler
|
||||
function addon:Error(msg, a1, a2, a3, a4, a5)
|
||||
local text = string.format(msg, a1, a2, a3, a4, a5)
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cFFFF0000[Error]|r |cFF00FF96Guda:|r " .. text)
|
||||
end
|
||||
|
||||
addon:Print("Loaded v%s", addon.VERSION)
|
||||
+150
@@ -0,0 +1,150 @@
|
||||
-- Guda Main Initialization
|
||||
-- Sets up all modules and auto-save system
|
||||
|
||||
local addon = Guda
|
||||
|
||||
local Main = {}
|
||||
addon.Modules.Main = Main
|
||||
|
||||
-- Auto-save timer
|
||||
local autoSaveFrame = CreateFrame("Frame")
|
||||
local timeSinceLastSave = 0
|
||||
local SAVE_INTERVAL = addon.Constants.SAVE_INTERVAL
|
||||
|
||||
-- Auto-save update
|
||||
autoSaveFrame:SetScript("OnUpdate", function()
|
||||
timeSinceLastSave = timeSinceLastSave + arg1
|
||||
|
||||
if timeSinceLastSave >= SAVE_INTERVAL then
|
||||
Main:AutoSave()
|
||||
timeSinceLastSave = 0
|
||||
end
|
||||
end)
|
||||
|
||||
-- Perform auto-save
|
||||
function Main:AutoSave()
|
||||
addon:Debug("Auto-saving data...")
|
||||
|
||||
-- Save bags
|
||||
addon.Modules.BagScanner:SaveToDatabase()
|
||||
|
||||
-- Save bank (if available)
|
||||
if addon.Modules.BankScanner:IsBankOpen() then
|
||||
addon.Modules.BankScanner:SaveToDatabase()
|
||||
end
|
||||
|
||||
-- Save money
|
||||
addon.Modules.MoneyTracker:Update()
|
||||
|
||||
addon:Debug("Auto-save complete")
|
||||
end
|
||||
|
||||
-- Initialize addon
|
||||
function Main:Initialize()
|
||||
-- Wait for PLAYER_LOGIN to ensure saved variables are loaded
|
||||
addon.Modules.Events:OnPlayerLogin(function()
|
||||
addon:Print("Initializing...")
|
||||
|
||||
-- Initialize database
|
||||
addon.Modules.DB:Initialize()
|
||||
|
||||
-- Initialize scanners
|
||||
addon.Modules.BagScanner:Initialize()
|
||||
addon.Modules.BankScanner:Initialize()
|
||||
addon.Modules.MoneyTracker:Initialize()
|
||||
|
||||
-- Initialize UI
|
||||
addon.Modules.BagFrame:Initialize()
|
||||
addon.Modules.BankFrame:Initialize()
|
||||
addon.Modules.SettingsPopup:Initialize()
|
||||
|
||||
-- Save on logout
|
||||
addon.Modules.Events:OnPlayerLogout(function()
|
||||
addon:Print("Saving data on logout...")
|
||||
Main:AutoSave()
|
||||
end, "Main")
|
||||
|
||||
-- Setup slash commands
|
||||
Main:SetupSlashCommands()
|
||||
|
||||
addon:Debug("Initialization complete")
|
||||
|
||||
-- Delay initial save to ensure everything is loaded
|
||||
local frame = CreateFrame("Frame")
|
||||
local elapsed = 0
|
||||
frame:SetScript("OnUpdate", function()
|
||||
elapsed = elapsed + arg1
|
||||
if elapsed >= 5 then
|
||||
frame:SetScript("OnUpdate", nil)
|
||||
Main:AutoSave()
|
||||
addon:Print("Ready! Type /guda to open bags")
|
||||
end
|
||||
end)
|
||||
end, "Main")
|
||||
end
|
||||
|
||||
-- Setup slash commands
|
||||
function Main:SetupSlashCommands()
|
||||
SLASH_Guda1 = "/Guda"
|
||||
SLASH_Guda2 = "/guda"
|
||||
SLASH_Guda3 = "/gn"
|
||||
|
||||
SlashCmdList["Guda"] = function(msg)
|
||||
msg = string.lower(msg or "")
|
||||
|
||||
if msg == "" or msg == "bags" then
|
||||
-- Toggle bags
|
||||
addon.Modules.BagFrame:Toggle()
|
||||
|
||||
elseif msg == "bank" then
|
||||
-- Toggle bank
|
||||
addon.Modules.BankFrame:Toggle()
|
||||
|
||||
elseif msg == "char" or msg == "chars" or msg == "characters" then
|
||||
-- Toggle character selector
|
||||
addon.Modules.CharacterSelector:Toggle()
|
||||
|
||||
elseif msg == "sort" then
|
||||
-- Sort bags
|
||||
addon.Modules.SortEngine:SortBags()
|
||||
|
||||
elseif msg == "sortbank" then
|
||||
-- Sort bank
|
||||
addon.Modules.SortEngine:SortBank()
|
||||
|
||||
elseif msg == "save" then
|
||||
-- Manual save
|
||||
Main:AutoSave()
|
||||
addon:Print("Data saved manually")
|
||||
|
||||
elseif msg == "debug" then
|
||||
-- Toggle debug
|
||||
addon.DEBUG = not addon.DEBUG
|
||||
addon:Print("Debug mode: %s", addon.DEBUG and "ON" or "OFF")
|
||||
|
||||
elseif msg == "cleanup" then
|
||||
-- Cleanup old characters
|
||||
addon.Modules.DB:CleanupOldCharacters()
|
||||
|
||||
elseif msg == "help" then
|
||||
-- Show help
|
||||
addon:Print("Commands:")
|
||||
addon:Print("/guda - Toggle bags")
|
||||
addon:Print("/guda bank - Toggle bank")
|
||||
addon:Print("/guda chars - Select character")
|
||||
addon:Print("/guda sort - Sort bags")
|
||||
addon:Print("/guda sortbank - Sort bank")
|
||||
addon:Print("/guda save - Manual save")
|
||||
addon:Print("/guda debug - Toggle debug mode")
|
||||
addon:Print("/guda cleanup - Remove old characters")
|
||||
|
||||
else
|
||||
addon:Print("Unknown command. Type /guda help for commands")
|
||||
end
|
||||
end
|
||||
|
||||
addon:Debug("Slash commands registered")
|
||||
end
|
||||
|
||||
-- Run initialization
|
||||
Main:Initialize()
|
||||
+138
@@ -0,0 +1,138 @@
|
||||
-- Guda Utility Functions
|
||||
|
||||
local addon = Guda
|
||||
|
||||
local Utils = {}
|
||||
addon.Modules.Utils = Utils
|
||||
|
||||
-- Format money (copper to gold/silver/copper string)
|
||||
function Utils:FormatMoney(copper, showZero)
|
||||
if not copper or copper == 0 then
|
||||
if showZero then
|
||||
return "0|cFFFFD700g|r 0|cFFC0C0C0s|r 0|cFFFF6600c|r"
|
||||
else
|
||||
return "0|cFFC0C0C0s|r"
|
||||
end
|
||||
end
|
||||
|
||||
local gold = math.floor(copper / 10000)
|
||||
local silver = math.floor(mod(copper, 10000) / 100)
|
||||
local bronze = mod(copper, 100)
|
||||
|
||||
local str = ""
|
||||
if gold > 0 then
|
||||
str = str .. gold .. "|cFFFFD700g|r "
|
||||
end
|
||||
if silver > 0 or gold > 0 then
|
||||
str = str .. silver .. "|cFFC0C0C0s|r "
|
||||
end
|
||||
str = str .. bronze .. "|cFFFF6600c|r"
|
||||
|
||||
return str
|
||||
end
|
||||
|
||||
-- Get item info with caching
|
||||
local itemCache = {}
|
||||
function Utils:GetItemInfo(itemLink)
|
||||
if not itemLink then return nil end
|
||||
|
||||
if itemCache[itemLink] then
|
||||
return unpack(itemCache[itemLink])
|
||||
end
|
||||
|
||||
local name, link, quality, iLevel, reqLevel, class, subclass, maxStack, equipSlot, texture = GetItemInfo(itemLink)
|
||||
|
||||
if name then
|
||||
itemCache[itemLink] = {name, link, quality, iLevel, reqLevel, class, subclass, maxStack, equipSlot, texture}
|
||||
return name, link, quality, iLevel, reqLevel, class, subclass, maxStack, equipSlot, texture
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
-- Get quality color
|
||||
function Utils:GetQualityColor(quality)
|
||||
local color = addon.Constants.QUALITY_COLORS[quality] or addon.Constants.QUALITY_COLORS[1]
|
||||
return color.r, color.g, color.b
|
||||
end
|
||||
|
||||
-- Create colored text
|
||||
function Utils:ColorText(text, r, g, b)
|
||||
local red = math.floor(r * 255)
|
||||
local green = math.floor(g * 255)
|
||||
local blue = math.floor(b * 255)
|
||||
return string.format("|cFF%02X%02X%02X%s|r", red, green, blue, text)
|
||||
end
|
||||
|
||||
-- Deep copy table
|
||||
function Utils:DeepCopy(orig)
|
||||
local orig_type = type(orig)
|
||||
local copy
|
||||
if orig_type == 'table' then
|
||||
copy = {}
|
||||
for orig_key, orig_value in next, orig, nil do
|
||||
copy[Utils:DeepCopy(orig_key)] = Utils:DeepCopy(orig_value)
|
||||
end
|
||||
setmetatable(copy, Utils:DeepCopy(getmetatable(orig)))
|
||||
else
|
||||
copy = orig
|
||||
end
|
||||
return copy
|
||||
end
|
||||
|
||||
-- Get class color
|
||||
function Utils:GetClassColor(class)
|
||||
local colors = {
|
||||
WARRIOR = {r = 0.78, g = 0.61, b = 0.43},
|
||||
PALADIN = {r = 0.96, g = 0.55, b = 0.73},
|
||||
HUNTER = {r = 0.67, g = 0.83, b = 0.45},
|
||||
ROGUE = {r = 1.00, g = 0.96, b = 0.41},
|
||||
PRIEST = {r = 1.00, g = 1.00, b = 1.00},
|
||||
SHAMAN = {r = 0.00, g = 0.44, b = 0.87},
|
||||
MAGE = {r = 0.41, g = 0.80, b = 0.94},
|
||||
WARLOCK = {r = 0.58, g = 0.51, b = 0.79},
|
||||
DRUID = {r = 1.00, g = 0.49, b = 0.04},
|
||||
}
|
||||
return colors[class] or {r = 0.5, g = 0.5, b = 0.5}
|
||||
end
|
||||
|
||||
-- Format time ago
|
||||
function Utils:FormatTimeAgo(timestamp)
|
||||
local diff = time() - timestamp
|
||||
if diff < 60 then
|
||||
return "Just now"
|
||||
elseif diff < 3600 then
|
||||
return math.floor(diff / 60) .. "m ago"
|
||||
elseif diff < 86400 then
|
||||
return math.floor(diff / 3600) .. "h ago"
|
||||
else
|
||||
return math.floor(diff / 86400) .. "d ago"
|
||||
end
|
||||
end
|
||||
|
||||
-- Get bag slot count
|
||||
function Utils:GetBagSlotCount(bagID)
|
||||
if bagID == -1 then
|
||||
-- Bank has 24 slots in vanilla
|
||||
return 24
|
||||
else
|
||||
return GetContainerNumSlots(bagID) or 0
|
||||
end
|
||||
end
|
||||
|
||||
-- Check if bag is valid
|
||||
function Utils:IsBagValid(bagID)
|
||||
if bagID == 0 or bagID == -1 then
|
||||
return true
|
||||
end
|
||||
return GetContainerNumSlots(bagID) and GetContainerNumSlots(bagID) > 0
|
||||
end
|
||||
|
||||
-- Truncate text to length
|
||||
function Utils:TruncateText(text, maxLen)
|
||||
if not text then return "" end
|
||||
if string.len(text) <= maxLen then
|
||||
return text
|
||||
end
|
||||
return string.sub(text, 1, maxLen - 3) .. "..."
|
||||
end
|
||||
Reference in New Issue
Block a user