WoWInterface SVN EasyDaily

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /trunk
    from Rev 149 to Rev 150
    Reverse comparison

Rev 149 → Rev 150

EasyDaily/inventory.lua New file
0,0 → 1,105
--[[
Desc:
Info: $Id: inventory.lua 17 2009-05-02 03:59:49Z draake $
]]
 
local _G = _G
local pairs, ipairs, type, select, tonumber, tostring = pairs, ipairs, type, select, tonumber, tostring
 
local tinsert, tremove, tsort = table.insert, table.remove, table.sort
local sformat = string.format
 
local L = LibStub("AceLocale-3.0"):GetLocale("EasyDaily_Base")
 
--------------------------------------------------------------------------------------------------
-- Content
--------------------------------------------------------------------------------------------------
 
function EasyDaily:ParseQuestLink(link)
local str, name = string.match(link, "^|c%x+|H(.+)|h%[(.*)%]")
if str then
local _, index = self:StrSplit(":", str)
return index, name
end
end
 
function EasyDaily:GetSearchStringType(search)
local searchType
if type(search) == "string" then
if string.find(search, "^|c%x+|H.+|h%[.*%]") then
searchType = "link"
else
searchType = "name"
end
elseif type(search) == "number" then
searchType = "id"
end
return searchType
end
 
function EasyDaily:ParseItemLink(itemLink)
if itemLink then
local color, itemString, name = string.match(itemLink, "^|c(%x+)|H(.+)|h%[(.*)%]")
if name then
local _, id, enchant, socket1, socket2, socket3, socket4, subid, guid, level = self:StrSplit(":", itemString)
return name, id, subId, enchant, socket1, socket2, socket3, socket4, color, guid, level
end
end
end
 
function EasyDaily:GetContainerItemInfo(bag, slot)
local itemLink = GetContainerItemLink(bag, slot)
if itemLink then
local itemName, itemId, subId, enchant, socket1, socket2, socket3, socket4, color, guid, level = self:ParseItemLink(itemLink)
itemLink = string.gsub(itemLink, ":[%-%d]+:([%-%d]+)|h", ":0:%1|h")
--~ local itemName, _, itemRarity, itemLevel, itemMinLevel, itemType, itemSubType, itemStackCount, itemEquipLoc, itemTexture = GetItemInfo(itemLink)
local _, itemCount, isLocked = GetContainerItemInfo(bag, slot)
return itemName, itemId, itemLink, itemCount
end
end
 
function EasyDaily:FindContainerItem(search) -- itemId or itemName or itemLink
local searchType = self:GetSearchStringType(search)
local r = {}
for bag = 0, 4, 1 do
for slot = 1, GetContainerNumSlots(bag), 1 do
local itemName, itemID, itemLink, itemCount = self:GetContainerItemInfo(bag, slot)
if itemName then
if ( searchType == "link" and itemLink == search ) or ( searchType == "name" and itemName == search ) or ( searchType == "id" and itemID == search ) then
table.insert(r, {bag=bag, slot=slot, name=itemName, id=itemID, link=itemLink, count=itemCount})
end
end
end
end
if #r > 0 then
return r
end
end
 
function EasyDaily:CountContainerItem(search) -- itemId or itemName or itemLink
local t = self:FindContainerItem(search)
if t then
local count = 0
for i, v in pairs(t) do
count = count + v.count
end
return count
else
return self:CountCurrency(search) or 0
end
end
 
function EasyDaily:CountCurrency(search)
local itemName = GetItemInfo(search)
if itemName then
local i = 1
while GetCurrencyListInfo(i) do
local name, isHeader, _, _, _, count = GetCurrencyListInfo(i)
if ( not isHeader ) and itemName == name then
return count
end
i = i + 1
end
end
end
 
EasyDaily/turnin.lua New file
0,0 → 1,434
--[[
Desc:
Info: $Id: turnin.lua 17 2009-05-02 03:59:49Z draake $
]]
 
local _G = _G
local pairs, ipairs, type, select, tonumber, tostring = pairs, ipairs, type, select, tonumber, tostring
 
local tinsert, tremove, tsort = table.insert, table.remove, table.sort
local sformat = string.format
 
local L = LibStub("AceLocale-3.0"):GetLocale("EasyDaily_Base")
 
--------------------------------------------------------------------------------------------------
-- Questlog Querying
--------------------------------------------------------------------------------------------------
 
function EasyDaily:GetQuestLogInfoByName(title)
for i = 1, GetNumQuestLogEntries(), 1 do
local questTitle, level, questTag, suggestedGroup, isHeader, _, isComplete, isDaily = GetQuestLogTitle(i)
if ( not isHeader ) and questTitle:find(title) then
local numObj = GetNumQuestLeaderBoards(i)
local questLink = GetQuestLink(i)
local index = self:ParseQuestLink(questLink)
return questTitle, level, questTag, suggestedGroup, isComplete, isDaily, numObj, index, questLink
end
end
end
 
function EasyDaily:GetQuestLogCompletionByName(title)
local _, _, _, _, isComplete, _, numObj = self:GetQuestLogInfoByName(title)
return ( isComplete == 1 ) or ( numObj == 0 )
end
 
--------------------------------------------------------------------------------------------------
-- Quest Advancement/Completion Eligibility
--------------------------------------------------------------------------------------------------
 
do
 
local ModOptToFunc = {
["ctrl"] = IsControlKeyDown,
["alt"] = IsAltKeyDown,
["shift"] = IsShiftKeyDown,
["none"] = function() return ( not IsModifierKeyDown() ); end,
}
 
function EasyDaily:ModKeyIsDown(x)
return x and ModOptToFunc[x] and ModOptToFunc[x]()
end
 
function EasyDaily:TypeIDActive(typeText)
return typeText and self:ModKeyIsDown( self:GetPVar("mod_" .. typeText) )
end
 
function EasyDaily:TagIDActive(tagText)
return tagText and self:GetPVar("tag_" .. tagText)
end
 
end
 
function EasyDaily:QuestEligibleForAdvancement(title)
if self:TypeIDActive("suspend") then
self.tracker.gossip[title] = false
return
end
if self:TypeIDActive("override") then
self.tracker.gossip[title] = true
return true
end
if self:GetPVar("stickyturnin") and self.tracker.gossip[title] ~= nil then
return self.tracker.gossip[title]
end
local found, _, questType, questTag, _, _, enabled = self:GetQuestInfo(title)
if ( not found ) then
return self:TypeIDActive("normal")
end
if ( not self:TypeIDActive(questType) ) or ( not self:TagIDActive(questTag) ) then
self.tracker.gossip[title] = false
return
end
self.tracker.gossip[title] = enabled
return enabled
end
 
function EasyDaily:CanAdvanceActiveQuest(title)
if self:QuestEligibleForAdvancement(title) then
return self:CanCompleteQuest(title)
end
end
 
function EasyDaily:CanAdvanceAvailableQuest(title)
if self:QuestEligibleForAdvancement(title) then
local _, _, questType = self:GetQuestInfo(title)
return ( questType ~= "repeat" ) or self:CanCompleteRepeatQuest(title)
end
end
 
function EasyDaily:CanCompleteQuest(title)
local _, _, questType = self:GetQuestInfo(title)
if questType == "repeat" then
return self:CanCompleteRepeatQuest(title)
else
return self:GetQuestLogCompletionByName(title)
end
end
 
function EasyDaily:CanCompleteRepeatQuest(title)
local _, _, questType, _, objective = self:GetQuestInfo(title)
if ( questType == "repeat" ) and objective then
local minimum
for i, v in ipairs(objective) do
local count = self:CountContainerItem(v.index)
local floor = math.floor( count / v.need )
self:Debug(v.name, count, v.need, floor)
minimum = math.min( floor, amount or math.huge )
end
return ( minimum > 0 ) and minimum
end
end
 
--------------------------------------------------------------------------------------------------
-- Quest/Gossip Frame Events/Functions
--------------------------------------------------------------------------------------------------
 
local autoText = sformat(NORMAL_QUEST_DISPLAY, L["Auto"])
 
-- Triggers on: Active, Available/Repeatable
-- Type: Parent
function EasyDaily:QUEST_GREETING()
self:Debug("QUEST_GREETING")
self:QuestGreeting()
end
 
function EasyDaily:QuestGreeting(refresh)
 
if ( not QuestFrameGreetingPanel:IsShown() ) or ( not self:IsEnabled() ) then
return
end
 
self.vars.questbutton:Hide()
 
self.tracker.gossip.parent = true
 
local r = {}
 
for n = 1, MAX_NUM_QUESTS, 1 do
local b = _G["GossipTitleButton" .. n]
if b:IsShown() then
local i = b:GetID()
local title, isTrivial, isActive
if b.type == "Available" then
title, isTrivial = GetAvailableTitle(i), IsAvailableQuestTrivial(i)
if ( not refresh ) and ( not r.title ) then
self:Debug("Checking Available Quest:", title)
if self:CanAdvanceAvailableQuest(title) then
self:Debug("Eligible Available Quest:", title)
r.title = title
r.active = index
end
end
elseif b.type == "Active" then
title, isTrivial, isActive = GetActiveTitle(i), IsActiveQuestTrivial(i), true
if ( not refresh ) and ( not r.title ) then
self:Debug("Checking Active Quest:", title)
if self:CanAdvanceActiveQuest(title) then
self:Debug("Eligible Active Quest:", title)
r.title = title
r.available = index
end
end
end
b.title = title
b.trivial = isTrivial
-- Extra Gossip text
if self:GetPVar("gossipstate") and self:QuestIsEnabled(title) then
b:SetFormattedText("%s (%s)", b:GetText(), autoText)
end
-- Icon Settings
if b.icon and self:GetPVar("gossipicons") then
self:SetGossipIcon(b.icon, title, isActive)
end
end
end
 
if r.active then
self:Debug("Selecting Active Quest:", r.title)
SelectActiveQuest(s.active)
elseif r.available then
self:Debug("Selecting Available Quest:", r.title)
SelectAvailableQuest(s.available)
end
 
end
 
-- Triggers on: Active, Available/Repeatable
-- Type: Parent
function EasyDaily:GOSSIP_SHOW()
self:Debug("GOSSIP_SHOW")
self:GossipShow()
end
 
function EasyDaily:GossipShow(refresh)
 
if ( not GossipFrame:IsShown() ) or ( not self:IsEnabled() ) then
return
end
 
self.tracker.gossip.parent = true
 
local v, j, g = self:Pack(GetGossipAvailableQuests()), self:Pack(GetGossipActiveQuests()), self:Pack(GetGossipOptions())
 
local r = {}
 
for n = 1, NUMGOSSIPBUTTONS, 1 do
local b = _G["GossipTitleButton" .. n]
if b:IsShown() then
local i = b:GetID()
local index = ( i - 1 ) * 3 + 1
local title, isTrivial, isActive
if b.type == "Available" then
title, isTrivial = v[index], v[index + 2]
if ( not refresh ) and ( not r.title ) then
self:Debug("Checking Available Quest:", title)
if self:CanAdvanceAvailableQuest(title) then
self:Debug("Eligible Available Quest:", title)
r.title = title
r.available = i
end
end
elseif b.type == "Active" then
title, isTrivial, isActive = j[index], j[index + 2], true
if ( not refresh ) and ( not r.title ) then
self:Debug("Checking Active Quest:", title)
if self:CanAdvanceActiveQuest(title) then
self:Debug("Eligible Active Quest:", title)
r.title = title
r.active = i
end
end
end
if b.type ~= "Gossip" then
b.title = title
b.trivial = isTrivial
-- Extra Gossip text
if self:GetPVar("gossipstate") and self:QuestIsEnabled(title) then
b:SetFormattedText("%s (%s)", b:GetText(), autoText)
end
-- Icon Settings
if b.icon and self:GetPVar("gossipicons") then
self:SetGossipIcon(b.icon, title, isActive)
end
end
end
end
 
if r.active then
self:Debug("Selecting Active Quest:", r.title)
SelectGossipActiveQuest(r.active)
elseif r.available then
self:Debug("Selecting Available Quest:", r.title)
SelectGossipAvailableQuest(r.available)
end
 
end
 
-- Triggers on: Available
-- Type: Child
function EasyDaily:QUEST_DETAIL(...)
self:Debug("QUEST_DETAIL")
self.vars.questbutton:Show()
local title = GetTitleText()
if self:QuestEligibleForAdvancement(title) then
if ( not self:GetPVar("skipflag") ) and QuestFlagsPVP() then
QuestFrame.dialog = StaticPopup_Show("CONFIRM_ACCEPT_PVP_QUEST")
else
AcceptQuest()
end
end
end
 
-- Triggers on: Active/Repeatable
-- Type: Child
function EasyDaily:QUEST_PROGRESS()
self:Debug("QUEST_PROGRESS")
self.vars.questbutton:Show()
local title = GetTitleText()
local isRepeat = ( not self:GetQuestLogInfoByName(title) )
if isRepeat then
-- Quest is repeatable
self:RegisterRepeatableQuest()
end
if self:QuestEligibleForAdvancement(title) then
print(isRepeat, self.tracker.gossip.parent)
if IsQuestCompletable() then
CompleteQuest()
elseif isRepeat and self.tracker.gossip.parent then
DeclineQuest()
end
end
end
 
-- Triggers on: Active/Repeatable
-- Type: Child
function EasyDaily:QUEST_COMPLETE()
self:Debug("QUEST_COMPLETE")
self.vars.questbutton:Show()
local title = GetTitleText()
if self:QuestEligibleForAdvancement(title) then
local money = GetQuestMoneyToGet()
if money and ( money > 0 ) and ( not self:GetPVar("skipmoney") ) then
QuestFrame.dialog = StaticPopup_Show("CONFIRM_COMPLETE_EXPENSIVE_QUEST")
if ( QuestFrame.dialog ) then
MoneyFrame_Update(QuestFrame.dialog:GetName().."MoneyFrame", money)
end
else
local choiceNum = GetNumQuestChoices()
if choiceNum > 0 then
if self:GetPVar("multiple") and self.db.profile.reward[title] then
GetQuestReward(self.db.profile.reward[title])
end
elseif self:GetPVar("single") then
GetQuestReward(0)
end
end
end
end
 
--------------------------------------------------------------------------------------------------
-- Gossip/Quest Frame Functions
--------------------------------------------------------------------------------------------------
 
function EasyDaily:GossipOrQuestClosed()
if ( not QuestFrame:IsShown() ) and ( not GossipFrame:IsShown() ) then
self:ClearTracker("gossip")
end
end
 
function EasyDaily:GetQuestReward(option)
local title = GetTitleText()
if ( GetNumQuestChoices() > 0 ) and self:GetPVar("multiple") and self:QuestIsEnabled(title) then
self:Debug("Storing reward option", title, option)
self.db.profile.reward[title] = option
end
self:QuestCompleteToday(title)
end
 
function EasyDaily:SetGossipIcon(icon, title, isActive)
 
local found, _, questType, questTag, _, _, questEnabled = self:GetQuestInfo(title)
 
local iconColor
if ( isActive or questType == "repeat" ) and ( not self:CanCompleteQuest(title) ) then
iconColor = "Grey"
elseif ( questType == "daily" ) or ( questType == "repeat" ) then
iconColor = "Daily"
else
iconColor = "Normal"
end
 
local iconState
if ( questType == "daily" ) or ( questType == "repeat" ) then
iconState = questEnabled and "Enable" or "Disable"
else
iconState = ""
end
 
local iconType
if isActive or ( questType == "repeat" ) then
iconType = "Active"
else
iconType = "Available"
end
 
self:Debug(title, isActive, questType, iconColor, iconState, iconType)
 
icon:SetTexture() -- Clear current icon
icon:SetTexture("Interface\\Addons\\EasyDaily\\Textures\\Gossip-Icons\\" .. iconColor .. iconState .. iconType)
 
if ( not icon:GetTexture() ) then
icon:SetTexture("Interface\\QuestFrame\\UI-Quest-BulletPoint")
end
 
end
 
function EasyDaily:RefreshGossipOrQuestFrame(skip)
if QuestFrameGreetingPanel:IsShown() then
self:ClearTracker("gossip")
QuestFrameGreetingPanel:Hide()
QuestFrameGreetingPanel:Show()
self:QuestGreeting(true)
elseif GossipFrame:IsShown() then
self:ClearTracker("gossip")
GossipFrameUpdate()
self:GossipShow(true)
end
end
 
function EasyDaily:GossipTitleButton_OnClick(frame, button)
if button == "RightButton" then
if ( frame.type == "Available" ) or ( frame.type == "Active" ) then
self:ToggleQuestState(frame.title)
end
else
self.hooks["GossipTitleButton_OnClick"](frame, button)
end
end
 
function EasyDaily:QuestTitleButton_OnClick(frame)
if arg1 == "RightButton" then
self:ToggleQuestState(frame.title)
else
self.hooks["QuestTitleButton_OnClick"](frame)
end
end
 
function EasyDaily:QuestCheckButtonOnShow(b)
local found, _, _, _, _, _, enabled = self:GetQuestInfo( GetTitleText() )
if found then
b:Enable()
b:SetChecked(enabled)
b.text:SetTextColor(1, 0.8, 0, 1)
else
b:SetChecked(nil)
b:Disable()
b.text:SetTextColor(0.5, 0.5, 0.5, 1)
end
end
 
function EasyDaily:QuestCheckButtonOnClick(button)
local newState = self:ToggleQuestState(GetTitleText())
button:SetChecked(newState)
end
 
EasyDaily/locales.xml New file
0,0 → 1,12
<Ui xmlns="http://www.blizzard.com/wow/ui/">
<!-- Generated by Babelfish script -->
<Script file="locales\deDE.lua"/>
<Script file="locales\frFR.lua"/>
<Script file="locales\esES.lua"/>
<Script file="locales\esMX.lua"/>
<Script file="locales\zhCN.lua"/>
<Script file="locales\zhTW.lua"/>
<Script file="locales\koKR.lua"/>
<Script file="locales\ruRU.lua"/>
<Script file="locales\enUS.lua"/>
</Ui>
\ No newline at end of file
EasyDaily/locales/koKR.lua New file
0,0 → 1,16
--[[ Generated by Babelfish script.
 
- Please use the Localization App on WoWAce or Curse to update this localization.
- http://www.wowace.com/projects/easydaily/localization/
- http://wow.curseforge.com/projects/easydaily/localization/
 
]] local L = LibStub("AceLocale-3.0"):NewLocale("EasyDaily_Base", "koKR"); if not L then return end
 
-- L["{Click} to open the options menu"] = ""
-- L["Debug"] = ""
-- L["Enabled"] = ""
-- L["Enable/Disable debug mode."] = ""
-- L["Enable/Disable the addon."] = ""
-- L["Minimap Icon"] = ""
-- L["Show an icon on the Minimap that will open the options menu."] = ""
 
EasyDaily/locales/enUS.lua New file
0,0 → 1,65
--[[ Generated by Babelfish script.
 
- This is the base locale. None of these values should be changed.
 
]] local L = LibStub("AceLocale-3.0"):NewLocale("EasyDaily_Base", "enUS", true); if not L then return end
 
L["Alt"] = true
L["Auto"] = true
L["Auto Turn-in"] = true
L["Auto Turn-in Text"] = true
L["Auto-Select rewards for quests with more than one reward."] = true
L["Auto-Select rewards for quests with one or less reward."] = true
L["Available"] = true
L["Battleground"] = true
L["Complete"] = true
L["Completed [%s] of [%s] dailies"] = true
L["Ctrl"] = true
L["Daily"] = true
L["Daily Quest Discovered"] = true
L["Debug"] = true
L["Disable"] = true
L["Disable Gold Pop-up"] = true
L["Disable PvP Pop-up"] = true
L["Disables the confirmation pop-up that appears when accepting a daily quest that flags you for pvp."] = true
L["Disables the confirmation pop-up that appears when completing a daily quest that requires gold."] = true
L["Displays a quests auto turn-in status in text."] = true
L["Enable/Disable debug mode."] = true
L["Enable/Disable the addon."] = true
L["Enabled"] = true
L["Enables Auto Turn-in for %s tagged quests."] = true
L["Force"] = true
L["General"] = true
L["Gossip Window"] = true
L["Heroic Dungeon"] = true
L["Minimap Icon"] = true
L["Multiple Rewards"] = true
L["None"] = true
L["Normal"] = true
L["Normal Dungeon"] = true
L["Note: The modifier 'None' refers to when no modifier is being held. Setting the modifier to 'Disable' disables the option."] = true
L["Quest Pop-ups"] = true
L["Quest Rewards"] = true
L["Quest Tags"] = true
L["Quests"] = true
L["Quick Info"] = true
L["Repeatable"] = true
L["Repeatable Quest Discovered"] = true
L["Replace Gossip Icons"] = true
L["Replaces the default gossip icons with color coded versions."] = true
L["Selection Modifiers"] = true
L["Shift"] = true
L["Show an icon on the Minimap."] = true
L["Single Reward"] = true
L["Special"] = true
L["Sticky Turn-in"] = true
L["Suspend"] = true
L["The [new day] begins in %s"] = true
L["Toggle this quest's state."] = true
L["Toggles 'Auto Turn-in' for this quest."] = true
L["Turn-in sequences will run to completion once they've been started regardless of its modifier's status."] = true
L["Use this modifier to Auto Turn-in %s quests."] = true
L["Use this modifier to forcibly Auto Turn-in any quest. Overrides all settings."] = true
L["Use this modifier to suspend the Auto Turn-in process."] = true
L["[Left-Click] to toggle the quest window"] = true
L["[Right-Click] to toggle the options menu"] = true
EasyDaily/locales/esMX.lua New file
0,0 → 1,16
--[[ Generated by Babelfish script.
 
- Please use the Localization App on WoWAce or Curse to update this localization.
- http://www.wowace.com/projects/easydaily/localization/
- http://wow.curseforge.com/projects/easydaily/localization/
 
]] local L = LibStub("AceLocale-3.0"):NewLocale("EasyDaily_Base", "esMX"); if not L then return end
 
-- L["{Click} to open the options menu"] = ""
-- L["Debug"] = ""
-- L["Enabled"] = ""
-- L["Enable/Disable debug mode."] = ""
-- L["Enable/Disable the addon."] = ""
-- L["Minimap Icon"] = ""
-- L["Show an icon on the Minimap that will open the options menu."] = ""
 
EasyDaily/locales/zhTW.lua New file
0,0 → 1,16
--[[ Generated by Babelfish script.
 
- Please use the Localization App on WoWAce or Curse to update this localization.
- http://www.wowace.com/projects/easydaily/localization/
- http://wow.curseforge.com/projects/easydaily/localization/
 
]] local L = LibStub("AceLocale-3.0"):NewLocale("EasyDaily_Base", "zhTW"); if not L then return end
 
-- L["{Click} to open the options menu"] = ""
-- L["Debug"] = ""
-- L["Enabled"] = ""
-- L["Enable/Disable debug mode."] = ""
-- L["Enable/Disable the addon."] = ""
-- L["Minimap Icon"] = ""
-- L["Show an icon on the Minimap that will open the options menu."] = ""
 
EasyDaily/locales/ruRU.lua New file
0,0 → 1,16
--[[ Generated by Babelfish script.
 
- Please use the Localization App on WoWAce or Curse to update this localization.
- http://www.wowace.com/projects/easydaily/localization/
- http://wow.curseforge.com/projects/easydaily/localization/
 
]] local L = LibStub("AceLocale-3.0"):NewLocale("EasyDaily_Base", "ruRU"); if not L then return end
 
-- L["{Click} to open the options menu"] = ""
L["Debug"] = "Диагностика"
L["Enabled"] = "Включено"
L["Enable/Disable debug mode."] = "Включить/отключить режим диагностики."
L["Enable/Disable the addon."] = "Включить/Отключить аддон"
L["Minimap Icon"] = "Иконка у миникарты"
L["Show an icon on the Minimap that will open the options menu."] = "Отображать у миникарты иконку, открывающую меню опций."
 
EasyDaily/locales/esES.lua New file
0,0 → 1,16
--[[ Generated by Babelfish script.
 
- Please use the Localization App on WoWAce or Curse to update this localization.
- http://www.wowace.com/projects/easydaily/localization/
- http://wow.curseforge.com/projects/easydaily/localization/
 
]] local L = LibStub("AceLocale-3.0"):NewLocale("EasyDaily_Base", "esES"); if not L then return end
 
-- L["{Click} to open the options menu"] = ""
-- L["Debug"] = ""
-- L["Enabled"] = ""
-- L["Enable/Disable debug mode."] = ""
-- L["Enable/Disable the addon."] = ""
-- L["Minimap Icon"] = ""
-- L["Show an icon on the Minimap that will open the options menu."] = ""
 
EasyDaily/locales/frFR.lua New file
0,0 → 1,16
--[[ Generated by Babelfish script.
 
- Please use the Localization App on WoWAce or Curse to update this localization.
- http://www.wowace.com/projects/easydaily/localization/
- http://wow.curseforge.com/projects/easydaily/localization/
 
]] local L = LibStub("AceLocale-3.0"):NewLocale("EasyDaily_Base", "frFR"); if not L then return end
 
L["{Click} to open the options menu"] = "{Clic} pour ouvrir le menu des options"
L["Debug"] = "Débogage"
L["Enabled"] = "Activé"
L["Enable/Disable debug mode."] = "Activer / désactiver le mode de débogage."
L["Enable/Disable the addon."] = "Activer / désactiver cet add-on."
L["Minimap Icon"] = "Icône de la minicarte"
L["Show an icon on the Minimap that will open the options menu."] = "Affiche une icône sur la minicarte pour accéder au menu des options."
 
EasyDaily/locales/deDE.lua New file
0,0 → 1,16
--[[ Generated by Babelfish script.
 
- Please use the Localization App on WoWAce or Curse to update this localization.
- http://www.wowace.com/projects/easydaily/localization/
- http://wow.curseforge.com/projects/easydaily/localization/
 
]] local L = LibStub("AceLocale-3.0"):NewLocale("EasyDaily_Base", "deDE"); if not L then return end
 
-- L["{Click} to open the options menu"] = ""
-- L["Debug"] = ""
-- L["Enabled"] = ""
-- L["Enable/Disable debug mode."] = ""
-- L["Enable/Disable the addon."] = ""
-- L["Minimap Icon"] = ""
-- L["Show an icon on the Minimap that will open the options menu."] = ""
 
EasyDaily/locales/zhCN.lua New file
0,0 → 1,16
--[[ Generated by Babelfish script.
 
- Please use the Localization App on WoWAce or Curse to update this localization.
- http://www.wowace.com/projects/easydaily/localization/
- http://wow.curseforge.com/projects/easydaily/localization/
 
]] local L = LibStub("AceLocale-3.0"):NewLocale("EasyDaily_Base", "zhCN"); if not L then return end
 
-- L["{Click} to open the options menu"] = ""
-- L["Debug"] = ""
-- L["Enabled"] = ""
-- L["Enable/Disable debug mode."] = ""
-- L["Enable/Disable the addon."] = ""
-- L["Minimap Icon"] = ""
-- L["Show an icon on the Minimap that will open the options menu."] = ""
 
EasyDaily/tracking.lua New file
0,0 → 1,236
--[[
Desc:
Info: $Id: tracking.lua 17 2009-05-02 03:59:49Z draake $
]]
 
local _G = _G
local pairs, ipairs, type, select, tonumber, tostring = pairs, ipairs, type, select, tonumber, tostring
 
local tinsert, tremove, tsort = table.insert, table.remove, table.sort
local sformat = string.format
 
local L = LibStub("AceLocale-3.0"):GetLocale("EasyDaily_Base")
 
--------------------------------------------------------------------------------------------------
-- Tracker
--------------------------------------------------------------------------------------------------
 
function EasyDaily:ClearTracker(name)
if self.tracker[name] then
--~ self:Debug("CleanTracker: ", name)
self:CleanTable(EasyDaily.tracker[name])
end
end
 
--------------------------------------------------------------------------------------------------
-- Logic Checks
--------------------------------------------------------------------------------------------------
 
function EasyDaily:UnitIsClose(unit)
return CheckInteractDistance(unit, 2) -- 11.11 yards
--~ return CheckInteractDistance(unit, 1) and CheckInteractDistance(unit, 2) and CheckInteractDistance(unit, 3) and CheckInteractDistance(unit, 4)
end
 
function EasyDaily:IsValidName(name)
return name and name ~= "" and name ~= UNKNOWNOBJECT and name ~= UKNOWNBEING
end
 
--------------------------------------------------------------------------------------------------
-- Units
--------------------------------------------------------------------------------------------------
 
function EasyDaily:UnitName(unit)
local name, guid, id, kind = UnitName(unit), UnitGUID(unit) or 0, 0, ""
if ( not self:IsValidName(name) ) then
return nil, 0, "", nil
end
local tid = bit.band(tonumber(string.sub(guid, -16, -14), 16), 0x00F)
if tid == 1 then
kind, id = "object", tonumber(string.sub(guid, -12, -7), 16)
elseif tid == 3 then
kind, id = "npc", tonumber(string.sub(guid, -12, -7), 16)
end
return name, id, kind
end
 
function EasyDaily:GetLocation()
local zone = GetRealZoneText() or ""
local x, y = GetPlayerMapPosition("player")
local dl = GetCurrentMapDungeonLevel() or 0
if ( not x ) or ( not y ) then
x, y = 0, 0
end
return zone, math.floor(x * 1000 + 0.5), math.floor(y * 1000 + 0.5), dl
end
 
--------------------------------------------------------------------------------------------------
-- Gossip/Quest Frame Registration
--------------------------------------------------------------------------------------------------
 
function EasyDaily:RegisterRepeatableQuest()
 
local questTitle = GetTitleText()
local unitName, nID, kind = self:UnitName("npc")
 
if ( not unitName ) or ( not nID ) or ( not kind ) or ( not questTitle ) then
return
end
 
local handler, isNew = self:GetHandler("quest", questTitle, true)
 
if isNew then
self:Display(L["Repeatable Quest Discovered"], questTitle)
end
 
self:Debug(handler._data)
 
local zone = self:GetLocation()
 
handler:SetVal("type", "repeat")
handler:SetVal("tag", "normal")
handler:SetVal("header", zone)
 
--~ for oID = 1, GetNumQuestItems(), 1 do
--~ local itemName, itemID = self:ParseItemLink( GetQuestItemLink("required", oID) )
--~ handler:SetData("obj", oID, "name", itemName)
--~ handler:SetData("obj", oID, "index", itemID)
--~ handler:SetData("obj", oID, "type", "item")
--~ handler:SetData("obj", oID, "need", self:SelectOne(3, GetQuestItemInfo("required", oID)))
--~ end
 
end
 
--------------------------------------------------------------------------------------------------
-- Quest Log
--------------------------------------------------------------------------------------------------
 
function EasyDaily:GetLeaderBoardDetails(boardIndex, questIndex)
local objText, objType, isDone = GetQuestLogLeaderBoard(boardIndex, questIndex)
-- "item", "object", "monster", "reputation", "event", "player"
local objName, objCurCount, objNeedCount = string.match(objText, "(.*):%s*([%d]+)%s*/%s*([%d]+)")
if objType == "monster" or objType == "player" then
objType = "kill"
elseif objType == "item" or objType == "object" then
objType = "collect"
end
return objType, objName, tonumber(objCurCount), tonumber(objNeedCount), objText, isDone
end
 
local TagTextToOpt = {
[GROUP] = "group",
[LFG_TYPE_DUNGEON] = "dungeon",
[RAID] = "raid",
[LFG_TYPE_HEROIC_DUNGEON] = "heroic",
[PVP] = "pvp",
[ELITE] = "elite",
}
 
function EasyDaily:QUEST_LOG_UPDATE()
 
self:Debug("QUEST_LOG_UPDATE")
 
self:UnregisterEvent("QUEST_LOG_UPDATE")
 
local numEntries, numQuests = GetNumQuestLogEntries()
 
local collapseHeaders = {}
local tempLog = {}
 
do
local tempHeader
local i = 1
while GetQuestLogTitle(i) do
local logName, _, questTag, _, isHeader, isCollapsed, isComplete, isDaily = GetQuestLogTitle(i)
if isHeader then
tempHeader = logName
if isCollapsed then
ExpandQuestHeader(i)
tinsert(collapseHeaders, i)
end
else
local index = self:ParseQuestLink( GetQuestLink(i) )
tempLog[index] = {}
tempLog[index].name = logName
tempLog[index].tag = ( questTag and TagTextToOpt[questTag] ) or "normal"
tempLog[index].header = tempHeader
tempLog[index].daily = isDaily
tempLog[index].complete = isComplete
tempLog[index].obj = {}
local numObj = GetNumQuestLeaderBoards(i)
for k = 1, numObj, 1 do
local objType, objName, objCurCount, objNeedCount, objText = self:GetLeaderBoardDetails(k, i)
tempLog[index].obj[k] = { type=objType, name=objName, text=objText, current=objCurCount, need=objNeedCount }
end
end
i = i + 1
end
end
 
for index, v in pairs(tempLog) do
 
if v.daily then
 
local handler, isNew = self:GetHandler("quest", index, true)
 
if isNew then
self:Display(L["Daily Quest Discovered"], v.name)
end
 
handler:SetVal("name", v.name)
handler:SetVal("type", v.daily and "daily" or "normal")
handler:SetVal("tag", v.tag)
handler:SetVal("header", v.header)
 
--~ for j, k in pairs(v.obj) do
--~ handler:SetData("obj", j, "name", k.name or k.text)
--~ handler:SetData("obj", j, "type", k.type)
--~ handler:SetData("obj", j, "need", k.need)
--~ end
end
 
end
 
tsort(collapseHeaders, function(a, b) return a > b; end)
 
for i, v in pairs(collapseHeaders) do
CollapseQuestHeader(v)
end
 
self:RegisterEvent("QUEST_LOG_UPDATE")
 
end
 
--------------------------------------------------------------------------------------------------
-- Daily Reset/Data
--------------------------------------------------------------------------------------------------
 
function EasyDaily:GetDailyResetDate()
local reset = GetQuestResetTime()
if reset and reset > 0 then
return reset + self:GetTime(), reset
end
end
 
function EasyDaily:GetDailyStats()
local current = GetDailyQuestsCompleted()
local max = GetMaxDailyQuests()
return current, max
end
 
function EasyDaily:RecordQuestComplete(name)
local handler = self:GetHandler("quest", name)
if handler and handler.__data.global.type == "daily" then
local resetDate, timeLeft = self:GetDailyResetDate()
handler:SetVal("reset", resetDate)
handler:SetVal("time", self:GetTime())
handler:SetVal("done", handler:SetVal("done") + 1)
end
end
 
function EasyDaily:QuestCompleteToday(name)
local reset, time, done = self:GetQuestResetInfo(name)
if reset then
return reset and ( reset > self:GetTime() )
end
end
 
EasyDaily/Changelog-EasyDaily-v2.0-beta.txt New file
0,0 → 1,77
------------------------------------------------------------------------
r19 | draake | 2009-05-02 04:13:01 +0000 (Sat, 02 May 2009) | 1 line
Changed paths:
A /tags/v2.0-beta (from /trunk:18)
 
Tagging as v2.0-beta
------------------------------------------------------------------------
r18 | draake | 2009-05-02 04:10:33 +0000 (Sat, 02 May 2009) | 1 line
Changed paths:
M /trunk/core.lua
 
Version text fix
------------------------------------------------------------------------
r17 | draake | 2009-05-02 03:59:49 +0000 (Sat, 02 May 2009) | 1 line
Changed paths:
M /trunk/.pkgmeta
M /trunk/EasyDaily.toc
M /trunk/core.lua
A /trunk/database.lua
M /trunk/inventory.lua
M /trunk/locales/enUS.lua
M /trunk/options.lua
M /trunk/scripts/Babelfish.lua
M /trunk/scripts/Strings.lua
A /trunk/textures
A /trunk/textures/Gossip-Icons
A /trunk/textures/Gossip-Icons/DailyActive.blp
A /trunk/textures/Gossip-Icons/DailyAvailable.blp
A /trunk/textures/Gossip-Icons/DailyDisableActive.blp
A /trunk/textures/Gossip-Icons/DailyDisableAvailable.blp
A /trunk/textures/Gossip-Icons/DailyEnableActive.blp
A /trunk/textures/Gossip-Icons/DailyEnableAvailable.blp
A /trunk/textures/Gossip-Icons/GreyActive.blp
A /trunk/textures/Gossip-Icons/GreyDisableActive.blp
A /trunk/textures/Gossip-Icons/GreyEnableActive.blp
A /trunk/textures/Gossip-Icons/NormalActive.blp
A /trunk/textures/Gossip-Icons/NormalAvailable.blp
A /trunk/textures/Gossip-Icons/NormalDisableActive.blp
A /trunk/textures/Gossip-Icons/NormalDisableAvailable.blp
A /trunk/textures/Gossip-Icons/NormalEnableActive.blp
A /trunk/textures/Gossip-Icons/NormalEnableAvailable.blp
M /trunk/tracking.lua
M /trunk/turnin.lua
D /trunk/util.lua
A /trunk/utility.lua (from /trunk/util.lua:16)
 
beta commit
------------------------------------------------------------------------
r16 | draake | 2009-04-03 00:57:19 +0000 (Fri, 03 Apr 2009) | 5 lines
Changed paths:
M /trunk/.pkgmeta
M /trunk/EasyDaily.toc
M /trunk/core.lua
D /trunk/guid.lua
M /trunk/options.lua
M /trunk/tracking.lua
M /trunk/turnin.lua
M /trunk/util.lua
 
N: Implemented data registration system.
N: Records relevant NPC locations.
N: Records repeatable quest item requirements.
N: Records daily quest data (id, name, objectives, etc).
C: Revised the way the addon version is displayed.
------------------------------------------------------------------------
r15 | draake | 2009-03-30 02:18:14 +0000 (Mon, 30 Mar 2009) | 3 lines
Changed paths:
M /trunk
M /trunk/core.lua
M /trunk/inventory.lua
M /trunk/turnin.lua
M /trunk/util.lua
 
N: Quest requirements for repeatable quests are now learned.
N: Added table utility functions.
C: Experimenting with repo variables.
------------------------------------------------------------------------
EasyDaily/textures/Gossip-Icons/DailyEnableActive.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
EasyDaily/textures/Gossip-Icons/GreyDisableActive.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
EasyDaily/textures/Gossip-Icons/DailyDisableAvailable.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
EasyDaily/textures/Gossip-Icons/NormalDisableActive.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
EasyDaily/textures/Gossip-Icons/GreyEnableActive.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
EasyDaily/textures/Gossip-Icons/NormalAvailable.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
EasyDaily/textures/Gossip-Icons/DailyEnableAvailable.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
EasyDaily/textures/Gossip-Icons/NormalEnableActive.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
EasyDaily/textures/Gossip-Icons/NormalDisableAvailable.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
EasyDaily/textures/Gossip-Icons/DailyActive.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
EasyDaily/textures/Gossip-Icons/NormalEnableAvailable.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
EasyDaily/textures/Gossip-Icons/DailyDisableActive.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
EasyDaily/textures/Gossip-Icons/GreyActive.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
EasyDaily/textures/Gossip-Icons/DailyAvailable.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
EasyDaily/textures/Gossip-Icons/NormalActive.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
EasyDaily/utility.lua New file
0,0 → 1,246
--[[
Desc:
Info: $Id: utility.lua 17 2009-05-02 03:59:49Z draake $
]]
 
local _G = _G
local pairs, ipairs, type, select, tonumber, tostring = pairs, ipairs, type, select, tonumber, tostring
 
local tinsert, tremove, tsort = table.insert, table.remove, table.sort
local sformat = string.format
 
local L = LibStub("AceLocale-3.0"):GetLocale("EasyDaily_Base")
 
--------------------------------------------------------------------------------------------------
-- Colors
--------------------------------------------------------------------------------------------------
 
-- string, red, green, blue
function EasyDaily:Colorize(s, r, g, b)
return string.format("|cff%02x%02x%02x%s|r", r*255, g*255, b*255, s)
end
 
--[[
-- string, capture1, red1, green1, blue1[, capture2][, red2, green2, blue2][, ...]
function EasyDaily:ColorizePattern(s, ...)
local offset = 0
for j = 1, select("#", ...), 4 do
local i = j + offset
local c, r, g, b = select(i, ...), select(i + 1, ...), select(i + 2, ...), select(i + 3, ...)
local m
if ( not b ) or ( type(b) ~= "number" ) then
c, r, g, b = select(i - 4, ...), c, r, g
offset = offset + 1
else
m = 1
end
s = string.gsub(s, c, function(w)
return self:Colorize(w, r, g, b)
end, m)
end
return s
end
]]
 
-- string, capture, red1, green1, blue1[, red2, green2, blue2][, ...]
function EasyDaily:ColorizePattern(s, c, ...)
local n = math.ceil( select("#", ...) / 3 )
local m
for i = 1, n * 3, 3 do
local r, g, b = select(i, ...), select(i + 1, ...), select(i + 2, ...)
if ( i + 2 ) / 3 < n then m = 1 else m = nil end
s = string.gsub(s, c, function(w)
return self:Colorize(w, r, g, b)
end, m)
end
return s
end
 
function EasyDaily:StripColors(s)
local r = string.gsub(s, "|c%x+(.-)|r", "%1")
return r
end
 
function EasyDaily:Pack(...)
return { n = select("#", ...), ... }
end
 
function EasyDaily:Unpack(t)
return unpack(t, 1, t.n or #t)
end
 
--------------------------------------------------------------------------------------------------
-- Logic
--------------------------------------------------------------------------------------------------
 
function EasyDaily:DeltaEqual(v1, v2, d)
return math.abs(v1 - v2) <= d
end
 
function EasyDaily:ValidInterval(v1, v2, d)
return math.abs(v1 - v2) <= (self:SelectOne(3, GetNetStats()) + d)
end
 
--------------------------------------------------------------------------------------------------
-- Tables
--------------------------------------------------------------------------------------------------
 
function EasyDaily:TableLength(t)
local c = 0
for _ in pairs(t) do
c = c + 1
end
return c
end
 
function EasyDaily:CopyTable(t)
local r = {}
for i, v in pairs(t) do
if type(v) == "table" then
r[i] = self:CopyTable(v)
else
r[i] = v
end
end
return r
end
 
-- table t with table k values merged into it
function EasyDaily:MergeTable(t, k)
for i, v in pairs(k) do
if type(v) == "table" and type(t[i]) == "table" then
t[i] = self:MergeTable(t[i], v)
else
t[i] = v
end
end
end
 
function EasyDaily:InsertUnique(t, m)
if self:TableCount(t, m) == 0 then
table.insert(t, m)
end
end
 
function EasyDaily:CleanTable(t)
for i, v in pairs(t) do
t[i] = nil
end
return t
end
 
function EasyDaily:TableCount(t, m)
local c = 0
for i, v in pairs(t) do
if ( type(m) == "table" and type(v) == "table" and self:TableIsCopy(m, v) ) or m == v then
c = c + 1
end
end
return c
end
 
function EasyDaily:RemoveTableDuplicates(t)
local r = {}
for i, v in pairs(t) do
if self:TableCount(r, v) == 0 then
if type == "table" then
r[i] = self:RemoveTableDuplicates(v)
else
r[i] = v
end
end
end
return r
end
 
function EasyDaily:TableIsCopy(t, k)
if self:TableLength(t) == self:TableLength(k) then
for i, v in pairs(t) do
if ( not k[i] ) then
return false
elseif type(v) == "table" then
if type(k[i]) ~= "table" or ( not self:IsCopy(v, k[i]) ) then
return false
end
elseif v ~= k[i] then
return false
end
end
return true
end
end
 
--------------------------------------------------------------------------------------------------
-- System
--------------------------------------------------------------------------------------------------
 
do
local timeOffset
function EasyDaily:GetTime()
if ( not TimeOffset ) then
local mo, d, y = select(2, CalendarGetDate())
local h, mi = GetGameTime()
timeOffset = math.floor( time({ year = y, month = mo, day = d, hour = h, min = mi }) - GetTime() )
end
return timeOffset + math.floor( GetTime() )
end
end
 
function EasyDaily:SelectOne(n, ...)
if n > 0 then
local r = select(n, ...); return r
end
end
 
function EasyDaily:StrSplit(p, s)
local r = {}
for m in string.gmatch(s, string.format("([^%s]+)", p)) do
table.insert(r, tonumber(m) or m)
end
return unpack(r)
end
 
function EasyDaily:GetNumArgs(...)
return select("#", ...)
end
 
--------------------------------------------------------------------------------------------------
-- Debugging
--------------------------------------------------------------------------------------------------
 
function EasyDaily:Debug(...)
if self.db.profile.debug then
if AceLibrary and AceLibrary:HasInstance("AceConsole-2.0") then
AceLibrary("AceConsole-2.0").PrintLiteral(self, ...)
else
self:ChatPrint("EasyDaily-Debug", 1, .5, .5, nil, nil, nil, ...)
end
end
end
 
function EasyDaily:Print(...)
self:ChatPrint(nil, 1, 1, .5, nil, nil, nil, ...)
end
 
function EasyDaily:Error(...)
self:ChatPrint("EasyDaily-Error", 1, .5, .5, nil, nil, nil, ...)
end
 
function EasyDaily:Display(msg, ...)
self:ChatPrint(msg, 1, 1, .5, nil, nil, nil, ...)
end
 
function EasyDaily:ChatPrint(info, r1, g1, b1, r2, g2, b2, ...)
 
local msg = ""
for i = 1, select("#", ...), 1 do
msg = msg .. tostring( select( i, ...) ) .. " "
end
 
local text = string.format("|cff%02x%02x%02x%s|r|cff%02x%02x%02x: %s|r",
(r1 or 1) * 255, (g1 or 1) * 255, (b1 or 1) * 255, info or "EasyDaily",
(r2 or 1) * 255, (g2 or 1) * 255, (b2 or 1) * 255, msg)
 
DEFAULT_CHAT_FRAME:AddMessage(text)
 
end
EasyDaily/database.lua New file
0,0 → 1,392
--[[
Desc:
Info: $Id: database.lua 17 2009-05-02 03:59:49Z draake $
]]
 
local _G = _G
local pairs, ipairs, type, select, tonumber, tostring = pairs, ipairs, type, select, tonumber, tostring
 
local tinsert, tremove, tsort = table.insert, table.remove, table.sort
local sformat = string.format
 
local EasyDaily = EasyDaily
 
local L = LibStub("AceLocale-3.0"):GetLocale("EasyDaily_Base")
 
--------------------------------------------------------------------------------------------------
-- DB Querying
--------------------------------------------------------------------------------------------------
 
-- name, index, questType, questTag, objective, side, enable = EasyDaily:GetQuestHandlerInfo(name)
function EasyDaily:GetQuestHandlerInfo(handler)
if handler and handler._type == "quest" then
local g = handler._data.global
return g.name, g.index, g.type, g.tag, g.obj, g.side, g.enable, g.header
end
end
 
function EasyDaily:GetQuestResetInfo(index)
local handler = self:GetHandler("quest", index)
if handler then
local c = handler._data.char
return c.reset, c.time, c.done
end
end
 
function EasyDaily:GetQuestInfo(index)
return self:GetQuestHandlerInfo( self:GetHandler("quest", index) )
end
 
function EasyDaily:QuestIsEnabled(title)
local _, _, _, _, _, _, enable = self:GetQuestInfo(title)
return enable
end
 
function EasyDaily:ToggleQuestState(title)
local t = self:GetQuestTableByName(title)
if t then
self:Debug("ToggleQuestState", title)
t.disabled = not t.disabled
self:RefreshGossipOrQuestFrame()
return t.disabled
end
end
 
--------------------------------------------------------------------------------------------------
-- Data Handlers
--------------------------------------------------------------------------------------------------
 
local handlerVals = {
name = { values = { db = "global", type = "string" }, mixins = { "SetVal", "GetVal", "Refresh" } },
enable = { values = { db = "global", type = "boolean"}, default = true, mixins = { "SetVal", "GetVal", "Refresh" } },
index = { values = { db = "global", type = "number" }, mixins = { "SetVal", "GetVal", "Refresh" } },
type = { values = { db = "global", type = "string" }, mixins = { "SetVal", "GetVal", "Refresh" } },
tag = { values = { db = "global", type = "string" }, mixins = { "SetVal", "GetVal", "Refresh" } },
header = { values = { db = "global", type = "string" }, mixins = { "SetVal", "GetVal", "Refresh" } },
time = { values = { db = "char", type = "number" }, mixins = { "SetVal", "GetVal", "Refresh" } },
reset = { values = { db = "char", type = "number" }, mixins = { "SetVal", "GetVal", "Refresh" } },
done = { values = { db = "char", type = "number" }, default = 0, mixins = { "SetVal", "GetVal", "Refresh" } },
side = { values = { db = "global", type = "number" }, mixins = { "SetVal", "GetVal", "Refresh" } },
 
unit = { values = { db = "global" }, key = "_unit", mixins = { "SetUnit", "GetUnit", "DelUnit", "Refresh" } },
obj = { values = { db = "global" }, key = "_obj", mixins = { "SetObj", "SetObj", "Refresh" } },
coord = { values = { db = "global" }, key = "_coord", mixins = { "SetCoord", "GetCoord", "Refresh" } },
}
 
local handlerSets = {
quest = { "name", "index", "enable", "type", "tag", "header", "time", "reset", "done", "unit", "obj" },
unit = { "name", "index", "type", "side", "coord" },
item = { "name", "index", "unit" },
}
 
local setMixins = {
 
SetUnit = function(this, h)
assert(handler, "Invalid arguments for SetUnit")
local t, i = this._unit, nil
for k = 1, #t, 1 do
if t[k] == h._index then
i = k; break
end
end
if ( not i ) then
table.insert(t, h._index)
this:Refresh()
end
end,
 
GetUnit = function(this)
return unpack(this._children.unit)
end,
 
DelUnit = function(this, index)
assert(index, "Invalid arguments for DelUnit")
local t, i = this._unit, nil
for k = 1, #t, 1 do
if t[k] == index then
i = k; break
end
end
if i then
table.remove(t, i)
this:Refresh()
end
end,
 
Refresh = function(this)
 
end,
 
Delete = function(this)
EasyDaily:DeleteHandler(this)
end,
 
SetCoord = function(this, zone, x, y, dl)
assert(zone and x and y, "Invalid arguments for SetCoord")
if type(this._coord[zone]) ~= "table" then this._coord[zone] = {}; end
local t, i = this._coord[zone], nil
for k = 1, #t, 1 do
if ( math.abs(x - t[k].x) <= 5 ) and ( math.abs(y - t[k].y) <= 5 ) and t[k].dl == dl then
i = k; break
end
end
if i then
local n = t[i].n
t[i].x = math.floor(( t[i].x * n + x ) / ( n + 1 ) + 0.5)
t[i].y = math.floor(( t[i].y * n + y ) / ( n + 1 ) + 0.5)
t[i].n = t[i].n + 1
else
table.insert(t, { x = x, y = y, dl = dl, n = 1 })
end
this:Refresh()
end,
 
GetCoord = function(this)
return this._coord
end,
 
SetVal = function(this, key, value)
if type(key) ~= nil and type(value) ~= nil and this._values[key] and this._values[key].type == type(value) then
this._data[ this._values[key].db ][ key ] = value
this:Refresh()
return value
else
EasyDaily:Debug(key, value)
error("Invalid key value for SetVal")
end
end,
 
GetVal = function(this, key)
if key and this._values[key] then
return this._data[ this._values[key].db ][ key ]
else
error("Invalid key value for GetVal")
end
end,
 
}
 
function EasyDaily:ResetDatabase()
local locale = GetLocale()
self.db.global.data[locale] = {}
self.db.char.data[locale] = {}
self.handlers = {}
end
 
function EasyDaily:RefreshHandlers()
for i, v in pairs(EasyDaily.handlers) do
v:Refresh()
end
end
 
function EasyDaily:DeleteHandler(h)
if type(h) == "table" and h._index then
if this._type == "unit" then
for i, v in pairs(self.handlers) do
if v.DelUnit then
v:DelUnit(this._index)
end
end
end
self.db.global.data[h._index] = false
self.db.char.data[h._index] = nil
self.handlers[h._index] = nil
for i in pairs(h) do h[i] = nil end
end
end
 
function EasyDaily:GetHandler(kind, index, create)
assert(kind and ( type(index) == "number" or type(index) == "string" ), "GetHandler")
for i, v in pairs(self.handlers) do
if kind == v._data.global.handler and ( ( type(index) == "number" and index == v._data.global.index ) or ( type(index) == "string" and index == v._data.global.name ) ) then
return v
end
end
if create then
return self:CreateHandler(kind, index), true
end
end
 
function EasyDaily:CreateHandler(kind, index)
 
assert(kind and ( type(index) == "number" or type(index) == "string" ), "CreateHandler")
 
local getHandler = self:GetHandler(kind, index)
if getHandler then
return getHandler
end
 
local locale = GetLocale()
 
local x, n = #self.db.global.data[locale], nil
if x > 0 then
for i = 1, x + 1, 1 do
if not self.db.global.data[locale][i] then
n = i; break
end
end
else
n = 1
end
 
local handler = {}
 
if not self.db.global.data[locale] then
self.db.global.data[locale] = {}
end
if not self.db.char.data[locale] then
self.db.char.data[locale] = {}
end
 
self.db.global.data[locale][n] = {}
self.db.char.data[locale][n] = {}
 
self.handlers[n] = handler
 
if handlerSets[kind] then
 
handler._index = n
handler._type = kind
 
handler._data = {
global = self.db.global.data[locale][n],
char = self.db.char.data[locale][n],
}
 
handler._data.global.handler = kind
 
if type(index) == "number" then
handler._data.global.index = index
elseif type(index) == "string" then
print(1)
handler._data.global.name = index
end
 
for _, v in pairs(handlerSets[kind]) do
 
for _, k in pairs(handlerVals[v].mixins) do
handler[k] = setMixins[k]
end
 
if handlerVals[v].key then
local db = handlerVals[v].values.db
if not handler._data[db][v] then
handler._data[db][v] = {}
end
handler[ handlerVals[v].key ] = handler._data[db][v]
else
if not handler._values then
handler._values = {}
end
handler._values[v] = handlerVals[v].values
end
 
if handlerVals[v].default then
handler._data[ handlerVals[v].values.db ][v] = handlerVals[v].default
end
 
end
 
return handler
 
end
 
end
 
function EasyDaily:InitHandlers()
 
self.handlers = {}
 
local locale = GetLocale()
 
for i, v in pairs(self.db.global.data[locale]) do
if v then
 
self.handlers[i] = {}
 
local handler = self.handlers[i]
local kind = v.handler
 
if handlerSets[kind] then
 
handler._index = n
handler._type = kind
 
handler._data = {
global = v,
char = self.db.char.data[locale][i],
}
 
for _, v in pairs(handlerSets[kind]) do
 
for _, k in pairs(handlerVals[v].mixins) do
handler[k] = setMixins[k]
end
 
if handlerVals[v].key then
local db = handlerVals[v].values.db
if not handler._data[db][v] then
handler._data[db][v] = {}
end
handler[ handlerVals[v].key ] = handler._data[db][v]
else
if not handler._values then
handler._values = {}
end
handler._values[v] = handlerVals[v].values
end
 
end
 
end
 
end
end
 
end
 
--------------------------------------------------------------------------------------------------
-- Linear Table Creation/Functions
--------------------------------------------------------------------------------------------------
 
do
 
regOps = {
init = { args = 1, func = function(a, b) if type(a) ~= "nil" then return a; end return b; end },
set = { args = 1, func = function(_, b) return b; end },
add = { args = 1, func = function(a, b) return (tonumber(a) or 0) + b; end },
clean = { args = 0, func = function(a, _) if type(a) == "table" then for i in pairs(a) do a[i] = nil; end else a = {}; end return a; end },
tinit = { args = 0, func = function(a, _) if type(a) ~= "nil" then return a; end return {}; end },
tinsert = { args = 1, val = 1, func = function(a, b) if type(a) ~= "table" then a = {}; end tinsert(a, b); return a; end },
}
 
setLinearLoop = function(info, array, index, ...)
if ( not array ) or ( not index ) then
return nil
elseif select("#", ...) == info.args then
array[index] = info.func(array[index], ...)
if info.val then return select(info.val, ...); else return array[index]; end
else
if ( not array[index] ) then array[index] = {}; end
return setLinearLoop(info, array[index], ...)
end
end
function EasyDaily:SetLinear(f, ...)
local info = regOps[f]
if info and select("#", ...) - 2 >= info.args then
return setLinearLoop(info, ...)
end
end
 
end
 
function EasyDaily:GetLinear(array, index, ...)
if ( type(array) ~= "table" ) or ( not index ) then
return nil
elseif select("#", ...) == 0 then
return array[index]
else
return self:GetLinear(array[index], ...)
end
end
 
EasyDaily/EasyDaily.toc New file
0,0 → 1,45
## Interface: 30100
## Title: EasyDaily
## Notes: Daily Quest Routine Optimizer!
## Authors: Draake
## OptionalDeps: Ace3, LibDBIcon-1.0, LibGratuity-3.0, LibAbacus-3.0, LibTourist-3.0, Babble-Faction-3.0, LibBabble-Zone-3.0
## SavedVariables: EasyDailyDB
## X-Curse-Packaged-Version: v2.0-beta
## X-Curse-Project-Name: EasyDaily 2.0
## X-Curse-Project-ID: easydaily
## X-Curse-Repository-ID: wow/easydaily/mainline
 
#@no-lib-strip@
libs\Libstub\Libstub.lua
libs\CallbackHandler-1.0\CallbackHandler-1.0.xml
libs\AceAddon-3.0\AceAddon-3.0.xml
libs\AceDB-3.0\AceDB-3.0.xml
libs\AceDBOptions-3.0\AceDBOptions-3.0.xml
libs\AceEvent-3.0\AceEvent-3.0.xml
libs\AceTimer-3.0\AceTimer-3.0.xml
libs\AceBucket-3.0\AceBucket-3.0.xml
libs\AceConsole-3.0\AceConsole-3.0.xml
libs\AceHook-3.0\AceHook-3.0.xml
libs\AceLocale-3.0\AceLocale-3.0.xml
libs\AceGUI-3.0\AceGUI-3.0.xml
libs\AceConfig-3.0\AceConfig-3.0.xml
libs\LibGratuity-3.0\lib.xml
libs\LibAbacus-3.0\lib.xml
libs\LibBabble-Faction-3.0\lib.xml
libs\LibBabble-Zone-3.0\lib.xml
libs\LibTourist-3.0\lib.xml
#@end-no-lib-strip@
libs\LibDataBroker-1.1\LibDataBroker-1.1.lua
#@no-lib-strip@
libs\LibDBIcon-1.0\LibDBIcon-1.0.lua
#@end-no-lib-strip@
 
locales.xml
 
core.lua
utility.lua
database.lua
inventory.lua
tracking.lua
turnin.lua
options.lua
EasyDaily/core.lua New file
0,0 → 1,239
--[[
Desc:
Info: $Id: core.lua 18 2009-05-02 04:10:33Z draake $
]]
 
local _G = _G
local pairs, ipairs, type, select, tonumber, tostring = pairs, ipairs, type, select, tonumber, tostring
 
local tinsert, tremove, tsort = table.insert, table.remove, table.sort
local sformat = string.format
 
EasyDaily = LibStub("AceAddon-3.0"):NewAddon("EasyDaily", "AceEvent-3.0", "AceConsole-3.0", "AceHook-3.0", "AceTimer-3.0", "AceBucket-3.0")
 
local L = LibStub("AceLocale-3.0"):GetLocale("EasyDaily_Base")
 
--------------------------------------------------------------------------------------------------
-- Defaults
--------------------------------------------------------------------------------------------------
 
-- Increasing this forces a database purse
local RESETDB = 0
 
local defaults = {
global = {
data = {},
},
profile = {
 
enabled = true,
debug = false,
 
skipflag = false,
skipmoney = false,
single = true,
multiple = false,
 
gossipstate = false,
gossipicons = true,
stickyturnin = true,
 
tag_normal = true,
tag_group = true,
tag_dungeon = true,
tag_raid = true,
tag_heroic = true,
tag_pvp = true,
tag_elite = true,
 
mod_normal = "disable",
mod_daily = "shift",
mod_repeat = "shift",
mod_override = "alt",
mod_suspend = "disable",
 
purge = 0,
mversion = 0,
 
minimapIcon = {},
 
reward = {},
 
},
char = {
data = {},
},
}
 
--------------------------------------------------------------------------------------------------
-- Enable/Disable
--------------------------------------------------------------------------------------------------
 
function EasyDaily:GetPVar(...)
return self:GetLinear(self.db.profile, ...)
end
function EasyDaily:SetPVar(...)
return self:SetLinear("set", self.db.profile, ...)
end
 
function EasyDaily:GetCVar(...)
return self:GetLoopTable(self.db.char, ...)
end
 
function EasyDaily:OnInitialize()
 
self.db = LibStub("AceDB-3.0"):New("EasyDailyDB", defaults, "Default")
 
self.version = {}
 
-- Version
self.version.revision = tonumber("18")
if self.version.revision then
local vtext = "v2.0-beta"
if string.find(vtext, "^r%d+$") then
self.version.text = string.format("r%s-alpha", self.version.revision)
else
self.version.major, self.version.minor, self.version.vtype = self:StrSplit("v%.%-", vtext)
self.version.text = string.format("v%s.%s.%s-%s", self.version.major or 0, self.version.minor or 0, self.version.revision, self.version.vtype or "???")
end
else
self.version.text = "SVN"
end
 
if self.version.major and ( self.db.profile.mversion < self.version.major ) then
self.db:ResetDB("Default")
self.db.profile.mversion = self.version.major
end
 
if ( self.db.profile.purge < RESETDB ) then
self:ResetDatabase()
self:Print("Database reset to default.")
self.db.profile.purge = RESETDB
end
 
local locale = GetLocale()
if not self.db.global.data[locale] then
self.db.global.data[locale] = {}
end
if not self.db.char.data[locale] then
self.db.char.data[locale] = {}
end
 
self:InitHandlers()
 
self.tracker = {
spell = {},
npc = {},
gossip = {},
}
 
self.vars = {
events = {},
}
 
self.LibTourist = LibStub("LibTourist-3.0")
self.LibAbacus = LibStub("LibAbacus-3.0")
 
do -- Create QuestFrame CheckButton
 
local b = CreateFrame("CheckButton", "EasyDailyQuestFrameCheckButton", QuestFrame, "UICheckButtonTemplate")
b:SetPoint("TOPLEFT", "QuestFrame", "TOPLEFT", 80, -50)
b:SetHitRectInsets(0, -70, 0, 0)
b:SetHeight(24)
b:SetWidth(24)
 
b.text = _G[ b:GetName() .. "Text" ]
b.text:ClearAllPoints()
b.text:SetPoint("LEFT", b:GetName(), "RIGHT", 0, 0)
b.text:SetText(L["Auto Turn-in"])
 
b:SetScript("OnShow", function(this)
EasyDaily:QuestCheckButtonOnShow(this)
end)
b:SetScript("OnClick", function(this)
EasyDaily:QuestCheckButtonOnClick(this)
end)
b:SetScript("OnEnter", function(this)
GameTooltip:SetOwner(this, "ANCHOR_LEFT")
GameTooltip:SetText(L["Toggles 'Auto Turn-in' for this quest."], nil, nil, nil, nil, 1)
end)
b:SetScript("OnLeave", GameTooltip_Hide)
 
self.vars.questbutton = b
 
end
 
-- Gossip/Quest Frame additional click registration
for i = 1, NUMGOSSIPBUTTONS, 1 do
local b = _G[ "GossipTitleButton" .. i ]
b:RegisterForClicks("LeftButtonUp", "RightButtonUp")
b.icon = _G[ "GossipTitleButton" .. i .. "GossipIcon" ]
end
for i = 1, MAX_NUM_QUESTS, 1 do
local b = _G[ "QuestTitleButton" .. i ]
b:RegisterForClicks("LeftButtonUp", "RightButtonUp")
b.icon = _G[ "QuestTitleButton" .. i .. "QuestIcon" ]
end
 
self:SetupOptions()
 
self:SetEnabledState(self.db.profile.enabled)
 
end
 
function EasyDaily:OnEnable()
 
-- Events and timers
self:RegisterEvent("QUEST_GREETING")
self:RegisterEvent("GOSSIP_SHOW")
self:RegisterEvent("QUEST_DETAIL")
self:RegisterEvent("QUEST_PROGRESS")
self:RegisterEvent("QUEST_COMPLETE")
 
self.vars.events["GossipClosed"] = self:RegisterBucketEvent({
"QUEST_FINISHED",
"GOSSIP_CLOSED"
}, 0, "GossipOrQuestClosed")
 
self:RegisterEvent("QUEST_LOG_UPDATE")
 
self:Hook("GetQuestReward", true)
 
self:RawHook("GossipTitleButton_OnClick", true)
self:RawHook("QuestTitleButton_OnClick", true)
 
-- Addon is enabled
self.db.profile.enabled = true
 
-- Startup functions
self:RefreshGossipOrQuestFrame()
 
end
 
function EasyDaily:OnDisable()
 
-- Events and timers
self:UnregisterEvent("QUEST_GREETING")
self:UnregisterEvent("GOSSIP_SHOW")
self:UnregisterEvent("QUEST_DETAIL")
self:UnregisterEvent("QUEST_PROGRESS")
self:UnregisterEvent("QUEST_COMPLETE")
 
self:UnregisterBucket( self.vars.events["GossipClosed"] )
 
self:UnregisterEvent("QUEST_LOG_UPDATE")
 
self:Unhook("GetQuestReward", true)
 
self:Unhook("GossipTitleButton_OnClick")
self:Unhook("QuestTitleButton_OnClick")
 
-- Addon is disabled
self.db.profile.enabled = false
 
-- Shutdown functions
self.vars.questbutton:Hide()
self:RefreshGossipOrQuestFrame()
 
end
 
EasyDaily/libs/AceBucket-3.0/AceBucket-3.0.xml New file
0,0 → 1,4
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="AceBucket-3.0.lua"/>
</Ui>
\ No newline at end of file
EasyDaily/libs/AceBucket-3.0/AceBucket-3.0.lua New file
0,0 → 1,291
--- A bucket to catch events in. **AceBucket-3.0** provides throttling of events that fire in bursts and
-- your addon only needs to know about the full burst.
--
-- This Bucket implementation works as follows:\\
-- Initially, no schedule is running, and its waiting for the first event to happen.\\
-- The first event will start the bucket, and get the scheduler running, which will collect all
-- events in the given interval. When that interval is reached, the bucket is pushed to the
-- callback and a new schedule is started. When a bucket is empty after its interval, the scheduler is
-- stopped, and the bucket is only listening for the next event to happen, basically back in its initial state.
--
-- In addition, the buckets collect information about the "arg1" argument of the events that fire, and pass those as a
-- table to your callback. This functionality was mostly designed for the UNIT_* events.\\
-- The table will have the different values of "arg1" as keys, and the number of occurances as their value, e.g.\\
-- { ["player"] = 2, ["target"] = 1, ["party1"] = 1 }
--
-- **AceBucket-3.0** can be embeded into your addon, either explicitly by calling AceBucket:Embed(MyAddon) or by
-- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
-- and can be accessed directly, without having to explicitly call AceBucket itself.\\
-- It is recommended to embed AceBucket, otherwise you'll have to specify a custom `self` on all calls you
-- make into AceBucket.
-- @usage
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("BucketExample", "AceBucket-3.0")
--
-- function MyAddon:OnEnable()
-- -- Register a bucket that listens to all the HP related events,
-- -- and fires once per second
-- self:RegisterBucketEvent({"UNIT_HEALTH", "UNIT_MAXHEALTH"}, 1, "UpdateHealth")
-- end
--
-- function MyAddon:UpdateHealth(units)
-- if units.player then
-- print("Your HP changed!")
-- end
-- end
-- @class file
-- @name AceBucket-3.0.lua
-- @release $Id: AceBucket-3.0.lua 781 2009-04-05 10:01:39Z nevcairiel $
 
local MAJOR, MINOR = "AceBucket-3.0", 3
local AceBucket, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
 
if not AceBucket then return end -- No Upgrade needed
 
AceBucket.buckets = AceBucket.buckets or {}
AceBucket.embeds = AceBucket.embeds or {}
 
-- the libraries will be lazyly bound later, to avoid errors due to loading order issues
local AceEvent, AceTimer
 
-- local upvalues
local type = type
local next = next
local pairs = pairs
local select = select
local tonumber = tonumber
local tostring = tostring
 
local bucketCache = setmetatable({}, {__mode='k'})
 
--[[
xpcall safecall implementation
]]
local xpcall = xpcall
 
local function errorhandler(err)
return geterrorhandler()(err)
end
 
local function CreateDispatcher(argCount)
local code = [[
local xpcall, eh = ...
local method, ARGS
local function call() return method(ARGS) end
 
local function dispatch(func, ...)
method = func
if not method then return end
ARGS = ...
return xpcall(call, eh)
end
 
return dispatch
]]
 
local ARGS = {}
for i = 1, argCount do ARGS[i] = "arg"..i end
code = code:gsub("ARGS", table.concat(ARGS, ", "))
return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(xpcall, errorhandler)
end
 
local Dispatchers = setmetatable({}, {__index=function(self, argCount)
local dispatcher = CreateDispatcher(argCount)
rawset(self, argCount, dispatcher)
return dispatcher
end})
Dispatchers[0] = function(func)
return xpcall(func, errorhandler)
end
 
local function safecall(func, ...)
return Dispatchers[select('#', ...)](func, ...)
end
 
-- FireBucket ( bucket )
--
-- send the bucket to the callback function and schedule the next FireBucket in interval seconds
local function FireBucket(bucket)
local received = bucket.received
 
-- we dont want to fire empty buckets
if next(received) then
local callback = bucket.callback
if type(callback) == "string" then
safecall(bucket.object[callback], bucket.object, received)
else
safecall(callback, received)
end
 
for k in pairs(received) do
received[k] = nil
end
 
-- if the bucket was not empty, schedule another FireBucket in interval seconds
bucket.timer = AceTimer.ScheduleTimer(bucket, FireBucket, bucket.interval, bucket)
else -- if it was empty, clear the timer and wait for the next event
bucket.timer = nil
end
end
 
-- BucketHandler ( event, arg1 )
--
-- callback func for AceEvent
-- stores arg1 in the received table, and schedules the bucket if necessary
local function BucketHandler(self, event, arg1)
if arg1 == nil then
arg1 = "nil"
end
 
self.received[arg1] = (self.received[arg1] or 0) + 1
 
-- if we are not scheduled yet, start a timer on the interval for our bucket to be cleared
if not self.timer then
self.timer = AceTimer.ScheduleTimer(self, FireBucket, self.interval, self)
end
end
 
-- RegisterBucket( event, interval, callback, isMessage )
--
-- event(string or table) - the event, or a table with the events, that this bucket listens to
-- interval(int) - time between bucket fireings
-- callback(func or string) - function pointer, or method name of the object, that gets called when the bucket is cleared
-- isMessage(boolean) - register AceEvent Messages instead of game events
local function RegisterBucket(self, event, interval, callback, isMessage)
-- try to fetch the librarys
if not AceEvent or not AceTimer then
AceEvent = LibStub:GetLibrary("AceEvent-3.0", true)
AceTimer = LibStub:GetLibrary("AceTimer-3.0", true)
if not AceEvent or not AceTimer then
error(MAJOR .. " requires AceEvent-3.0 and AceTimer-3.0", 3)
end
end
 
if type(event) ~= "string" and type(event) ~= "table" then error("Usage: RegisterBucket(event, interval, callback): 'event' - string or table expected.", 3) end
if not callback then
if type(event) == "string" then
callback = event
else
error("Usage: RegisterBucket(event, interval, callback): cannot omit callback when event is not a string.", 3)
end
end
if not tonumber(interval) then error("Usage: RegisterBucket(event, interval, callback): 'interval' - number expected.", 3) end
if type(callback) ~= "string" and type(callback) ~= "function" then error("Usage: RegisterBucket(event, interval, callback): 'callback' - string or function or nil expected.", 3) end
if type(callback) == "string" and type(self[callback]) ~= "function" then error("Usage: RegisterBucket(event, interval, callback): 'callback' - method not found on target object.", 3) end
 
local bucket = next(bucketCache)
if bucket then
bucketCache[bucket] = nil
else
bucket = { handler = BucketHandler, received = {} }
end
bucket.object, bucket.callback, bucket.interval = self, callback, tonumber(interval)
 
local regFunc = isMessage and AceEvent.RegisterMessage or AceEvent.RegisterEvent
 
if type(event) == "table" then
for _,e in pairs(event) do
regFunc(bucket, e, "handler")
end
else
regFunc(bucket, event, "handler")
end
 
local handle = tostring(bucket)
AceBucket.buckets[handle] = bucket
 
return handle
end
 
--- Register a Bucket for an event (or a set of events)
-- @param event The event to listen for, or a table of events.
-- @param interval The Bucket interval (burst interval)
-- @param callback The callback function, either as a function reference, or a string pointing to a method of the addon object.
-- @return The handle of the bucket (for unregistering)
-- @usage
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon", "AceBucket-3.0")
-- MyAddon:RegisterBucketEvent("BAG_UPDATE", 0.2, "UpdateBags")
--
-- function MyAddon:UpdateBags()
-- -- do stuff
-- end
function AceBucket:RegisterBucketEvent(event, interval, callback)
return RegisterBucket(self, event, interval, callback, false)
end
 
--- Register a Bucket for an AceEvent-3.0 addon message (or a set of messages)
-- @param message The message to listen for, or a table of messages.
-- @param interval The Bucket interval (burst interval)
-- @param callback The callback function, either as a function reference, or a string pointing to a method of the addon object.
-- @return The handle of the bucket (for unregistering)
-- @usage
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon", "AceBucket-3.0")
-- MyAddon:RegisterBucketEvent("SomeAddon_InformationMessage", 0.2, "ProcessData")
--
-- function MyAddon:ProcessData()
-- -- do stuff
-- end
function AceBucket:RegisterBucketMessage(message, interval, callback)
return RegisterBucket(self, message, interval, callback, true)
end
 
--- Unregister any events and messages from the bucket and clear any remaining data.
-- @param handle The handle of the bucket as returned by RegisterBucket*
function AceBucket:UnregisterBucket(handle)
local bucket = AceBucket.buckets[handle]
if bucket then
AceEvent.UnregisterAllEvents(bucket)
AceEvent.UnregisterAllMessages(bucket)
 
-- clear any remaining data in the bucket
for k in pairs(bucket.received) do
bucket.received[k] = nil
end
 
if bucket.timer then
AceTimer.CancelTimer(bucket, bucket.timer)
bucket.timer = nil
end
 
AceBucket.buckets[handle] = nil
-- store our bucket in the cache
bucketCache[bucket] = true
end
end
 
--- Unregister all buckets of the current addon object (or custom "self").
function AceBucket:UnregisterAllBuckets()
-- hmm can we do this more efficient? (it is not done often so shouldn't matter much)
for handle, bucket in pairs(AceBucket.buckets) do
if bucket.object == self then
AceBucket.UnregisterBucket(self, handle)
end
end
end
 
 
 
-- embedding and embed handling
local mixins = {
"RegisterBucketEvent",
"RegisterBucketMessage",
"UnregisterBucket",
"UnregisterAllBuckets",
}
 
-- Embeds AceBucket into the target object making the functions from the mixins list available on target:..
-- @param target target object to embed AceBucket in
function AceBucket:Embed( target )
for _, v in pairs( mixins ) do
target[v] = self[v]
end
self.embeds[target] = true
return target
end
 
function AceBucket:OnEmbedDisable( target )
target:UnregisterAllBuckets()
end
 
for addon in pairs(AceBucket.embeds) do
AceBucket:Embed(addon)
end
EasyDaily/libs/CallbackHandler-1.0/CallbackHandler-1.0.xml New file
0,0 → 1,4
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="CallbackHandler-1.0.lua"/>
</Ui>
\ No newline at end of file
EasyDaily/libs/CallbackHandler-1.0/CallbackHandler-1.0.lua New file
0,0 → 1,239
--[[ $Id: CallbackHandler-1.0.lua 504 2008-02-07 11:04:06Z nevcairiel $ ]]
local MAJOR, MINOR = "CallbackHandler-1.0", 3
local CallbackHandler = LibStub:NewLibrary(MAJOR, MINOR)
 
if not CallbackHandler then return end -- No upgrade needed
 
local meta = {__index = function(tbl, key) tbl[key] = {} return tbl[key] end}
 
local type = type
local pcall = pcall
local pairs = pairs
local assert = assert
local concat = table.concat
local loadstring = loadstring
local next = next
local select = select
local type = type
local xpcall = xpcall
 
local function errorhandler(err)
return geterrorhandler()(err)
end
 
local function CreateDispatcher(argCount)
local code = [[
local next, xpcall, eh = ...
 
local method, ARGS
local function call() method(ARGS) end
 
local function dispatch(handlers, ...)
local index
index, method = next(handlers)
if not method then return end
local OLD_ARGS = ARGS
ARGS = ...
repeat
xpcall(call, eh)
index, method = next(handlers, index)
until not method
ARGS = OLD_ARGS
end
 
return dispatch
]]
 
local ARGS, OLD_ARGS = {}, {}
for i = 1, argCount do ARGS[i], OLD_ARGS[i] = "arg"..i, "old_arg"..i end
code = code:gsub("OLD_ARGS", concat(OLD_ARGS, ", ")):gsub("ARGS", concat(ARGS, ", "))
return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(next, xpcall, errorhandler)
end
 
local Dispatchers = setmetatable({}, {__index=function(self, argCount)
local dispatcher = CreateDispatcher(argCount)
rawset(self, argCount, dispatcher)
return dispatcher
end})
 
--------------------------------------------------------------------------
-- CallbackHandler:New
--
-- target - target object to embed public APIs in
-- RegisterName - name of the callback registration API, default "RegisterCallback"
-- UnregisterName - name of the callback unregistration API, default "UnregisterCallback"
-- UnregisterAllName - name of the API to unregister all callbacks, default "UnregisterAllCallbacks". false == don't publish this API.
 
function CallbackHandler:New(target, RegisterName, UnregisterName, UnregisterAllName, OnUsed, OnUnused)
-- TODO: Remove this after beta has gone out
assert(not OnUsed and not OnUnused, "ACE-80: OnUsed/OnUnused are deprecated. Callbacks are now done to registry.OnUsed and registry.OnUnused")
 
RegisterName = RegisterName or "RegisterCallback"
UnregisterName = UnregisterName or "UnregisterCallback"
if UnregisterAllName==nil then -- false is used to indicate "don't want this method"
UnregisterAllName = "UnregisterAllCallbacks"
end
 
-- we declare all objects and exported APIs inside this closure to quickly gain access
-- to e.g. function names, the "target" parameter, etc
 
 
-- Create the registry object
local events = setmetatable({}, meta)
local registry = { recurse=0, events=events }
 
-- registry:Fire() - fires the given event/message into the registry
function registry:Fire(eventname, ...)
if not rawget(events, eventname) or not next(events[eventname]) then return end
local oldrecurse = registry.recurse
registry.recurse = oldrecurse + 1
 
Dispatchers[select('#', ...) + 1](events[eventname], eventname, ...)
 
registry.recurse = oldrecurse
 
if registry.insertQueue and oldrecurse==0 then
-- Something in one of our callbacks wanted to register more callbacks; they got queued
for eventname,callbacks in pairs(registry.insertQueue) do
local first = not rawget(events, eventname) or not next(events[eventname]) -- test for empty before. not test for one member after. that one member may have been overwritten.
for self,func in pairs(callbacks) do
events[eventname][self] = func
-- fire OnUsed callback?
if first and registry.OnUsed then
registry.OnUsed(registry, target, eventname)
first = nil
end
end
end
registry.insertQueue = nil
end
end
 
-- Registration of a callback, handles:
-- self["method"], leads to self["method"](self, ...)
-- self with function ref, leads to functionref(...)
-- "addonId" (instead of self) with function ref, leads to functionref(...)
-- all with an optional arg, which, if present, gets passed as first argument (after self if present)
target[RegisterName] = function(self, eventname, method, ... --[[actually just a single arg]])
if type(eventname) ~= "string" then
error("Usage: "..RegisterName.."(eventname, method[, arg]): 'eventname' - string expected.", 2)
end
 
method = method or eventname
 
local first = not rawget(events, eventname) or not next(events[eventname]) -- test for empty before. not test for one member after. that one member may have been overwritten.
 
if type(method) ~= "string" and type(method) ~= "function" then
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - string or function expected.", 2)
end
 
local regfunc
 
if type(method) == "string" then
-- self["method"] calling style
if type(self) ~= "table" then
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): self was not a table?", 2)
elseif self==target then
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): do not use Library:"..RegisterName.."(), use your own 'self'", 2)
elseif type(self[method]) ~= "function" then
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - method '"..tostring(method).."' not found on self.", 2)
end
 
if select("#",...)>=1 then -- this is not the same as testing for arg==nil!
local arg=select(1,...)
regfunc = function(...) self[method](self,arg,...) end
else
regfunc = function(...) self[method](self,...) end
end
else
-- function ref with self=object or self="addonId"
if type(self)~="table" and type(self)~="string" then
error("Usage: "..RegisterName.."(self or \"addonId\", eventname, method): 'self or addonId': table or string expected.", 2)
end
 
if select("#",...)>=1 then -- this is not the same as testing for arg==nil!
local arg=select(1,...)
regfunc = function(...) method(arg,...) end
else
regfunc = method
end
end
 
 
if events[eventname][self] or registry.recurse<1 then
-- if registry.recurse<1 then
-- we're overwriting an existing entry, or not currently recursing. just set it.
events[eventname][self] = regfunc
-- fire OnUsed callback?
if registry.OnUsed and first then
registry.OnUsed(registry, target, eventname)
end
else
-- we're currently processing a callback in this registry, so delay the registration of this new entry!
-- yes, we're a bit wasteful on garbage, but this is a fringe case, so we're picking low implementation overhead over garbage efficiency
registry.insertQueue = registry.insertQueue or setmetatable({},meta)
registry.insertQueue[eventname][self] = regfunc
end
end
 
-- Unregister a callback
target[UnregisterName] = function(self, eventname)
if not self or self==target then
error("Usage: "..UnregisterName.."(eventname): bad 'self'", 2)
end
if type(eventname) ~= "string" then
error("Usage: "..UnregisterName.."(eventname): 'eventname' - string expected.", 2)
end
if rawget(events, eventname) and events[eventname][self] then
events[eventname][self] = nil
-- Fire OnUnused callback?
if registry.OnUnused and not next(events[eventname]) then
registry.OnUnused(registry, target, eventname)
end
end
if registry.insertQueue and rawget(registry.insertQueue, eventname) and registry.insertQueue[eventname][self] then
registry.insertQueue[eventname][self] = nil
end
end
 
-- OPTIONAL: Unregister all callbacks for given selfs/addonIds
if UnregisterAllName then
target[UnregisterAllName] = function(...)
if select("#",...)<1 then
error("Usage: "..UnregisterAllName.."([whatFor]): missing 'self' or \"addonId\" to unregister events for.", 2)
end
if select("#",...)==1 and ...==target then
error("Usage: "..UnregisterAllName.."([whatFor]): supply a meaningful 'self' or \"addonId\"", 2)
end
 
 
for i=1,select("#",...) do
local self = select(i,...)
if registry.insertQueue then
for eventname, callbacks in pairs(registry.insertQueue) do
if callbacks[self] then
callbacks[self] = nil
end
end
end
for eventname, callbacks in pairs(events) do
if callbacks[self] then
callbacks[self] = nil
-- Fire OnUnused callback?
if registry.OnUnused and not next(callbacks) then
registry.OnUnused(registry, target, eventname)
end
end
end
end
end
end
 
return registry
end
 
 
-- CallbackHandler purposefully does NOT do explicit embedding. Nor does it
-- try to upgrade old implicit embeds since the system is selfcontained and
-- relies on closures to work.
 
EasyDaily/libs/AceTimer-3.0/AceTimer-3.0.xml New file
0,0 → 1,4
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="AceTimer-3.0.lua"/>
</Ui>
\ No newline at end of file
EasyDaily/libs/AceTimer-3.0/AceTimer-3.0.lua New file
0,0 → 1,467
--- **AceTimer-3.0** provides a central facility for registering timers.
-- AceTimer supports one-shot timers and repeating timers. All timers are stored in an efficient
-- data structure that allows easy dispatching and fast rescheduling. Timers can be registered, rescheduled
-- or canceled at any time, even from within a running timer, without conflict or large overhead.\\
-- AceTimer is currently limited to firing timers at a frequency of 0.1s. This constant may change
-- in the future, but for now it seemed like a good compromise in efficiency and accuracy.
--
-- All `:Schedule` functions will return a handle to the current timer, which you will need to store if you
-- need to cancel or reschedule the timer you just registered.
--
-- **AceTimer-3.0** can be embeded into your addon, either explicitly by calling AceTimer:Embed(MyAddon) or by
-- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
-- and can be accessed directly, without having to explicitly call AceTimer itself.\\
-- It is recommended to embed AceTimer, otherwise you'll have to specify a custom `self` on all calls you
-- make into AceTimer.
-- @class file
-- @name AceTimer-3.0
-- @release $Id: AceTimer-3.0.lua 769 2009-04-04 11:05:08Z nevcairiel $
 
--[[
Basic assumptions:
* In a typical system, we do more re-scheduling per second than there are timer pulses per second
* Regardless of timer implementation, we cannot guarantee timely delivery due to FPS restriction (may be as low as 10)
 
This implementation:
CON: The smallest timer interval is constrained by HZ (currently 1/10s).
PRO: It will still correctly fire any timer slower than HZ over a length of time, e.g. 0.11s interval -> 90 times over 10 seconds
PRO: In lag bursts, the system simly skips missed timer intervals to decrease load
CON: Algorithms depending on a timer firing "N times per minute" will fail
PRO: (Re-)scheduling is O(1) with a VERY small constant. It's a simple linked list insertion in a hash bucket.
CAUTION: The BUCKETS constant constrains how many timers can be efficiently handled. With too many hash collisions, performance will decrease.
 
Major assumptions upheld:
- ALLOWS scheduling multiple timers with the same funcref/method
- ALLOWS scheduling more timers during OnUpdate processing
- ALLOWS unscheduling ANY timer (including the current running one) at any time, including during OnUpdate processing
]]
 
local MAJOR, MINOR = "AceTimer-3.0", 5
local AceTimer, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
 
if not AceTimer then return end -- No upgrade needed
 
AceTimer.hash = AceTimer.hash or {} -- Array of [0..BUCKET-1] = linked list of timers (using .next member)
-- Linked list gets around ACE-88 and ACE-90.
AceTimer.selfs = AceTimer.selfs or {} -- Array of [self]={[handle]=timerobj, [handle2]=timerobj2, ...}
AceTimer.frame = AceTimer.frame or CreateFrame("Frame", "AceTimer30Frame")
 
local type = type
local next = next
local pairs = pairs
local select = select
local tostring = tostring
local floor = floor
local max = max
 
-- Simple ONE-SHOT timer cache. Much more efficient than a full compost for our purposes.
local timerCache = nil
 
--[[
Timers will not be fired more often than HZ-1 times per second.
Keep at intended speed PLUS ONE or we get bitten by floating point rounding errors (n.5 + 0.1 can be n.599999)
If this is ever LOWERED, all existing timers need to be enforced to have a delay >= 1/HZ on lib upgrade.
If this number is ever changed, all entries need to be rehashed on lib upgrade.
]]
local HZ = 11
 
--[[
Prime for good distribution
If this number is ever changed, all entries need to be rehashed on lib upgrade.
]]
local BUCKETS = 131
 
local hash = AceTimer.hash
for i=1,BUCKETS do
hash[i] = hash[i] or false -- make it an integer-indexed array; it's faster than hashes
end
 
--[[
xpcall safecall implementation
]]
local xpcall = xpcall
 
local function errorhandler(err)
return geterrorhandler()(err)
end
 
local function CreateDispatcher(argCount)
local code = [[
local xpcall, eh = ... -- our arguments are received as unnamed values in "..." since we don't have a proper function declaration
local method, ARGS
local function call() return method(ARGS) end
 
local function dispatch(func, ...)
method = func
if not method then return end
ARGS = ...
return xpcall(call, eh)
end
 
return dispatch
]]
 
local ARGS = {}
for i = 1, argCount do ARGS[i] = "arg"..i end
code = code:gsub("ARGS", table.concat(ARGS, ", "))
return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(xpcall, errorhandler)
end
 
local Dispatchers = setmetatable({}, {
__index=function(self, argCount)
local dispatcher = CreateDispatcher(argCount)
rawset(self, argCount, dispatcher)
return dispatcher
end
})
Dispatchers[0] = function(func)
return xpcall(func, errorhandler)
end
 
local function safecall(func, ...)
return Dispatchers[select('#', ...)](func, ...)
end
 
local lastint = floor(GetTime() * HZ)
 
-- --------------------------------------------------------------------
-- OnUpdate handler
--
-- traverse buckets, always chasing "now", and fire timers that have expired
 
local function OnUpdate()
local now = GetTime()
local nowint = floor(now * HZ)
 
-- Have we passed into a new hash bucket?
if nowint == lastint then return end
 
local soon = now + 1 -- +1 is safe as long as 1 < HZ < BUCKETS/2
 
-- Pass through each bucket at most once
-- Happens on e.g. instance loads, but COULD happen on high local load situations also
for curint = (max(lastint, nowint - BUCKETS) + 1), nowint do -- loop until we catch up with "now", usually only 1 iteration
local curbucket = (curint % BUCKETS)+1
-- Yank the list of timers out of the bucket and empty it. This allows reinsertion in the currently-processed bucket from callbacks.
local nexttimer = hash[curbucket]
hash[curbucket] = false -- false rather than nil to prevent the array from becoming a hash
 
while nexttimer do
local timer = nexttimer
nexttimer = timer.next
local when = timer.when
 
if when < soon then
-- Call the timer func, either as a method on given object, or a straight function ref
local callback = timer.callback
if type(callback) == "string" then
safecall(timer.object[callback], timer.object, timer.arg)
elseif callback then
safecall(callback, timer.arg)
else
-- probably nilled out by CancelTimer
timer.delay = nil -- don't reschedule it
end
 
local delay = timer.delay -- NOW make a local copy, can't do it earlier in case the timer cancelled itself in the callback
 
if not delay then
-- single-shot timer (or cancelled)
AceTimer.selfs[timer.object][tostring(timer)] = nil
timerCache = timer
else
-- repeating timer
local newtime = when + delay
if newtime < now then -- Keep lag from making us firing a timer unnecessarily. (Note that this still won't catch too-short-delay timers though.)
newtime = now + delay
end
timer.when = newtime
 
-- add next timer execution to the correct bucket
local bucket = (floor(newtime * HZ) % BUCKETS) + 1
timer.next = hash[bucket]
hash[bucket] = timer
end
else -- if when>=soon
-- reinsert (yeah, somewhat expensive, but shouldn't be happening too often either due to hash distribution)
timer.next = hash[curbucket]
hash[curbucket] = timer
end -- if when<soon ... else
end -- while nexttimer do
end -- for curint=lastint,nowint
 
lastint = nowint
end
 
-- ---------------------------------------------------------------------
-- Reg( callback, delay, arg, repeating )
--
-- callback( function or string ) - direct function ref or method name in our object for the callback
-- delay(int) - delay for the timer
-- arg(variant) - any argument to be passed to the callback function
-- repeating(boolean) - repeating timer, or oneshot
--
-- returns the handle of the timer for later processing (canceling etc)
local function Reg(self, callback, delay, arg, repeating)
if type(callback) ~= "string" and type(callback) ~= "function" then
local error_origin = repeating and "ScheduleRepeatingTimer" or "ScheduleTimer"
error(MAJOR..": " .. error_origin .. "(callback, delay, arg): 'callback' - function or method name expected.", 3)
end
if type(callback) == "string" then
if type(self)~="table" then
local error_origin = repeating and "ScheduleRepeatingTimer" or "ScheduleTimer"
error(MAJOR..": " .. error_origin .. "(\"methodName\", delay, arg): 'self' - must be a table.", 3)
end
if type(self[callback]) ~= "function" then
local error_origin = repeating and "ScheduleRepeatingTimer" or "ScheduleTimer"
error(MAJOR..": " .. error_origin .. "(\"methodName\", delay, arg): 'methodName' - method not found on target object.", 3)
end
end
 
if delay < (1 / (HZ - 1)) then
delay = 1 / (HZ - 1)
end
 
-- Create and stuff timer in the correct hash bucket
local now = GetTime()
 
local timer = timerCache or {} -- Get new timer object (from cache if available)
timerCache = nil
 
timer.object = self
timer.callback = callback
timer.delay = (repeating and delay)
timer.arg = arg
timer.when = now + delay
 
local bucket = (floor((now+delay)*HZ) % BUCKETS) + 1
timer.next = hash[bucket]
hash[bucket] = timer
 
-- Insert timer in our self->handle->timer registry
local handle = tostring(timer)
 
local selftimers = AceTimer.selfs[self]
if not selftimers then
selftimers = {}
AceTimer.selfs[self] = selftimers
end
selftimers[handle] = timer
selftimers.__ops = (selftimers.__ops or 0) + 1
 
return handle
end
 
--- Schedule a new one-shot timer.
-- The timer will fire once in `delay` seconds, unless canceled before.
-- @param callback Callback function for the timer pulse (funcref or method name).
-- @param delay Delay for the timer, in seconds.
-- @param arg An optional argument to be passed to the callback function.
-- @usage
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("TimerTest", "AceTimer-3.0")
--
-- function MyAddon:OnEnable()
-- self:ScheduleTimer("TimerFeedback", 5)
-- end
--
-- function MyAddon:TimerFeedback()
-- print("5 seconds passed")
-- end
function AceTimer:ScheduleTimer(callback, delay, arg)
return Reg(self, callback, delay, arg)
end
 
--- Schedule a repeating timer.
-- The timer will fire every `delay` seconds, until canceled.
-- @param callback Callback function for the timer pulse (funcref or method name).
-- @param delay Delay for the timer, in seconds.
-- @param arg An optional argument to be passed to the callback function.
-- @usage
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("TimerTest", "AceTimer-3.0")
--
-- function MyAddon:OnEnable()
-- self.timerCount = 0
-- self.testTimer = self:ScheduleRepeatingTimer("TimerFeedback", 5)
-- end
--
-- function MyAddon:TimerFeedback()
-- self.timerCount = self.timerCount + 1
-- print(("%d seconds passed"):format(5 * self.timerCount))
-- -- run 30 seconds in total
-- if self.timerCount == 6 then
-- self:CancelTimer(self.testTimer)
-- end
-- end
function AceTimer:ScheduleRepeatingTimer(callback, delay, arg)
return Reg(self, callback, delay, arg, true)
end
 
--- Cancels a timer with the given handle, registered by the same addon object as used for `:ScheduleTimer`
-- Both one-shot and repeating timers can be canceled with this function, as long as the `handle` is valid
-- and the timer has not fired yet or was canceled before.
-- @param handle The handle of the timer, as returned by `:ScheduleTimer` or `:ScheduleRepeatingTimer`
-- @param silent If true, no error is raised if the timer handle is invalid (expired or already canceled)
-- @return True if the timer was successfully cancelled.
function AceTimer:CancelTimer(handle, silent)
if not handle then return end -- nil handle -> bail out without erroring
if type(handle) ~= "string" then
error(MAJOR..": CancelTimer(handle): 'handle' - expected a string", 2) -- for now, anyway
end
local selftimers = AceTimer.selfs[self]
local timer = selftimers and selftimers[handle]
if silent then
if timer then
timer.callback = nil -- don't run it again
timer.delay = nil -- if this is the currently-executing one: don't even reschedule
-- The timer object is removed in the OnUpdate loop
end
return not not timer -- might return "true" even if we double-cancel. we'll live.
else
if not timer then
geterrorhandler()(MAJOR..": CancelTimer(handle[, silent]): '"..tostring(handle).."' - no such timer registered")
return false
end
if not timer.callback then
geterrorhandler()(MAJOR..": CancelTimer(handle[, silent]): '"..tostring(handle).."' - timer already cancelled or expired")
return false
end
timer.callback = nil -- don't run it again
timer.delay = nil -- if this is the currently-executing one: don't even reschedule
return true
end
end
 
--- Cancels all timers registered to the current addon object ('self')
function AceTimer:CancelAllTimers()
if not(type(self) == "string" or type(self) == "table") then
error(MAJOR..": CancelAllTimers(): 'self' - must be a string or a table",2)
end
if self == AceTimer then
error(MAJOR..": CancelAllTimers(): supply a meaningful 'self'", 2)
end
 
local selftimers = AceTimer.selfs[self]
if selftimers then
for handle,v in pairs(selftimers) do
if type(v) == "table" then -- avoid __ops, etc
AceTimer.CancelTimer(self, handle, true)
end
end
end
end
 
--- Returns the time left for a timer with the given handle, registered by the current addon object ('self').
-- This function will raise a warning when the handle is invalid, but not stop execution.
-- @param handle The handle of the timer, as returned by `:ScheduleTimer` or `:ScheduleRepeatingTimer`
-- @return The time left on the timer, or false if the handle is invalid.
function AceTimer:TimeLeft(handle)
if not handle then return end
if type(handle) ~= "string" then
error(MAJOR..": TimeLeft(handle): 'handle' - expected a string", 2) -- for now, anyway
end
local selftimers = AceTimer.selfs[self]
local timer = selftimers and selftimers[handle]
if not timer then
geterrorhandler()(MAJOR..": TimeLeft(handle): '"..tostring(handle).."' - no such timer registered")
return false
end
return timer.when - GetTime()
end
 
 
-- ---------------------------------------------------------------------
-- PLAYER_REGEN_ENABLED: Run through our .selfs[] array step by step
-- and clean it out - otherwise the table indices can grow indefinitely
-- if an addon starts and stops a lot of timers. AceBucket does this!
--
-- See ACE-94 and tests/AceTimer-3.0-ACE-94.lua
 
local lastCleaned = nil
 
local function OnEvent(this, event)
if event~="PLAYER_REGEN_ENABLED" then
return
end
 
-- Get the next 'self' to process
local selfs = AceTimer.selfs
local self = next(selfs, lastCleaned)
if not self then
self = next(selfs)
end
lastCleaned = self
if not self then -- should only happen if .selfs[] is empty
return
end
 
-- Time to clean it out?
local list = selfs[self]
if (list.__ops or 0) < 250 then -- 250 slosh indices = ~10KB wasted (max!). For one 'self'.
return
end
 
-- Create a new table and copy all members over
local newlist = {}
local n=0
for k,v in pairs(list) do
newlist[k] = v
n=n+1
end
newlist.__ops = 0 -- Reset operation count
 
-- And since we now have a count of the number of live timers, check that it's reasonable. Emit a warning if not.
if n>BUCKETS then
DEFAULT_CHAT_FRAME:AddMessage(MAJOR..": Warning: The addon/module '"..tostring(self).."' has "..n.." live timers. Surely that's not intended?")
end
 
selfs[self] = newlist
end
 
-- ---------------------------------------------------------------------
-- Embed handling
 
AceTimer.embeds = AceTimer.embeds or {}
 
local mixins = {
"ScheduleTimer", "ScheduleRepeatingTimer",
"CancelTimer", "CancelAllTimers",
"TimeLeft"
}
 
function AceTimer:Embed(target)
AceTimer.embeds[target] = true
for _,v in pairs(mixins) do
target[v] = AceTimer[v]
end
return target
end
 
-- AceTimer:OnEmbedDisable( target )
-- target (object) - target object that AceTimer is embedded in.
--
-- cancel all timers registered for the object
function AceTimer:OnEmbedDisable( target )
target:CancelAllTimers()
end
 
 
for addon in pairs(AceTimer.embeds) do
AceTimer:Embed(addon)
end
 
-- ---------------------------------------------------------------------
-- Debug tools (expose copies of internals to test suites)
AceTimer.debug = AceTimer.debug or {}
AceTimer.debug.HZ = HZ
AceTimer.debug.BUCKETS = BUCKETS
 
-- ---------------------------------------------------------------------
-- Finishing touchups
 
AceTimer.frame:SetScript("OnUpdate", OnUpdate)
AceTimer.frame:SetScript("OnEvent", OnEvent)
AceTimer.frame:RegisterEvent("PLAYER_REGEN_ENABLED")
 
-- In theory, we should hide&show the frame based on there being timers or not.
-- However, this job is fairly expensive, and the chance that there will
-- actually be zero timers running is diminuitive to say the lest.
EasyDaily/libs/AceEvent-3.0/AceEvent-3.0.xml New file
0,0 → 1,4
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="AceEvent-3.0.lua"/>
</Ui>
\ No newline at end of file
EasyDaily/libs/AceEvent-3.0/AceEvent-3.0.lua New file
0,0 → 1,125
--- AceEvent-3.0 provides event registration and secure dispatching.
-- All dispatching is done using **CallbackHandler-1.0**. AceEvent is a simple wrapper around
-- CallbackHandler, and dispatches all game events or addon message to the registrees.
--
-- **AceEvent-3.0** can be embeded into your addon, either explicitly by calling AceEvent:Embed(MyAddon) or by
-- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
-- and can be accessed directly, without having to explicitly call AceEvent itself.\\
-- It is recommended to embed AceEvent, otherwise you'll have to specify a custom `self` on all calls you
-- make into AceEvent.
-- @class file
-- @name AceEvent-3.0
-- @release $Id: AceEvent-3.0.lua 766 2009-04-04 08:26:05Z nevcairiel $
local MAJOR, MINOR = "AceEvent-3.0", 3
local AceEvent = LibStub:NewLibrary(MAJOR, MINOR)
 
if not AceEvent then return end
 
local CallbackHandler = LibStub:GetLibrary("CallbackHandler-1.0")
 
 
AceEvent.frame = AceEvent.frame or CreateFrame("Frame", "AceEvent30Frame") -- our event frame
AceEvent.embeds = AceEvent.embeds or {} -- what objects embed this lib
 
 
-- APIs and registry for blizzard events, using CallbackHandler lib
if not AceEvent.events then
AceEvent.events = CallbackHandler:New(AceEvent,
"RegisterEvent", "UnregisterEvent", "UnregisterAllEvents")
end
 
function AceEvent.events:OnUsed(target, eventname)
AceEvent.frame:RegisterEvent(eventname)
end
 
function AceEvent.events:OnUnused(target, eventname)
AceEvent.frame:UnregisterEvent(eventname)
end
 
 
-- APIs and registry for IPC messages, using CallbackHandler lib
if not AceEvent.messages then
AceEvent.messages = CallbackHandler:New(AceEvent,
"RegisterMessage", "UnregisterMessage", "UnregisterAllMessages"
)
AceEvent.SendMessage = AceEvent.messages.Fire
end
 
--- embedding and embed handling
local mixins = {
"RegisterEvent", "UnregisterEvent",
"RegisterMessage", "UnregisterMessage",
"SendMessage",
"UnregisterAllEvents", "UnregisterAllMessages",
}
 
--- Register for a Blizzard Event.
-- The callback will always be called with the event as the first argument, and if supplied, the `arg` as second argument.
-- Any arguments to the event will be passed on after that.
-- @name AceEvent:RegisterEvent
-- @class function
-- @paramsig event[, callback [, arg]]
-- @param event The event to register for
-- @param callback The callback function to call when the event is triggered (funcref or method, defaults to a method with the event name)
-- @param arg An optional argument to pass to the callback function
 
--- Unregister an event.
-- @name AceEvent:UnregisterEvent
-- @class function
-- @paramsig event
-- @param event The event to unregister
 
--- Register for a custom AceEvent-internal message.
-- The callback will always be called with the event as the first argument, and if supplied, the `arg` as second argument.
-- Any arguments to the event will be passed on after that.
-- @name AceEvent:RegisterMessage
-- @class function
-- @paramsig message[, callback [, arg]]
-- @param message The message to register for
-- @param callback The callback function to call when the message is triggered (funcref or method, defaults to a method with the event name)
-- @param arg An optional argument to pass to the callback function
 
--- Unregister a message
-- @name AceEvent:UnregisterMessage
-- @class function
-- @paramsig message
-- @param message The message to unregister
 
--- Send a message over the AceEvent-3.0 internal message system to other addons registered for this message.
-- @name AceEvent:SendMessage
-- @class function
-- @paramsig message, ...
-- @param message The message to send
-- @param ... Any arguments to the message
 
 
-- Embeds AceEvent into the target object making the functions from the mixins list available on target:..
-- @param target target object to embed AceEvent in
function AceEvent:Embed(target)
for k, v in pairs(mixins) do
target[v] = self[v]
end
self.embeds[target] = true
return target
end
 
-- AceEvent:OnEmbedDisable( target )
-- target (object) - target object that is being disabled
--
-- Unregister all events messages etc when the target disables.
-- this method should be called by the target manually or by an addon framework
function AceEvent:OnEmbedDisable(target)
target:UnregisterAllEvents()
target:UnregisterAllMessages()
end
 
-- Script to fire blizzard events into the event listeners
local events = AceEvent.events
AceEvent.frame:SetScript("OnEvent", function(this, event, ...)
events:Fire(event, ...)
end)
 
--- Finally: upgrade our old embeds
for target, v in pairs(AceEvent.embeds) do
AceEvent:Embed(target)
end
EasyDaily/libs/AceGUI-3.0/widgets/AceGUIWidget-SimpleGroup.lua New file
0,0 → 1,97
local AceGUI = LibStub("AceGUI-3.0")
 
 
-------------
-- Widgets --
-------------
--[[
Widgets must provide the following functions
Acquire() - Called when the object is aquired, should set everything to a default hidden state
Release() - Called when the object is Released, should remove any anchors and hide the Widget
 
And the following members
frame - the frame or derivitive object that will be treated as the widget for size and anchoring purposes
type - the type of the object, same as the name given to :RegisterWidget()
 
Widgets contain a table called userdata, this is a safe place to store data associated with the wigdet
It will be cleared automatically when a widget is released
Placing values directly into a widget object should be avoided
 
If the Widget can act as a container for other Widgets the following
content - frame or derivitive that children will be anchored to
 
The Widget can supply the following Optional Members
 
 
]]
 
--------------------------
-- Simple Group --
--------------------------
--[[
This is a simple grouping container, no selection, no borders
It will resize automatically to the height of the controls added to it
]]
 
do
local Type = "SimpleGroup"
local Version = 5
 
local function OnAcquire(self)
self:SetWidth(300)
self:SetHeight(100)
end
 
local function OnRelease(self)
self.frame:ClearAllPoints()
self.frame:Hide()
end
 
local function LayoutFinished(self, width, height)
if self.noAutoHeight then return end
self:SetHeight(height or 0)
end
 
local function OnWidthSet(self, width)
local content = self.content
content:SetWidth(width)
content.width = width
end
 
local function OnHeightSet(self, height)
local content = self.content
content:SetHeight(height)
content.height = height
end
 
local function Constructor()
local frame = CreateFrame("Frame",nil,UIParent)
local self = {}
self.type = Type
 
self.OnRelease = OnRelease
self.OnAcquire = OnAcquire
self.frame = frame
self.LayoutFinished = LayoutFinished
self.OnWidthSet = OnWidthSet
self.OnHeightSet = OnHeightSet
 
frame.obj = self
 
frame:SetHeight(100)
frame:SetWidth(100)
frame:SetFrameStrata("FULLSCREEN_DIALOG")
 
--Container Support
local content = CreateFrame("Frame",nil,frame)
self.content = content
content.obj = self
content:SetPoint("TOPLEFT",frame,"TOPLEFT",0,0)
content:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,0)
 
AceGUI:RegisterAsContainer(self)
return self
end
 
AceGUI:RegisterWidgetType(Type,Constructor,Version)
end
EasyDaily/libs/AceGUI-3.0/widgets/AceGUIWidget-ScrollFrame.lua New file
0,0 → 1,225
local AceGUI = LibStub("AceGUI-3.0")
 
-------------
-- Widgets --
-------------
--[[
Widgets must provide the following functions
Acquire() - Called when the object is aquired, should set everything to a default hidden state
Release() - Called when the object is Released, should remove any anchors and hide the Widget
 
And the following members
frame - the frame or derivitive object that will be treated as the widget for size and anchoring purposes
type - the type of the object, same as the name given to :RegisterWidget()
 
Widgets contain a table called userdata, this is a safe place to store data associated with the wigdet
It will be cleared automatically when a widget is released
Placing values directly into a widget object should be avoided
 
If the Widget can act as a container for other Widgets the following
content - frame or derivitive that children will be anchored to
 
The Widget can supply the following Optional Members
 
 
]]
 
--------------------------
-- Scroll Frame --
--------------------------
do
local Type = "ScrollFrame"
local Version = 4
 
local function OnAcquire(self)
 
end
 
local function OnRelease(self)
self.frame:ClearAllPoints()
self.frame:Hide()
self.status = nil
for k in pairs(self.localstatus) do
self.localstatus[k] = nil
end
end
 
local function SetScroll(self, value)
 
local status = self.status or self.localstatus
 
local frame, child = self.scrollframe, self.content
local viewheight = frame:GetHeight()
local height = child:GetHeight()
local offset
if viewheight > height then
offset = 0
else
offset = floor((height - viewheight) / 1000.0 * value)
end
child:ClearAllPoints()
child:SetPoint("TOPLEFT",frame,"TOPLEFT",0,offset)
child:SetPoint("TOPRIGHT",frame,"TOPRIGHT",0,offset)
status.offset = offset
status.scrollvalue = value
end
 
local function MoveScroll(self, value)
local status = self.status or self.localstatus
local frame, child = self.scrollframe, self.content
local height, viewheight = frame:GetHeight(), child:GetHeight()
if height > viewheight then
self.scrollbar:Hide()
else
self.scrollbar:Show()
local diff = height - viewheight
local delta = 1
if value < 0 then
delta = -1
end
self.scrollbar:SetValue(math.min(math.max(status.scrollvalue + delta*(1000/(diff/45)),0), 1000))
end
end
 
 
local function FixScroll(self)
local status = self.status or self.localstatus
local frame, child = self.scrollframe, self.content
local height, viewheight = frame:GetHeight(), child:GetHeight()
local offset = status.offset
if not offset then
offset = 0
end
local curvalue = self.scrollbar:GetValue()
if viewheight < height then
self.scrollbar:Hide()
self.scrollbar:SetValue(0)
--self.scrollframe:SetPoint("BOTTOMRIGHT",self.frame,"BOTTOMRIGHT",0,0)
else
self.scrollbar:Show()
--self.scrollframe:SetPoint("BOTTOMRIGHT",self.frame,"BOTTOMRIGHT",-16,0)
local value = (offset / (viewheight - height) * 1000)
if value > 1000 then value = 1000 end
self.scrollbar:SetValue(value)
self:SetScroll(value)
if value < 1000 then
child:ClearAllPoints()
child:SetPoint("TOPLEFT",frame,"TOPLEFT",0,offset)
child:SetPoint("TOPRIGHT",frame,"TOPRIGHT",0,offset)
status.offset = offset
end
end
end
 
local function OnMouseWheel(this,value)
this.obj:MoveScroll(value)
end
 
local function OnScrollValueChanged(this, value)
this.obj:SetScroll(value)
end
 
local function FixScrollOnUpdate(this)
this:SetScript("OnUpdate", nil)
this.obj:FixScroll()
end
local function OnSizeChanged(this)
--this:SetScript("OnUpdate", FixScrollOnUpdate)
this.obj:FixScroll()
end
 
local function LayoutFinished(self,width,height)
self.content:SetHeight(height or 0 + 20)
self:FixScroll()
end
 
-- called to set an external table to store status in
local function SetStatusTable(self, status)
assert(type(status) == "table")
self.status = status
if not status.scrollvalue then
status.scrollvalue = 0
end
end
 
 
local createdcount = 0
 
local function OnWidthSet(self, width)
local content = self.content
content.width = width
end
 
 
local function OnHeightSet(self, height)
local content = self.content
content.height = height
end
 
local function Constructor()
local frame = CreateFrame("Frame",nil,UIParent)
local self = {}
self.type = Type
 
self.OnRelease = OnRelease
self.OnAcquire = OnAcquire
 
self.MoveScroll = MoveScroll
self.FixScroll = FixScroll
self.SetScroll = SetScroll
self.LayoutFinished = LayoutFinished
self.SetStatusTable = SetStatusTable
self.OnWidthSet = OnWidthSet
self.OnHeightSet = OnHeightSet
 
self.localstatus = {}
self.frame = frame
frame.obj = self
 
--Container Support
local scrollframe = CreateFrame("ScrollFrame",nil,frame)
local content = CreateFrame("Frame",nil,scrollframe)
createdcount = createdcount + 1
local scrollbar = CreateFrame("Slider",("AceConfigDialogScrollFrame%dScrollBar"):format(createdcount),scrollframe,"UIPanelScrollBarTemplate")
local scrollbg = scrollbar:CreateTexture(nil,"BACKGROUND")
scrollbg:SetAllPoints(scrollbar)
scrollbg:SetTexture(0,0,0,0.4)
self.scrollframe = scrollframe
self.content = content
self.scrollbar = scrollbar
 
scrollbar.obj = self
scrollframe.obj = self
content.obj = self
 
scrollframe:SetScrollChild(content)
scrollframe:SetPoint("TOPLEFT",frame,"TOPLEFT",0,0)
scrollframe:SetPoint("BOTTOMRIGHT",self.frame,"BOTTOMRIGHT",-20,0)
scrollframe:EnableMouseWheel(true)
scrollframe:SetScript("OnMouseWheel", OnMouseWheel)
scrollframe:SetScript("OnSizeChanged", OnSizeChanged)
 
 
content:SetPoint("TOPLEFT",scrollframe,"TOPLEFT",0,0)
content:SetPoint("TOPRIGHT",scrollframe,"TOPRIGHT",0,0)
content:SetHeight(400)
 
scrollbar:SetPoint("TOPLEFT",scrollframe,"TOPRIGHT",4,-16)
scrollbar:SetPoint("BOTTOMLEFT",scrollframe,"BOTTOMRIGHT",4,16)
scrollbar:SetScript("OnValueChanged", OnScrollValueChanged)
scrollbar:SetMinMaxValues(0,1000)
scrollbar:SetValueStep(1)
scrollbar:SetValue(0)
scrollbar:SetWidth(16)
 
self.localstatus.scrollvalue = 0
 
 
self:FixScroll()
AceGUI:RegisterAsContainer(self)
--AceGUI:RegisterAsWidget(self)
return self
end
 
AceGUI:RegisterWidgetType(Type,Constructor,Version)
end
EasyDaily/libs/AceGUI-3.0/widgets/AceGUIWidget-DropDownGroup.lua New file
0,0 → 1,168
local AceGUI = LibStub("AceGUI-3.0")
 
--[[
Selection Group controls all have an interface to select a group for thier contents
None of them will auto size to thier contents, and should usually be used with a scrollframe
unless you know that the controls will fit inside
]]
 
--------------------------
-- Dropdown Group --
--------------------------
--[[
Events :
OnGroupSelected
 
]]
do
local Type = "DropdownGroup"
local Version = 11
 
local function OnAcquire(self)
self.dropdown:SetText("")
self:SetDropdownWidth(200)
end
 
local function OnRelease(self)
self.frame:ClearAllPoints()
self.frame:Hide()
self.dropdown.list = nil
self.status = nil
for k in pairs(self.localstatus) do
self.localstatus[k] = nil
end
end
 
local PaneBackdrop = {
bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
tile = true, tileSize = 16, edgeSize = 16,
insets = { left = 3, right = 3, top = 5, bottom = 3 }
}
 
local function SetTitle(self,title)
self.titletext:SetText(title)
end
 
 
local function SelectedGroup(self,event,value)
local group = self.parentgroup
local status = group.status or group.localstatus
status.selected = value
self.parentgroup:Fire("OnGroupSelected", value)
end
 
local function SetGroupList(self,list)
self.dropdown:SetList(list)
end
 
-- called to set an external table to store status in
local function SetStatusTable(self, status)
assert(type(status) == "table")
self.status = status
end
 
local function SetGroup(self,group)
self.dropdown:SetValue(group)
local status = self.status or self.localstatus
status.selected = group
self:Fire("OnGroupSelected", group)
end
 
local function OnWidthSet(self, width)
local content = self.content
local contentwidth = width - 26
if contentwidth < 0 then
contentwidth = 0
end
content:SetWidth(contentwidth)
content.width = contentwidth
end
 
 
local function OnHeightSet(self, height)
local content = self.content
local contentheight = height - 63
if contentheight < 0 then
contentheight = 0
end
content:SetHeight(contentheight)
content.height = contentheight
end
 
local function LayoutFinished(self, width, height)
self:SetHeight((height or 0) + 63)
end
 
local function SetDropdownWidth(self, width)
self.dropdown:SetWidth(width)
end
 
local function Constructor()
local frame = CreateFrame("Frame")
local self = {}
self.type = Type
 
self.OnRelease = OnRelease
self.OnAcquire = OnAcquire
 
self.SetTitle = SetTitle
self.SetGroupList = SetGroupList
self.SetGroup = SetGroup
self.SetStatusTable = SetStatusTable
self.SetDropdownWidth = SetDropdownWidth
self.OnWidthSet = OnWidthSet
self.OnHeightSet = OnHeightSet
self.LayoutFinished = LayoutFinished
 
self.localstatus = {}
 
self.frame = frame
frame.obj = self
 
 
frame:SetHeight(100)
frame:SetWidth(100)
frame:SetFrameStrata("FULLSCREEN_DIALOG")
 
local titletext = frame:CreateFontString(nil,"OVERLAY","GameFontNormal")
titletext:SetPoint("TOPLEFT",frame,"TOPLEFT",4,0)
titletext:SetPoint("TOPRIGHT",frame,"TOPRIGHT",-4,0)
titletext:SetJustifyH("LEFT")
titletext:SetHeight(18)
 
 
self.titletext = titletext
 
local dropdown = AceGUI:Create("Dropdown")
self.dropdown = dropdown
dropdown.frame:SetParent(frame)
dropdown.parentgroup = self
dropdown:SetCallback("OnValueChanged",SelectedGroup)
 
dropdown.frame:SetPoint("TOPLEFT",titletext,"BOTTOMLEFT",-3,3)
dropdown.frame:Show()
dropdown:SetLabel("")
 
local border = CreateFrame("Frame",nil,frame)
self.border = border
border:SetPoint("TOPLEFT",frame,"TOPLEFT",3,-40)
border:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-3,3)
 
border:SetBackdrop(PaneBackdrop)
border:SetBackdropColor(0.1,0.1,0.1,0.5)
border:SetBackdropBorderColor(0.4,0.4,0.4)
 
--Container Support
local content = CreateFrame("Frame",nil,border)
self.content = content
content.obj = self
content:SetPoint("TOPLEFT",border,"TOPLEFT",10,-10)
content:SetPoint("BOTTOMRIGHT",border,"BOTTOMRIGHT",-10,10)
 
AceGUI:RegisterAsContainer(self)
return self
end
 
AceGUI:RegisterWidgetType(Type,Constructor,Version)
end
EasyDaily/libs/AceGUI-3.0/widgets/AceGUIWidget-Button.lua New file
0,0 → 1,100
local AceGUI = LibStub("AceGUI-3.0")
 
--------------------------
-- Button --
--------------------------
do
local Type = "Button"
local Version = 10
 
local function OnAcquire(self)
-- restore default values
self:SetHeight(24)
self:SetWidth(200)
end
 
local function OnRelease(self)
self.frame:ClearAllPoints()
self.frame:Hide()
self:SetDisabled(false)
end
 
local function Button_OnClick(this)
this.obj:Fire("OnClick")
AceGUI:ClearFocus()
end
 
local function Button_OnEnter(this)
this.obj:Fire("OnEnter")
end
 
local function Button_OnLeave(this)
this.obj:Fire("OnLeave")
end
 
local function SetText(self, text)
self.text:SetText(text or "")
end
 
local function SetDisabled(self, disabled)
self.disabled = disabled
if disabled then
self.frame:Disable()
else
self.frame:Enable()
end
end
 
local function Constructor()
local num = AceGUI:GetNextWidgetNum(Type)
local name = "AceGUI30Button"..num
local frame = CreateFrame("Button",name,UIParent,"UIPanelButtonTemplate2")
local self = {}
self.num = num
self.type = Type
self.frame = frame
 
local left = _G[name .. "Left"]
local right = _G[name .. "Right"]
local middle = _G[name .. "Middle"]
 
left:SetPoint("TOP", frame, "TOP", 0, -1)
left:SetPoint("BOTTOM", frame, "BOTTOM", 0, 1)
 
right:SetPoint("TOP", frame, "TOP", 0, -1)
right:SetPoint("BOTTOM", frame, "BOTTOM", 0, 1)
 
middle:SetPoint("TOP", frame, "TOP", 0, -1)
middle:SetPoint("BOTTOM", frame, "BOTTOM", 0, 1)
 
local text = frame:GetFontString()
self.text = text
text:ClearAllPoints()
text:SetPoint("TOPLEFT",frame,"TOPLEFT", 15, -1)
text:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT", -15, 1)
text:SetJustifyV("MIDDLE")
 
frame:SetScript("OnClick",Button_OnClick)
frame:SetScript("OnEnter",Button_OnEnter)
frame:SetScript("OnLeave",Button_OnLeave)
 
self.SetText = SetText
self.SetDisabled = SetDisabled
 
frame:EnableMouse(true)
 
frame:SetHeight(24)
frame:SetWidth(200)
 
self.OnRelease = OnRelease
self.OnAcquire = OnAcquire
 
self.frame = frame
frame.obj = self
 
AceGUI:RegisterAsWidget(self)
return self
end
 
AceGUI:RegisterWidgetType(Type,Constructor,Version)
end
EasyDaily/libs/AceGUI-3.0/widgets/AceGUIWidget-DropDown-Items.lua New file
0,0 → 1,453
--[[ $Id: AceGUIWidget-DropDown-Items.lua 656 2008-05-31 11:47:08Z nargiddley $ ]]--
 
local AceGUI = LibStub("AceGUI-3.0")
 
local function fixlevels(parent,...)
local i = 1
local child = select(i, ...)
while child do
child:SetFrameLevel(parent:GetFrameLevel()+1)
fixlevels(child, child:GetChildren())
i = i + 1
child = select(i, ...)
end
end
 
local function fixstrata(strata, parent, ...)
local i = 1
local child = select(i, ...)
parent:SetFrameStrata(strata)
while child do
fixstrata(strata, child, child:GetChildren())
i = i + 1
child = select(i, ...)
end
end
 
-- ItemBase is the base "class" for all dropdown items.
-- Each item has to use ItemBase.Create(widgetType) to
-- create an initial 'self' value.
-- ItemBase will add common functions and ui event handlers.
-- Be sure to keep basic usage when you override functions.
 
local ItemBase = {
-- NOTE: The ItemBase version is added to each item's version number
-- to ensure proper updates on ItemBase changes.
-- Use at least 1000er steps.
version = 1000,
counter = 0,
}
 
function ItemBase.Frame_OnEnter(this)
local self = this.obj
 
if self.useHighlight then
self.highlight:Show()
end
self:Fire("OnEnter")
 
if self.specialOnEnter then
self.specialOnEnter(self)
end
end
 
function ItemBase.Frame_OnLeave(this)
local self = this.obj
 
self.highlight:Hide()
self:Fire("OnLeave")
 
if self.specialOnLeave then
self.specialOnLeave(self)
end
end
 
-- exported, AceGUI callback
function ItemBase.OnAcquire(self)
self.frame:SetToplevel(true)
self.frame:SetFrameStrata("FULLSCREEN_DIALOG")
end
 
-- exported, AceGUI callback
function ItemBase.OnRelease(self)
self:SetDisabled(false)
self.pullout = nil
self.frame:SetParent(nil)
self.frame:ClearAllPoints()
self.frame:Hide()
end
 
-- exported
-- NOTE: this is called by a Dropdown-Pullout.
-- Do not call this method directly
function ItemBase.SetPullout(self, pullout)
self.pullout = pullout
 
self.frame:SetParent(nil)
self.frame:SetParent(pullout.itemFrame)
self.parent = pullout.itemFrame
fixlevels(pullout.itemFrame, pullout.itemFrame:GetChildren())
end
 
-- exported
function ItemBase.SetText(self, text)
self.text:SetText(text or "")
end
 
-- exported
function ItemBase.GetText(self)
return self.text:GetText()
end
 
-- exported
function ItemBase.SetPoint(self, ...)
self.frame:SetPoint(...)
end
 
-- exported
function ItemBase.Show(self)
self.frame:Show()
end
 
-- exported
function ItemBase.Hide(self)
self.frame:Hide()
end
 
-- exported
function ItemBase.SetDisabled(self, disabled)
self.disabled = disabled
if disabled then
self.useHighlight = false
self.text:SetTextColor(.5, .5, .5)
else
self.useHighlight = true
self.text:SetTextColor(1, 1, 1)
end
end
 
-- exported
-- NOTE: this is called by a Dropdown-Pullout.
-- Do not call this method directly
function ItemBase.SetOnLeave(self, func)
self.specialOnLeave = func
end
 
-- exported
-- NOTE: this is called by a Dropdown-Pullout.
-- Do not call this method directly
function ItemBase.SetOnEnter(self, func)
self.specialOnEnter = func
end
 
function ItemBase.Create(type)
-- NOTE: Most of the following code is copied from AceGUI-3.0/Dropdown widget
local count = AceGUI:GetNextWidgetNum(type)
local frame = CreateFrame("Button", "AceGUI30DropDownItem"..count)
local self = {}
self.frame = frame
frame.obj = self
self.type = type
 
self.useHighlight = true
 
frame:SetHeight(17)
frame:SetFrameStrata("FULLSCREEN_DIALOG")
 
local text = frame:CreateFontString(nil,"OVERLAY","GameFontNormalSmall")
text:SetTextColor(1,1,1)
text:SetJustifyH("LEFT")
text:SetPoint("TOPLEFT",frame,"TOPLEFT",18,0)
text:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-8,0)
self.text = text
 
local highlight = frame:CreateTexture(nil, "OVERLAY")
highlight:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight")
highlight:SetBlendMode("ADD")
highlight:SetHeight(14)
highlight:ClearAllPoints()
highlight:SetPoint("RIGHT",frame,"RIGHT",-3,0)
highlight:SetPoint("LEFT",frame,"LEFT",5,0)
highlight:Hide()
self.highlight = highlight
 
local check = frame:CreateTexture("OVERLAY")
check:SetWidth(16)
check:SetHeight(16)
check:SetPoint("LEFT",frame,"LEFT",3,-1)
check:SetTexture("Interface\\Buttons\\UI-CheckBox-Check")
check:Hide()
self.check = check
 
local sub = frame:CreateTexture("OVERLAY")
sub:SetWidth(16)
sub:SetHeight(16)
sub:SetPoint("RIGHT",frame,"RIGHT",-3,-1)
sub:SetTexture("Interface\\ChatFrame\\ChatFrameExpandArrow")
sub:Hide()
self.sub = sub
 
frame:SetScript("OnEnter", ItemBase.Frame_OnEnter)
frame:SetScript("OnLeave", ItemBase.Frame_OnLeave)
 
self.OnAcquire = ItemBase.OnAcquire
self.OnRelease = ItemBase.OnRelease
 
self.SetPullout = ItemBase.SetPullout
self.GetText = ItemBase.GetText
self.SetText = ItemBase.SetText
self.SetDisabled = ItemBase.SetDisabled
 
self.SetPoint = ItemBase.SetPoint
self.Show = ItemBase.Show
self.Hide = ItemBase.Hide
 
self.SetOnLeave = ItemBase.SetOnLeave
self.SetOnEnter = ItemBase.SetOnEnter
 
return self
end
 
--[[
Template for items:
 
-- Item:
--
do
local widgetType = "Dropdown-Item-"
local widgetVersion = 1
 
local function Constructor()
local self = ItemBase.Create(widgetType)
 
AceGUI:RegisterAsWidget(self)
return self
end
 
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version)
end
--]]
 
-- Item: Header
-- A single text entry.
-- Special: Different text color and no highlight
do
local widgetType = "Dropdown-Item-Header"
local widgetVersion = 1
 
local function OnEnter(this)
local self = this.obj
self:Fire("OnEnter")
 
if self.specialOnEnter then
self.specialOnEnter(self)
end
end
 
local function OnLeave(this)
local self = this.obj
self:Fire("OnLeave")
 
if self.specialOnLeave then
self.specialOnLeave(self)
end
end
 
-- exported, override
local function SetDisabled(self, disabled)
ItemBase.SetDisabled(self, disabled)
if not disabled then
self.text:SetTextColor(1, 1, 0)
end
end
 
local function Constructor()
local self = ItemBase.Create(widgetType)
 
self.SetDisabled = SetDisabled
 
self.frame:SetScript("OnEnter", OnEnter)
self.frame:SetScript("OnLeave", OnLeave)
 
self.text:SetTextColor(1, 1, 0)
 
AceGUI:RegisterAsWidget(self)
return self
end
 
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version)
end
 
-- Item: Execute
-- A simple button
do
local widgetType = "Dropdown-Item-Execute"
local widgetVersion = 1
 
local function Frame_OnClick(this, button)
local self = this.obj
if self.disabled then return end
self:Fire("OnClick")
if self.pullout then
self.pullout:Close()
end
end
 
local function Constructor()
local self = ItemBase.Create(widgetType)
 
self.frame:SetScript("OnClick", Frame_OnClick)
 
AceGUI:RegisterAsWidget(self)
return self
end
 
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version)
end
 
-- Item: Toggle
-- Some sort of checkbox for dropdown menus.
-- Does not close the pullout on click.
do
local widgetType = "Dropdown-Item-Toggle"
local widgetVersion = 2
 
local function UpdateToggle(self)
if self.value then
self.check:Show()
else
self.check:Hide()
end
end
 
local function OnRelease(self)
ItemBase.OnRelease(self)
self:SetValue(nil)
end
 
local function Frame_OnClick(this, button)
local self = this.obj
if self.disabled then return end
self.value = not self.value
UpdateToggle(self)
self:Fire("OnValueChanged", self.value)
end
 
-- exported
local function SetValue(self, value)
self.value = value
UpdateToggle(self)
end
 
-- exported
local function GetValue(self)
return self.value
end
 
local function Constructor()
local self = ItemBase.Create(widgetType)
 
self.frame:SetScript("OnClick", Frame_OnClick)
 
self.SetValue = SetValue
self.GetValue = GetValue
self.OnRelease = OnRelease
 
AceGUI:RegisterAsWidget(self)
return self
end
 
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version)
end
 
-- Item: Menu
-- Shows a submenu on mouse over
-- Does not close the pullout on click
do
local widgetType = "Dropdown-Item-Menu"
local widgetVersion = 1
 
local function OnEnter(this)
local self = this.obj
self:Fire("OnEnter")
 
if self.specialOnEnter then
self.specialOnEnter(self)
end
 
self.highlight:Show()
 
if not self.disabled and self.submenu then
self.submenu:Open("TOPLEFT", self.frame, "TOPRIGHT", self.pullout:GetRightBorderWidth(), 0, self.frame:GetFrameLevel() + 100)
end
end
 
local function OnHide(this)
local self = this.obj
if self.submenu then
self.submenu:Close()
end
end
 
-- exported
function SetMenu(self, menu)
assert(menu.type == "Dropdown-Pullout")
self.submenu = menu
end
 
-- exported
function CloseMenu(self)
self.submenu:Close()
end
 
local function Constructor()
local self = ItemBase.Create(widgetType)
 
self.sub:Show()
 
self.frame:SetScript("OnEnter", OnEnter)
self.frame:SetScript("OnHide", OnHide)
 
self.SetMenu = SetMenu
self.CloseMenu = CloseMenu
 
AceGUI:RegisterAsWidget(self)
return self
end
 
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version)
end
 
-- Item: Separator
-- A single line to separate items
do
local widgetType = "Dropdown-Item-Separator"
local widgetVersion = 1
 
-- exported, override
local function SetDisabled(self, disabled)
ItemBase.SetDisabled(self, disabled)
self.useHighlight = false
end
 
local function Constructor()
local self = ItemBase.Create(widgetType)
 
self.SetDisabled = SetDisabled
 
local line = self.frame:CreateTexture(nil, "OVERLAY")
line:SetHeight(1)
line:SetTexture(.5, .5, .5)
line:SetPoint("LEFT", self.frame, "LEFT", 10, 0)
line:SetPoint("RIGHT", self.frame, "RIGHT", -10, 0)
 
self.text:Hide()
 
self.useHighlight = false
 
AceGUI:RegisterAsWidget(self)
return self
end
 
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version)
end
EasyDaily/libs/AceGUI-3.0/widgets/AceGUIWidget-TreeGroup.lua New file
0,0 → 1,715
local AceGUI = LibStub("AceGUI-3.0")
 
-- Recycling functions
local new, del
do
local pool = setmetatable({},{__mode='k'})
function new()
local t = next(pool)
if t then
pool[t] = nil
return t
else
return {}
end
end
function del(t)
for k in pairs(t) do
t[k] = nil
end
pool[t] = true
end
end
 
--------------
-- TreeView --
--------------
 
do
local Type = "TreeGroup"
local Version = 20
 
local DEFAULT_TREE_WIDTH = 175
local DEFAULT_TREE_SIZABLE = true
 
local PaneBackdrop = {
bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
tile = true, tileSize = 16, edgeSize = 16,
insets = { left = 3, right = 3, top = 5, bottom = 3 }
}
 
local DraggerBackdrop = {
bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
edgeFile = nil,
tile = true, tileSize = 16, edgeSize = 0,
insets = { left = 3, right = 3, top = 7, bottom = 7 }
}
 
local function OnAcquire(self)
self:SetTreeWidth(DEFAULT_TREE_WIDTH,DEFAULT_TREE_SIZABLE)
self:EnableButtonTooltips(true)
end
 
local function OnRelease(self)
 
self.frame:ClearAllPoints()
self.frame:Hide()
self.status = nil
for k, v in pairs(self.localstatus) do
if k == "groups" then
for k2 in pairs(v) do
v[k2] = nil
end
else
self.localstatus[k] = nil
end
end
self.localstatus.scrollvalue = 0
self.localstatus.treewidth = DEFAULT_TREE_WIDTH
self.localstatus.treesizable = DEFAULT_TREE_SIZABLE
end
 
local function GetButtonParents(line)
local parent = line.parent
if parent and parent.value then
return parent.value, GetButtonParents(parent)
end
end
 
local function GetButtonUniqueValue(line)
local parent = line.parent
if parent and parent.value then
return GetButtonUniqueValue(parent).."\001"..line.value
else
return line.value
end
end
 
local function ButtonOnClick(this)
local self = this.obj
self:Fire("OnClick",this.uniquevalue, this.selected)
if not this.selected then
self:SetSelected(this.uniquevalue)
this.selected = true
this:LockHighlight()
self:RefreshTree()
end
AceGUI:ClearFocus()
end
 
local function ExpandOnClick(this)
local button = this.button
local self = button.obj
local status = (self.status or self.localstatus).groups
status[button.uniquevalue] = not status[button.uniquevalue]
self:RefreshTree()
end
 
local function ButtonOnDoubleClick(button)
local self = button.obj
local status = self.status or self.localstatus
local status = (self.status or self.localstatus).groups
status[button.uniquevalue] = not status[button.uniquevalue]
self:RefreshTree()
end
 
local function EnableButtonTooltips(self, enable)
self.enabletooltips = enable
end
 
local function Button_OnEnter(this)
local self = this.obj
self:Fire("OnButtonEnter", this.uniquevalue, this)
 
if self.enabletooltips then
GameTooltip:SetOwner(this, "ANCHOR_NONE")
GameTooltip:SetPoint("LEFT",this,"RIGHT")
GameTooltip:SetText(this.text:GetText() or "", 1, .82, 0, 1)
 
GameTooltip:Show()
end
end
 
local function Button_OnLeave(this)
local self = this.obj
self:Fire("OnButtonLeave", this.uniquevalue, this)
 
if self.enabletooltips then
GameTooltip:Hide()
end
end
 
 
local buttoncount = 1
local function CreateButton(self)
local button = CreateFrame("Button",("AceGUI30TreeButton%d"):format(buttoncount),self.treeframe, "OptionsListButtonTemplate")
buttoncount = buttoncount + 1
button.obj = self
 
local icon = button:CreateTexture(nil, "OVERLAY")
icon:SetWidth(14)
icon:SetHeight(14)
button.icon = icon
 
button:SetScript("OnClick",ButtonOnClick)
button:SetScript("OnDoubleClick", ButtonOnDoubleClick)
button:SetScript("OnEnter",Button_OnEnter)
button:SetScript("OnLeave",Button_OnLeave)
 
button.toggle.button = button
button.toggle:SetScript("OnClick",ExpandOnClick)
 
return button
end
 
local function UpdateButton(button, treeline, selected, canExpand, isExpanded)
local self = button.obj
local toggle = button.toggle
local frame = self.frame
local text = treeline.text or ""
local icon = treeline.icon
local level = treeline.level
local value = treeline.value
local uniquevalue = treeline.uniquevalue
local disabled = treeline.disabled
 
button.treeline = treeline
button.value = value
button.uniquevalue = uniquevalue
if selected then
button:LockHighlight()
button.selected = true
else
button:UnlockHighlight()
button.selected = false
end
local normalTexture = button:GetNormalTexture()
local line = button.line
button.level = level
if ( level == 1 ) then
button:SetNormalFontObject("GameFontNormal")
button:SetHighlightFontObject("GameFontHighlight")
button.text:SetPoint("LEFT", (icon and 16 or 0) + 8, 2)
else
button:SetNormalFontObject("GameFontHighlightSmall")
button:SetHighlightFontObject("GameFontHighlightSmall")
button.text:SetPoint("LEFT", (icon and 16 or 0) + 8 * level, 2)
end
 
if disabled then
button:EnableMouse(false)
button.text:SetText("|cff808080"..text..FONT_COLOR_CODE_CLOSE)
else
button.text:SetText(text)
button:EnableMouse(true)
end
 
if icon then
button.icon:SetTexture(icon)
button.icon:SetPoint("LEFT", button, "LEFT", 8 * level, (level == 1) and 0 or 1)
else
button.icon:SetTexture(nil)
end
 
if canExpand then
if not isExpanded then
toggle:SetNormalTexture("Interface\\Buttons\\UI-PlusButton-UP")
toggle:SetPushedTexture("Interface\\Buttons\\UI-PlusButton-DOWN")
else
toggle:SetNormalTexture("Interface\\Buttons\\UI-MinusButton-UP")
toggle:SetPushedTexture("Interface\\Buttons\\UI-MinusButton-DOWN")
end
toggle:Show()
else
toggle:Hide()
end
end
 
 
local function OnScrollValueChanged(this, value)
if this.obj.noupdate then return end
local self = this.obj
local status = self.status or self.localstatus
status.scrollvalue = value
self:RefreshTree()
AceGUI:ClearFocus()
end
 
-- called to set an external table to store status in
local function SetStatusTable(self, status)
assert(type(status) == "table")
self.status = status
if not status.groups then
status.groups = {}
end
if not status.scrollvalue then
status.scrollvalue = 0
end
if not status.treewidth then
status.treewidth = DEFAULT_TREE_WIDTH
end
if not status.treesizable then
status.treesizable = DEFAULT_TREE_SIZABLE
end
self:SetTreeWidth(status.treewidth,status.treesizable)
self:RefreshTree()
end
 
--sets the tree to be displayed
--[[
example tree
 
Alpha
Bravo
-Charlie
-Delta
-Echo
Foxtrot
 
tree = {
{
value = "A",
text = "Alpha"
},
{
value = "B",
text = "Bravo",
children = {
{
value = "C",
text = "Charlie"
},
{
value = "D",
text = "Delta"
children = {
{
value = "E",
text = "Echo"
}
}
}
}
},
{
value = "F",
text = "Foxtrot"
},
}
]]
local function SetTree(self, tree, filter)
self.filter = filter
if tree then
assert(type(tree) == "table")
end
self.tree = tree
self:RefreshTree()
end
 
local function ShouldDisplayLevel(tree)
local result = false
for k, v in ipairs(tree) do
if v.children == nil and v.visible ~= false then
result = true
elseif v.children then
result = result or ShouldDisplayLevel(v.children)
end
if result then return result end
end
return false
end
 
local function addLine(self, v, tree, level, parent)
local line = new()
line.value = v.value
line.text = v.text
line.icon = v.icon
line.disabled = v.disabled
line.tree = tree
line.level = level
line.parent = parent
line.visible = v.visible
line.uniquevalue = GetButtonUniqueValue(line)
if v.children then
line.hasChildren = true
else
line.hasChildren = nil
end
self.lines[#self.lines+1] = line
return line
end
 
local function BuildLevel(self, tree, level, parent)
local groups = (self.status or self.localstatus).groups
local hasChildren = self.hasChildren
 
for i, v in ipairs(tree) do
if v.children then
if not self.filter or ShouldDisplayLevel(v.children) then
local line = addLine(self, v, tree, level, parent)
if groups[line.uniquevalue] then
self:BuildLevel(v.children, level+1, line)
end
end
elseif v.visible ~= false or not self.filter then
addLine(self, v, tree, level, parent)
end
end
end
 
--fire an update after one frame to catch the treeframes height
local function FirstFrameUpdate(this)
local self = this.obj
this:SetScript("OnUpdate",nil)
self:RefreshTree()
end
 
local function ResizeUpdate(this)
this.obj:RefreshTree()
end
 
local function RefreshTree(self)
local buttons = self.buttons
local lines = self.lines
 
for i, v in ipairs(buttons) do
v:Hide()
end
while lines[1] do
local t = tremove(lines)
for k in pairs(t) do
t[k] = nil
end
del(t)
end
 
if not self.tree then return end
--Build the list of visible entries from the tree and status tables
local status = self.status or self.localstatus
local groupstatus = status.groups
local tree = self.tree
 
local treeframe = self.treeframe
 
self:BuildLevel(tree, 1)
 
local numlines = #lines
 
local maxlines = (math.floor(((self.treeframe:GetHeight()or 0) - 20 ) / 18))
 
local first, last
 
if numlines <= maxlines then
--the whole tree fits in the frame
status.scrollvalue = 0
self:ShowScroll(false)
first, last = 1, numlines
else
self:ShowScroll(true)
--scrolling will be needed
self.noupdate = true
self.scrollbar:SetMinMaxValues(0, numlines - maxlines)
--check if we are scrolled down too far
if numlines - status.scrollvalue < maxlines then
status.scrollvalue = numlines - maxlines
self.scrollbar:SetValue(status.scrollvalue)
end
self.noupdate = nil
first, last = status.scrollvalue+1, status.scrollvalue + maxlines
end
 
local buttonnum = 1
for i = first, last do
local line = lines[i]
local button = buttons[buttonnum]
if not button then
button = self:CreateButton()
 
buttons[buttonnum] = button
button:SetParent(treeframe)
button:SetFrameLevel(treeframe:GetFrameLevel()+1)
button:ClearAllPoints()
if i == 1 then
if self.showscroll then
button:SetPoint("TOPRIGHT", self.treeframe,"TOPRIGHT",-22,-10)
button:SetPoint("TOPLEFT", self.treeframe, "TOPLEFT", 0, -10)
else
button:SetPoint("TOPRIGHT", self.treeframe,"TOPRIGHT",0,-10)
button:SetPoint("TOPLEFT", self.treeframe, "TOPLEFT", 0, -10)
end
else
button:SetPoint("TOPRIGHT", buttons[buttonnum-1], "BOTTOMRIGHT",0,0)
button:SetPoint("TOPLEFT", buttons[buttonnum-1], "BOTTOMLEFT",0,0)
end
end
 
UpdateButton(button, line, status.selected == line.uniquevalue, line.hasChildren, groupstatus[line.uniquevalue] )
button:Show()
buttonnum = buttonnum + 1
end
 
end
 
local function SetSelected(self, value)
local status = self.status or self.localstatus
if status.selected ~= value then
status.selected = value
self:Fire("OnGroupSelected", value)
end
end
 
local function BuildUniqueValue(...)
local n = select('#', ...)
if n == 1 then
return ...
else
return (...).."\001"..BuildUniqueValue(select(2,...))
end
end
 
local function Select(self, uniquevalue, ...)
self.filter = false
local status = self.status or self.localstatus
local groups = status.groups
for i = 1, select('#', ...) do
groups[BuildUniqueValue(select(i, ...))] = true
end
status.selected = uniquevalue
self:RefreshTree()
self:Fire("OnGroupSelected", uniquevalue)
end
 
local function SelectByPath(self, ...)
self:Select(BuildUniqueValue(...), ...)
end
 
--Selects a tree node by UniqueValue
local function SelectByValue(self, uniquevalue)
self:Select(uniquevalue,string.split("\001", uniquevalue))
end
 
 
local function ShowScroll(self, show)
self.showscroll = show
if show then
self.scrollbar:Show()
if self.buttons[1] then
self.buttons[1]:SetPoint("TOPRIGHT", self.treeframe,"TOPRIGHT",-22,-10)
end
else
self.scrollbar:Hide()
if self.buttons[1] then
self.buttons[1]:SetPoint("TOPRIGHT", self.treeframe,"TOPRIGHT",0,-10)
end
end
end
 
local function OnWidthSet(self, width)
local content = self.content
local treeframe = self.treeframe
local status = self.status or self.localstatus
 
local contentwidth = width - status.treewidth - 20
if contentwidth < 0 then
contentwidth = 0
end
content:SetWidth(contentwidth)
content.width = contentwidth
 
local maxtreewidth = math.min(400, width - 50)
 
if maxtreewidth > 100 and status.treewidth > maxtreewidth then
self:SetTreeWidth(maxtreewidth, status.treesizable)
end
treeframe:SetMaxResize(maxtreewidth,1600)
end
 
 
local function OnHeightSet(self, height)
local content = self.content
local contentheight = height - 20
if contentheight < 0 then
contentheight = 0
end
content:SetHeight(contentheight)
content.height = contentheight
end
 
 
local function TreeOnMouseWheel(this, delta)
local self = this.obj
if self.showscroll then
local scrollbar = self.scrollbar
local min, max = scrollbar:GetMinMaxValues()
local value = scrollbar:GetValue()
local newvalue = math.min(max,math.max(min,value - delta))
if value ~= newvalue then
scrollbar:SetValue(newvalue)
end
end
end
 
local function SetTreeWidth(self, treewidth, resizable)
if not resizable then
if type(treewidth) == 'number' then
resizable = false
elseif type(treewidth) == 'boolean' then
resizable = treewidth
treewidth = DEFAULT_TREE_WIDTH
else
resizable = false
treewidth = DEFAULT_TREE_WIDTH
end
end
self.treeframe:SetWidth(treewidth)
self.dragger:EnableMouse(resizable)
 
local status = self.status or self.localstatus
status.treewidth = treewidth
status.treesizable = resizable
end
 
local function draggerLeave(this)
this:SetBackdropColor(1, 1, 1, 0)
end
 
local function draggerEnter(this)
this:SetBackdropColor(1, 1, 1, 0.8)
end
 
local function draggerDown(this)
local treeframe = this:GetParent()
treeframe:StartSizing("RIGHT")
end
 
local function draggerUp(this)
local treeframe = this:GetParent()
local self = treeframe.obj
local frame = treeframe:GetParent()
treeframe:StopMovingOrSizing()
--treeframe:SetScript("OnUpdate", nil)
treeframe:SetUserPlaced(false)
--Without this :GetHeight will get stuck on the current height, causing the tree contents to not resize
treeframe:SetHeight(0)
treeframe:SetPoint("TOPLEFT",frame,"TOPLEFT",0,0)
treeframe:SetPoint("BOTTOMLEFT",frame,"BOTTOMLEFT",0,0)
treeframe.obj:Fire("OnTreeResize",treeframe:GetWidth())
 
local status = self.status or self.localstatus
status.treewidth = treeframe:GetWidth()
end
 
local function LayoutFinished(self, width, height)
if self.noAutoHeight then return end
self:SetHeight((height or 0) + 20)
end
 
local createdcount = 0
local function Constructor()
local frame = CreateFrame("Frame",nil,UIParent)
local self = {}
self.type = Type
self.lines = {}
self.levels = {}
self.buttons = {}
self.hasChildren = {}
self.localstatus = {}
self.localstatus.groups = {}
self.filter = false
 
local treeframe = CreateFrame("Frame",nil,frame)
treeframe.obj = self
treeframe:SetPoint("TOPLEFT",frame,"TOPLEFT",0,0)
treeframe:SetPoint("BOTTOMLEFT",frame,"BOTTOMLEFT",0,0)
treeframe:SetWidth(DEFAULT_TREE_WIDTH)
treeframe:SetScript("OnUpdate",FirstFrameUpdate)
treeframe:SetScript("OnSizeChanged",ResizeUpdate)
 
treeframe:EnableMouseWheel(true)
treeframe:SetScript("OnMouseWheel", TreeOnMouseWheel)
treeframe:SetBackdrop(PaneBackdrop)
treeframe:SetBackdropColor(0.1,0.1,0.1,0.5)
treeframe:SetBackdropBorderColor(0.4,0.4,0.4)
 
treeframe:SetResizable(true)
treeframe:SetMinResize(100, 1)
treeframe:SetMaxResize(400,1600)
local dragger = CreateFrame("Frame", nil, treeframe)
dragger:SetWidth(8)
dragger:SetPoint("TOP", treeframe, "TOPRIGHT")
dragger:SetPoint("BOTTOM", treeframe, "BOTTOMRIGHT")
dragger:SetBackdrop(DraggerBackdrop)
dragger:SetBackdropColor(1, 1, 1, 0)
dragger:SetScript("OnMouseDown", draggerDown)
dragger:SetScript("OnMouseUp", draggerUp)
dragger:SetScript("OnEnter", draggerEnter)
dragger:SetScript("OnLeave", draggerLeave)
 
self.dragger = dragger
self.treeframe = treeframe
self.OnRelease = OnRelease
self.OnAcquire = OnAcquire
 
self.SetTree = SetTree
self.SetTreeWidth = SetTreeWidth
self.RefreshTree = RefreshTree
self.SetStatusTable = SetStatusTable
self.BuildLevel = BuildLevel
self.CreateButton = CreateButton
self.SetSelected = SetSelected
self.ShowScroll = ShowScroll
self.SetStatusTable = SetStatusTable
self.Select = Select
self.SelectByValue = SelectByValue
self.SelectByPath = SelectByPath
self.OnWidthSet = OnWidthSet
self.OnHeightSet = OnHeightSet
self.EnableButtonTooltips = EnableButtonTooltips
self.Filter = Filter
self.LayoutFinished = LayoutFinished
 
self.frame = frame
frame.obj = self
 
createdcount = createdcount + 1
local scrollbar = CreateFrame("Slider",("AceConfigDialogTreeGroup%dScrollBar"):format(createdcount),treeframe,"UIPanelScrollBarTemplate")
self.scrollbar = scrollbar
local scrollbg = scrollbar:CreateTexture(nil,"BACKGROUND")
scrollbg:SetAllPoints(scrollbar)
scrollbg:SetTexture(0,0,0,0.4)
scrollbar.obj = self
self.noupdate = true
scrollbar:SetPoint("TOPRIGHT",treeframe,"TOPRIGHT",-10,-26)
scrollbar:SetPoint("BOTTOMRIGHT",treeframe,"BOTTOMRIGHT",-10,26)
scrollbar:SetScript("OnValueChanged", OnScrollValueChanged)
scrollbar:SetMinMaxValues(0,0)
self.localstatus.scrollvalue = 0
scrollbar:SetValueStep(1)
scrollbar:SetValue(0)
scrollbar:SetWidth(16)
self.noupdate = nil
 
local border = CreateFrame("Frame",nil,frame)
self.border = border
border:SetPoint("TOPLEFT",treeframe,"TOPRIGHT", 0,0)
border:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,0)
 
border:SetBackdrop(PaneBackdrop)
border:SetBackdropColor(0.1,0.1,0.1,0.5)
border:SetBackdropBorderColor(0.4,0.4,0.4)
 
--Container Support
local content = CreateFrame("Frame",nil,border)
self.content = content
content.obj = self
content:SetPoint("TOPLEFT",border,"TOPLEFT",10,-10)
content:SetPoint("BOTTOMRIGHT",border,"BOTTOMRIGHT",-10,10)
 
AceGUI:RegisterAsContainer(self)
--AceGUI:RegisterAsWidget(self)
return self
end
 
AceGUI:RegisterWidgetType(Type,Constructor,Version)
end
EasyDaily/libs/AceGUI-3.0/widgets/AceGUIWidget-ColorPicker.lua New file
0,0 → 1,172
local AceGUI = LibStub("AceGUI-3.0")
 
--------------------------
-- ColorPicker --
--------------------------
do
local Type = "ColorPicker"
local Version = 10
 
local function OnAcquire(self)
self.HasAlpha = false
self:SetColor(0,0,0,1)
self:SetHeight(24)
self:SetWidth(200)
end
 
local function SetLabel(self, text)
self.text:SetText(text)
end
 
local function SetColor(self,r,g,b,a)
self.r = r
self.g = g
self.b = b
self.a = a or 1
self.colorSwatch:SetVertexColor(r,g,b,a)
end
 
local function Control_OnEnter(this)
this.obj:Fire("OnEnter")
end
 
local function Control_OnLeave(this)
this.obj:Fire("OnLeave")
end
 
local function SetHasAlpha(self, HasAlpha)
self.HasAlpha = HasAlpha
end
 
local function ColorCallback(self,r,g,b,a,isAlpha)
if not self.HasAlpha then
a = 1
end
self:SetColor(r,g,b,a)
if ColorPickerFrame:IsVisible() then
--colorpicker is still open
 
self:Fire("OnValueChanged",r,g,b,a)
else
--colorpicker is closed, color callback is first, ignore it,
--alpha callback is the final call after it closes so confirm now
if isAlpha then
self:Fire("OnValueConfirmed",r,g,b,a)
end
end
end
 
local function ColorSwatch_OnClick(this)
HideUIPanel(ColorPickerFrame)
local self = this.obj
if not self.disabled then
ColorPickerFrame:SetFrameStrata("FULLSCREEN_DIALOG")
 
ColorPickerFrame.func = function()
local r,g,b = ColorPickerFrame:GetColorRGB()
local a = 1 - OpacitySliderFrame:GetValue()
ColorCallback(self,r,g,b,a)
end
 
ColorPickerFrame.hasOpacity = self.HasAlpha
ColorPickerFrame.opacityFunc = function()
local r,g,b = ColorPickerFrame:GetColorRGB()
local a = 1 - OpacitySliderFrame:GetValue()
ColorCallback(self,r,g,b,a,true)
end
local r, g, b, a = self.r, self.g, self.b, self.a
if self.HasAlpha then
ColorPickerFrame.opacity = 1 - (a or 0)
end
ColorPickerFrame:SetColorRGB(r, g, b)
 
ColorPickerFrame.cancelFunc = function()
ColorCallback(self,r,g,b,a,true)
end
ShowUIPanel(ColorPickerFrame)
end
AceGUI:ClearFocus()
end
 
local function OnRelease(self)
self.frame:ClearAllPoints()
self.frame:Hide()
end
 
local function SetDisabled(self, disabled)
self.disabled = disabled
if self.disabled then
self.text:SetTextColor(0.5,0.5,0.5)
else
self.text:SetTextColor(1,1,1)
end
end
 
local function Constructor()
local frame = CreateFrame("Button",nil,UIParent)
local self = {}
self.type = Type
 
self.OnRelease = OnRelease
self.OnAcquire = OnAcquire
 
self.SetLabel = SetLabel
self.SetColor = SetColor
self.SetDisabled = SetDisabled
self.SetHasAlpha = SetHasAlpha
 
self.frame = frame
frame.obj = self
 
local text = frame:CreateFontString(nil,"OVERLAY","GameFontHighlight")
self.text = text
text:SetJustifyH("LEFT")
text:SetTextColor(1,1,1)
frame:SetHeight(24)
frame:SetWidth(200)
text:SetHeight(24)
frame:SetScript("OnClick", ColorSwatch_OnClick)
frame:SetScript("OnEnter",Control_OnEnter)
frame:SetScript("OnLeave",Control_OnLeave)
 
local colorSwatch = frame:CreateTexture(nil, "OVERLAY")
self.colorSwatch = colorSwatch
colorSwatch:SetWidth(19)
colorSwatch:SetHeight(19)
colorSwatch:SetTexture("Interface\\ChatFrame\\ChatFrameColorSwatch")
local texture = frame:CreateTexture(nil, "BACKGROUND")
colorSwatch.texture = texture
texture:SetWidth(16)
texture:SetHeight(16)
texture:SetTexture(1,1,1)
texture:Show()
 
local checkers = frame:CreateTexture(nil, "BACKGROUND")
colorSwatch.checkers = checkers
checkers:SetTexture("Tileset\\Generic\\Checkers")
checkers:SetDesaturated(true)
checkers:SetVertexColor(1,1,1,0.75)
checkers:SetTexCoord(.25,0,0.5,.25)
checkers:SetWidth(14)
checkers:SetHeight(14)
checkers:Show()
 
local highlight = frame:CreateTexture(nil, "BACKGROUND")
self.highlight = highlight
highlight:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight")
highlight:SetBlendMode("ADD")
highlight:SetAllPoints(frame)
highlight:Hide()
 
texture:SetPoint("CENTER", colorSwatch, "CENTER")
checkers:SetPoint("CENTER", colorSwatch, "CENTER")
colorSwatch:SetPoint("LEFT", frame, "LEFT", 0, 0)
text:SetPoint("LEFT",colorSwatch,"RIGHT",2,0)
text:SetPoint("RIGHT",frame,"RIGHT")
 
AceGUI:RegisterAsWidget(self)
return self
end
 
AceGUI:RegisterWidgetType(Type,Constructor,Version)
end
EasyDaily/libs/AceGUI-3.0/widgets/AceGUIWidget-InteractiveLabel.lua New file
0,0 → 1,188
local AceGUI = LibStub("AceGUI-3.0")
 
--------------------------
-- Label --
--------------------------
do
local Type = "InteractiveLabel"
local Version = 3
 
local function OnAcquire(self)
self:SetHeight(18)
self:SetWidth(200)
self:SetText("")
self:SetImage(nil)
self:SetColor()
self:SetFontObject()
self:SetHighlight()
self:SetHighlightTexCoord()
end
 
local function OnRelease(self)
self.frame:ClearAllPoints()
self.frame:Hide()
end
 
local function UpdateImageAnchor(self)
local width = self.frame.width or self.frame:GetWidth() or 0
local image = self.image
local label = self.label
local frame = self.frame
local height
 
label:ClearAllPoints()
image:ClearAllPoints()
 
if self.imageshown then
local imagewidth = image:GetWidth()
if (width - imagewidth) < 200 or (label:GetText() or "") == "" then
--image goes on top centered when less than 200 width for the text, or if there is no text
image:SetPoint("TOP",frame,"TOP",0,0)
label:SetPoint("TOP",image,"BOTTOM",0,0)
label:SetPoint("LEFT",frame,"LEFT",0,0)
label:SetWidth(width)
height = image:GetHeight() + label:GetHeight()
else
--image on the left
image:SetPoint("TOPLEFT",frame,"TOPLEFT",0,0)
label:SetPoint("TOPLEFT",image,"TOPRIGHT",0,0)
label:SetWidth(width - imagewidth)
height = math.max(image:GetHeight(), label:GetHeight())
end
else
--no image shown
label:SetPoint("TOPLEFT",frame,"TOPLEFT",0,0)
label:SetWidth(width)
height = self.label:GetHeight()
end
 
self.resizing = true
self.frame:SetHeight(height)
self.frame.height = height
self.resizing = nil
end
 
local function SetText(self, text)
self.label:SetText(text or "")
UpdateImageAnchor(self)
end
 
local function SetColor(self, r, g, b)
if not (r and g and b) then
r, g, b = 1, 1, 1
end
self.label:SetVertexColor(r, g, b)
end
 
local function OnWidthSet(self, width)
if self.resizing then return end
UpdateImageAnchor(self)
end
 
local function SetImage(self, path, ...)
local image = self.image
image:SetTexture(path)
 
if image:GetTexture() then
self.imageshown = true
local n = select('#', ...)
if n == 4 or n == 8 then
image:SetTexCoord(...)
end
else
self.imageshown = nil
end
UpdateImageAnchor(self)
end
 
local function SetFont(self, font, height, flags)
self.label:SetFont(font, height, flags)
end
 
local function SetFontObject(self, font)
self.label:SetFontObject(font or GameFontHighlightSmall)
end
 
local function SetImageSize(self, width, height)
self.image:SetWidth(width)
self.image:SetHeight(height)
UpdateImageAnchor(self)
end
 
local function SetHighlight(self, ...)
self.highlight:SetTexture(...)
end
 
local function SetHighlightTexCoord(self, ...)
if select('#', ...) >= 1 then
self.highlight:SetTexCoord(...)
else
self.highlight:SetTexCoord(0, 1, 0, 1)
end
end
 
local function OnEnter(this)
this.obj.highlight:Show()
this.obj:Fire("OnEnter")
end
 
local function OnLeave(this)
this.obj.highlight:Hide()
this.obj:Fire("OnLeave")
end
 
local function OnClick(this, ...)
this.obj:Fire("OnClick", ...)
AceGUI:ClearFocus()
end
 
local function Constructor()
local frame = CreateFrame("Frame",nil,UIParent)
local self = {}
self.type = Type
 
frame:EnableMouse(true)
frame:SetScript("OnEnter", OnEnter)
frame:SetScript("OnLeave", OnLeave)
frame:SetScript("OnMouseDown", OnClick)
 
self.OnRelease = OnRelease
self.OnAcquire = OnAcquire
self.SetText = SetText
self.SetColor = SetColor
self.frame = frame
self.OnWidthSet = OnWidthSet
self.SetImage = SetImage
self.SetImageSize = SetImageSize
self.SetFont = SetFont
self.SetFontObject = SetFontObject
self.SetHighlight = SetHighlight
self.SetHighlightTexCoord = SetHighlightTexCoord
frame.obj = self
 
frame:SetHeight(18)
frame:SetWidth(200)
local label = frame:CreateFontString(nil,"BACKGROUND","GameFontHighlightSmall")
label:SetPoint("TOPLEFT",frame,"TOPLEFT",0,0)
label:SetWidth(200)
label:SetJustifyH("LEFT")
label:SetJustifyV("TOP")
self.label = label
 
local highlight = frame:CreateTexture(nil, "OVERLAY")
highlight:SetTexture(nil)
highlight:SetAllPoints()
highlight:SetBlendMode("ADD")
highlight:Hide()
self.highlight = highlight
 
local image = frame:CreateTexture(nil,"BACKGROUND")
self.image = image
 
AceGUI:RegisterAsWidget(self)
return self
end
 
AceGUI:RegisterWidgetType(Type,Constructor,Version)
end
 
EasyDaily/libs/AceGUI-3.0/widgets/AceGUIWidget-Label.lua New file
0,0 → 1,145
local AceGUI = LibStub("AceGUI-3.0")
 
--------------------------
-- Label --
--------------------------
do
local Type = "Label"
local Version = 10
 
local function OnAcquire(self)
self:SetHeight(18)
self:SetWidth(200)
self:SetText("")
self:SetImage(nil)
self:SetColor()
self:SetFontObject()
end
 
local function OnRelease(self)
self.frame:ClearAllPoints()
self.frame:Hide()
end
 
local function UpdateImageAnchor(self)
local width = self.frame.width or self.frame:GetWidth() or 0
local image = self.image
local label = self.label
local frame = self.frame
local height
 
label:ClearAllPoints()
image:ClearAllPoints()
 
if self.imageshown then
local imagewidth = image:GetWidth()
if (width - imagewidth) < 200 or (label:GetText() or "") == "" then
--image goes on top centered when less than 200 width for the text, or if there is no text
image:SetPoint("TOP",frame,"TOP",0,0)
label:SetPoint("TOP",image,"BOTTOM",0,0)
label:SetPoint("LEFT",frame,"LEFT",0,0)
label:SetWidth(width)
height = image:GetHeight() + label:GetHeight()
else
--image on the left
image:SetPoint("TOPLEFT",frame,"TOPLEFT",0,0)
label:SetPoint("TOPLEFT",image,"TOPRIGHT",0,0)
label:SetWidth(width - imagewidth)
height = math.max(image:GetHeight(), label:GetHeight())
end
else
--no image shown
label:SetPoint("TOPLEFT",frame,"TOPLEFT",0,0)
label:SetWidth(width)
height = self.label:GetHeight()
end
 
self.resizing = true
self.frame:SetHeight(height)
self.frame.height = height
self.resizing = nil
end
 
local function SetText(self, text)
self.label:SetText(text or "")
UpdateImageAnchor(self)
end
 
local function SetColor(self, r, g, b)
if not (r and g and b) then
r, g, b = 1, 1, 1
end
self.label:SetVertexColor(r, g, b)
end
 
local function OnWidthSet(self, width)
if self.resizing then return end
UpdateImageAnchor(self)
end
 
local function SetImage(self, path, ...)
local image = self.image
image:SetTexture(path)
 
if image:GetTexture() then
self.imageshown = true
local n = select('#', ...)
if n == 4 or n == 8 then
image:SetTexCoord(...)
end
else
self.imageshown = nil
end
UpdateImageAnchor(self)
end
 
local function SetFont(self, font, height, flags)
self.label:SetFont(font, height, flags)
end
 
local function SetFontObject(self, font)
self.label:SetFontObject(font or GameFontHighlightSmall)
end
 
local function SetImageSize(self, width, height)
self.image:SetWidth(width)
self.image:SetHeight(height)
UpdateImageAnchor(self)
end
 
local function Constructor()
local frame = CreateFrame("Frame",nil,UIParent)
local self = {}
self.type = Type
 
self.OnRelease = OnRelease
self.OnAcquire = OnAcquire
self.SetText = SetText
self.SetColor = SetColor
self.frame = frame
self.OnWidthSet = OnWidthSet
self.SetImage = SetImage
self.SetImageSize = SetImageSize
self.SetFont = SetFont
self.SetFontObject = SetFontObject
frame.obj = self
 
frame:SetHeight(18)
frame:SetWidth(200)
local label = frame:CreateFontString(nil,"BACKGROUND","GameFontHighlightSmall")
label:SetPoint("TOPLEFT",frame,"TOPLEFT",0,0)
label:SetWidth(200)
label:SetJustifyH("LEFT")
label:SetJustifyV("TOP")
self.label = label
 
local image = frame:CreateTexture(nil,"BACKGROUND")
self.image = image
 
AceGUI:RegisterAsWidget(self)
return self
end
 
AceGUI:RegisterWidgetType(Type,Constructor,Version)
end
 
EasyDaily/libs/AceGUI-3.0/widgets/AceGUIWidget-MultiLineEditBox.lua New file
0,0 → 1,318
 
--[[
--Multiline Editbox Widget, Originally by bam
 
--]]
local assert, error, ipairs, next, pairs, select, tonumber, tostring, type, unpack, pcall, xpcall =
assert, error, ipairs, next, pairs, select, tonumber, tostring, type, unpack, pcall, xpcall
local getmetatable, setmetatable, rawequal, rawget, rawset, getfenv, setfenv, loadstring, debugstack =
getmetatable, setmetatable, rawequal, rawget, rawset, getfenv, setfenv, loadstring, debugstack
local math, string, table = math, string, table
local find, format, gmatch, gsub, tolower, match, toupper, join, split, trim =
string.find, string.format, string.gmatch, string.gsub, string.lower, string.match, string.upper, string.join, string.split, string.trim
local concat, insert, maxn, remove, sort = table.concat, table.insert, table.maxn, table.remove, table.sort
local max, min, abs, ceil, floor = math.max, math.min, math.abs, math.ceil, math.floor
 
local LibStub = assert(LibStub)
 
local ChatFontNormal = ChatFontNormal
local ClearCursor = ClearCursor
local CreateFrame = CreateFrame
local GetCursorInfo = GetCursorInfo
local GetSpellName = GetSpellName
local UIParent = UIParent
local UISpecialFrames = UISpecialFrames
 
-- No global variables after this!
 
local _G = getfenv()
 
local AceGUI = LibStub("AceGUI-3.0")
 
local Version = 10
---------------------
-- Common Elements --
---------------------
 
local FrameBackdrop = {
bgFile="Interface\\DialogFrame\\UI-DialogBox-Background",
edgeFile="Interface\\DialogFrame\\UI-DialogBox-Border",
tile = true, tileSize = 32, edgeSize = 32,
insets = { left = 8, right = 8, top = 8, bottom = 8 }
}
 
local PaneBackdrop = {
 
bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
tile = true, tileSize = 16, edgeSize = 16,
insets = { left = 3, right = 3, top = 5, bottom = 3 }
}
 
local ControlBackdrop = {
bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
tile = true, tileSize = 16, edgeSize = 16,
insets = { left = 3, right = 3, top = 3, bottom = 3 }
}
 
--------------------------
-- Edit box --
--------------------------
--[[
Events :
OnTextChanged
OnEnterPressed
 
]]
do
local Type = "MultiLineEditBox"
 
local MultiLineEditBox = {}
 
local function EditBox_OnEnterPressed(this)
local self = this.obj
local value = this:GetText()
local cancel = self:Fire("OnEnterPressed",value)
if not cancel then
self.button:Disable()
end
end
 
local function Button_OnClick(this)
local editbox = this.obj.editbox
editbox:ClearFocus()
EditBox_OnEnterPressed(editbox)
end
 
local function EditBox_OnReceiveDrag(this)
local self = this.obj
local type, id, info = GetCursorInfo()
if type == "item" then
self:SetText(info)
self:Fire("OnEnterPressed",info)
ClearCursor()
elseif type == "spell" then
local name, rank = GetSpellName(id, info)
if rank and rank:match("%d") then
name = name.."("..rank..")"
end
self:SetText(name)
self:Fire("OnEnterPressed",name)
ClearCursor()
end
--self.button:Disable()
AceGUI:ClearFocus()
end
 
function MultiLineEditBox:OnAcquire()
self:SetWidth(200)
self:SetHeight(116)
self:SetNumLines(4)
self:SetDisabled(false)
self:ShowButton(true)
end
 
function MultiLineEditBox:OnRelease()
self.frame:ClearAllPoints()
self.frame:Hide()
self:SetDisabled(false)
end
 
function MultiLineEditBox:SetDisabled(disabled)
self.disabled = disabled
if disabled then
self.editbox:EnableMouse(false)
self.scrollframe:EnableMouse(false)
self.editbox:ClearFocus()
self.editbox:SetTextColor(0.5, 0.5, 0.5)
self.label:SetTextColor(0.5,0.5,0.5)
else
self.editbox:EnableMouse(true)
self.scrollframe:EnableMouse(true)
self.editbox:SetTextColor(1, 1, 1)
self.label:SetTextColor(1,.82,0)
end
end
 
function MultiLineEditBox:SetText(text)
text = text or ""
local editbox = self.editbox
local oldText = editbox:GetText()
local dummy = format(" %s", text)
self.lasttext = dummy -- prevents OnTextChanged from firing
editbox:SetText(dummy)
editbox:HighlightText(0, 1)
self.lasttext = oldText
editbox:Insert("")
end
 
function MultiLineEditBox:SetLabel(text)
if (text or "") == "" then
self.backdrop:SetPoint("TOPLEFT",self.frame,"TOPLEFT",0,0)
self.label:Hide()
self.label:SetText("")
else
self.backdrop:SetPoint("TOPLEFT",self.frame,"TOPLEFT",0,-20)
self.label:Show()
self.label:SetText(text)
end
end
 
function MultiLineEditBox:SetNumLines(number)
number = number or 4
self:SetHeight(60 + (14*number))
end
 
function MultiLineEditBox:GetText()
return self.editbox:GetText()
end
 
function MultiLineEditBox:ShowButton(show)
if show then
self.backdrop:SetPoint("BOTTOMRIGHT",self.frame,"BOTTOMRIGHT",0,22)
self.button:Show()
else
self.backdrop:SetPoint("BOTTOMRIGHT",self.frame,"BOTTOMRIGHT",0,0)
self.button:Hide()
end
end
 
local function Constructor()
local frame = CreateFrame("Frame", nil, UIParent)
local backdrop = CreateFrame("Frame", nil, frame)
local self = {}
for k, v in pairs(MultiLineEditBox) do self[k] = v end
self.type = Type
self.frame = frame
self.backdrop = backdrop
frame.obj = self
 
backdrop:SetBackdrop(ControlBackdrop)
backdrop:SetBackdropColor(0, 0, 0)
backdrop:SetBackdropBorderColor(0.4, 0.4, 0.4)
 
backdrop:SetPoint("TOPLEFT",frame,"TOPLEFT",0, -20)
backdrop:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,22)
 
local scrollframe = CreateFrame("ScrollFrame", format("%s@%s@%s", Type, "ScrollFrame", tostring(self)), backdrop, "UIPanelScrollFrameTemplate")
scrollframe:SetPoint("TOPLEFT", 5, -6)
scrollframe:SetPoint("BOTTOMRIGHT", -28, 6)
scrollframe.obj = self
self.scrollframe = scrollframe
 
--local scrollchild = CreateFrame("Frame", nil, scrollframe)
--scrollframe:SetScrollChild(scrollchild)
--scrollchild:SetHeight(2)
--scrollchild:SetWidth(2)
 
local label = frame:CreateFontString(nil,"OVERLAY","GameFontNormalSmall")
label:SetPoint("TOPLEFT",frame,"TOPLEFT",0,-2)
label:SetPoint("TOPRIGHT",frame,"TOPRIGHT",0,-2)
label:SetJustifyH("LEFT")
label:SetHeight(18)
self.label = label
 
local editbox = CreateFrame("EditBox", nil, scrollframe)
self.editbox = editbox
editbox.obj = self
editbox:SetPoint("TOPLEFT")
editbox:SetPoint("BOTTOMLEFT")
editbox:SetHeight(50)
editbox:SetWidth(50)
editbox:SetMultiLine(true)
-- editbox:SetMaxLetters(7500)
editbox:SetTextInsets(5, 5, 3, 3)
editbox:EnableMouse(true)
editbox:SetAutoFocus(false)
editbox:SetFontObject(ChatFontNormal)
scrollframe:SetScrollChild(editbox)
 
local button = CreateFrame("Button",nil,scrollframe,"UIPanelButtonTemplate")
button:SetWidth(80)
button:SetHeight(20)
button:SetPoint("BOTTOMLEFT",frame,"BOTTOMLEFT",0,2)
button:SetText(ACCEPT)
button:SetScript("OnClick", Button_OnClick)
button:SetFrameLevel(editbox:GetFrameLevel() + 1)
button:Disable()
button:Hide()
self.button = button
button.obj = self
 
scrollframe:EnableMouse(true)
scrollframe:SetScript("OnMouseUp", function() editbox:SetFocus() end)
scrollframe:SetScript("OnEnter", function(this) this.obj:Fire("OnEnter") end)
scrollframe:SetScript("OnLeave", function(this) this.obj:Fire("OnLeave") end)
 
editbox:SetScript("OnEnter", function(this) this.obj:Fire("OnEnter") end)
editbox:SetScript("OnLeave", function(this) this.obj:Fire("OnLeave") end)
 
local function FixSize()
--scrollchild:SetHeight(scrollframe:GetHeight())
--scrollchild:SetWidth(scrollframe:GetWidth())
editbox:SetWidth(scrollframe:GetWidth())
end
scrollframe:SetScript("OnShow", FixSize)
scrollframe:SetScript("OnSizeChanged", FixSize)
 
editbox:SetScript("OnEscapePressed", editbox.ClearFocus)
editbox:SetScript("OnTextChanged", function(_, ...)
scrollframe:UpdateScrollChildRect()
local value = editbox:GetText()
if value ~= self.lasttext then
self:Fire("OnTextChanged", value)
self.lasttext = value
self.button:Enable()
end
end)
 
editbox:SetScript("OnReceiveDrag", EditBox_OnReceiveDrag)
editbox:SetScript("OnMouseDown", EditBox_OnReceiveDrag)
 
do
local cursorOffset, cursorHeight
local idleTime
local function FixScroll(_, elapsed)
if cursorOffset and cursorHeight then
idleTime = 0
local height = scrollframe:GetHeight()
local range = scrollframe:GetVerticalScrollRange()
local scroll = scrollframe:GetVerticalScroll()
local size = height + range
cursorOffset = -cursorOffset
while cursorOffset < scroll do
scroll = scroll - (height / 2)
if scroll < 0 then scroll = 0 end
scrollframe:SetVerticalScroll(scroll)
end
while cursorOffset + cursorHeight > scroll + height and scroll < range do
scroll = scroll + (height / 2)
if scroll > range then scroll = range end
scrollframe:SetVerticalScroll(scroll)
end
elseif not idleTime or idleTime > 2 then
frame:SetScript("OnUpdate", nil)
idleTime = nil
else
idleTime = idleTime + elapsed
end
cursorOffset = nil
end
editbox:SetScript("OnCursorChanged", function(_, x, y, w, h)
cursorOffset, cursorHeight = y, h
if not idleTime then
frame:SetScript("OnUpdate", FixScroll)
end
end)
end
 
AceGUI:RegisterAsWidget(self)
return self
end
 
AceGUI:RegisterWidgetType(Type, Constructor, Version)
end
 
 
 
EasyDaily/libs/AceGUI-3.0/widgets/AceGUIWidget-Slider.lua New file
0,0 → 1,255
local AceGUI = LibStub("AceGUI-3.0")
 
--------------------------
-- Slider --
--------------------------
do
local Type = "Slider"
local Version = 7
 
local function OnAcquire(self)
self:SetWidth(200)
self:SetHeight(44)
self:SetDisabled(false)
self:SetIsPercent(nil)
self:SetSliderValues(0,100,1)
self:SetValue(0)
end
 
local function OnRelease(self)
self.frame:ClearAllPoints()
self.frame:Hide()
self.slider:EnableMouseWheel(false)
self:SetDisabled(false)
end
 
local function Control_OnEnter(this)
this.obj:Fire("OnEnter")
end
 
local function Control_OnLeave(this)
this.obj:Fire("OnLeave")
end
 
local function UpdateText(self)
local value = self.value or 0
if self.ispercent then
self.editbox:SetText(("%s%%"):format(math.floor(value*1000+0.5)/10))
else
self.editbox:SetText(math.floor(value*100+0.5)/100)
end
end
 
local function UpdateLabels(self)
local min, max = (self.min or 0), (self.max or 100)
if self.ispercent then
self.lowtext:SetFormattedText("%s%%",(min * 100))
self.hightext:SetFormattedText("%s%%",(max * 100))
else
self.lowtext:SetText(min)
self.hightext:SetText(max)
end
end
 
local function Slider_OnValueChanged(this)
local self = this.obj
if not this.setup then
local newvalue
newvalue = this:GetValue()
if newvalue ~= self.value and not self.disabled then
self.value = newvalue
self:Fire("OnValueChanged", newvalue)
end
if self.value then
local value = self.value
UpdateText(self)
end
end
end
 
local function Slider_OnMouseUp(this)
local self = this.obj
self:Fire("OnMouseUp",this:GetValue())
end
 
local function Slider_OnMouseWheel(this, v)
local self = this.obj
if not self.disabled then
local value = self.value
if v > 0 then
value = math.min(value + (self.step or 1),self.max)
else
value = math.max(value - (self.step or 1), self.min)
end
self.slider:SetValue(value)
end
end
 
local function SetDisabled(self, disabled)
self.disabled = disabled
if disabled then
self.slider:EnableMouse(false)
self.label:SetTextColor(.5,.5,.5)
self.hightext:SetTextColor(.5,.5,.5)
self.lowtext:SetTextColor(.5,.5,.5)
--self.valuetext:SetTextColor(.5,.5,.5)
self.editbox:SetTextColor(.5,.5,.5)
self.editbox:EnableMouse(false)
self.editbox:ClearFocus()
else
self.slider:EnableMouse(true)
self.label:SetTextColor(1,.82,0)
self.hightext:SetTextColor(1,1,1)
self.lowtext:SetTextColor(1,1,1)
--self.valuetext:SetTextColor(1,1,1)
self.editbox:SetTextColor(1,1,1)
self.editbox:EnableMouse(true)
end
end
 
local function SetValue(self, value)
self.slider.setup = true
self.slider:SetValue(value)
self.value = value
UpdateText(self)
self.slider.setup = nil
end
 
local function SetLabel(self, text)
self.label:SetText(text)
end
 
local function SetSliderValues(self, min, max, step)
local frame = self.slider
frame.setup = true
self.min = min
self.max = max
self.step = step
frame:SetMinMaxValues(min or 0,max or 100)
UpdateLabels(self)
frame:SetValueStep(step or 1)
frame.setup = nil
end
 
local function EditBox_OnEscapePressed(this)
this:ClearFocus()
end
 
local function EditBox_OnEnterPressed(this)
local self = this.obj
local value = this:GetText()
if self.ispercent then
value = value:gsub('%%','')
value = tonumber(value) / 100
else
value = tonumber(value)
end
 
if value then
self:Fire("OnMouseUp",value)
end
end
 
local function SetIsPercent(self, value)
self.ispercent = value
UpdateLabels(self)
UpdateText(self)
end
 
local function FrameOnMouseDown(this)
this.obj.slider:EnableMouseWheel(true)
AceGUI:ClearFocus()
end
 
local SliderBackdrop = {
bgFile = "Interface\\Buttons\\UI-SliderBar-Background",
edgeFile = "Interface\\Buttons\\UI-SliderBar-Border",
tile = true, tileSize = 8, edgeSize = 8,
insets = { left = 3, right = 3, top = 6, bottom = 6 }
}
 
local function Constructor()
local frame = CreateFrame("Frame",nil,UIParent)
local self = {}
self.type = Type
 
self.OnRelease = OnRelease
self.OnAcquire = OnAcquire
 
self.frame = frame
frame.obj = self
 
self.SetDisabled = SetDisabled
self.SetValue = SetValue
self.SetSliderValues = SetSliderValues
self.SetLabel = SetLabel
self.SetIsPercent = SetIsPercent
 
self.alignoffset = 25
 
frame:EnableMouse(true)
frame:SetScript("OnMouseDown",FrameOnMouseDown)
self.slider = CreateFrame("Slider",nil,frame)
local slider = self.slider
slider:SetScript("OnEnter",Control_OnEnter)
slider:SetScript("OnLeave",Control_OnLeave)
slider:SetScript("OnMouseUp", Slider_OnMouseUp)
slider.obj = self
slider:SetOrientation("HORIZONTAL")
slider:SetHeight(15)
slider:SetHitRectInsets(0,0,-10,0)
slider:SetBackdrop(SliderBackdrop)
--slider:EnableMouseWheel(true)
slider:SetScript("OnMouseWheel", Slider_OnMouseWheel)
 
local label = frame:CreateFontString(nil,"OVERLAY","GameFontNormal")
label:SetPoint("TOPLEFT",frame,"TOPLEFT",0,0)
label:SetPoint("TOPRIGHT",frame,"TOPRIGHT",0,0)
label:SetJustifyH("CENTER")
label:SetHeight(15)
self.label = label
 
self.lowtext = slider:CreateFontString(nil,"ARTWORK","GameFontHighlightSmall")
self.lowtext:SetPoint("TOPLEFT",slider,"BOTTOMLEFT",2,3)
 
self.hightext = slider:CreateFontString(nil,"ARTWORK","GameFontHighlightSmall")
self.hightext:SetPoint("TOPRIGHT",slider,"BOTTOMRIGHT",-2,3)
 
 
local editbox = CreateFrame("EditBox",nil,frame)
editbox:SetAutoFocus(false)
editbox:SetFontObject(GameFontHighlightSmall)
editbox:SetPoint("TOP",slider,"BOTTOM",0,0)
editbox:SetHeight(14)
editbox:SetWidth(70)
editbox:SetJustifyH("CENTER")
editbox:EnableMouse(true)
editbox:SetScript("OnEscapePressed",EditBox_OnEscapePressed)
editbox:SetScript("OnEnterPressed",EditBox_OnEnterPressed)
self.editbox = editbox
editbox.obj = self
 
local bg = editbox:CreateTexture(nil,"BACKGROUND")
editbox.bg = bg
bg:SetTexture("Interface\\ChatFrame\\ChatFrameBackground")
bg:SetVertexColor(0,0,0,0.25)
bg:SetAllPoints(editbox)
 
slider:SetThumbTexture("Interface\\Buttons\\UI-SliderBar-Button-Horizontal")
 
frame:SetWidth(200)
frame:SetHeight(44)
slider:SetPoint("TOP",label,"BOTTOM",0,0)
slider:SetPoint("LEFT",frame,"LEFT",3,0)
slider:SetPoint("RIGHT",frame,"RIGHT",-3,0)
 
 
slider:SetValue(self.value or 0)
slider:SetScript("OnValueChanged",Slider_OnValueChanged)
 
AceGUI:RegisterAsWidget(self)
return self
end
 
AceGUI:RegisterWidgetType(Type,Constructor,Version)
end
EasyDaily/libs/AceGUI-3.0/widgets/AceGUIWidget-TabGroup.lua New file
0,0 → 1,365
local AceGUI = LibStub("AceGUI-3.0")
 
-------------
-- Widgets --
-------------
--[[
Widgets must provide the following functions
Acquire() - Called when the object is aquired, should set everything to a default hidden state
Release() - Called when the object is Released, should remove any anchors and hide the Widget
 
And the following members
frame - the frame or derivitive object that will be treated as the widget for size and anchoring purposes
type - the type of the object, same as the name given to :RegisterWidget()
 
Widgets contain a table called userdata, this is a safe place to store data associated with the wigdet
It will be cleared automatically when a widget is released
Placing values directly into a widget object should be avoided
 
If the Widget can act as a container for other Widgets the following
content - frame or derivitive that children will be anchored to
 
The Widget can supply the following Optional Members
 
 
]]
 
--------------------------
-- Tab Group --
--------------------------
 
do
local Type = "TabGroup"
local Version = 20
 
local PaneBackdrop = {
bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
tile = true, tileSize = 16, edgeSize = 16,
insets = { left = 3, right = 3, top = 5, bottom = 3 }
}
 
local function OnAcquire(self)
 
end
 
local function OnRelease(self)
self.frame:ClearAllPoints()
self.frame:Hide()
self.status = nil
for k in pairs(self.localstatus) do
self.localstatus[k] = nil
end
self.tablist = nil
for _, tab in pairs(self.tabs) do
tab:Hide()
end
end
 
local function Tab_SetText(self, text)
self:_SetText(text)
local width = self.obj.frame.width or self.obj.frame:GetWidth() or 0
PanelTemplates_TabResize(self, 0, nil, width)
end
 
local function UpdateTabLook(self)
if self.disabled then
PanelTemplates_SetDisabledTabState(self)
elseif self.selected then
PanelTemplates_SelectTab(self)
else
PanelTemplates_DeselectTab(self)
end
end
 
local function Tab_SetSelected(self, selected)
self.selected = selected
UpdateTabLook(self)
end
 
local function Tab_OnClick(self)
if not (self.selected or self.disabled) then
self.obj:SelectTab(self.value)
end
end
 
local function Tab_SetDisabled(self, disabled)
self.disabled = disabled
UpdateTabLook(self)
end
 
local function Tab_OnEnter(this)
local self = this.obj
self:Fire("OnTabEnter", self.tabs[this.id].value, this)
end
 
local function Tab_OnLeave(this)
local self = this.obj
self:Fire("OnTabLeave", self.tabs[this.id].value, this)
end
 
local function Tab_OnShow(this)
_G[this:GetName().."HighlightTexture"]:SetWidth(this:GetTextWidth() + 30)
end
 
local function CreateTab(self, id)
local tabname = "AceGUITabGroup"..self.num.."Tab"..id
local tab = CreateFrame("Button",tabname,self.border,"OptionsFrameTabButtonTemplate")
tab.obj = self
tab.id = id
 
tab.text = _G[tabname .. "Text"]
tab.text:ClearAllPoints()
tab.text:SetPoint("LEFT", tab, "LEFT", 14, -3)
tab.text:SetPoint("RIGHT", tab, "RIGHT", -12, -3)
 
tab:SetScript("OnClick",Tab_OnClick)
tab:SetScript("OnEnter",Tab_OnEnter)
tab:SetScript("OnLeave",Tab_OnLeave)
tab:SetScript("OnShow", Tab_OnShow)
 
tab._SetText = tab.SetText
tab.SetText = Tab_SetText
tab.SetSelected = Tab_SetSelected
tab.SetDisabled = Tab_SetDisabled
 
return tab
end
 
local function SetTitle(self, text)
self.titletext:SetText(text or "")
end
 
-- called to set an external table to store status in
local function SetStatusTable(self, status)
assert(type(status) == "table")
self.status = status
end
 
local function SelectTab(self, value)
local status = self.status or self.localstatus
 
local found
for i, v in ipairs(self.tabs) do
if v.value == value then
v:SetSelected(true)
found = true
else
v:SetSelected(false)
end
end
status.selected = value
if found then
self:Fire("OnGroupSelected",value)
end
end
 
local function SetTabs(self, tabs)
self.tablist = tabs
self:BuildTabs()
end
 
 
local widths = {}
local rowwidths = {}
local rowends = {}
local function BuildTabs(self)
local status = self.status or self.localstatus
local tablist = self.tablist
local tabs = self.tabs
 
if not tablist then return end
 
local width = self.frame.width or self.frame:GetWidth() or 0
 
for i = #widths, 1, -1 do
widths[i] = nil
end
for i = #rowwidths, 1, -1 do
rowwidths[i] = nil
end
for i = #rowends, 1, -1 do
rowends[i] = nil
end
 
--Place Text into tabs and get thier initial width
for i, v in ipairs(tablist) do
local tab = tabs[i]
if not tab then
tab = self:CreateTab(i)
tabs[i] = tab
end
 
tab:Show()
tab:SetText(v.text)
tab:SetDisabled(v.disabled)
tab.value = v.value
 
widths[i] = tab:GetWidth() - 6 --tabs are anchored 10 pixels from the right side of the previous one to reduce spacing, but add a fixed 4px padding for the text
end
 
for i = (#tablist)+1, #tabs, 1 do
tabs[i]:Hide()
end
 
--First pass, find the minimum number of rows needed to hold all tabs and the initial tab layout
local numtabs = #tablist
local numrows = 1
local usedwidth = 0
 
for i = 1, #tablist do
--If this is not the first tab of a row and there isn't room for it
if usedwidth ~= 0 and (width - usedwidth - widths[i]) < 0 then
rowwidths[numrows] = usedwidth + 10 --first tab in each row takes up an extra 10px
rowends[numrows] = i - 1
numrows = numrows + 1
usedwidth = 0
end
usedwidth = usedwidth + widths[i]
end
rowwidths[numrows] = usedwidth + 10 --first tab in each row takes up an extra 10px
rowends[numrows] = #tablist
 
--Fix for single tabs being left on the last row, move a tab from the row above if applicable
if numrows > 1 then
--if the last row has only one tab
if rowends[numrows-1] == numtabs-1 then
--if there are more than 2 tabs in the 2nd last row
if (numrows == 2 and rowends[numrows-1] > 2) or (rowends[numrows] - rowends[numrows-1] > 2) then
--move 1 tab from the second last row to the last, if there is enough space
if (rowwidths[numrows] + widths[numtabs-1]) <= width then
rowends[numrows-1] = rowends[numrows-1] - 1
rowwidths[numrows] = rowwidths[numrows] + widths[numtabs-1]
rowwidths[numrows-1] = rowwidths[numrows-1] - widths[numtabs-1]
end
end
end
end
 
--anchor the rows as defined and resize tabs to fill thier row
local starttab = 1
for row, endtab in ipairs(rowends) do
local first = true
for tabno = starttab, endtab do
local tab = tabs[tabno]
tab:ClearAllPoints()
if first then
tab:SetPoint("TOPLEFT", self.frame, "TOPLEFT", 0, -7-(row-1)*20 )
first = false
else
tab:SetPoint("LEFT", tabs[tabno-1], "RIGHT", -10, 0)
end
end
 
-- equal padding for each tab to fill the available width,
-- if the used space is above 75% already
local padding = 0
if not (numrows == 1 and rowwidths[1] < width*0.75) then
padding = (width - rowwidths[row]) / (endtab - starttab+1)
end
 
for i = starttab, endtab do
PanelTemplates_TabResize(tabs[i], padding + 4, nil, width)
end
starttab = endtab + 1
end
 
self.borderoffset = 10+((numrows)*20)
self.border:SetPoint("TOPLEFT",self.frame,"TOPLEFT",3,-self.borderoffset)
end
 
local function BuildTabsOnUpdate(this)
BuildTabs(this.obj)
this:SetScript("OnUpdate", nil)
end
 
local function OnWidthSet(self, width)
local content = self.content
local contentwidth = width - 60
if contentwidth < 0 then
contentwidth = 0
end
content:SetWidth(contentwidth)
content.width = contentwidth
BuildTabs(self)
self.frame:SetScript("OnUpdate", BuildTabsOnUpdate)
end
 
 
local function OnHeightSet(self, height)
local content = self.content
local contentheight = height - (self.borderoffset + 23)
if contentheight < 0 then
contentheight = 0
end
content:SetHeight(contentheight)
content.height = contentheight
end
 
local function LayoutFinished(self, width, height)
if self.noAutoHeight then return end
self:SetHeight((height or 0) + (self.borderoffset + 23))
end
 
local function Constructor()
local frame = CreateFrame("Frame",nil,UIParent)
local self = {}
self.type = Type
 
self.num = AceGUI:GetNextWidgetNum(Type)
 
self.localstatus = {}
 
self.OnRelease = OnRelease
self.OnAcquire = OnAcquire
self.SetTitle = SetTitle
self.CreateTab = CreateTab
self.SelectTab = SelectTab
self.BuildTabs = BuildTabs
self.SetStatusTable = SetStatusTable
self.SetTabs = SetTabs
self.LayoutFinished = LayoutFinished
self.frame = frame
 
self.OnWidthSet = OnWidthSet
self.OnHeightSet = OnHeightSet
 
frame.obj = self
 
frame:SetHeight(100)
frame:SetWidth(100)
frame:SetFrameStrata("FULLSCREEN_DIALOG")
 
local titletext = frame:CreateFontString(nil,"OVERLAY","GameFontNormal")
titletext:SetPoint("TOPLEFT",frame,"TOPLEFT",14,0)
titletext:SetPoint("TOPRIGHT",frame,"TOPRIGHT",-14,0)
titletext:SetJustifyH("LEFT")
titletext:SetHeight(18)
 
self.titletext = titletext
 
local border = CreateFrame("Frame",nil,frame)
self.border = border
self.borderoffset = 27
border:SetPoint("TOPLEFT",frame,"TOPLEFT",3,-27)
border:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-3,3)
 
border:SetBackdrop(PaneBackdrop)
border:SetBackdropColor(0.1,0.1,0.1,0.5)
border:SetBackdropBorderColor(0.4,0.4,0.4)
 
self.tabs = {}
 
--Container Support
local content = CreateFrame("Frame",nil,border)
self.content = content
content.obj = self
content:SetPoint("TOPLEFT",border,"TOPLEFT",10,-10)
content:SetPoint("BOTTOMRIGHT",border,"BOTTOMRIGHT",-10,10)
 
AceGUI:RegisterAsContainer(self)
return self
end
 
AceGUI:RegisterWidgetType(Type,Constructor,Version)
end
EasyDaily/libs/AceGUI-3.0/widgets/AceGUIWidget-Keybinding.lua New file
0,0 → 1,219
local AceGUI = LibStub("AceGUI-3.0")
 
--------------------------
-- Keybinding --
--------------------------
 
do
local Type = "Keybinding"
local Version = 12
 
local ControlBackdrop = {
bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
tile = true, tileSize = 16, edgeSize = 16,
insets = { left = 3, right = 3, top = 3, bottom = 3 }
}
 
local function Control_OnEnter(this)
this.obj:Fire("OnEnter")
end
 
local function Control_OnLeave(this)
this.obj:Fire("OnLeave")
end
 
local function keybindingMsgFixWidth(this)
this:SetWidth(this.msg:GetWidth()+10)
this:SetScript("OnUpdate",nil)
end
 
local function Keybinding_OnClick(this, button)
if button == "LeftButton" or button == "RightButton" then
local self = this.obj
if self.waitingForKey then
this:EnableKeyboard(false)
self.msgframe:Hide()
this:UnlockHighlight()
self.waitingForKey = nil
else
this:EnableKeyboard(true)
self.msgframe:Show()
this:LockHighlight()
self.waitingForKey = true
end
end
AceGUI:ClearFocus()
end
 
local ignoreKeys = nil
local function Keybinding_OnKeyDown(this, key)
local self = this.obj
if self.waitingForKey then
local keyPressed = key
if keyPressed == "ESCAPE" then
keyPressed = ""
else
if not ignoreKeys then
ignoreKeys = {
["BUTTON1"] = true, ["BUTTON2"] = true,
["UNKNOWN"] = true,
["LSHIFT"] = true, ["LCTRL"] = true, ["LALT"] = true,
["RSHIFT"] = true, ["RCTRL"] = true, ["RALT"] = true,
}
end
if ignoreKeys[keyPressed] then return end
if IsShiftKeyDown() then
keyPressed = "SHIFT-"..keyPressed
end
if IsControlKeyDown() then
keyPressed = "CTRL-"..keyPressed
end
if IsAltKeyDown() then
keyPressed = "ALT-"..keyPressed
end
end
 
this:EnableKeyboard(false)
self.msgframe:Hide()
this:UnlockHighlight()
self.waitingForKey = nil
 
if not self.disabled then
self:SetKey(keyPressed)
self:Fire("OnKeyChanged",keyPressed)
end
end
end
 
local function Keybinding_OnMouseDown(this, button)
if button == "LeftButton" or button == "RightButton" then
return
elseif button == "MiddleButton" then
button = "BUTTON3"
elseif button == "Button4" then
button = "BUTTON4"
elseif button == "Button5" then
button = "BUTTON5"
end
Keybinding_OnKeyDown(this, button)
end
 
local function OnAcquire(self)
self:SetWidth(200)
self:SetHeight(44)
self:SetLabel("")
self:SetKey("")
end
 
local function OnRelease(self)
self.frame:ClearAllPoints()
self.frame:Hide()
self.waitingForKey = nil
self.msgframe:Hide()
end
 
local function SetDisabled(self, disabled)
self.disabled = disabled
if disabled then
self.button:Disable()
self.label:SetTextColor(0.5,0.5,0.5)
else
self.button:Enable()
self.label:SetTextColor(1,1,1)
end
end
 
local function SetKey(self, key)
if (key or "") == "" then
self.button:SetText(NOT_BOUND)
self.button:SetNormalFontObject("GameFontNormal")
else
self.button:SetText(key)
self.button:SetNormalFontObject("GameFontHighlight")
end
end
 
local function SetLabel(self, label)
self.label:SetText(label or "")
if (label or "") == "" then
self.alignoffset = nil
self:SetHeight(24)
else
self.alignoffset = 30
self:SetHeight(44)
end
end
 
local function Constructor()
local num = AceGUI:GetNextWidgetNum(Type)
local frame = CreateFrame("Frame",nil,UIParent)
 
local button = CreateFrame("Button","AceGUI-3.0 KeybindingButton"..num,frame,"UIPanelButtonTemplate2")
 
local self = {}
self.type = Type
self.num = num
 
local text = button:GetFontString()
text:SetPoint("LEFT",button,"LEFT",7,0)
text:SetPoint("RIGHT",button,"RIGHT",-7,0)
 
button:SetScript("OnClick",Keybinding_OnClick)
button:SetScript("OnKeyDown",Keybinding_OnKeyDown)
button:SetScript("OnEnter",Control_OnEnter)
button:SetScript("OnLeave",Control_OnLeave)
button:SetScript("OnMouseDown",Keybinding_OnMouseDown)
button:RegisterForClicks("AnyDown")
button:EnableMouse()
 
button:SetHeight(24)
button:SetWidth(200)
button:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT",0,0)
button:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,0)
 
frame:SetWidth(200)
frame:SetHeight(44)
 
self.alignoffset = 30
 
self.button = button
 
local label = frame:CreateFontString(nil,"OVERLAY","GameFontHighlight")
label:SetPoint("TOPLEFT",frame,"TOPLEFT",0,0)
label:SetPoint("TOPRIGHT",frame,"TOPRIGHT",0,0)
label:SetJustifyH("CENTER")
label:SetHeight(18)
self.label = label
 
local msgframe = CreateFrame("Frame",nil,UIParent)
msgframe:SetHeight(30)
msgframe:SetBackdrop(ControlBackdrop)
msgframe:SetBackdropColor(0,0,0)
msgframe:SetFrameStrata("FULLSCREEN_DIALOG")
msgframe:SetFrameLevel(1000)
self.msgframe = msgframe
local msg = msgframe:CreateFontString(nil,"OVERLAY","GameFontNormal")
msg:SetText("Press a key to bind, ESC to clear the binding or click the button again to cancel")
msgframe.msg = msg
msg:SetPoint("TOPLEFT",msgframe,"TOPLEFT",5,-5)
msgframe:SetScript("OnUpdate", keybindingMsgFixWidth)
msgframe:SetPoint("BOTTOM",button,"TOP",0,0)
msgframe:Hide()
 
self.OnRelease = OnRelease
self.OnAcquire = OnAcquire
self.SetLabel = SetLabel
self.SetDisabled = SetDisabled
self.SetKey = SetKey
 
self.frame = frame
frame.obj = self
button.obj = self
 
AceGUI:RegisterAsWidget(self)
return self
end
 
AceGUI:RegisterWidgetType(Type,Constructor,Version)
end
EasyDaily/libs/AceGUI-3.0/widgets/AceGUIWidget-CheckBox.lua New file
0,0 → 1,219
local AceGUI = LibStub("AceGUI-3.0")
 
--------------------------
-- Check Box --
--------------------------
--[[
Events :
OnValueChanged
 
]]
do
local Type = "CheckBox"
local Version = 5
 
local function OnAcquire(self)
self:SetValue(false)
self.tristate = nil
self:SetHeight(24)
self:SetWidth(200)
end
 
local function OnRelease(self)
self.frame:ClearAllPoints()
self.frame:Hide()
self.check:Hide()
self.highlight:Hide()
self.down = nil
self.checked = nil
self:SetType()
self:SetDisabled(false)
end
 
local function CheckBox_OnEnter(this)
local self = this.obj
if not self.disabled then
self.highlight:Show()
end
self:Fire("OnEnter")
end
 
local function CheckBox_OnLeave(this)
local self = this.obj
if not self.down then
self.highlight:Hide()
end
self:Fire("OnLeave")
end
 
local function CheckBox_OnMouseUp(this)
local self = this.obj
if not self.disabled then
self:ToggleChecked()
self:Fire("OnValueChanged",self.checked)
self.text:SetPoint("LEFT",self.check,"RIGHT",0,0)
end
self.down = nil
end
 
local function CheckBox_OnMouseDown(this)
local self = this.obj
if not self.disabled then
self.text:SetPoint("LEFT",self.check,"RIGHT",1,-1)
self.down = true
end
AceGUI:ClearFocus()
end
 
local function SetDisabled(self,disabled)
self.disabled = disabled
if disabled then
self.text:SetTextColor(0.5,0.5,0.5)
SetDesaturation(self.check, true)
else
self.text:SetTextColor(1,1,1)
if self.tristate and self.checked == nil then
SetDesaturation(self.check, true)
else
SetDesaturation(self.check, false)
end
end
end
 
local function SetValue(self,value)
local check = self.check
self.checked = value
if value then
SetDesaturation(self.check, false)
check:SetWidth(24)
check:SetHeight(24)
self.check:Show()
else
--Nil is the unknown tristate value
if self.tristate and value == nil then
SetDesaturation(self.check, true)
check:SetWidth(20)
check:SetHeight(20)
self.check:Show()
else
SetDesaturation(self.check, false)
check:SetWidth(24)
check:SetHeight(24)
self.check:Hide()
end
end
end
 
local function SetTriState(self, enabled)
self.tristate = enabled
self:SetValue(self:GetValue())
end
 
local function GetValue(self)
return self.checked
end
 
local function SetType(self, type)
local checkbg = self.checkbg
local check = self.check
local highlight = self.highlight
 
if type == "radio" then
checkbg:SetTexture("Interface\\Buttons\\UI-RadioButton")
checkbg:SetTexCoord(0,0.25,0,1)
check:SetTexture("Interface\\Buttons\\UI-RadioButton")
check:SetTexCoord(0.5,0.75,0,1)
check:SetBlendMode("ADD")
highlight:SetTexture("Interface\\Buttons\\UI-RadioButton")
highlight:SetTexCoord(0.5,0.75,0,1)
else
checkbg:SetTexture("Interface\\Buttons\\UI-CheckBox-Up")
checkbg:SetTexCoord(0,1,0,1)
check:SetTexture("Interface\\Buttons\\UI-CheckBox-Check")
check:SetTexCoord(0,1,0,1)
check:SetBlendMode("BLEND")
highlight:SetTexture("Interface\\Buttons\\UI-CheckBox-Highlight")
highlight:SetTexCoord(0,1,0,1)
end
end
 
local function ToggleChecked(self)
local value = self:GetValue()
if self.tristate then
--cycle in true, nil, false order
if value then
self:SetValue(nil)
elseif value == nil then
self:SetValue(false)
else
self:SetValue(true)
end
else
self:SetValue(not self:GetValue())
end
end
 
local function SetLabel(self, label)
self.text:SetText(label)
end
 
local function Constructor()
local frame = CreateFrame("Button",nil,UIParent)
local self = {}
self.type = Type
 
self.OnRelease = OnRelease
self.OnAcquire = OnAcquire
 
self.SetValue = SetValue
self.GetValue = GetValue
self.SetDisabled = SetDisabled
self.SetType = SetType
self.ToggleChecked = ToggleChecked
self.SetLabel = SetLabel
self.SetTriState = SetTriState
 
self.frame = frame
frame.obj = self
 
local text = frame:CreateFontString(nil,"OVERLAY","GameFontHighlight")
self.text = text
 
frame:SetScript("OnEnter",CheckBox_OnEnter)
frame:SetScript("OnLeave",CheckBox_OnLeave)
frame:SetScript("OnMouseUp",CheckBox_OnMouseUp)
frame:SetScript("OnMouseDown",CheckBox_OnMouseDown)
frame:EnableMouse()
local checkbg = frame:CreateTexture(nil,"ARTWORK")
self.checkbg = checkbg
checkbg:SetWidth(24)
checkbg:SetHeight(24)
checkbg:SetPoint("LEFT",frame,"LEFT",0,0)
checkbg:SetTexture("Interface\\Buttons\\UI-CheckBox-Up")
local check = frame:CreateTexture(nil,"OVERLAY")
self.check = check
check:SetWidth(24)
check:SetHeight(24)
check:SetPoint("CENTER",checkbg,"CENTER",0,0)
check:SetTexture("Interface\\Buttons\\UI-CheckBox-Check")
 
local highlight = frame:CreateTexture(nil, "BACKGROUND")
self.highlight = highlight
highlight:SetTexture("Interface\\Buttons\\UI-CheckBox-Highlight")
highlight:SetBlendMode("ADD")
highlight:SetAllPoints(checkbg)
highlight:Hide()
 
text:SetJustifyH("LEFT")
frame:SetHeight(24)
frame:SetWidth(200)
text:SetHeight(18)
text:SetPoint("LEFT",check,"RIGHT",0,0)
text:SetPoint("RIGHT",frame,"RIGHT",0,0)
 
AceGUI:RegisterAsWidget(self)
return self
end
 
AceGUI:RegisterWidgetType(Type,Constructor,Version)
end
EasyDaily/libs/AceGUI-3.0/widgets/AceGUIWidget-Icon.lua New file
0,0 → 1,126
local AceGUI = LibStub("AceGUI-3.0")
 
--------------------------
-- Label --
--------------------------
do
local Type = "Icon"
local Version = 9
 
local function OnAcquire(self)
self:SetHeight(110)
self:SetWidth(110)
self:SetLabel("")
self:SetImage(nil)
self:SetImageSize(64, 64)
end
 
local function OnRelease(self)
self.frame:ClearAllPoints()
self.frame:Hide()
end
 
local function SetLabel(self, text)
if text and text ~= "" then
self.label:Show()
self.label:SetText(text)
self.frame:SetHeight(self.image:GetHeight() + 25)
else
self.label:Hide()
self.frame:SetHeight(self.image:GetHeight() + 10)
end
end
 
local function SetImage(self, path, ...)
local image = self.image
image:SetTexture(path)
 
if image:GetTexture() then
self.imageshown = true
local n = select('#', ...)
if n == 4 or n == 8 then
image:SetTexCoord(...)
end
else
self.imageshown = nil
end
end
 
local function SetImageSize(self, width, height)
self.image:SetWidth(width)
self.image:SetHeight(height)
--self.frame:SetWidth(width + 30)
if self.label:IsShown() then
self.frame:SetHeight(height + 25)
else
self.frame:SetHeight(height + 10)
end
end
 
local function OnClick(this, button)
this.obj:Fire("OnClick", button)
AceGUI:ClearFocus()
end
 
local function OnEnter(this)
this.obj.highlight:Show()
this.obj:Fire("OnEnter")
end
 
local function OnLeave(this)
this.obj.highlight:Hide()
this.obj:Fire("OnLeave")
end
 
local function Constructor()
local frame = CreateFrame("Button",nil,UIParent)
local self = {}
self.type = Type
 
self.OnRelease = OnRelease
self.OnAcquire = OnAcquire
self.SetLabel = SetLabel
self.frame = frame
self.SetImage = SetImage
self.SetImageSize = SetImageSize
 
-- SetText should be deprecated along the way
self.SetText = SetLabel
 
frame.obj = self
 
frame:SetHeight(110)
frame:SetWidth(110)
frame:EnableMouse(true)
frame:SetScript("OnClick", OnClick)
frame:SetScript("OnLeave", OnLeave)
frame:SetScript("OnEnter", OnEnter)
local label = frame:CreateFontString(nil,"BACKGROUND","GameFontHighlight")
label:SetPoint("BOTTOMLEFT",frame,"BOTTOMLEFT",0,0)
label:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,0)
label:SetJustifyH("CENTER")
label:SetJustifyV("TOP")
label:SetHeight(18)
self.label = label
 
local image = frame:CreateTexture(nil,"BACKGROUND")
self.image = image
image:SetWidth(64)
image:SetHeight(64)
image:SetPoint("TOP",frame,"TOP",0,-5)
 
local highlight = frame:CreateTexture(nil,"OVERLAY")
self.highlight = highlight
highlight:SetAllPoints(image)
highlight:SetTexture("Interface\\PaperDollInfoFrame\\UI-Character-Tab-Highlight")
highlight:SetTexCoord(0,1,0.23,0.77)
highlight:SetBlendMode("ADD")
highlight:Hide()
 
AceGUI:RegisterAsWidget(self)
return self
end
 
AceGUI:RegisterWidgetType(Type,Constructor,Version)
end
 
EasyDaily/libs/AceGUI-3.0/widgets/AceGUIWidget-BlizOptionsGroup.lua New file
0,0 → 1,150
local AceGUI = LibStub("AceGUI-3.0")
 
 
-------------
-- Widgets --
-------------
--[[
Widgets must provide the following functions
Acquire() - Called when the object is aquired, should set everything to a default hidden state
Release() - Called when the object is Released, should remove any anchors and hide the Widget
 
And the following members
frame - the frame or derivitive object that will be treated as the widget for size and anchoring purposes
type - the type of the object, same as the name given to :RegisterWidget()
 
Widgets contain a table called userdata, this is a safe place to store data associated with the wigdet
It will be cleared automatically when a widget is released
Placing values directly into a widget object should be avoided
 
If the Widget can act as a container for other Widgets the following
content - frame or derivitive that children will be anchored to
 
The Widget can supply the following Optional Members
 
 
]]
 
----------------------------------
-- Blizzard Options Group --
----------------------------------
--[[
Group Designed to be added to the bliz interface options panel
]]
 
do
local Type = "BlizOptionsGroup"
local Version = 6
 
local function OnAcquire(self)
 
end
 
local function OnRelease(self)
self.frame:ClearAllPoints()
self.frame:Hide()
self:SetName()
end
 
local function okay(this)
this.obj:Fire("okay")
end
 
local function cancel(this)
this.obj:Fire("cancel")
end
 
local function defaults(this)
this.obj:Fire("defaults")
end
 
local function SetName(self, name, parent)
self.frame.name = name
self.frame.parent = parent
end
 
local function OnShow(this)
this.obj:Fire("OnShow")
end
 
local function OnHide(this)
this.obj:Fire("OnHide")
end
 
local function OnWidthSet(self, width)
local content = self.content
local contentwidth = width - 63
if contentwidth < 0 then
contentwidth = 0
end
content:SetWidth(contentwidth)
content.width = contentwidth
end
 
 
local function OnHeightSet(self, height)
local content = self.content
local contentheight = height - 26
if contentheight < 0 then
contentheight = 0
end
content:SetHeight(contentheight)
content.height = contentheight
end
 
local function SetTitle(self, title)
local content = self.content
content:ClearAllPoints()
if not title or title == "" then
content:SetPoint("TOPLEFT",self.frame,"TOPLEFT",15,-10)
self.label:SetText("")
else
content:SetPoint("TOPLEFT",self.frame,"TOPLEFT",15,-40)
self.label:SetText(title)
end
content:SetPoint("BOTTOMRIGHT",self.frame,"BOTTOMRIGHT",-10,10)
end
 
local function Constructor()
local frame = CreateFrame("Frame")
local self = {}
self.type = Type
 
self.OnRelease = OnRelease
self.OnAcquire = OnAcquire
self.frame = frame
self.SetName = SetName
 
self.OnWidthSet = OnWidthSet
self.OnHeightSet = OnHeightSet
self.SetTitle = SetTitle
 
frame.obj = self
frame.okay = okay
frame.cancel = cancel
frame.defaults = defaults
 
frame:Hide()
frame:SetScript("OnHide",OnHide)
frame:SetScript("OnShow",OnShow)
 
local label = frame:CreateFontString(nil,"OVERLAY","GameFontNormalLarge")
self.label = label
label:SetPoint("TOPLEFT", frame, "TOPLEFT", 15, -15)
label:SetPoint("BOTTOMRIGHT", frame, "TOPRIGHT", 10, -45)
label:SetJustifyH("LEFT")
label:SetJustifyV("TOP")
 
--Container Support
local content = CreateFrame("Frame",nil,frame)
self.content = content
content.obj = self
content:SetPoint("TOPLEFT",frame,"TOPLEFT",15,-10)
content:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-10,10)
 
AceGUI:RegisterAsContainer(self)
return self
end
 
AceGUI:RegisterWidgetType(Type,Constructor,Version)
end
EasyDaily/libs/AceGUI-3.0/widgets/AceGUIWidget-Frame.lua New file
0,0 → 1,299
local AceGUI = LibStub("AceGUI-3.0")
 
----------------
-- Main Frame --
----------------
--[[
Events :
OnClose
 
]]
do
local Type = "Frame"
local Version = 7
 
local FrameBackdrop = {
bgFile="Interface\\DialogFrame\\UI-DialogBox-Background",
edgeFile="Interface\\DialogFrame\\UI-DialogBox-Border",
tile = true, tileSize = 32, edgeSize = 32,
insets = { left = 8, right = 8, top = 8, bottom = 8 }
}
 
local PaneBackdrop = {
bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
tile = true, tileSize = 16, edgeSize = 16,
insets = { left = 3, right = 3, top = 5, bottom = 3 }
}
 
local function frameOnClose(this)
this.obj:Fire("OnClose")
end
 
local function closeOnClick(this)
this.obj:Hide()
end
 
local function frameOnMouseDown(this)
AceGUI:ClearFocus()
end
 
local function titleOnMouseDown(this)
this:GetParent():StartMoving()
AceGUI:ClearFocus()
end
 
local function frameOnMouseUp(this)
local frame = this:GetParent()
frame:StopMovingOrSizing()
local self = frame.obj
local status = self.status or self.localstatus
status.width = frame:GetWidth()
status.height = frame:GetHeight()
status.top = frame:GetTop()
status.left = frame:GetLeft()
end
 
local function sizerseOnMouseDown(this)
this:GetParent():StartSizing("BOTTOMRIGHT")
AceGUI:ClearFocus()
end
 
local function sizersOnMouseDown(this)
this:GetParent():StartSizing("BOTTOM")
AceGUI:ClearFocus()
end
 
local function sizereOnMouseDown(this)
this:GetParent():StartSizing("RIGHT")
AceGUI:ClearFocus()
end
 
local function sizerOnMouseUp(this)
this:GetParent():StopMovingOrSizing()
end
 
local function SetTitle(self,title)
self.titletext:SetText(title)
end
 
local function SetStatusText(self,text)
self.statustext:SetText(text)
end
 
local function Hide(self)
self.frame:Hide()
end
 
local function Show(self)
self.frame:Show()
end
 
local function OnAcquire(self)
self.frame:SetParent(UIParent)
self.frame:SetFrameStrata("FULLSCREEN_DIALOG")
self:ApplyStatus()
end
 
local function OnRelease(self)
self.status = nil
for k in pairs(self.localstatus) do
self.localstatus[k] = nil
end
end
 
-- called to set an external table to store status in
local function SetStatusTable(self, status)
assert(type(status) == "table")
self.status = status
self:ApplyStatus()
end
 
local function ApplyStatus(self)
local status = self.status or self.localstatus
local frame = self.frame
self:SetWidth(status.width or 700)
self:SetHeight(status.height or 500)
if status.top and status.left then
frame:SetPoint("TOP",UIParent,"BOTTOM",0,status.top)
frame:SetPoint("LEFT",UIParent,"LEFT",status.left,0)
else
frame:SetPoint("CENTER",UIParent,"CENTER")
end
end
 
local function OnWidthSet(self, width)
local content = self.content
local contentwidth = width - 34
if contentwidth < 0 then
contentwidth = 0
end
content:SetWidth(contentwidth)
content.width = contentwidth
end
 
 
local function OnHeightSet(self, height)
local content = self.content
local contentheight = height - 57
if contentheight < 0 then
contentheight = 0
end
content:SetHeight(contentheight)
content.height = contentheight
end
 
local function Constructor()
local frame = CreateFrame("Frame",nil,UIParent)
local self = {}
self.type = "Frame"
 
self.Hide = Hide
self.Show = Show
self.SetTitle = SetTitle
self.OnRelease = OnRelease
self.OnAcquire = OnAcquire
self.SetStatusText = SetStatusText
self.SetStatusTable = SetStatusTable
self.ApplyStatus = ApplyStatus
self.OnWidthSet = OnWidthSet
self.OnHeightSet = OnHeightSet
 
self.localstatus = {}
 
self.frame = frame
frame.obj = self
frame:SetWidth(700)
frame:SetHeight(500)
frame:SetPoint("CENTER",UIParent,"CENTER",0,0)
frame:EnableMouse()
frame:SetMovable(true)
frame:SetResizable(true)
frame:SetFrameStrata("FULLSCREEN_DIALOG")
frame:SetScript("OnMouseDown", frameOnMouseDown)
 
frame:SetBackdrop(FrameBackdrop)
frame:SetBackdropColor(0,0,0,1)
frame:SetScript("OnHide",frameOnClose)
frame:SetMinResize(400,200)
frame:SetToplevel(true)
 
local closebutton = CreateFrame("Button",nil,frame,"UIPanelButtonTemplate")
closebutton:SetScript("OnClick", closeOnClick)
closebutton:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-27,17)
closebutton:SetHeight(20)
closebutton:SetWidth(100)
closebutton:SetText("Close")
 
self.closebutton = closebutton
closebutton.obj = self
 
local statusbg = CreateFrame("Frame",nil,frame)
statusbg:SetPoint("BOTTOMLEFT",frame,"BOTTOMLEFT",15,15)
statusbg:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-132,15)
statusbg:SetHeight(24)
statusbg:SetBackdrop(PaneBackdrop)
statusbg:SetBackdropColor(0.1,0.1,0.1)
statusbg:SetBackdropBorderColor(0.4,0.4,0.4)
self.statusbg = statusbg
 
local statustext = statusbg:CreateFontString(nil,"OVERLAY","GameFontNormal")
self.statustext = statustext
statustext:SetPoint("TOPLEFT",statusbg,"TOPLEFT",7,-2)
statustext:SetPoint("BOTTOMRIGHT",statusbg,"BOTTOMRIGHT",-7,2)
statustext:SetHeight(20)
statustext:SetJustifyH("LEFT")
statustext:SetText("")
 
local title = CreateFrame("Frame",nil,frame)
self.title = title
title:EnableMouse()
title:SetScript("OnMouseDown",titleOnMouseDown)
title:SetScript("OnMouseUp", frameOnMouseUp)
 
 
local titlebg = frame:CreateTexture(nil,"OVERLAY")
titlebg:SetTexture("Interface\\DialogFrame\\UI-DialogBox-Header")
titlebg:SetTexCoord(0.31,0.67,0,0.63)
titlebg:SetPoint("TOP",frame,"TOP",0,12)
titlebg:SetWidth(100)
titlebg:SetHeight(40)
 
local titlebg_l = frame:CreateTexture(nil,"OVERLAY")
titlebg_l:SetTexture("Interface\\DialogFrame\\UI-DialogBox-Header")
titlebg_l:SetTexCoord(0.21,0.31,0,0.63)
titlebg_l:SetPoint("RIGHT",titlebg,"LEFT",0,0)
titlebg_l:SetWidth(30)
titlebg_l:SetHeight(40)
 
local titlebg_right = frame:CreateTexture(nil,"OVERLAY")
titlebg_right:SetTexture("Interface\\DialogFrame\\UI-DialogBox-Header")
titlebg_right:SetTexCoord(0.67,0.77,0,0.63)
titlebg_right:SetPoint("LEFT",titlebg,"RIGHT",0,0)
titlebg_right:SetWidth(30)
titlebg_right:SetHeight(40)
 
title:SetAllPoints(titlebg)
local titletext = title:CreateFontString(nil,"OVERLAY","GameFontNormal")
titletext:SetPoint("TOP",titlebg,"TOP",0,-14)
 
self.titletext = titletext
 
local sizer_se = CreateFrame("Frame",nil,frame)
sizer_se:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,0)
sizer_se:SetWidth(25)
sizer_se:SetHeight(25)
sizer_se:EnableMouse()
sizer_se:SetScript("OnMouseDown",sizerseOnMouseDown)
sizer_se:SetScript("OnMouseUp", sizerOnMouseUp)
self.sizer_se = sizer_se
 
local line1 = sizer_se:CreateTexture(nil, "BACKGROUND")
self.line1 = line1
line1:SetWidth(14)
line1:SetHeight(14)
line1:SetPoint("BOTTOMRIGHT", -8, 8)
line1:SetTexture("Interface\\Tooltips\\UI-Tooltip-Border")
local x = 0.1 * 14/17
line1:SetTexCoord(0.05 - x, 0.5, 0.05, 0.5 + x, 0.05, 0.5 - x, 0.5 + x, 0.5)
 
local line2 = sizer_se:CreateTexture(nil, "BACKGROUND")
self.line2 = line2
line2:SetWidth(8)
line2:SetHeight(8)
line2:SetPoint("BOTTOMRIGHT", -8, 8)
line2:SetTexture("Interface\\Tooltips\\UI-Tooltip-Border")
local x = 0.1 * 8/17
line2:SetTexCoord(0.05 - x, 0.5, 0.05, 0.5 + x, 0.05, 0.5 - x, 0.5 + x, 0.5)
 
local sizer_s = CreateFrame("Frame",nil,frame)
sizer_s:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-25,0)
sizer_s:SetPoint("BOTTOMLEFT",frame,"BOTTOMLEFT",0,0)
sizer_s:SetHeight(25)
sizer_s:EnableMouse()
sizer_s:SetScript("OnMouseDown",sizersOnMouseDown)
sizer_s:SetScript("OnMouseUp", sizerOnMouseUp)
self.sizer_s = sizer_s
 
local sizer_e = CreateFrame("Frame",nil,frame)
sizer_e:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,25)
sizer_e:SetPoint("TOPRIGHT",frame,"TOPRIGHT",0,0)
sizer_e:SetWidth(25)
sizer_e:EnableMouse()
sizer_e:SetScript("OnMouseDown",sizereOnMouseDown)
sizer_e:SetScript("OnMouseUp", sizerOnMouseUp)
self.sizer_e = sizer_e
 
--Container Support
local content = CreateFrame("Frame",nil,frame)
self.content = content
content.obj = self
content:SetPoint("TOPLEFT",frame,"TOPLEFT",17,-27)
content:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-17,40)
 
AceGUI:RegisterAsContainer(self)
return self
end
 
AceGUI:RegisterWidgetType(Type,Constructor,Version)
end
EasyDaily/libs/AceGUI-3.0/widgets/AceGUIWidget-InlineGroup.lua New file
0,0 → 1,136
local AceGUI = LibStub("AceGUI-3.0")
 
 
-------------
-- Widgets --
-------------
--[[
Widgets must provide the following functions
Acquire() - Called when the object is aquired, should set everything to a default hidden state
Release() - Called when the object is Released, should remove any anchors and hide the Widget
 
And the following members
frame - the frame or derivitive object that will be treated as the widget for size and anchoring purposes
type - the type of the object, same as the name given to :RegisterWidget()
 
Widgets contain a table called userdata, this is a safe place to store data associated with the wigdet
It will be cleared automatically when a widget is released
Placing values directly into a widget object should be avoided
 
If the Widget can act as a container for other Widgets the following
content - frame or derivitive that children will be anchored to
 
The Widget can supply the following Optional Members
 
 
]]
 
--------------------------
-- Inline Group --
--------------------------
--[[
This is a simple grouping container, no selection
It will resize automatically to the height of the controls added to it
]]
 
do
local Type = "InlineGroup"
local Version = 5
 
local function OnAcquire(self)
self:SetWidth(300)
self:SetHeight(100)
end
 
local function OnRelease(self)
self.frame:ClearAllPoints()
self.frame:Hide()
end
 
local PaneBackdrop = {
bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
tile = true, tileSize = 16, edgeSize = 16,
insets = { left = 3, right = 3, top = 5, bottom = 3 }
}
 
local function SetTitle(self,title)
self.titletext:SetText(title)
end
 
 
local function LayoutFinished(self, width, height)
if self.noAutoHeight then return end
self:SetHeight((height or 0) + 40)
end
 
local function OnWidthSet(self, width)
local content = self.content
local contentwidth = width - 20
if contentwidth < 0 then
contentwidth = 0
end
content:SetWidth(contentwidth)
content.width = contentwidth
end
 
 
local function OnHeightSet(self, height)
local content = self.content
local contentheight = height - 20
if contentheight < 0 then
contentheight = 0
end
content:SetHeight(contentheight)
content.height = contentheight
end
 
local function Constructor()
local frame = CreateFrame("Frame",nil,UIParent)
local self = {}
self.type = Type
 
self.OnRelease = OnRelease
self.OnAcquire = OnAcquire
self.SetTitle = SetTitle
self.frame = frame
self.LayoutFinished = LayoutFinished
self.OnWidthSet = OnWidthSet
self.OnHeightSet = OnHeightSet
 
frame.obj = self
 
frame:SetHeight(100)
frame:SetWidth(100)
frame:SetFrameStrata("FULLSCREEN_DIALOG")
 
local titletext = frame:CreateFontString(nil,"OVERLAY","GameFontNormal")
titletext:SetPoint("TOPLEFT",frame,"TOPLEFT",14,0)
titletext:SetPoint("TOPRIGHT",frame,"TOPRIGHT",-14,0)
titletext:SetJustifyH("LEFT")
titletext:SetHeight(18)
 
self.titletext = titletext
 
local border = CreateFrame("Frame",nil,frame)
self.border = border
border:SetPoint("TOPLEFT",frame,"TOPLEFT",3,-17)
border:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-3,3)
 
border:SetBackdrop(PaneBackdrop)
border:SetBackdropColor(0.1,0.1,0.1,0.5)
border:SetBackdropBorderColor(0.4,0.4,0.4)
 
--Container Support
local content = CreateFrame("Frame",nil,border)
self.content = content
content.obj = self
content:SetPoint("TOPLEFT",border,"TOPLEFT",10,-10)
content:SetPoint("BOTTOMRIGHT",border,"BOTTOMRIGHT",-10,10)
 
AceGUI:RegisterAsContainer(self)
return self
end
 
AceGUI:RegisterWidgetType(Type,Constructor,Version)
end
EasyDaily/libs/AceGUI-3.0/widgets/AceGUIWidget-DropDown.lua New file
0,0 → 1,687
--[[ $Id: AceGUIWidget-DropDown.lua 793 2009-04-07 09:26:44Z nevcairiel $ ]]--
local min, max, floor = math.min, math.max, math.floor
 
local AceGUI = LibStub("AceGUI-3.0")
 
local function fixlevels(parent,...)
local i = 1
local child = select(i, ...)
while child do
child:SetFrameLevel(parent:GetFrameLevel()+1)
fixlevels(child, child:GetChildren())
i = i + 1
child = select(i, ...)
end
end
 
local function fixstrata(strata, parent, ...)
local i = 1
local child = select(i, ...)
parent:SetFrameStrata(strata)
while child do
fixstrata(strata, child, child:GetChildren())
i = i + 1
child = select(i, ...)
end
end
 
do
local widgetType = "Dropdown-Pullout"
local widgetVersion = 2
 
--[[ Static data ]]--
 
local backdrop = {
bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background",
edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
edgeSize = 32,
tileSize = 32,
tile = true,
insets = { left = 11, right = 12, top = 12, bottom = 11 },
}
local sliderBackdrop = {
bgFile = "Interface\\Buttons\\UI-SliderBar-Background",
edgeFile = "Interface\\Buttons\\UI-SliderBar-Border",
tile = true, tileSize = 8, edgeSize = 8,
insets = { left = 3, right = 3, top = 3, bottom = 3 }
}
 
local defaultWidth = 200
local defaultMaxHeight = 600
 
--[[ UI Event Handlers ]]--
 
-- HACK: This should be no part of the pullout, but there
-- is no other 'clean' way to response to any item-OnEnter
-- Used to close Submenus when an other item is entered
local function OnEnter(item)
local self = item.pullout
for k, v in ipairs(self.items) do
if v.CloseMenu and v ~= item then
v:CloseMenu()
end
end
end
 
-- See the note in Constructor() for each scroll related function
local function OnMouseWheel(this, value)
this.obj:MoveScroll(value)
end
 
local function OnScrollValueChanged(this, value)
this.obj:SetScroll(value)
end
 
local function OnSizeChanged(this)
this.obj:FixScroll()
end
 
--[[ Exported methods ]]--
 
-- exported
local function SetScroll(self, value)
local status = self.scrollStatus
local frame, child = self.scrollFrame, self.itemFrame
local height, viewheight = frame:GetHeight(), child:GetHeight()
 
local offset
if height > viewheight then
offset = 0
else
offset = floor((viewheight - height) / 1000 * value)
end
child:ClearAllPoints()
child:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, offset)
child:SetPoint("TOPRIGHT", frame, "TOPRIGHT", self.slider:IsShown() and -12 or 0, offset)
status.offset = offset
status.scrollvalue = value
end
 
-- exported
local function MoveScroll(self, value)
local status = self.scrollStatus
local frame, child = self.scrollFrame, self.itemFrame
local height, viewheight = frame:GetHeight(), child:GetHeight()
 
if height > viewheight then
self.slider:Hide()
else
self.slider:Show()
local diff = height - viewheight
local delta = 1
if value < 0 then
delta = -1
end
self.slider:SetValue(min(max(status.scrollvalue + delta*(1000/(diff/45)),0), 1000))
end
end
 
-- exported
local function FixScroll(self)
local status = self.scrollStatus
local frame, child = self.scrollFrame, self.itemFrame
local height, viewheight = frame:GetHeight(), child:GetHeight()
local offset = status.offset or 0
 
if viewheight < height then
self.slider:Hide()
child:SetPoint("TOPRIGHT", frame, "TOPRIGHT", 0, offset)
self.slider:SetValue(0)
else
self.slider:Show()
local value = (offset / (viewheight - height) * 1000)
if value > 1000 then value = 1000 end
self.slider:SetValue(value)
self:SetScroll(value)
if value < 1000 then
child:ClearAllPoints()
child:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, offset)
child:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -12, offset)
status.offset = offset
end
end
end
 
-- exported, AceGUI callback
local function OnAcquire(self)
self.frame:SetParent(UIParent)
--self.itemFrame:SetToplevel(true)
end
 
-- exported, AceGUI callback
local function OnRelease(self)
self:Clear()
self.frame:ClearAllPoints()
self.frame:Hide()
end
 
-- exported
local function AddItem(self, item)
self.items[#self.items + 1] = item
 
local h = #self.items * 16
self.itemFrame:SetHeight(h)
self.frame:SetHeight(min(h + 34, self.maxHeight)) -- +34: 20 for scrollFrame placement (10 offset) and +14 for item placement
 
item.frame:SetPoint("LEFT", self.itemFrame, "LEFT")
item.frame:SetPoint("RIGHT", self.itemFrame, "RIGHT")
 
item:SetPullout(self)
item:SetOnEnter(OnEnter)
end
 
-- exported
local function Open(self, point, relFrame, relPoint, x, y)
local items = self.items
local frame = self.frame
local itemFrame = self.itemFrame
 
frame:SetPoint(point, relFrame, relPoint, x, y)
 
 
local height = 8
for i, item in pairs(items) do
if i == 1 then
item:SetPoint("TOP", itemFrame, "TOP", 0, -2)
else
item:SetPoint("TOP", items[i-1].frame, "BOTTOM", 0, 1)
end
 
item:Show()
 
height = height + 16
end
itemFrame:SetHeight(height)
fixstrata("TOOLTIP", frame, frame:GetChildren())
frame:Show()
self:Fire("OnOpen")
end
 
-- exported
local function Close(self)
self.frame:Hide()
self:Fire("OnClose")
end
 
-- exported
local function Clear(self)
local items = self.items
for i, item in pairs(items) do
AceGUI:Release(item)
items[i] = nil
end
end
 
-- exported
local function IterateItems(self)
return ipairs(self.items)
end
 
-- exported
local function SetHideOnLeave(self, val)
self.hideOnLeave = val
end
 
-- exported
local function SetMaxHeight(self, height)
self.maxHeight = height or defaultMaxHeight
if self.frame:GetHeight() > height then
self.frame:SetHeight(height)
elseif (self.itemFrame:GetHeight() + 34) < height then
self.frame:SetHeight(self.itemFrame:GetHeight() + 34) -- see :AddItem
end
end
 
-- exported
local function GetRightBorderWidth(self)
return 6 + (self.slider:IsShown() and 12 or 0)
end
 
-- exported
local function GetLeftBorderWidth(self)
return 6
end
 
--[[ Constructor ]]--
 
local function Constructor()
local count = AceGUI:GetNextWidgetNum(widgetType)
local frame = CreateFrame("Frame", "AceGUI30Pullout"..count, UIParent)
local self = {}
self.count = count
self.type = widgetType
self.frame = frame
frame.obj = self
 
self.OnAcquire = OnAcquire
self.OnRelease = OnRelease
 
self.AddItem = AddItem
self.Open = Open
self.Close = Close
self.Clear = Clear
self.IterateItems = IterateItems
self.SetHideOnLeave = SetHideOnLeave
 
self.SetScroll = SetScroll
self.MoveScroll = MoveScroll
self.FixScroll = FixScroll
 
self.SetMaxHeight = SetMaxHeight
self.GetRightBorderWidth = GetRightBorderWidth
self.GetLeftBorderWidth = GetLeftBorderWidth
 
self.items = {}
 
self.scrollStatus = {
scrollvalue = 0,
}
 
self.maxHeight = defaultMaxHeight
 
frame:SetBackdrop(backdrop)
frame:SetBackdropColor(0, 0, 0)
frame:SetFrameStrata("FULLSCREEN_DIALOG")
frame:SetClampedToScreen(true)
frame:SetWidth(defaultWidth)
frame:SetHeight(self.maxHeight)
--frame:SetToplevel(true)
 
-- NOTE: The whole scroll frame code is copied from the AceGUI-3.0 widget ScrollFrame
local scrollFrame = CreateFrame("ScrollFrame", nil, frame)
local itemFrame = CreateFrame("Frame", nil, scrollFrame)
 
self.scrollFrame = scrollFrame
self.itemFrame = itemFrame
 
scrollFrame.obj = self
itemFrame.obj = self
 
local slider = CreateFrame("Slider", "AceGUI30PulloutScrollbar"..count, scrollFrame)
slider:SetOrientation("VERTICAL")
slider:SetHitRectInsets(0, 0, -10, 0)
slider:SetBackdrop(sliderBackdrop)
slider:SetWidth(8)
slider:SetThumbTexture("Interface\\Buttons\\UI-SliderBar-Button-Vertical")
slider:SetFrameStrata("FULLSCREEN_DIALOG")
self.slider = slider
slider.obj = self
 
scrollFrame:SetScrollChild(itemFrame)
scrollFrame:SetPoint("TOPLEFT", frame, "TOPLEFT", 6, -12)
scrollFrame:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -6, 12)
scrollFrame:EnableMouseWheel(true)
scrollFrame:SetScript("OnMouseWheel", OnMouseWheel)
scrollFrame:SetScript("OnSizeChanged", OnSizeChanged)
scrollFrame:SetToplevel(true)
scrollFrame:SetFrameStrata("FULLSCREEN_DIALOG")
 
itemFrame:SetPoint("TOPLEFT", scrollFrame, "TOPLEFT", 0, 0)
itemFrame:SetPoint("TOPRIGHT", scrollFrame, "TOPRIGHT", -12, 0)
itemFrame:SetHeight(400)
itemFrame:SetToplevel(true)
itemFrame:SetFrameStrata("FULLSCREEN_DIALOG")
 
slider:SetPoint("TOPLEFT", scrollFrame, "TOPRIGHT", -16, 0)
slider:SetPoint("BOTTOMLEFT", scrollFrame, "BOTTOMRIGHT", -16, 0)
slider:SetScript("OnValueChanged", OnScrollValueChanged)
slider:SetMinMaxValues(0, 1000)
slider:SetValueStep(1)
slider:SetValue(0)
 
scrollFrame:Show()
itemFrame:Show()
slider:Hide()
 
self:FixScroll()
 
AceGUI:RegisterAsWidget(self)
return self
end
 
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion)
end
 
do
local widgetType = "Dropdown"
local widgetVersion = 19
 
--[[ Static data ]]--
 
--[[ UI event handler ]]--
 
local function Control_OnEnter(this)
this.obj:Fire("OnEnter")
end
 
local function Control_OnLeave(this)
this.obj:Fire("OnLeave")
end
 
local function Dropdown_OnHide(this)
local self = this.obj
if self.open then
self.pullout:Close()
end
end
 
local function Dropdown_TogglePullout(this)
local self = this.obj
if self.open then
self.open = nil
self.pullout:Close()
AceGUI:ClearFocus()
else
self.open = true
self.pullout:SetWidth(self.frame:GetWidth())
self.pullout:Open("TOPLEFT", self.frame, "BOTTOMLEFT", 0, self.label:IsShown() and -2 or 0)
AceGUI:SetFocus(self)
end
end
 
local function OnPulloutOpen(this)
local self = this.userdata.obj
local value = self.value
 
if not self.multiselect then
for i, item in this:IterateItems() do
item:SetValue(item.userdata.value == value)
end
end
 
self.open = true
end
 
local function OnPulloutClose(this)
local self = this.userdata.obj
self.open = nil
self:Fire("OnClosed")
end
 
local function ShowMultiText(self)
local text
for i, widget in self.pullout:IterateItems() do
if widget.type == "Dropdown-Item-Toggle" then
if widget:GetValue() then
if text then
text = text..", "..widget:GetText()
else
text = widget:GetText()
end
end
end
end
self:SetText(text)
end
 
local function OnItemValueChanged(this, event, checked)
local self = this.userdata.obj
 
if self.multiselect then
self:Fire("OnValueChanged", this.userdata.value, checked)
ShowMultiText(self)
else
if checked then
self:SetValue(this.userdata.value)
self:Fire("OnValueChanged", this.userdata.value)
else
this:SetValue(true)
end
if self.open then
self.pullout:Close()
end
end
end
 
--[[ Exported methods ]]--
 
-- exported, AceGUI callback
local function OnAcquire(self)
local pullout = AceGUI:Create("Dropdown-Pullout")
self.pullout = pullout
pullout.userdata.obj = self
pullout:SetCallback("OnClose", OnPulloutClose)
pullout:SetCallback("OnOpen", OnPulloutOpen)
self.pullout.frame:SetFrameLevel(self.frame:GetFrameLevel() + 1)
fixlevels(self.pullout.frame, self.pullout.frame:GetChildren())
 
self:SetHeight(44)
self:SetWidth(200)
end
 
-- exported, AceGUI callback
local function OnRelease(self)
if self.open then
self.pullout:Close()
end
AceGUI:Release(self.pullout)
 
self:SetText("")
self:SetLabel("")
self:SetDisabled(false)
self:SetMultiselect(false)
 
self.value = nil
self.list = nil
self.open = nil
self.hasClose = nil
 
self.frame:ClearAllPoints()
self.frame:Hide()
end
 
-- exported
local function SetDisabled(self, disabled)
self.disabled = disabled
if disabled then
self.text:SetTextColor(0.5,0.5,0.5)
self.button:Disable()
self.label:SetTextColor(0.5,0.5,0.5)
else
self.button:Enable()
self.label:SetTextColor(1,.82,0)
self.text:SetTextColor(1,1,1)
end
end
 
-- exported
local function ClearFocus(self)
if self.open then
self.pullout:Close()
end
end
 
-- exported
local function SetText(self, text)
self.text:SetText(text or "")
end
 
-- exported
local function SetLabel(self, text)
if text and text ~= "" then
self.label:SetText(text)
self.label:Show()
self.dropdown:SetPoint("TOPLEFT",self.frame,"TOPLEFT",-15,-18)
self.frame:SetHeight(44)
else
self.label:SetText("")
self.label:Hide()
self.dropdown:SetPoint("TOPLEFT",self.frame,"TOPLEFT",-15,0)
self.frame:SetHeight(26)
end
end
 
-- exported
local function SetValue(self, value)
if self.list then
self:SetText(self.list[value] or "")
end
self.value = value
end
 
-- exported
local function SetItemValue(self, item, value)
if not self.multiselect then return end
for i, widget in self.pullout:IterateItems() do
if widget.userdata.value == item then
if widget.SetValue then
widget:SetValue(value)
end
end
end
ShowMultiText(self)
end
 
-- exported
local function SetItemDisabled(self, item, disabled)
for i, widget in self.pullout:IterateItems() do
if widget.userdata.value == item then
widget:SetDisabled(disabled)
end
end
end
 
local function AddListItem(self, value, text)
local item = AceGUI:Create("Dropdown-Item-Toggle")
item:SetText(text)
item.userdata.obj = self
item.userdata.value = value
item:SetCallback("OnValueChanged", OnItemValueChanged)
self.pullout:AddItem(item)
end
 
local function AddCloseButton(self)
if not self.hasClose then
local close = AceGUI:Create("Dropdown-Item-Execute")
close:SetText(CLOSE)
self.pullout:AddItem(close)
self.hasClose = true
end
end
 
-- exported
local sortlist = {}
local function SetList(self, list)
self.list = list
self.pullout:Clear()
self.hasClose = nil
if not list then return end
 
for v in pairs(list) do
sortlist[#sortlist + 1] = v
end
table.sort(sortlist)
 
for i, value in pairs(sortlist) do
AddListItem(self, value, list[value])
sortlist[i] = nil
end
if self.multiselect then
ShowMultiText(self)
AddCloseButton(self)
end
end
 
-- exported
local function AddItem(self, value, text)
if self.list then
self.list[value] = text
AddListItem(self, value, text)
end
end
 
-- exported
local function SetMultiselect(self, multi)
self.multiselect = multi
if multi then
ShowMultiText(self)
AddCloseButton(self)
end
end
 
-- exported
local function GetMultiselect(self)
return self.multiselect
end
 
--[[ Constructor ]]--
 
local function Constructor()
local count = AceGUI:GetNextWidgetNum(widgetType)
local frame = CreateFrame("Frame", nil, UIParent)
local dropdown = CreateFrame("Frame", "AceGUI30DropDown"..count, frame, "UIDropDownMenuTemplate")
 
local self = {}
self.type = widgetType
self.frame = frame
self.dropdown = dropdown
self.count = count
frame.obj = self
dropdown.obj = self
 
self.OnRelease = OnRelease
self.OnAcquire = OnAcquire
 
self.ClearFocus = ClearFocus
 
self.SetText = SetText
self.SetValue = SetValue
self.SetList = SetList
self.SetLabel = SetLabel
self.SetDisabled = SetDisabled
self.AddItem = AddItem
self.SetMultiselect = SetMultiselect
self.GetMultiselect = GetMultiselect
self.SetItemValue = SetItemValue
self.SetItemDisabled = SetItemDisabled
 
self.alignoffset = 31
 
frame:SetHeight(44)
frame:SetWidth(200)
frame:SetScript("OnHide",Dropdown_OnHide)
 
dropdown:ClearAllPoints()
dropdown:SetPoint("TOPLEFT",frame,"TOPLEFT",-15,0)
dropdown:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",17,0)
dropdown:SetScript("OnHide", nil)
 
local left = _G[dropdown:GetName() .. "Left"]
local middle = _G[dropdown:GetName() .. "Middle"]
local right = _G[dropdown:GetName() .. "Right"]
 
middle:ClearAllPoints()
right:ClearAllPoints()
 
middle:SetPoint("LEFT", left, "RIGHT", 0, 0)
middle:SetPoint("RIGHT", right, "LEFT", 0, 0)
right:SetPoint("TOPRIGHT", dropdown, "TOPRIGHT", 0, 17)
 
local button = _G[dropdown:GetName() .. "Button"]
self.button = button
button.obj = self
button:SetScript("OnEnter",Control_OnEnter)
button:SetScript("OnLeave",Control_OnLeave)
button:SetScript("OnClick",Dropdown_TogglePullout)
 
local text = _G[dropdown:GetName() .. "Text"]
self.text = text
text.obj = self
text:ClearAllPoints()
text:SetPoint("RIGHT", right, "RIGHT" ,-43, 2)
text:SetPoint("LEFT", left, "LEFT", 25, 2)
 
local label = frame:CreateFontString(nil,"OVERLAY","GameFontNormalSmall")
label:SetPoint("TOPLEFT",frame,"TOPLEFT",0,0)
label:SetPoint("TOPRIGHT",frame,"TOPRIGHT",0,0)
label:SetJustifyH("LEFT")
label:SetHeight(18)
label:Hide()
self.label = label
 
AceGUI:RegisterAsWidget(self)
return self
end
 
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion)
end
EasyDaily/libs/AceGUI-3.0/widgets/AceGUIWidget-EditBox.lua New file
0,0 → 1,204
local AceGUI = LibStub("AceGUI-3.0")
 
--------------------------
-- Edit box --
--------------------------
--[[
Events :
OnTextChanged
OnEnterPressed
 
]]
do
local Type = "EditBox"
local Version = 11
 
local function OnAcquire(self)
self:SetHeight(26)
self:SetWidth(200)
self:SetDisabled(false)
self:SetLabel()
self.showbutton = true
end
 
local function OnRelease(self)
self.frame:ClearAllPoints()
self.frame:Hide()
self:SetDisabled(false)
end
 
local function Control_OnEnter(this)
this.obj:Fire("OnEnter")
end
 
local function Control_OnLeave(this)
this.obj:Fire("OnLeave")
end
 
local function EditBox_OnEscapePressed(this)
this:ClearFocus()
end
 
local function ShowButton(self)
if self.showbutton then
self.button:Show()
self.editbox:SetTextInsets(0,20,3,3)
end
end
 
local function HideButton(self)
self.button:Hide()
self.editbox:SetTextInsets(0,0,3,3)
end
 
local function EditBox_OnEnterPressed(this)
local self = this.obj
local value = this:GetText()
local cancel = self:Fire("OnEnterPressed",value)
if not cancel then
HideButton(self)
end
end
 
local function Button_OnClick(this)
local editbox = this.obj.editbox
editbox:ClearFocus()
EditBox_OnEnterPressed(editbox)
end
 
local function EditBox_OnReceiveDrag(this)
local self = this.obj
local type, id, info = GetCursorInfo()
if type == "item" then
self:SetText(info)
self:Fire("OnEnterPressed",info)
ClearCursor()
elseif type == "spell" then
local name, rank = GetSpellName(id, info)
if rank and rank:match("%d") then
name = name.."("..rank..")"
end
self:SetText(name)
self:Fire("OnEnterPressed",name)
ClearCursor()
end
HideButton(self)
AceGUI:ClearFocus()
end
 
local function EditBox_OnTextChanged(this)
local self = this.obj
local value = this:GetText()
if value ~= self.lasttext then
self:Fire("OnTextChanged",value)
self.lasttext = value
ShowButton(self)
end
end
 
local function SetDisabled(self, disabled)
self.disabled = disabled
if disabled then
self.editbox:EnableMouse(false)
self.editbox:ClearFocus()
self.editbox:SetTextColor(0.5,0.5,0.5)
self.label:SetTextColor(0.5,0.5,0.5)
else
self.editbox:EnableMouse(true)
self.editbox:SetTextColor(1,1,1)
self.label:SetTextColor(1,.82,0)
end
end
 
local function SetText(self, text)
self.lasttext = text or ""
self.editbox:SetText(text or "")
self.editbox:SetCursorPosition(0)
HideButton(self)
end
 
local function SetLabel(self, text)
if text and text ~= "" then
self.label:SetText(text)
self.label:Show()
self.editbox:SetPoint("TOPLEFT",self.frame,"TOPLEFT",7,-18)
self:SetHeight(44)
self.alignoffset = 30
else
self.label:SetText("")
self.label:Hide()
self.editbox:SetPoint("TOPLEFT",self.frame,"TOPLEFT",7,0)
self:SetHeight(26)
self.alignoffset = 12
end
end
 
 
local function Constructor()
local num = AceGUI:GetNextWidgetNum(Type)
local frame = CreateFrame("Frame",nil,UIParent)
local editbox = CreateFrame("EditBox","AceGUI-3.0EditBox"..num,frame,"InputBoxTemplate")
 
local self = {}
self.type = Type
self.num = num
 
self.OnRelease = OnRelease
self.OnAcquire = OnAcquire
 
self.SetDisabled = SetDisabled
self.SetText = SetText
self.SetLabel = SetLabel
 
self.frame = frame
frame.obj = self
self.editbox = editbox
editbox.obj = self
 
self.alignoffset = 30
 
frame:SetHeight(44)
frame:SetWidth(200)
 
editbox:SetScript("OnEnter",Control_OnEnter)
editbox:SetScript("OnLeave",Control_OnLeave)
 
editbox:SetAutoFocus(false)
editbox:SetFontObject(ChatFontNormal)
editbox:SetScript("OnEscapePressed",EditBox_OnEscapePressed)
editbox:SetScript("OnEnterPressed",EditBox_OnEnterPressed)
editbox:SetScript("OnTextChanged",EditBox_OnTextChanged)
editbox:SetScript("OnReceiveDrag", EditBox_OnReceiveDrag)
editbox:SetScript("OnMouseDown", EditBox_OnReceiveDrag)
 
editbox:SetTextInsets(0,0,3,3)
editbox:SetMaxLetters(256)
 
editbox:SetPoint("BOTTOMLEFT",frame,"BOTTOMLEFT",6,0)
editbox:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,0)
editbox:SetHeight(19)
 
local label = frame:CreateFontString(nil,"OVERLAY","GameFontNormalSmall")
label:SetPoint("TOPLEFT",frame,"TOPLEFT",0,-2)
label:SetPoint("TOPRIGHT",frame,"TOPRIGHT",0,-2)
label:SetJustifyH("LEFT")
label:SetHeight(18)
self.label = label
 
local button = CreateFrame("Button",nil,editbox,"UIPanelButtonTemplate")
button:SetWidth(40)
button:SetHeight(20)
button:SetPoint("RIGHT",editbox,"RIGHT",-2,0)
button:SetText(OKAY)
button:SetScript("OnClick", Button_OnClick)
button:Hide()
 
self.button = button
button.obj = self
 
AceGUI:RegisterAsWidget(self)
return self
end
 
AceGUI:RegisterWidgetType(Type,Constructor,Version)
end
EasyDaily/libs/AceGUI-3.0/widgets/AceGUIWidget-Heading.lua New file
0,0 → 1,73
local AceGUI = LibStub("AceGUI-3.0")
 
--------------------------
-- Heading --
--------------------------
do
local Type = "Heading"
local Version = 5
 
local function OnAcquire(self)
self:SetText("")
self:SetFullWidth()
self:SetHeight(18)
end
 
local function OnRelease(self)
self.frame:ClearAllPoints()
self.frame:Hide()
end
 
local function SetText(self, text)
self.label:SetText(text or "")
if (text or "") == "" then
self.left:SetPoint("RIGHT",self.frame,"RIGHT",-3,0)
self.right:Hide()
else
self.left:SetPoint("RIGHT",self.label,"LEFT",-5,0)
self.right:Show()
end
end
 
local function Constructor()
local frame = CreateFrame("Frame",nil,UIParent)
local self = {}
self.type = Type
 
self.OnRelease = OnRelease
self.OnAcquire = OnAcquire
self.SetText = SetText
self.frame = frame
frame.obj = self
 
frame:SetHeight(18)
 
local label = frame:CreateFontString(nil,"BACKGROUND","GameFontNormal")
label:SetPoint("TOP",frame,"TOP",0,0)
label:SetPoint("BOTTOM",frame,"BOTTOM",0,0)
label:SetJustifyH("CENTER")
label:SetHeight(18)
self.label = label
 
local left = frame:CreateTexture(nil, "BACKGROUND")
self.left = left
left:SetHeight(8)
left:SetPoint("LEFT",frame,"LEFT",3,0)
left:SetPoint("RIGHT",label,"LEFT",-5,0)
left:SetTexture("Interface\\Tooltips\\UI-Tooltip-Border")
left:SetTexCoord(0.81, 0.94, 0.5, 1)
 
local right = frame:CreateTexture(nil, "BACKGROUND")
self.right = right
right:SetHeight(8)
right:SetPoint("RIGHT",frame,"RIGHT",-3,0)
right:SetPoint("LEFT",label,"RIGHT",5,0)
right:SetTexture("Interface\\Tooltips\\UI-Tooltip-Border")
right:SetTexCoord(0.81, 0.94, 0.5, 1)
 
AceGUI:RegisterAsWidget(self)
return self
end
 
AceGUI:RegisterWidgetType(Type,Constructor,Version)
end
EasyDaily/libs/AceGUI-3.0/AceGUI-3.0.xml New file
0,0 → 1,25
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="AceGUI-3.0.lua"/>
<Script file="widgets\AceGUIWidget-Button.lua"/>
<Script file="widgets\AceGUIWidget-CheckBox.lua"/>
<Script file="widgets\AceGUIWidget-ColorPicker.lua"/>
<Script file="widgets\AceGUIWidget-DropDownGroup.lua"/>
<Script file="widgets\AceGUIWidget-DropDown.lua"/>
<Script file="widgets\AceGUIWidget-DropDown-Items.lua"/>
<Script file="widgets\AceGUIWidget-EditBox.lua"/>
<Script file="widgets\AceGUIWidget-Frame.lua"/>
<Script file="widgets\AceGUIWidget-Heading.lua"/>
<Script file="widgets\AceGUIWidget-InlineGroup.lua"/>
<Script file="widgets\AceGUIWidget-Keybinding.lua"/>
<Script file="widgets\AceGUIWidget-ScrollFrame.lua"/>
<Script file="widgets\AceGUIWidget-SimpleGroup.lua"/>
<Script file="widgets\AceGUIWidget-Slider.lua"/>
<Script file="widgets\AceGUIWidget-TabGroup.lua"/>
<Script file="widgets\AceGUIWidget-TreeGroup.lua"/>
<Script file="widgets\AceGUIWidget-Label.lua"/>
<Script file="widgets\AceGUIWidget-MultiLineEditBox.lua"/>
<Script file="widgets\AceGUIWidget-BlizOptionsGroup.lua"/>
<Script file="widgets\AceGUIWidget-InteractiveLabel.lua"/>
<Script file="widgets\AceGUIWidget-Icon.lua"/>
</Ui>
\ No newline at end of file
EasyDaily/libs/AceGUI-3.0/AceGUI-3.0.lua New file
0,0 → 1,831
--- **AceGUI-3.0** provides access to numerous widgets which can be used to create GUIs.
-- AceGUI is used by AceConfigDialog to create the option GUIs, but you can use it by itself
-- to create any custom GUI. There are more extensive examples in the test suite in the Ace3
-- stand-alone distribution.
--
-- **Note**: When using AceGUI-3.0 directly, please do not modify the frames of the widgets directly,
-- as any "unknown" change to the widgets will cause addons that get your widget out of the widget pool
-- to misbehave. If you think some part of a widget should be modifiable, please open a ticket, and we'll
-- implement a proper API to modify it.
-- @usage
-- local AceGUI = LibStub("AceGUI-3.0")
-- -- Create a container frame
-- local f = AceGUI:Create("Frame")
-- f:SetCallback("OnClose",function(widget) AceGUI:Release(widget) end)
-- f:SetTitle("AceGUI-3.0 Example")
-- f:SetStatusText("Status Bar")
-- f:SetLayout("Flow")
-- -- Create a button
-- local btn = AceGUI:Create("Button")
-- btn:SetWidth(170)
-- btn:SetText("Button !")
-- btn:SetCallback("OnClick", function() print("Click!") end)
-- -- Add the button to the container
-- f:AddChild(btn)
-- @class file
-- @name AceGUI-3.0
-- @release $Id: AceGUI-3.0.lua 803 2009-04-14 12:37:54Z nevcairiel $
local ACEGUI_MAJOR, ACEGUI_MINOR = "AceGUI-3.0", 23
local AceGUI, oldminor = LibStub:NewLibrary(ACEGUI_MAJOR, ACEGUI_MINOR)
 
if not AceGUI then return end -- No upgrade needed
 
--local con = LibStub("AceConsole-3.0",true)
 
AceGUI.WidgetRegistry = AceGUI.WidgetRegistry or {}
AceGUI.LayoutRegistry = AceGUI.LayoutRegistry or {}
AceGUI.WidgetBase = AceGUI.WidgetBase or {}
AceGUI.WidgetContainerBase = AceGUI.WidgetContainerBase or {}
AceGUI.WidgetVersions = AceGUI.WidgetVersions or {}
 
-- local upvalues
local WidgetRegistry = AceGUI.WidgetRegistry
local LayoutRegistry = AceGUI.LayoutRegistry
local WidgetVersions = AceGUI.WidgetVersions
 
local pcall = pcall
local select = select
local pairs = pairs
local ipairs = ipairs
local type = type
local assert = assert
local tinsert = tinsert
local tremove = tremove
local CreateFrame = CreateFrame
local UIParent = UIParent
 
--[[
xpcall safecall implementation
]]
local xpcall = xpcall
 
local function errorhandler(err)
return geterrorhandler()(err)
end
 
local function CreateDispatcher(argCount)
local code = [[
local xpcall, eh = ...
local method, ARGS
local function call() return method(ARGS) end
 
local function dispatch(func, ...)
method = func
if not method then return end
ARGS = ...
return xpcall(call, eh)
end
 
return dispatch
]]
 
local ARGS = {}
for i = 1, argCount do ARGS[i] = "arg"..i end
code = code:gsub("ARGS", table.concat(ARGS, ", "))
return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(xpcall, errorhandler)
end
 
local Dispatchers = setmetatable({}, {__index=function(self, argCount)
local dispatcher = CreateDispatcher(argCount)
rawset(self, argCount, dispatcher)
return dispatcher
end})
Dispatchers[0] = function(func)
return xpcall(func, errorhandler)
end
 
local function safecall(func, ...)
return Dispatchers[select('#', ...)](func, ...)
end
 
-- Recycling functions
local new, del
do
AceGUI.objPools = AceGUI.objPools or {}
local objPools = AceGUI.objPools
--Returns a new instance, if none are available either returns a new table or calls the given contructor
function new(type,constructor,...)
if not type then
type = "table"
end
if not objPools[type] then
objPools[type] = {}
end
local newObj = tremove(objPools[type])
if not newObj then
newObj = constructor and constructor(...) or {}
end
return newObj
end
-- Releases an instance to the Pool
function del(obj,type)
if not type then
type = "table"
end
if not objPools[type] then
objPools[type] = {}
end
for i,v in ipairs(objPools[type]) do
if v == obj then
error("Attempt to Release Widget that is already released")
return
end
end
tinsert(objPools[type],obj)
end
end
 
 
-------------------
-- API Functions --
-------------------
 
-- Gets a widget Object
 
--- Create a new Widget of the given type.
-- This function will instantiate a new widget (or use one from the widget pool), and call the
-- OnAcquire function on it, before returning.
-- @param type The type of the widget.
-- @return The newly created widget.
function AceGUI:Create(type)
local reg = WidgetRegistry
if reg[type] then
local widget = new(type,reg[type])
 
if rawget(widget,'Acquire') then
widget.OnAcquire = widget.Acquire
widget.Acquire = nil
elseif rawget(widget,'Aquire') then
widget.OnAcquire = widget.Aquire
widget.Aquire = nil
end
 
if rawget(widget,'Release') then
widget.OnRelease = rawget(widget,'Release')
widget.Release = nil
end
 
if widget.OnAcquire then
widget:OnAcquire()
else
error(("Widget type %s doesn't supply an OnAcquire Function"):format(type))
end
-- Set the default Layout ('List')
safecall(widget.SetLayout, widget, 'List')
safecall(widget.ResumeLayout, widget)
return widget
end
end
 
--- Releases a widget Object.
-- This function calls OnRelease on the widget and places it back in the widget pool.
-- Any data on the widget is being erased, and the widget will be hidden.\\
-- If this widget is a Container-Widget, all of its Child-Widgets will be releases as well.
-- @param widget The widget to release
function AceGUI:Release(widget)
safecall( widget.PauseLayout, widget )
widget:Fire("OnRelease")
safecall( widget.ReleaseChildren, widget )
 
if widget.OnRelease then
widget:OnRelease()
else
error(("Widget type %s doesn't supply an OnRelease Function"):format(type))
end
for k in pairs(widget.userdata) do
widget.userdata[k] = nil
end
for k in pairs(widget.events) do
widget.events[k] = nil
end
widget.width = nil
widget.relWidth = nil
widget.height = nil
widget.relHeight = nil
widget.noAutoHeight = nil
widget.frame:ClearAllPoints()
widget.frame:Hide()
widget.frame:SetParent(nil)
widget.frame.width = nil
widget.frame.height = nil
if widget.content then
widget.content.width = nil
widget.content.height = nil
end
del(widget,widget.type)
end
 
-----------
-- Focus --
-----------
 
 
--- Called when a widget has taken focus.
-- e.g. Dropdowns opening, Editboxes gaining kb focus
-- @param widget The widget that should be focused
function AceGUI:SetFocus(widget)
if self.FocusedWidget and self.FocusedWidget ~= widget then
safecall(self.FocusedWidget.ClearFocus, self.FocusedWidget)
end
self.FocusedWidget = widget
end
 
 
--- Called when something has happened that could cause widgets with focus to drop it
-- e.g. titlebar of a frame being clicked
function AceGUI:ClearFocus()
if self.FocusedWidget then
safecall(self.FocusedWidget.ClearFocus, self.FocusedWidget)
self.FocusedWidget = nil
end
end
 
-------------
-- Widgets --
-------------
--[[
Widgets must provide the following functions
OnAcquire() - Called when the object is acquired, should set everything to a default hidden state
OnRelease() - Called when the object is Released, should remove any anchors and hide the Widget
 
And the following members
frame - the frame or derivitive object that will be treated as the widget for size and anchoring purposes
type - the type of the object, same as the name given to :RegisterWidget()
 
Widgets contain a table called userdata, this is a safe place to store data associated with the wigdet
It will be cleared automatically when a widget is released
Placing values directly into a widget object should be avoided
 
If the Widget can act as a container for other Widgets the following
content - frame or derivitive that children will be anchored to
 
The Widget can supply the following Optional Members
:OnWidthSet(width) - Called when the width of the widget is changed
:OnHeightSet(height) - Called when the height of the widget is changed
Widgets should not use the OnSizeChanged events of thier frame or content members, use these methods instead
AceGUI already sets a handler to the event
:OnLayoutFinished(width, height) - called after a layout has finished, the width and height will be the width and height of the
area used for controls. These can be nil if the layout used the existing size to layout the controls.
 
]]
 
--------------------------
-- Widget Base Template --
--------------------------
do
local function fixlevels(parent,...)
local i = 1
local child = select(i, ...)
while child do
child:SetFrameLevel(parent:GetFrameLevel()+1)
fixlevels(child, child:GetChildren())
i = i + 1
child = select(i, ...)
end
end
 
local WidgetBase = AceGUI.WidgetBase
 
WidgetBase.SetParent = function(self, parent)
local frame = self.frame
frame:SetParent(nil)
frame:SetParent(parent.content)
self.parent = parent
--fixlevels(parent.frame,parent.frame:GetChildren())
end
 
WidgetBase.SetCallback = function(self, name, func)
if type(func) == "function" then
self.events[name] = func
end
end
 
WidgetBase.Fire = function(self, name, ...)
if self.events[name] then
local success, ret = safecall(self.events[name], self, name, ...)
if success then
return ret
end
end
end
 
WidgetBase.SetWidth = function(self, width)
self.frame:SetWidth(width)
self.frame.width = width
if self.OnWidthSet then
self:OnWidthSet(width)
end
end
 
WidgetBase.SetRelativeWidth = function(self, width)
if width <= 0 or width > 1 then
error(":SetRelativeWidth(width): Invalid relative width.", 2)
end
self.relWidth = width
self.width = "relative"
end
 
WidgetBase.SetHeight = function(self, height)
self.frame:SetHeight(height)
self.frame.height = height
if self.OnHeightSet then
self:OnHeightSet(height)
end
end
 
--[[ WidgetBase.SetRelativeHeight = function(self, height)
if height <= 0 or height > 1 then
error(":SetRelativeHeight(height): Invalid relative height.", 2)
end
self.relHeight = height
self.height = "relative"
end ]]
 
WidgetBase.IsVisible = function(self)
return self.frame:IsVisible()
end
 
WidgetBase.IsShown= function(self)
return self.frame:IsShown()
end
 
WidgetBase.Release = function(self)
AceGUI:Release(self)
end
 
WidgetBase.SetPoint = function(self, ...)
return self.frame:SetPoint(...)
end
 
WidgetBase.ClearAllPoints = function(self)
return self.frame:ClearAllPoints()
end
 
WidgetBase.GetNumPoints = function(self)
return self.frame:GetNumPoints()
end
 
WidgetBase.GetPoint = function(self, ...)
return self.frame:GetPoint(...)
end
 
WidgetBase.GetUserDataTable = function(self)
return self.userdata
end
 
WidgetBase.SetUserData = function(self, key, value)
self.userdata[key] = value
end
 
WidgetBase.GetUserData = function(self, key)
return self.userdata[key]
end
 
WidgetBase.IsFullHeight = function(self)
return self.height == "fill"
end
 
WidgetBase.SetFullHeight = function(self, isFull)
if isFull then
self.height = "fill"
else
self.height = nil
end
end
 
WidgetBase.IsFullWidth = function(self)
return self.width == "fill"
end
 
WidgetBase.SetFullWidth = function(self, isFull)
if isFull then
self.width = "fill"
else
self.width = nil
end
end
 
-- local function LayoutOnUpdate(this)
-- this:SetScript("OnUpdate",nil)
-- this.obj:PerformLayout()
-- end
 
local WidgetContainerBase = AceGUI.WidgetContainerBase
 
WidgetContainerBase.PauseLayout = function(self)
self.LayoutPaused = true
end
 
WidgetContainerBase.ResumeLayout = function(self)
self.LayoutPaused = nil
end
 
WidgetContainerBase.PerformLayout = function(self)
if self.LayoutPaused then
return
end
safecall(self.LayoutFunc,self.content, self.children)
end
 
--call this function to layout, makes sure layed out objects get a frame to get sizes etc
WidgetContainerBase.DoLayout = function(self)
self:PerformLayout()
-- if not self.parent then
-- self.frame:SetScript("OnUpdate", LayoutOnUpdate)
-- end
end
 
WidgetContainerBase.AddChild = function(self, child, beforeWidget)
if beforeWidget then
local siblingIndex = 1
for _, widget in pairs(self.children) do
if widget == beforeWidget then
break
end
siblingIndex = siblingIndex + 1
end
tinsert(self.children, siblingIndex, child)
else
tinsert(self.children, child)
end
child:SetParent(self)
child.frame:Show()
self:DoLayout()
end
 
WidgetContainerBase.AddChildren = function(self, ...)
for i = 1, select("#", ...) do
local child = select(i, ...)
tinsert(self.children, child)
child:SetParent(self)
child.frame:Show()
end
self:DoLayout()
end
 
WidgetContainerBase.ReleaseChildren = function(self)
local children = self.children
for i in ipairs(children) do
AceGUI:Release(children[i])
children[i] = nil
end
end
 
WidgetContainerBase.SetLayout = function(self, Layout)
self.LayoutFunc = AceGUI:GetLayout(Layout)
end
 
WidgetContainerBase.SetAutoAdjustHeight = function(self, adjust)
if adjust then
self.noAutoHeight = nil
else
self.noAutoHeight = true
end
end
 
local function FrameResize(this)
local self = this.obj
if this:GetWidth() and this:GetHeight() then
if self.OnWidthSet then
self:OnWidthSet(this:GetWidth())
end
if self.OnHeightSet then
self:OnHeightSet(this:GetHeight())
end
end
end
 
local function ContentResize(this)
if this:GetWidth() and this:GetHeight() then
this.width = this:GetWidth()
this.height = this:GetHeight()
this.obj:DoLayout()
end
end
 
setmetatable(WidgetContainerBase,{__index=WidgetBase})
 
--One of these function should be called on each Widget Instance as part of its creation process
 
--- Register a widget-class as a container for newly created widgets.
-- @param widget The widget class
function AceGUI:RegisterAsContainer(widget)
widget.children = {}
widget.userdata = {}
widget.events = {}
widget.base = WidgetContainerBase
widget.content.obj = widget
widget.frame.obj = widget
widget.content:SetScript("OnSizeChanged",ContentResize)
widget.frame:SetScript("OnSizeChanged",FrameResize)
setmetatable(widget,{__index=WidgetContainerBase})
widget:SetLayout("List")
end
 
--- Register a widget-class as a widget.
-- @param widget The widget class
function AceGUI:RegisterAsWidget(widget)
widget.userdata = {}
widget.events = {}
widget.base = WidgetBase
widget.frame.obj = widget
widget.frame:SetScript("OnSizeChanged",FrameResize)
setmetatable(widget,{__index=WidgetBase})
end
end
 
 
 
 
------------------
-- Widget API --
------------------
 
--- Registers a widget Constructor, this function returns a new instance of the Widget
-- @param Name The name of the widget
-- @param Constructor The widget constructor function
-- @param Version The version of the widget
function AceGUI:RegisterWidgetType(Name, Constructor, Version)
assert(type(Constructor) == "function")
assert(type(Version) == "number")
 
local oldVersion = WidgetVersions[Name]
if oldVersion and oldVersion >= Version then return end
 
WidgetVersions[Name] = Version
WidgetRegistry[Name] = Constructor
end
 
--- Registers a Layout Function
-- @param Name The name of the layout
-- @param LayoutFunc Reference to the layout function
function AceGUI:RegisterLayout(Name, LayoutFunc)
assert(type(LayoutFunc) == "function")
if type(Name) == "string" then
Name = Name:upper()
end
LayoutRegistry[Name] = LayoutFunc
end
 
--- Get a Layout Function from the registry
-- @param Name The name of the layout
function AceGUI:GetLayout(Name)
if type(Name) == "string" then
Name = Name:upper()
end
return LayoutRegistry[Name]
end
 
AceGUI.counts = AceGUI.counts or {}
 
--- A type-based counter to count the number of widgets created.
-- This is used by widgets that require a named frame, e.g. when a Blizzard
-- Template requires it.
-- @param type The widget type
function AceGUI:GetNextWidgetNum(type)
if not self.counts[type] then
self.counts[type] = 0
end
self.counts[type] = self.counts[type] + 1
return self.counts[type]
end
 
--[[ Widget Template
 
--------------------------
-- Widget Name --
--------------------------
do
local Type = "Type"
 
local function OnAcquire(self)
 
end
 
local function OnRelease(self)
self.frame:ClearAllPoints()
self.frame:Hide()
end
 
 
local function Constructor()
local frame = CreateFrame("Frame",nil,UIParent)
local self = {}
self.type = Type
 
self.OnRelease = OnRelease
self.OnAcquire = OnAcquire
 
self.frame = frame
frame.obj = self
 
--Container Support
--local content = CreateFrame("Frame",nil,frame)
--self.content = content
 
--AceGUI:RegisterAsContainer(self)
AceGUI:RegisterAsWidget(self)
return self
end
 
AceGUI:RegisterWidgetType(Type,Constructor)
end
 
 
]]
 
-------------
-- Layouts --
-------------
 
--[[
A Layout is a func that takes 2 parameters
content - the frame that widgets will be placed inside
children - a table containing the widgets to layout
 
]]
 
-- Very simple Layout, Children are stacked on top of each other down the left side
AceGUI:RegisterLayout("List",
function(content, children)
 
local height = 0
local width = content.width or content:GetWidth() or 0
for i, child in ipairs(children) do
 
 
local frame = child.frame
frame:ClearAllPoints()
frame:Show()
if i == 1 then
frame:SetPoint("TOPLEFT",content,"TOPLEFT",0,0)
else
frame:SetPoint("TOPLEFT",children[i-1].frame,"BOTTOMLEFT",0,0)
end
 
if child.width == "fill" then
child:SetWidth(width)
frame:SetPoint("RIGHT",content,"RIGHT")
if child.OnWidthSet then
child:OnWidthSet(content.width or content:GetWidth())
end
if child.DoLayout then
child:DoLayout()
end
elseif child.width == "relative" then
child:SetWidth(width * child.relWidth)
if child.OnWidthSet then
child:OnWidthSet(content.width or content:GetWidth())
end
if child.DoLayout then
child:DoLayout()
end
end
 
height = height + (frame.height or frame:GetHeight() or 0)
end
safecall( content.obj.LayoutFinished, content.obj, nil, height )
end
)
 
-- A single control fills the whole content area
AceGUI:RegisterLayout("Fill",
function(content, children)
if children[1] then
children[1]:SetWidth(content:GetWidth() or 0)
children[1]:SetHeight(content:GetHeight() or 0)
children[1].frame:SetAllPoints(content)
children[1].frame:Show()
safecall( content.obj.LayoutFinished, content.obj, nil, children[1].frame:GetHeight() )
end
end
)
 
AceGUI:RegisterLayout("Flow",
function(content, children)
--used height so far
local height = 0
--width used in the current row
local usedwidth = 0
--height of the current row
local rowheight = 0
local rowoffset = 0
local lastrowoffset
 
local width = content.width or content:GetWidth() or 0
 
--control at the start of the row
local rowstart
local rowstartoffset
local lastrowstart
local isfullheight
 
local frameoffset
local lastframeoffset
local oversize
for i, child in ipairs(children) do
oversize = nil
local frame = child.frame
local frameheight = frame.height or frame:GetHeight() or 0
local framewidth = frame.width or frame:GetWidth() or 0
lastframeoffset = frameoffset
frameoffset = child.alignoffset or (frameheight / 2)
 
if child.width == "relative" then
framewidth = width * child.relWidth
end
 
frame:Show()
frame:ClearAllPoints()
if i == 1 then
-- anchor the first control to the top left
--frame:SetPoint("TOPLEFT",content,"TOPLEFT",0,0)
rowheight = frameheight
rowoffset = frameoffset
rowstart = frame
rowstartoffset = frameoffset
usedwidth = framewidth
if usedwidth > width then
oversize = true
end
else
-- if there isn't available width for the control start a new row
-- if a control is "fill" it will be on a row of its own full width
if usedwidth == 0 or ((framewidth) + usedwidth > width) or child.width == "fill" then
--anchor the previous row, we will now know its height and offset
rowstart:SetPoint("TOPLEFT",content,"TOPLEFT",0,-(height+(rowoffset-rowstartoffset)+3))
height = height + rowheight + 3
--save this as the rowstart so we can anchor it after the row is complete and we have the max height and offset of controls in it
rowstart = frame
rowstartoffset = frameoffset
rowheight = frameheight
rowoffset = frameoffset
usedwidth = framewidth
if usedwidth > width then
oversize = true
end
-- put the control on the current row, adding it to the width and checking if the height needs to be increased
else
--handles cases where the new height is higher than either control because of the offsets
--math.max(rowheight-rowoffset+frameoffset, frameheight-frameoffset+rowoffset)
 
--offset is always the larger of the two offsets
rowoffset = math.max(rowoffset, frameoffset)
 
rowheight = math.max(rowheight,rowoffset+(frameheight/2))
frame:SetPoint("TOPLEFT",children[i-1].frame,"TOPRIGHT",0,frameoffset-lastframeoffset)
usedwidth = framewidth + usedwidth
end
end
 
if child.width == "fill" then
child:SetWidth(width)
frame:SetPoint("RIGHT",content,"RIGHT",0,0)
 
usedwidth = 0
rowstart = frame
rowstartoffset = frameoffset
 
if child.OnWidthSet then
child:OnWidthSet(width)
end
if child.DoLayout then
child:DoLayout()
end
rowheight = frame.height or frame:GetHeight() or 0
rowoffset = child.alignoffset or (rowheight / 2)
rowstartoffset = rowoffset
elseif child.width == "relative" then
child:SetWidth(width * child.relWidth)
 
if child.OnWidthSet then
child:OnWidthSet(width)
end
 
if child.DoLayout then
child:DoLayout()
end
elseif oversize then
if width > 1 then
frame:SetPoint("RIGHT",content,"RIGHT",0,0)
end
end
 
if child.height == "fill" then
frame:SetPoint("BOTTOM",content,"BOTTOM")
isfullheight = true
break
end
end
 
--anchor the last row, if its full height needs a special case since its height has just been changed by the anchor
if isfullheight then
rowstart:SetPoint("TOPLEFT",content,"TOPLEFT",0,-height)
elseif rowstart then
rowstart:SetPoint("TOPLEFT",content,"TOPLEFT",0,-(height+(rowoffset-rowstartoffset)+3))
end
 
height = height + rowheight + 3
safecall( content.obj.LayoutFinished, content.obj, nil, height )
end
)
EasyDaily/libs/AceAddon-3.0/AceAddon-3.0.xml New file
0,0 → 1,4
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="AceAddon-3.0.lua"/>
</Ui>
\ No newline at end of file
EasyDaily/libs/AceAddon-3.0/AceAddon-3.0.lua New file
0,0 → 1,634
--- **AceAddon-3.0** provides a template for creating addon objects.
-- It'll provide you with a set of callback functions that allow you to simplify the loading
-- process of your addon.\\
-- Callbacks provided are:\\
-- * **OnInitialize**, which is called directly after the addon is fully loaded.
-- * **OnEnable** which gets called during the PLAYER_LOGIN event, when most of the data provided by the game is already present.
-- * **OnDisable**, which is only called when your addon is manually being disabled.
-- @usage
-- -- A small (but complete) addon, that doesn't do anything,
-- -- but shows usage of the callbacks.
-- local MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon")
--
-- function MyAddon:OnInitialize()
-- -- do init tasks here, like loading the Saved Variables,
-- -- or setting up slash commands.
-- end
--
-- function MyAddon:OnEnable()
-- -- Do more initialization here, that really enables the use of your addon.
-- -- Register Events, Hook functions, Create Frames, Get information from
-- -- the game that wasn't available in OnInitialize
-- end
--
-- function MyAddon:OnDisable()
-- -- Unhook, Unregister Events, Hide frames that you created.
-- -- You would probably only use an OnDisable if you want to
-- -- build a "standby" mode, or be able to toggle modules on/off.
-- end
-- @class file
-- @name AceAddon-3.0.lua
-- @release $Id: AceAddon-3.0.lua 777 2009-04-04 20:16:09Z nevcairiel $
local MAJOR, MINOR = "AceAddon-3.0", 5
local AceAddon, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
 
if not AceAddon then return end -- No Upgrade needed.
 
AceAddon.frame = AceAddon.frame or CreateFrame("Frame", "AceAddon30Frame") -- Our very own frame
AceAddon.addons = AceAddon.addons or {} -- addons in general
AceAddon.statuses = AceAddon.statuses or {} -- statuses of addon.
AceAddon.initializequeue = AceAddon.initializequeue or {} -- addons that are new and not initialized
AceAddon.enablequeue = AceAddon.enablequeue or {} -- addons that are initialized and waiting to be enabled
AceAddon.embeds = AceAddon.embeds or setmetatable({}, {__index = function(tbl, key) tbl[key] = {} return tbl[key] end }) -- contains a list of libraries embedded in an addon
 
local tinsert, tconcat = table.insert, table.concat
local fmt = string.format
local pairs, next, type = pairs, next, type
 
--[[
xpcall safecall implementation
]]
local xpcall = xpcall
 
local function errorhandler(err)
return geterrorhandler()(err)
end
 
local function CreateDispatcher(argCount)
local code = [[
local xpcall, eh = ...
local method, ARGS
local function call() return method(ARGS) end
 
local function dispatch(func, ...)
method = func
if not method then return end
ARGS = ...
return xpcall(call, eh)
end
 
return dispatch
]]
 
local ARGS = {}
for i = 1, argCount do ARGS[i] = "arg"..i end
code = code:gsub("ARGS", tconcat(ARGS, ", "))
return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(xpcall, errorhandler)
end
 
local Dispatchers = setmetatable({}, {__index=function(self, argCount)
local dispatcher = CreateDispatcher(argCount)
rawset(self, argCount, dispatcher)
return dispatcher
end})
Dispatchers[0] = function(func)
return xpcall(func, errorhandler)
end
 
local function safecall(func, ...)
-- we check to see if the func is passed is actually a function here and don't error when it isn't
-- this safecall is used for optional functions like OnInitialize OnEnable etc. When they are not
-- present execution should continue without hinderance
if type(func) == "function" then
return Dispatchers[select('#', ...)](func, ...)
end
end
 
-- local functions that will be implemented further down
local Enable, Disable, EnableModule, DisableModule, Embed, NewModule, GetModule, GetName, SetDefaultModuleState, SetDefaultModuleLibraries, SetEnabledState, SetDefaultModulePrototype
 
-- used in the addon metatable
local function addontostring( self ) return self.name end
 
--- Create a new AceAddon-3.0 addon.
-- Any libraries you specified will be embeded, and the addon will be scheduled for
-- its OnInitialize and OnEnable callbacks.
-- The final addon object, with all libraries embeded, will be returned.
-- @paramsig [object ,]name[, lib, ...]
-- @param object Table to use as a base for the addon (optional)
-- @param name Name of the addon object to create
-- @param lib List of libraries to embed into the addon
-- @usage
-- -- Create a simple addon object
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon", "AceEvent-3.0")
--
-- -- Create a Addon object based on the table of a frame
-- local MyFrame = CreateFrame("Frame")
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon(MyFrame, "MyAddon", "AceEvent-3.0")
function AceAddon:NewAddon(objectorname, ...)
local object,name
local i=1
if type(objectorname)=="table" then
object=objectorname
name=...
i=2
else
name=objectorname
end
if type(name)~="string" then
error(("Usage: NewAddon([object,] name, [lib, lib, lib, ...]): 'name' - string expected got '%s'."):format(type(name)), 2)
end
if self.addons[name] then
error(("Usage: NewAddon([object,] name, [lib, lib, lib, ...]): 'name' - Addon '%s' already exists."):format(name), 2)
end
 
object = object or {}
object.name = name
 
local addonmeta = {}
local oldmeta = getmetatable(object)
if oldmeta then
for k, v in pairs(oldmeta) do addonmeta[k] = v end
end
addonmeta.__tostring = addontostring
 
setmetatable( object, addonmeta )
self.addons[name] = object
object.modules = {}
object.defaultModuleLibraries = {}
Embed( object ) -- embed NewModule, GetModule methods
self:EmbedLibraries(object, select(i,...))
 
-- add to queue of addons to be initialized upon ADDON_LOADED
tinsert(self.initializequeue, object)
return object
end
 
 
--- Get the addon object by its name from the internal AceAddon registry.
-- Throws an error if the addon object cannot be found (except if silent is set).
-- @param name unique name of the addon object
-- @param silent if true, the addon is optional, silently return nil if its not found
-- @usage
-- -- Get the Addon
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
function AceAddon:GetAddon(name, silent)
if not silent and not self.addons[name] then
error(("Usage: GetAddon(name): 'name' - Cannot find an AceAddon '%s'."):format(tostring(name)), 2)
end
return self.addons[name]
end
 
-- - Embed a list of libraries into the specified addon.
-- This function will try to embed all of the listed libraries into the addon
-- and error if a single one fails.
--
-- **Note:** This function is for internal use by :NewAddon/:NewModule
-- @paramsig addon, [lib, ...]
-- @param addon addon object to embed the libs in
-- @param lib List of libraries to embed into the addon
function AceAddon:EmbedLibraries(addon, ...)
for i=1,select("#", ... ) do
local libname = select(i, ...)
self:EmbedLibrary(addon, libname, false, 4)
end
end
 
-- - Embed a library into the addon object.
-- This function will check if the specified library is registered with LibStub
-- and if it has a :Embed function to call. It'll error if any of those conditions
-- fails.
--
-- **Note:** This function is for internal use by :EmbedLibraries
-- @paramsig addon, libname[, silent[, offset]]
-- @param addon addon object to embed the library in
-- @param libname name of the library to embed
-- @param silent marks an embed to fail silently if the library doesn't exist (optional)
-- @param offset will push the error messages back to said offset, defaults to 2 (optional)
function AceAddon:EmbedLibrary(addon, libname, silent, offset)
local lib = LibStub:GetLibrary(libname, true)
if not lib and not silent then
error(("Usage: EmbedLibrary(addon, libname, silent, offset): 'libname' - Cannot find a library instance of %q."):format(tostring(libname)), offset or 2)
elseif lib and type(lib.Embed) == "function" then
lib:Embed(addon)
tinsert(self.embeds[addon], libname)
return true
elseif lib then
error(("Usage: EmbedLibrary(addon, libname, silent, offset): 'libname' - Library '%s' is not Embed capable"):format(libname), offset or 2)
end
end
 
--- Return the specified module from an addon object.
-- Throws an error if the addon object cannot be found (except if silent is set)
-- @name //addon//:GetModule
-- @paramsig name[, silent]
-- @param name unique name of the module
-- @param silent if true, the module is optional, silently return nil if its not found (optional)
-- @usage
-- -- Get the Addon
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
-- -- Get the Module
-- MyModule = MyAddon:GetModule("MyModule")
function GetModule(self, name, silent)
if not self.modules[name] and not silent then
error(("Usage: GetModule(name, silent): 'name' - Cannot find module '%s'."):format(tostring(name)), 2)
end
return self.modules[name]
end
 
local function IsModuleTrue(self) return true end
 
--- Create a new module for the addon.
-- The new module can have its own embeded libraries and/or use a module prototype to be mixed into the module.\\
-- A module has the same functionality as a real addon, it can have modules of its own, and has the same API as
-- an addon object.
-- @name //addon//:NewModule
-- @paramsig name[, prototype|lib[, lib, ...]]
-- @param name unique name of the module
-- @param prototype object to derive this module from, methods and values from this table will be mixed into the module (optional)
-- @param lib List of libraries to embed into the addon
-- @usage
-- -- Create a module with some embeded libraries
-- MyModule = MyAddon:NewModule("MyModule", "AceEvent-3.0", "AceHook-3.0")
--
-- -- Create a module with a prototype
-- local prototype = { OnEnable = function(self) print("OnEnable called!") end }
-- MyModule = MyAddon:NewModule("MyModule", prototype, "AceEvent-3.0", "AceHook-3.0")
function NewModule(self, name, prototype, ...)
if type(name) ~= "string" then error(("Usage: NewModule(name, [prototype, [lib, lib, lib, ...]): 'name' - string expected got '%s'."):format(type(name)), 2) end
if type(prototype) ~= "string" and type(prototype) ~= "table" and type(prototype) ~= "nil" then error(("Usage: NewModule(name, [prototype, [lib, lib, lib, ...]): 'prototype' - table (prototype), string (lib) or nil expected got '%s'."):format(type(prototype)), 2) end
 
if self.modules[name] then error(("Usage: NewModule(name, [prototype, [lib, lib, lib, ...]): 'name' - Module '%s' already exists."):format(name), 2) end
 
-- modules are basically addons. We treat them as such. They will be added to the initializequeue properly as well.
-- NewModule can only be called after the parent addon is present thus the modules will be initialized after their parent is.
local module = AceAddon:NewAddon(fmt("%s_%s", self.name or tostring(self), name))
 
module.IsModule = IsModuleTrue
module:SetEnabledState(self.defaultModuleState)
module.moduleName = name
 
if type(prototype) == "string" then
AceAddon:EmbedLibraries(module, prototype, ...)
else
AceAddon:EmbedLibraries(module, ...)
end
AceAddon:EmbedLibraries(module, unpack(self.defaultModuleLibraries))
 
if not prototype or type(prototype) == "string" then
prototype = self.defaultModulePrototype or nil
end
 
if type(prototype) == "table" then
local mt = getmetatable(module)
mt.__index = prototype
setmetatable(module, mt) -- More of a Base class type feel.
end
 
safecall(self.OnModuleCreated, self, module) -- Was in Ace2 and I think it could be a cool thing to have handy.
self.modules[name] = module
 
return module
end
 
--- Returns the real name of the addon or module, without any prefix.
-- @name //addon//:GetName
-- @paramsig
-- @usage
-- print(MyAddon:GetName())
-- -- prints "MyAddon"
function GetName(self)
return self.moduleName or self.name
end
 
--- Enables the Addon, if possible, return true or false depending on success.
-- This internally calls AceAddon:EnableAddon(), thus dispatching a OnEnable callback
-- and enabling all modules of the addon (unless explicitly disabled).\\
-- :Enable() also sets the internal `enableState` variable to true
-- @name //addon//:Enable
-- @paramsig
-- @usage
-- -- Enable MyModule
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
-- MyModule = MyAddon:GetModule("MyModule")
-- MyModule:Enable()
function Enable(self)
self:SetEnabledState(true)
return AceAddon:EnableAddon(self)
end
 
--- Disables the Addon, if possible, return true or false depending on success.
-- This internally calls AceAddon:DisableAddon(), thus dispatching a OnDisable callback
-- and disabling all modules of the addon.\\
-- :Disable() also sets the internal `enableState` variable to false
-- @name //addon//:Disable
-- @paramsig
-- @usage
-- -- Disable MyAddon
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
-- MyAddon:Disable()
function Disable(self)
self:SetEnabledState(false)
return AceAddon:DisableAddon(self)
end
 
--- Enables the Module, if possible, return true or false depending on success.
-- Short-hand function that retrieves the module via `:GetModule` and calls `:Enable` on the module object.
-- @name //addon//:EnableModule
-- @paramsig name
-- @usage
-- -- Enable MyModule using :GetModule
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
-- MyModule = MyAddon:GetModule("MyModule")
-- MyModule:Enable()
--
-- -- Enable MyModule using the short-hand
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
-- MyAddon:EnableModule("MyModule")
function EnableModule(self, name)
local module = self:GetModule( name )
return module:Enable()
end
 
--- Disables the Module, if possible, return true or false depending on success.
-- Short-hand function that retrieves the module via `:GetModule` and calls `:Disable` on the module object.
-- @name //addon//:DisableModule
-- @paramsig name
-- @usage
-- -- Disable MyModule using :GetModule
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
-- MyModule = MyAddon:GetModule("MyModule")
-- MyModule:Disable()
--
-- -- Disable MyModule using the short-hand
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
-- MyAddon:DisableModule("MyModule")
function DisableModule(self, name)
local module = self:GetModule( name )
return module:Disable()
end
 
--- Set the default libraries to be mixed into all modules created by this object.
-- Note that you can only change the default module libraries before any module is created.
-- @name //addon//:SetDefaultModuleLibraries
-- @paramsig lib[, lib, ...]
-- @param lib List of libraries to embed into the addon
-- @usage
-- -- Create the addon object
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon")
-- -- Configure default libraries for modules (all modules need AceEvent-3.0)
-- MyAddon:SetDefaultModuleLibraries("AceEvent-3.0")
-- -- Create a module
-- MyModule = MyAddon:NewModule("MyModule")
function SetDefaultModuleLibraries(self, ...)
if next(self.modules) then
error("Usage: SetDefaultModuleLibraries(...): cannot change the module defaults after a module has been registered.", 2)
end
self.defaultModuleLibraries = {...}
end
 
--- Set the default state in which new modules are being created.
-- Note that you can only change the default state before any module is created.
-- @name //addon//:SetDefaultModuleState
-- @paramsig state
-- @param state Default state for new modules, true for enabled, false for disabled
-- @usage
-- -- Create the addon object
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon")
-- -- Set the default state to "disabled"
-- MyAddon:SetDefaultModuleState(false)
-- -- Create a module and explicilty enable it
-- MyModule = MyAddon:NewModule("MyModule")
-- MyModule:Enable()
function SetDefaultModuleState(self, state)
if next(self.modules) then
error("Usage: SetDefaultModuleState(state): cannot change the module defaults after a module has been registered.", 2)
end
self.defaultModuleState = state
end
 
--- Set the default prototype to use for new modules on creation.
-- Note that you can only change the default prototype before any module is created.
-- @name //addon//:SetDefaultModulePrototype
-- @paramsig prototype
-- @param prototype Default prototype for the new modules (table)
-- @usage
-- -- Define a prototype
-- local prototype = { OnEnable = function(self) print("OnEnable called!") end }
-- -- Set the default prototype
-- MyAddon:SetDefaultModulePrototype(prototype)
-- -- Create a module and explicitly Enable it
-- MyModule = MyAddon:NewModule("MyModule")
-- MyModule:Enable()
-- -- should print "OnEnable called!" now
-- @see NewModule
function SetDefaultModulePrototype(self, prototype)
if next(self.modules) then
error("Usage: SetDefaultModulePrototype(prototype): cannot change the module defaults after a module has been registered.", 2)
end
if type(prototype) ~= "table" then
error(("Usage: SetDefaultModulePrototype(prototype): 'prototype' - table expected got '%s'."):format(type(prototype)), 2)
end
self.defaultModulePrototype = prototype
end
 
--- Set the state of an addon or module
-- This should only be called before any enabling actually happend, e.g. in/before OnInitialize.
-- @name //addon//:SetEnabledState
-- @paramsig state
-- @param state the state of an addon or module (enabled=true, disabled=false)
function SetEnabledState(self, state)
self.enabledState = state
end
 
 
--- Return an iterator of all modules associated to the addon.
-- @name //addon//:IterateModules
-- @paramsig
-- @usage
-- -- Enable all modules
-- for name, module in MyAddon:IterateModules() do
-- module:Enable()
-- end
local function IterateModules(self) return pairs(self.modules) end
 
-- Returns an iterator of all embeds in the addon
-- @name //addon//:IterateEmbeds
-- @paramsig
local function IterateEmbeds(self) return pairs(AceAddon.embeds[self]) end
 
--- Query the enabledState of an addon.
-- @name //addon//:IsEnabled
-- @paramsig
-- @usage
-- if MyAddon:IsEnabled() then
-- MyAddon:Disable()
-- end
local function IsEnabled(self) return self.enabledState end
local mixins = {
NewModule = NewModule,
GetModule = GetModule,
Enable = Enable,
Disable = Disable,
EnableModule = EnableModule,
DisableModule = DisableModule,
IsEnabled = IsEnabled,
SetDefaultModuleLibraries = SetDefaultModuleLibraries,
SetDefaultModuleState = SetDefaultModuleState,
SetDefaultModulePrototype = SetDefaultModulePrototype,
SetEnabledState = SetEnabledState,
IterateModules = IterateModules,
IterateEmbeds = IterateEmbeds,
GetName = GetName,
}
local function IsModule(self) return false end
local pmixins = {
defaultModuleState = true,
enabledState = true,
IsModule = IsModule,
}
-- Embed( target )
-- target (object) - target object to embed aceaddon in
--
-- this is a local function specifically since it's meant to be only called internally
function Embed(target)
for k, v in pairs(mixins) do
target[k] = v
end
for k, v in pairs(pmixins) do
target[k] = target[k] or v
end
end
 
 
-- - Initialize the addon after creation.
-- This function is only used internally during the ADDON_LOADED event
-- It will call the **OnInitialize** function on the addon object (if present),
-- and the **OnEmbedInitialize** function on all embeded libraries.
--
-- **Note:** Do not call this function manually, unless you're absolutely sure that you know what you are doing.
-- @param addon addon object to intialize
function AceAddon:InitializeAddon(addon)
safecall(addon.OnInitialize, addon)
 
local embeds = self.embeds[addon]
for i = 1, #embeds do
local lib = LibStub:GetLibrary(embeds[i], true)
if lib then safecall(lib.OnEmbedInitialize, lib, addon) end
end
 
-- we don't call InitializeAddon on modules specifically, this is handled
-- from the event handler and only done _once_
end
 
-- - Enable the addon after creation.
-- Note: This function is only used internally during the PLAYER_LOGIN event, or during ADDON_LOADED,
-- if IsLoggedIn() already returns true at that point, e.g. for LoD Addons.
-- It will call the **OnEnable** function on the addon object (if present),
-- and the **OnEmbedEnable** function on all embeded libraries.\\
-- This function does not toggle the enable state of the addon itself, and will return early if the addon is disabled.
--
-- **Note:** Do not call this function manually, unless you're absolutely sure that you know what you are doing.
-- Use :Enable on the addon itself instead.
-- @param addon addon object to enable
function AceAddon:EnableAddon(addon)
if type(addon) == "string" then addon = AceAddon:GetAddon(addon) end
if self.statuses[addon.name] or not addon.enabledState then return false end
 
-- set the statuses first, before calling the OnEnable. this allows for Disabling of the addon in OnEnable.
self.statuses[addon.name] = true
 
safecall(addon.OnEnable, addon)
 
-- make sure we're still enabled before continueing
if self.statuses[addon.name] then
local embeds = self.embeds[addon]
for i = 1, #embeds do
local lib = LibStub:GetLibrary(embeds[i], true)
if lib then safecall(lib.OnEmbedEnable, lib, addon) end
end
 
-- enable possible modules.
for name, module in pairs(addon.modules) do
self:EnableAddon(module)
end
end
return self.statuses[addon.name] -- return true if we're disabled
end
 
-- - Disable the addon
-- Note: This function is only used internally.
-- It will call the **OnDisable** function on the addon object (if present),
-- and the **OnEmbedDisable** function on all embeded libraries.\\
-- This function does not toggle the enable state of the addon itself, and will return early if the addon is still enabled.
--
-- **Note:** Do not call this function manually, unless you're absolutely sure that you know what you are doing.
-- Use :Disable on the addon itself instead.
-- @param addon addon object to enable
function AceAddon:DisableAddon(addon)
if type(addon) == "string" then addon = AceAddon:GetAddon(addon) end
if not self.statuses[addon.name] then return false end
 
-- set statuses first before calling OnDisable, this allows for aborting the disable in OnDisable.
self.statuses[addon.name] = false
 
safecall( addon.OnDisable, addon )
 
-- make sure we're still disabling...
if not self.statuses[addon.name] then
local embeds = self.embeds[addon]
for i = 1, #embeds do
local lib = LibStub:GetLibrary(embeds[i], true)
if lib then safecall(lib.OnEmbedDisable, lib, addon) end
end
-- disable possible modules.
for name, module in pairs(addon.modules) do
self:DisableAddon(module)
end
end
 
return not self.statuses[addon.name] -- return true if we're disabled
end
 
--- Get an iterator over all registered addons.
-- @usage
-- -- Print a list of all installed AceAddon's
-- for name, addon in AceAddon:IterateAddons() do
-- print("Addon: " .. name)
-- end
function AceAddon:IterateAddons() return pairs(self.addons) end
 
--- Get an iterator over the internal status registry.
-- @usage
-- -- Print a list of all enabled addons
-- for name, status in AceAddon:IterateAddonStatus() do
-- if status then
-- print("EnabledAddon: " .. name)
-- end
-- end
function AceAddon:IterateAddonStatus() return pairs(self.statuses) end
 
-- Following Iterators are deprecated, and their addon specific versions should be used
-- e.g. addon:IterateEmbeds() instead of :IterateEmbedsOnAddon(addon)
function AceAddon:IterateEmbedsOnAddon(addon) return pairs(self.embeds[addon]) end
function AceAddon:IterateModulesOfAddon(addon) return pairs(addon.modules) end
 
-- Event Handling
local function onEvent(this, event, arg1)
if event == "ADDON_LOADED" or event == "PLAYER_LOGIN" then
-- if a addon loads another addon, recursion could happen here, so we need to validate the table on every iteration
while(#AceAddon.initializequeue > 0) do
local addon = tremove(AceAddon.initializequeue, 1)
-- this might be an issue with recursion - TODO: validate
if event == "ADDON_LOADED" then addon.baseName = arg1 end
AceAddon:InitializeAddon(addon)
tinsert(AceAddon.enablequeue, addon)
end
 
if IsLoggedIn() then
while(#AceAddon.enablequeue > 0) do
local addon = tremove(AceAddon.enablequeue, 1)
AceAddon:EnableAddon(addon)
end
end
end
end
 
AceAddon.frame:RegisterEvent("ADDON_LOADED")
AceAddon.frame:RegisterEvent("PLAYER_LOGIN")
AceAddon.frame:SetScript("OnEvent", onEvent)
 
-- upgrade embeded
for name, addon in pairs(AceAddon.addons) do
Embed(addon)
end
EasyDaily/libs/AceDB-3.0/AceDB-3.0.xml New file
0,0 → 1,4
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="AceDB-3.0.lua"/>
</Ui>
\ No newline at end of file
EasyDaily/libs/AceDB-3.0/AceDB-3.0.lua New file
0,0 → 1,683
--- **AceDB-3.0** manages the SavedVariables of your addon.
-- It offers profile management, smart defaults and namespaces for modules.\\
-- Data can be saved in different data-types, depending on its intended usage.
-- The most common data-type is the `profile` type, which allows the user to choose
-- the active profile, and manage the profiles of all of his characters.\\
-- The following data types are available:
-- * **char** Character-specific data. Every character has its own database.
-- * **realm** Realm-specific data. All of the players characters on the same realm share this database.
-- * **class** Class-specific data. All of the players characters of the same class share this database.
-- * **race** Race-specific data. All of the players characters of the same race share this database.
-- * **faction** Faction-specific data. All of the players characters of the same faction share this database.
-- * **factionrealm** Faction and realm specific data. All of the players characters on the same realm and of the same faction share this database.
-- * **global** Global Data. All characters on the same account share this database.
-- * **profile** Profile-specific data. All characters using the same profile share this database. The user can control which profile should be used.
--
-- Creating a new Database using the `:New` function will return a new DBObject. A database will inherit all functions
-- of the DBObjectLib listed here. \\
-- If you create a new namespaced child-database (`:RegisterNamespace`), you'll get a DBObject as well, but note
-- that the child-databases cannot individually change their profile, and are linked to their parents profile - and because of that,
-- the profile related APIs are not available. Only `:RegisterDefaults` and `:ResetProfile` are available on child-databases.
--
-- For more details on how to use AceDB-3.0, see the [[AceDB-3.0 Tutorial]].
-- @usage
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("DBExample")
--
-- -- declare defaults to be used in the DB
-- local defaults = {
-- profile = {
-- setting = true,
-- }
-- }
--
-- function MyAddon:OnInitialize()
-- -- Assuming the .toc says ## SavedVariables: MyAddonDB
-- self.db = LibStub("AceDB-3.0"):New("MyAddonDB", defaults, true)
-- end
-- @class file
-- @name AceDB-3.0.lua
-- @release $Id: AceDB-3.0.lua 799 2009-04-09 05:00:05Z kaelten $
local ACEDB_MAJOR, ACEDB_MINOR = "AceDB-3.0", 13
local AceDB, oldminor = LibStub:NewLibrary(ACEDB_MAJOR, ACEDB_MINOR)
 
if not AceDB then return end -- No upgrade needed
 
local type = type
local pairs, next = pairs, next
local rawget, rawset = rawget, rawset
local setmetatable = setmetatable
 
AceDB.db_registry = AceDB.db_registry or {}
AceDB.frame = AceDB.frame or CreateFrame("Frame")
 
local CallbackHandler
local CallbackDummy = { Fire = function() end }
 
local DBObjectLib = {}
 
--[[-------------------------------------------------------------------------
AceDB Utility Functions
---------------------------------------------------------------------------]]
 
-- Simple shallow copy for copying defaults
local function copyTable(src, dest)
if type(dest) ~= "table" then dest = {} end
if type(src) == "table" then
for k,v in pairs(src) do
if type(v) == "table" then
-- try to index the key first so that the metatable creates the defaults, if set, and use that table
v = copyTable(v, dest[k])
end
dest[k] = v
end
end
return dest
end
 
-- Called to add defaults to a section of the database
--
-- When a ["*"] default section is indexed with a new key, a table is returned
-- and set in the host table. These tables must be cleaned up by removeDefaults
-- in order to ensure we don't write empty default tables.
local function copyDefaults(dest, src)
-- this happens if some value in the SV overwrites our default value with a non-table
--if type(dest) ~= "table" then return end
for k, v in pairs(src) do
if k == "*" or k == "**" then
if type(v) == "table" then
-- This is a metatable used for table defaults
local mt = {
-- This handles the lookup and creation of new subtables
__index = function(t,k)
if k == nil then return nil end
local tbl = {}
copyDefaults(tbl, v)
rawset(t, k, tbl)
return tbl
end,
}
setmetatable(dest, mt)
-- handle already existing tables in the SV
for dk, dv in pairs(dest) do
if not rawget(src, dk) and type(dv) == "table" then
copyDefaults(dv, v)
end
end
else
-- Values are not tables, so this is just a simple return
local mt = {__index = function(t,k) return k~=nil and v or nil end}
setmetatable(dest, mt)
end
elseif type(v) == "table" then
if not rawget(dest, k) then rawset(dest, k, {}) end
if type(dest[k]) == "table" then
copyDefaults(dest[k], v)
if src['**'] then
copyDefaults(dest[k], src['**'])
end
end
else
if rawget(dest, k) == nil then
rawset(dest, k, v)
end
end
end
end
 
-- Called to remove all defaults in the default table from the database
local function removeDefaults(db, defaults, blocker)
for k,v in pairs(defaults) do
if k == "*" or k == "**" then
if type(v) == "table" then
-- Loop through all the actual k,v pairs and remove
for key, value in pairs(db) do
if type(value) == "table" then
-- if the key was not explicitly specified in the defaults table, just strip everything from * and ** tables
if defaults[key] == nil and (not blocker or blocker[key] == nil) then
removeDefaults(value, v)
-- if the table is empty afterwards, remove it
if next(value) == nil then
db[key] = nil
end
-- if it was specified, only strip ** content, but block values which were set in the key table
elseif k == "**" then
removeDefaults(value, v, defaults[key])
end
end
end
elseif k == "*" then
-- check for non-table default
for key, value in pairs(db) do
if defaults[key] == nil and v == value then
db[key] = nil
end
end
end
elseif type(v) == "table" and type(db[k]) == "table" then
-- if a blocker was set, dive into it, to allow multi-level defaults
removeDefaults(db[k], v, blocker and blocker[k])
if next(db[k]) == nil then
db[k] = nil
end
else
-- check if the current value matches the default, and that its not blocked by another defaults table
if db[k] == defaults[k] and (not blocker or blocker[k] == nil) then
db[k] = nil
end
end
end
-- remove all metatables from the db
setmetatable(db, nil)
end
 
-- This is called when a table section is first accessed, to set up the defaults
local function initSection(db, section, svstore, key, defaults)
local sv = rawget(db, "sv")
 
local tableCreated
if not sv[svstore] then sv[svstore] = {} end
if not sv[svstore][key] then
sv[svstore][key] = {}
tableCreated = true
end
 
local tbl = sv[svstore][key]
 
if defaults then
copyDefaults(tbl, defaults)
end
rawset(db, section, tbl)
 
return tableCreated, tbl
end
 
-- Metatable to handle the dynamic creation of sections and copying of sections.
local dbmt = {
__index = function(t, section)
local keys = rawget(t, "keys")
local key = keys[section]
if key then
local defaultTbl = rawget(t, "defaults")
local defaults = defaultTbl and defaultTbl[section]
 
if section == "profile" then
local new = initSection(t, section, "profiles", key, defaults)
if new then
-- Callback: OnNewProfile, database, newProfileKey
t.callbacks:Fire("OnNewProfile", t, key)
end
elseif section == "profiles" then
local sv = rawget(t, "sv")
if not sv.profiles then sv.profiles = {} end
rawset(t, "profiles", sv.profiles)
elseif section == "global" then
local sv = rawget(t, "sv")
if not sv.global then sv.global = {} end
if defaults then
copyDefaults(sv.global, defaults)
end
rawset(t, section, sv.global)
else
initSection(t, section, section, key, defaults)
end
end
 
return rawget(t, section)
end
}
 
local function validateDefaults(defaults, keyTbl, offset)
if not defaults then return end
offset = offset or 0
for k in pairs(defaults) do
if not keyTbl[k] or k == "profiles" then
error(("Usage: AceDBObject:RegisterDefaults(defaults): '%s' is not a valid datatype."):format(k), 3 + offset)
end
end
end
 
local preserve_keys = {
["callbacks"] = true,
["RegisterCallback"] = true,
["UnregisterCallback"] = true,
["UnregisterAllCallbacks"] = true,
["children"] = true,
}
 
local realmKey = GetRealmName()
local charKey = UnitName("player") .. " - " .. realmKey
local _, classKey = UnitClass("player")
local _, raceKey = UnitRace("player")
local factionKey = UnitFactionGroup("player")
local factionrealmKey = factionKey .. " - " .. realmKey
-- Actual database initialization function
local function initdb(sv, defaults, defaultProfile, olddb, parent)
-- Generate the database keys for each section
 
-- Make a container for profile keys
if not sv.profileKeys then sv.profileKeys = {} end
 
-- map "true" to our "Default" profile
if defaultProfile == true then defaultProfile = "Default" end
 
-- Try to get the profile selected from the char db
local profileKey = sv.profileKeys[charKey] or defaultProfile or charKey
sv.profileKeys[charKey] = profileKey
 
-- This table contains keys that enable the dynamic creation
-- of each section of the table. The 'global' and 'profiles'
-- have a key of true, since they are handled in a special case
local keyTbl= {
["char"] = charKey,
["realm"] = realmKey,
["class"] = classKey,
["race"] = raceKey,
["faction"] = factionKey,
["factionrealm"] = factionrealmKey,
["profile"] = profileKey,
["global"] = true,
["profiles"] = true,
}
 
validateDefaults(defaults, keyTbl, 1)
 
-- This allows us to use this function to reset an entire database
-- Clear out the old database
if olddb then
for k,v in pairs(olddb) do if not preserve_keys[k] then olddb[k] = nil end end
end
 
-- Give this database the metatable so it initializes dynamically
local db = setmetatable(olddb or {}, dbmt)
 
if not rawget(db, "callbacks") then
-- try to load CallbackHandler-1.0 if it loaded after our library
if not CallbackHandler then CallbackHandler = LibStub:GetLibrary("CallbackHandler-1.0", true) end
db.callbacks = CallbackHandler and CallbackHandler:New(db) or CallbackDummy
end
 
-- Copy methods locally into the database object, to avoid hitting
-- the metatable when calling methods
 
if not parent then
for name, func in pairs(DBObjectLib) do
db[name] = func
end
else
-- hack this one in
db.RegisterDefaults = DBObjectLib.RegisterDefaults
db.ResetProfile = DBObjectLib.ResetProfile
end
 
-- Set some properties in the database object
db.profiles = sv.profiles
db.keys = keyTbl
db.sv = sv
--db.sv_name = name
db.defaults = defaults
db.parent = parent
 
-- store the DB in the registry
AceDB.db_registry[db] = true
 
return db
end
 
-- handle PLAYER_LOGOUT
-- strip all defaults from all databases
local function logoutHandler(frame, event)
if event == "PLAYER_LOGOUT" then
for db in pairs(AceDB.db_registry) do
db.callbacks:Fire("OnDatabaseShutdown", db)
for section, key in pairs(db.keys) do
if db.defaults and db.defaults[section] and rawget(db, section) then
removeDefaults(db[section], db.defaults[section])
end
end
end
end
end
 
AceDB.frame:RegisterEvent("PLAYER_LOGOUT")
AceDB.frame:SetScript("OnEvent", logoutHandler)
 
 
--[[-------------------------------------------------------------------------
AceDB Object Method Definitions
---------------------------------------------------------------------------]]
 
--- Sets the defaults table for the given database object by clearing any
-- that are currently set, and then setting the new defaults.
-- @param defaults A table of defaults for this database
function DBObjectLib:RegisterDefaults(defaults)
if defaults and type(defaults) ~= "table" then
error("Usage: AceDBObject:RegisterDefaults(defaults): 'defaults' - table or nil expected.", 2)
end
 
validateDefaults(defaults, self.keys)
 
-- Remove any currently set defaults
if self.defaults then
for section,key in pairs(self.keys) do
if self.defaults[section] and rawget(self, section) then
removeDefaults(self[section], self.defaults[section])
end
end
end
 
-- Set the DBObject.defaults table
self.defaults = defaults
 
-- Copy in any defaults, only touching those sections already created
if defaults then
for section,key in pairs(self.keys) do
if defaults[section] and rawget(self, section) then
copyDefaults(self[section], defaults[section])
end
end
end
end
 
--- Changes the profile of the database and all of it's namespaces to the
-- supplied named profile
-- @param name The name of the profile to set as the current profile
function DBObjectLib:SetProfile(name)
if type(name) ~= "string" then
error("Usage: AceDBObject:SetProfile(name): 'name' - string expected.", 2)
end
 
-- changing to the same profile, dont do anything
if name == self.keys.profile then return end
 
local oldProfile = self.profile
local defaults = self.defaults and self.defaults.profile
 
-- Callback: OnProfileShutdown, database
self.callbacks:Fire("OnProfileShutdown", self)
 
if oldProfile and defaults then
-- Remove the defaults from the old profile
removeDefaults(oldProfile, defaults)
end
 
self.profile = nil
self.keys["profile"] = name
self.sv.profileKeys[charKey] = name
 
-- populate to child namespaces
if self.children then
for _, db in pairs(self.children) do
DBObjectLib.SetProfile(db, name)
end
end
 
-- Callback: OnProfileChanged, database, newProfileKey
self.callbacks:Fire("OnProfileChanged", self, name)
end
 
--- Returns a table with the names of the existing profiles in the database.
-- You can optionally supply a table to re-use for this purpose.
-- @param tbl A table to store the profile names in (optional)
function DBObjectLib:GetProfiles(tbl)
if tbl and type(tbl) ~= "table" then
error("Usage: AceDBObject:GetProfiles(tbl): 'tbl' - table or nil expected.", 2)
end
 
-- Clear the container table
if tbl then
for k,v in pairs(tbl) do tbl[k] = nil end
else
tbl = {}
end
 
local curProfile = self.keys.profile
 
local i = 0
for profileKey in pairs(self.profiles) do
i = i + 1
tbl[i] = profileKey
if curProfile and profileKey == curProfile then curProfile = nil end
end
 
-- Add the current profile, if it hasn't been created yet
if curProfile then
i = i + 1
tbl[i] = curProfile
end
 
return tbl, i
end
 
--- Returns the current profile name used by the database
function DBObjectLib:GetCurrentProfile()
return self.keys.profile
end
 
--- Deletes a named profile. This profile must not be the active profile.
-- @param name The name of the profile to be deleted
-- @param silent If true, do not raise an error when the profile does not exist
function DBObjectLib:DeleteProfile(name, silent)
if type(name) ~= "string" then
error("Usage: AceDBObject:DeleteProfile(name): 'name' - string expected.", 2)
end
 
if self.keys.profile == name then
error("Cannot delete the active profile in an AceDBObject.", 2)
end
 
if not rawget(self.sv.profiles, name) and not silent then
error("Cannot delete profile '" .. name .. "'. It does not exist.", 2)
end
 
self.sv.profiles[name] = nil
 
-- populate to child namespaces
if self.children then
for _, db in pairs(self.children) do
DBObjectLib.DeleteProfile(db, name, true)
end
end
 
-- Callback: OnProfileDeleted, database, profileKey
self.callbacks:Fire("OnProfileDeleted", self, name)
end
 
--- Copies a named profile into the current profile, overwriting any conflicting
-- settings.
-- @param name The name of the profile to be copied into the current profile
-- @param silent If true, do not raise an error when the profile does not exist
function DBObjectLib:CopyProfile(name, silent)
if type(name) ~= "string" then
error("Usage: AceDBObject:CopyProfile(name): 'name' - string expected.", 2)
end
 
if name == self.keys.profile then
error("Cannot have the same source and destination profiles.", 2)
end
 
if not rawget(self.sv.profiles, name) and not silent then
error("Cannot copy profile '" .. name .. "'. It does not exist.", 2)
end
 
-- Reset the profile before copying
DBObjectLib.ResetProfile(self)
 
local profile = self.profile
local source = self.sv.profiles[name]
 
copyTable(source, profile)
 
-- populate to child namespaces
if self.children then
for _, db in pairs(self.children) do
DBObjectLib.CopyProfile(db, name, true)
end
end
 
-- Callback: OnProfileCopied, database, sourceProfileKey
self.callbacks:Fire("OnProfileCopied", self, name)
end
 
--- Resets the current profile to the default values (if specified).
-- @param noChildren if set to true, the reset will not be populated to the child namespaces of this DB object
function DBObjectLib:ResetProfile(noChildren)
local profile = self.profile
 
for k,v in pairs(profile) do
profile[k] = nil
end
 
local defaults = self.defaults and self.defaults.profile
if defaults then
copyDefaults(profile, defaults)
end
 
-- populate to child namespaces
if self.children and not noChildren then
for _, db in pairs(self.children) do
DBObjectLib.ResetProfile(db)
end
end
 
-- Callback: OnProfileReset, database
self.callbacks:Fire("OnProfileReset", self)
end
 
--- Resets the entire database, using the string defaultProfile as the new default
-- profile.
-- @param defaultProfile The profile name to use as the default
function DBObjectLib:ResetDB(defaultProfile)
if defaultProfile and type(defaultProfile) ~= "string" then
error("Usage: AceDBObject:ResetDB(defaultProfile): 'defaultProfile' - string or nil expected.", 2)
end
 
local sv = self.sv
for k,v in pairs(sv) do
sv[k] = nil
end
 
local parent = self.parent
 
initdb(sv, self.defaults, defaultProfile, self)
 
-- fix the child namespaces
if self.children then
if not sv.namespaces then sv.namespaces = {} end
for name, db in pairs(self.children) do
if not sv.namespaces[name] then sv.namespaces[name] = {} end
initdb(sv.namespaces[name], db.defaults, self.keys.profile, db, self)
end
end
 
-- Callback: OnDatabaseReset, database
self.callbacks:Fire("OnDatabaseReset", self)
-- Callback: OnProfileChanged, database, profileKey
self.callbacks:Fire("OnProfileChanged", self, self.keys["profile"])
 
return self
end
 
--- Creates a new database namespace, directly tied to the database. This
-- is a full scale database in it's own rights other than the fact that
-- it cannot control its profile individually
-- @param name The name of the new namespace
-- @param defaults A table of values to use as defaults
function DBObjectLib:RegisterNamespace(name, defaults)
if type(name) ~= "string" then
error("Usage: AceDBObject:RegisterNamespace(name, defaults): 'name' - string expected.", 2)
end
if defaults and type(defaults) ~= "table" then
error("Usage: AceDBObject:RegisterNamespace(name, defaults): 'defaults' - table or nil expected.", 2)
end
if self.children and self.children[name] then
error ("Usage: AceDBObject:RegisterNamespace(name, defaults): 'name' - a namespace with that name already exists.", 2)
end
 
local sv = self.sv
if not sv.namespaces then sv.namespaces = {} end
if not sv.namespaces[name] then
sv.namespaces[name] = {}
end
 
local newDB = initdb(sv.namespaces[name], defaults, self.keys.profile, nil, self)
 
if not self.children then self.children = {} end
self.children[name] = newDB
return newDB
end
 
--- Returns an already existing namespace from the database object.
-- @param name The name of the new namespace
-- @param silent if true, the addon is optional, silently return nil if its not found
-- @usage
-- local namespace = self.db:GetNamespace('namespace')
-- @return the namespace object if found
function DBObjectLib:GetNamespace(name, silent)
if type(name) ~= "string" then
error("Usage: AceDBObject:GetNamespace(name): 'name' - string expected.", 2)
end
if not silent and not (self.children and self.children[name]) then
error ("Usage: AceDBObject:GetNamespace(name): 'name' - namespace does not exist.", 2)
end
if not self.children then self.children = {} end
return self.children[name]
end
 
--[[-------------------------------------------------------------------------
AceDB Exposed Methods
---------------------------------------------------------------------------]]
 
--- Creates a new database object that can be used to handle database settings and profiles.
-- By default, an empty DB is created, using a character specific profile.
--
-- You can override the default profile used by passing any profile name as the third argument,
-- or by passing //true// as the third argument to use a globally shared profile called "Default".
--
-- Note that there is no token replacement in the default profile name, passing a defaultProfile as "char"
-- will use a profile named "char", and not a character-specific profile.
-- @param tbl The name of variable, or table to use for the database
-- @param defaults A table of database defaults
-- @param defaultProfile The name of the default profile. If not set, a character specific profile will be used as the default.
-- You can also pass //true// to use a shared global profile called "Default".
-- @usage
-- -- Create an empty DB using a character-specific default profile.
-- self.db = LibStub("AceDB-3.0"):New("MyAddonDB")
-- @usage
-- -- Create a DB using defaults and using a shared default profile
-- self.db = LibStub("AceDB-3.0"):New("MyAddonDB", defaults, true)
function AceDB:New(tbl, defaults, defaultProfile)
if type(tbl) == "string" then
local name = tbl
tbl = getglobal(name)
if not tbl then
tbl = {}
setglobal(name, tbl)
end
end
 
if type(tbl) ~= "table" then
error("Usage: AceDB:New(tbl, defaults, defaultProfile): 'tbl' - table expected.", 2)
end
 
if defaults and type(defaults) ~= "table" then
error("Usage: AceDB:New(tbl, defaults, defaultProfile): 'defaults' - table expected.", 2)
end
 
if defaultProfile and type(defaultProfile) ~= "string" and defaultProfile ~= true then
error("Usage: AceDB:New(tbl, defaults, defaultProfile): 'defaultProfile' - string or true expected.", 2)
end
 
return initdb(tbl, defaults, defaultProfile)
end
 
-- upgrade existing databases
for db in pairs(AceDB.db_registry) do
if not db.parent then
for name,func in pairs(DBObjectLib) do
db[name] = func
end
else
db.RegisterDefaults = DBObjectLib.RegisterDefaults
db.ResetProfile = DBObjectLib.ResetProfile
end
end
EasyDaily/libs/LibGratuity-3.0/LibGratuity-3.0.lua New file
0,0 → 1,247
--[[
Name: LibGratuity-3.0
Revision: $Rev: 39 $
Author: Tekkub Stoutwrithe (tekkub@gmail.com)
SVN: svn://svn.wowace.com/root/trunk/LibGratuity-3.0
Description: Tooltip parsing library
Dependencies: (optional) Deformat-2.0
]]
 
local vmajor, vminor = "LibGratuity-3.0", 90000 + tonumber(("$Revision: 39 $"):match("%d+"))
 
local lib = LibStub:NewLibrary(vmajor, vminor)
if not lib then
return
end
 
local methods = {
"SetBagItem", "SetAction", "SetAuctionItem", "SetAuctionSellItem", "SetBuybackItem",
"SetCraftItem", "SetCraftSpell", "SetHyperlink", "SetInboxItem", "SetInventoryItem",
"SetLootItem", "SetLootRollItem", "SetMerchantItem", "SetPetAction", "SetPlayerBuff",
"SetQuestItem", "SetQuestLogItem", "SetQuestRewardSpell", "SetSendMailItem", "SetShapeshift",
"SetSpell", "SetTalent", "SetTrackingSpell", "SetTradePlayerItem", "SetTradeSkillItem", "SetTradeTargetItem",
"SetTrainerService", "SetUnit", "SetUnitBuff", "SetUnitDebuff", "SetGuildBankItem",
}
 
function lib:CreateTooltip()
local tt = CreateFrame("GameTooltip")
 
self.vars.tooltip = tt
tt:SetOwner(UIParent, "ANCHOR_NONE")
-- tt:SetOwner(tt, "ANCHOR_NONE")
-- tooltip:SetParent()
 
self.vars.Llines, self.vars.Rlines = {}, {}
for i=1,30 do
self.vars.Llines[i], self.vars.Rlines[i] = tt:CreateFontString(), tt:CreateFontString()
self.vars.Llines[i]:SetFontObject(GameFontNormal)
self.vars.Rlines[i]:SetFontObject(GameFontNormal)
tt:AddFontStrings(self.vars.Llines[i], self.vars.Rlines[i])
end
end
 
 
-- Clears the tooltip completely, none of this "erase left, hide right" crap blizzard does
function lib:Erase()
self.vars.tooltip:ClearLines() -- Ensures tooltip's NumLines is reset
for i=1,30 do self.vars.Rlines[i]:SetText() end -- Clear text from right side (ClearLines only hides them)
-- if not self.vars.tooltip:IsOwned(self.vars.tooltip) then self.vars.tooltip:SetOwner(self.vars.tooltip, "ANCHOR_NONE") end
if not self.vars.tooltip:IsOwned(UIParent) then self.vars.tooltip:SetOwner(UIParent, "ANCHOR_NONE") end
-- if not self.vars.tooltip:IsOwned(self.vars.tooltip) then
-- error("Gratuity's tooltip is not scannable", 2)
-- end
if not self.vars.tooltip:IsOwned(UIParent) then
error("Gratuity's tooltip is not scannable", 2)
end
end
 
 
-- Get the number of lines
-- Arg: endln - If passed and tooltip's NumLines is higher, endln is returned back
function lib:NumLines(endln)
local num = self.vars.tooltip:NumLines()
return endln and num > endln and endln or num or 0
end
 
local FindDefault = function(str, pattern)
return string.find(str, pattern);
end;
 
local FindExact = function(str, pattern)
if (str == pattern) then
return string.find(str, pattern);
end;
end;
 
-- If text is found on tooltip then results of string.find are returned
-- Args:
-- txt - The text string to find
-- startln - First tooltip line to check, default 1
-- endln - Last line to test, default 30
-- ignoreleft / ignoreright - Causes text on one side of the tooltip to be ignored
-- exact - the compare will be an exact match vs the default behaviour of
function lib:Find(txt, startln, endln, ignoreleft, ignoreright, exact)
local searchFunction = FindDefault;
if (exact == true) then
searchFunction = FindExact;
end;
assert(type(txt) == "string" or type(txt) == "number")
local t1, t2 = type(startln or 1), type(self:NumLines(endln))
if (t1 ~= "number" or t2 ~= "number") then print(t1, t2, (startln or 1),self:NumLines(endln)) end
for i=(startln or 1),self:NumLines(endln) do
if not ignoreleft and self.vars.Llines[i] then
local txtl = self.vars.Llines[i]:GetText()
if (txtl and searchFunction(txtl, txt)) then return string.find(txtl, txt) end
end
 
if not ignoreright and self.vars.Rlines[i] then
local txtr = self.vars.Rlines[i]:GetText()
if (txtr and searchFunction(txtr, txt)) then return string.find(txtr, txt) end
end
end
end
 
 
-- Calls Find many times.
-- Args are passed directly to Find, t1-t10 replace the txt arg
-- Returns Find results for the first match found, if any
function lib:MultiFind(startln, endln, ignoreleft, ignoreright, t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
assert(type(t1) == "string" or type(t1) == "number")
if t1 and self:Find(t1, startln, endln, ignoreleft, ignoreright) then return self:Find(t1, startln, endln, ignoreleft, ignoreright)
elseif t2 then return self:MultiFind(startln, endln, ignoreleft, ignoreright, t2,t3,t4,t5,t6,t7,t8,t9,t10) end
end
 
 
local deformat
-- If text is found on tooltip then results of deformat:Deformat are returned
-- Args:
-- txt - The text string to deformat and serach for
-- startln - First tooltip line to check, default 1
-- endln - Last line to test, default 30
-- ignoreleft / ignoreright - Causes text on one side of the tooltip to be ignored
function lib:FindDeformat(txt, startln, endln, ignoreleft, ignoreright)
assert(type(txt) == "string" or type(txt) == "number")
if not deformat then
if not AceLibrary or not AceLibrary:HasInstance("Deformat-2.0") then
error("FindDeformat requires Deformat-2.0 to be available", 2)
end
deformat = AceLibrary("Deformat-2.0")
end
 
for i=(startln or 1),self:NumLines(endln) do
if not ignoreleft and self.vars.Llines[i] then
local txtl = self.vars.Llines[i]:GetText()
if (txtl and deformat(txtl, txt)) then return deformat(txtl, txt) end
end
 
if not ignoreright and self.vars.Rlines[i] then
local txtr = self.vars.Rlines[i]:GetText()
if (txtr and deformat(txtr, txt)) then return deformat(txtr, txt) end
end
end
end
 
 
-- Returns a table of strings pulled from the tooltip, or nil if no strings in tooltip
-- Args:
-- startln - First tooltip line to check, default 1
-- endln - Last line to test, default 30
-- ignoreleft / ignoreright - Causes text on one side of the tooltip to be ignored
function lib:GetText(startln, endln, ignoreleft, ignoreright)
local retval
 
for i=(startln or 1),(endln or 30) do
local txtl, txtr
if not ignoreleft and self.vars.Llines[i] then txtl = self.vars.Llines[i]:GetText() end
if not ignoreright and self.vars.Rlines[i] then txtr = self.vars.Rlines[i]:GetText() end
if txtl or txtr then
if not retval then retval = {} end
local t = {txtl, txtr}
table.insert(retval, t)
end
end
 
return retval
end
 
 
-- Returns the text from a specific line (both left and right unless second arg is true)
-- Args:
-- line - the line number you wish to retrieve
-- getright - if passed the right line will be returned, if not the left will be returned
function lib:GetLine(line, getright)
assert(type(line) == "number")
if self.vars.tooltip:NumLines() < line then return end
if getright then return self.vars.Rlines[line] and self.vars.Rlines[line]:GetText()
elseif self.vars.Llines[line] then
return self.vars.Llines[line]:GetText(), self.vars.Rlines[line]:GetText()
end
end
 
 
-----------------------------------
-- Set tooltip methods --
-----------------------------------
 
-- These methods are designed to immitate the GameTooltip API
local testmethods = {
SetAction = function(id) return HasAction(id) end,
}
local gettrue = function() return true end
 
local function handlePcall(success, ...)
if not success then
geterrorhandler()(...)
return
end
return ...
end
 
function lib:CreateSetMethods()
for _,m in pairs(methods) do
local meth = m
local func = testmethods[meth] or gettrue
self[meth] = function(self, ...)
self:Erase()
if not func(...) then return end
return handlePcall(pcall(self.vars.tooltip[meth], self.vars.tooltip, ...))
end
end
end
 
-- Activate a new instance of this library
if not lib.vars then
lib.vars = {}
lib:CreateTooltip()
end
lib:CreateSetMethods()
 
local function createCompat()
createCompat = nil
local Gratuity20 = setmetatable({}, {__index=function(self, key)
if type(lib[key]) == "function" then
self[key] = function(self, ...)
return lib[key](lib, ...)
end
else
self[key] = lib[key]
end
return self[key]
end})
AceLibrary:Register(Gratuity20, "Gratuity-2.0", vminor+70000000)
end
if not AceLibrary then
local frame = CreateFrame("Frame")
frame:RegisterEvent("ADDON_LOADED")
frame:SetScript("OnEvent", function(this)
if not AceLibrary then
return
end
createCompat()
frame:SetScript("OnEvent", nil)
frame:UnregisterAllEvents()
frame:Hide()
end)
else
createCompat()
end
EasyDaily/libs/LibGratuity-3.0/LibGratuity-3.0.toc New file
0,0 → 1,16
## Interface: 20300
## LoadOnDemand: 1
## Title: Lib: Gratuity-3.0
## Notes: Tooltip scanning library.
## Author: Tekkub Stoutwrithe
## Version: r$Revision: 41183 $
## LastUpdate: $Date: 2007-06-21 15:59:31 -1000 (Thu, 21 Jun 2007) $
## X-Category: Library
## X-AceLibrary-Gratuity-2.0: true
## X-Curse-Packaged-Version: r41
## X-Curse-Project-Name: LibGratuity-3.0
## X-Curse-Project-ID: libgratuity-3-0
## X-Curse-Repository-ID: wow/libgratuity-3-0/mainline
 
LibStub\LibStub.lua
lib.xml
EasyDaily/libs/LibGratuity-3.0/LibStub/LibStub.lua New file
0,0 → 1,30
-- LibStub is a simple versioning stub meant for use in Libraries. http://www.wowace.com/wiki/LibStub for more info
-- LibStub is hereby placed in the Public Domain Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke
local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2 -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS!
local LibStub = _G[LIBSTUB_MAJOR]
 
if not LibStub or LibStub.minor < LIBSTUB_MINOR then
LibStub = LibStub or {libs = {}, minors = {} }
_G[LIBSTUB_MAJOR] = LibStub
LibStub.minor = LIBSTUB_MINOR
 
function LibStub:NewLibrary(major, minor)
assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)")
minor = assert(tonumber(strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.")
 
local oldminor = self.minors[major]
if oldminor and oldminor >= minor then return nil end
self.minors[major], self.libs[major] = minor, self.libs[major] or {}
return self.libs[major], oldminor
end
 
function LibStub:GetLibrary(major, silent)
if not self.libs[major] and not silent then
error(("Cannot find a library instance of %q."):format(tostring(major)), 2)
end
return self.libs[major], self.minors[major]
end
 
function LibStub:IterateLibraries() return pairs(self.libs) end
setmetatable(LibStub, { __call = LibStub.GetLibrary })
end
EasyDaily/libs/LibGratuity-3.0/lib.xml New file
0,0 → 1,4
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="LibGratuity-3.0.lua" />
</Ui>
\ No newline at end of file
EasyDaily/libs/LibTourist-3.0/LICENSE.txt New file
0,0 → 1,22
Copyright (C) 2006-2007 ckknight
 
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
 
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
 
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
EasyDaily/libs/LibTourist-3.0/LibTourist-3.0.toc New file
0,0 → 1,17
## Interface: 30100
## LoadOnDemand: 1
## Title: Lib: Tourist-3.0
## Notes: A library to provide information about zones and instances.
## Author: ckknight
## X-eMail: ckknight@gmail.com
## X-Category: Library
## Dependencies: LibBabble-Zone-3.0
## X-License: MIT
## X-Credits: Abydos
## X-Curse-Packaged-Version: r85
## X-Curse-Project-Name: LibTourist-3.0
## X-Curse-Project-ID: libtourist-3-0
## X-Curse-Repository-ID: wow/libtourist-3-0/mainline
 
LibStub\LibStub.lua
lib.xml
EasyDaily/libs/LibTourist-3.0/LibStub/LibStub.lua New file
0,0 → 1,30
-- LibStub is a simple versioning stub meant for use in Libraries. http://www.wowace.com/wiki/LibStub for more info
-- LibStub is hereby placed in the Public Domain Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke
local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2 -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS!
local LibStub = _G[LIBSTUB_MAJOR]
 
if not LibStub or LibStub.minor < LIBSTUB_MINOR then
LibStub = LibStub or {libs = {}, minors = {} }
_G[LIBSTUB_MAJOR] = LibStub
LibStub.minor = LIBSTUB_MINOR
 
function LibStub:NewLibrary(major, minor)
assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)")
minor = assert(tonumber(strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.")
 
local oldminor = self.minors[major]
if oldminor and oldminor >= minor then return nil end
self.minors[major], self.libs[major] = minor, self.libs[major] or {}
return self.libs[major], oldminor
end
 
function LibStub:GetLibrary(major, silent)
if not self.libs[major] and not silent then
error(("Cannot find a library instance of %q."):format(tostring(major)), 2)
end
return self.libs[major], self.minors[major]
end
 
function LibStub:IterateLibraries() return pairs(self.libs) end
setmetatable(LibStub, { __call = LibStub.GetLibrary })
end
EasyDaily/libs/LibTourist-3.0/lib.xml New file
0,0 → 1,4
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="LibTourist-3.0.lua" />
</Ui>
\ No newline at end of file
EasyDaily/libs/LibTourist-3.0/LibTourist-3.0.lua New file
0,0 → 1,3394
--[[
Name: LibTourist-3.0
Revision: $Rev: 85 $
Author(s): ckknight (ckknight@gmail.com)
Website: http://ckknight.wowinterface.com/
Documentation: http://www.wowace.com/wiki/LibTourist-3.0
SVN: http://svn.wowace.com/root/trunk/LibTourist-3.0
Description: A library to provide information about zones and instances.
Dependencies: LibBabble-Zone-3.0
License: MIT
 
Note:
WOTLK data is unconfirmed / incomplete
]]
 
local MAJOR_VERSION = "LibTourist-3.0"
local MINOR_VERSION = 90000 + tonumber(("$Revision: 85 $"):match("(%d+)"))
 
if not LibStub then error(MAJOR_VERSION .. " requires LibStub") end
if not LibStub("LibBabble-Zone-3.0") then error(MAJOR_VERSION .. " requires LibBabble-Zone-3.0.") end
 
local Tourist, oldLib = LibStub:NewLibrary(MAJOR_VERSION, MINOR_VERSION)
if not Tourist then
return
end
if oldLib then
oldLib = {}
for k, v in pairs(Tourist) do
Tourist[k] = nil
oldLib[k] = v
end
end
 
local BZ = LibStub("LibBabble-Zone-3.0"):GetLookupTable()
local BZR = LibStub("LibBabble-Zone-3.0"):GetReverseLookupTable()
 
local playerLevel = 1
local _,race = UnitRace("player")
local isHorde = (race == "Orc" or race == "Troll" or race == "Tauren" or race == "Scourge" or race == "BloodElf")
local isWestern = GetLocale() == "enUS" or GetLocale() == "deDE" or GetLocale() == "frFR" or GetLocale() == "esES"
 
local Kalimdor, Eastern_Kingdoms, Outland, Northrend = GetMapContinents()
if not Outland then
Outland = "Outland"
end
if not Northrend then
Northrend = "Northrend"
end
local Azeroth = BZ["Azeroth"]
 
local X_Y_ZEPPELIN = "%s/%s Zeppelin"
local X_Y_BOAT = "%s/%s Boat"
local X_Y_PORTAL = "%s/%s Portal"
 
if GetLocale() == "zhCN" then
X_Y_ZEPPELIN = "%s/%s 飞艇"
X_Y_BOAT = "%s/%s 船"
X_Y_PORTAL = "%s/%s 传送门"
elseif GetLocale() == "zhTW" then
X_Y_ZEPPELIN = "%s/%s 飛艇"
X_Y_BOAT = "%s/%s 船"
X_Y_PORTAL = "%s/%s 傳送門"
elseif GetLocale() == "frFR" then
X_Y_ZEPPELIN = "Zeppelin %s/%s"
X_Y_BOAT = "Bateau %s/%s"
X_Y_PORTAL = "Portail %s/%s"
elseif GetLocale() == "koKR" then
X_Y_ZEPPELIN = "%s/%s 비행선"
X_Y_BOAT = "%s/%s ë°°"
X_Y_PORTAL = "%s/%s 차원문"
end
 
local recZones = {}
local recInstances = {}
local lows = setmetatable({}, {__index = function() return 0 end})
local highs = setmetatable({}, getmetatable(lows))
local continents = {}
local instances = {}
local paths = {}
local types = {}
local groupSizes = {}
local groupAltSizes = {}
local factions = {}
local yardWidths = {}
local yardHeights = {}
local yardXOffsets = {}
local yardYOffsets = {}
local fishing = {}
local cost = {}
local textures = {}
local textures_rev = {}
local complexes = {}
local entrancePortals_zone = {}
local entrancePortals_x = {}
local entrancePortals_y = {}
 
local function PLAYER_LEVEL_UP(self, level)
playerLevel = level or UnitLevel("player")
for k in pairs(recZones) do
recZones[k] = nil
end
for k in pairs(recInstances) do
recInstances[k] = nil
end
for k in pairs(cost) do
cost[k] = nil
end
for zone in pairs(lows) do
if not self:IsHostile(zone) then
local low, high = self:GetLevel(zone)
if types[zone] == "Zone" or types[zone] == "PvP Zone" and low and high then
if low <= playerLevel and playerLevel <= high then
recZones[zone] = true
end
elseif types[zone] == "Battleground" and low and high then
local playerLevel = playerLevel
if zone == BZ["Alterac Valley"] then
playerLevel = playerLevel - 1
end
if playerLevel >= low and (playerLevel == MAX_PLAYER_LEVEL or math.fmod(playerLevel, 10) >= 6) then
recInstances[zone] = true
end
elseif types[zone] == "Instance" and low and high then
if low <= playerLevel and playerLevel <= high then
recInstances[zone] = true
end
end
end
end
end
 
-- minimum fishing skill to fish these zones
function Tourist:GetFishingLevel(zone)
return fishing[zone]
end
 
function Tourist:GetLevel(zone)
if types[zone] == "Battleground" then
if zone == BZ["Eye of the Storm"] then
return 61, 70
elseif zone == BZ["Alterac Valley"] and playerLevel >= 61 then
return 61, 70
elseif zone == BZ["Alterac Valley"] then
return 51, 60
elseif playerLevel >= MAX_PLAYER_LEVEL then
return MAX_PLAYER_LEVEL, MAX_PLAYER_LEVEL
elseif playerLevel >= 60 then
return 60, 69
elseif playerLevel >= 50 then
return 50, 59
elseif playerLevel >= 40 then
return 40, 49
elseif playerLevel >= 30 then
return 30, 39
elseif playerLevel >= 20 or zone == BZ["Arathi Basin"] then
return 20, 29
else
return 10, 19
end
end
return lows[zone], highs[zone]
end
 
function Tourist:GetLevelColor(zone)
if types[zone] == "Battleground" then
if (playerLevel < 61 and zone == BZ["Eye of the Storm"]) or (playerLevel < 51 and zone == BZ["Alterac Valley"]) or (playerLevel < 20 and zone == BZ["Arathi Basin"]) or (playerLevel < 10 and zone == BZ["Warsong Gulch"]) then
return 1, 0, 0
end
local playerLevel = playerLevel
if zone == BZ["Alterac Valley"] or zone == "Eye of the Storm" then
playerLevel = playerLevel - 1
end
if playerLevel == MAX_PLAYER_LEVEL then
return 1, 1, 0
end
playerLevel = math.fmod(playerLevel, 10)
if playerLevel <= 5 then
return 1, playerLevel / 10, 0
elseif playerLevel <= 7 then
return 1, (playerLevel - 3) / 4, 0
else
return (9 - playerLevel) / 2, 1, 0
end
end
local low, high = lows[zone], highs[zone]
 
if low <= 0 and high <= 0 then
-- City
return 1, 1, 1
elseif playerLevel == low and playerLevel == high then
return 1, 1, 0
elseif playerLevel <= low - 3 then
return 1, 0, 0
elseif playerLevel <= low then
return 1, (playerLevel - low - 3) / -6, 0
elseif playerLevel <= (low + high) / 2 then
return 1, (playerLevel - low) / (high - low) + 0.5, 0
elseif playerLevel <= high then
return 2 * (playerLevel - high) / (low - high), 1, 0
elseif playerLevel <= high + 3 then
local num = (playerLevel - high) / 6
return num, 1 - num, num
else
return 0.5, 0.5, 0.5
end
end
 
function Tourist:GetFactionColor(zone)
if factions[zone] == (isHorde and "Alliance" or "Horde") then
return 1, 0, 0
elseif factions[zone] == (isHorde and "Horde" or "Alliance") then
return 0, 1, 0
else
return 1, 1, 0
end
end
 
function Tourist:GetZoneYardSize(zone)
return yardWidths[zone], yardHeights[zone]
end
 
local ekXOffset = 15525.32200715066
local ekYOffset = 672.3934326738229
 
local kalXOffset = -8310.762035321373
local kalYOffset = 1815.149000954498
 
function Tourist:GetYardDistance(zone1, x1, y1, zone2, x2, y2)
local zone1_yardXOffset = yardXOffsets[zone1]
if not zone1_yardXOffset then
return nil
end
local zone2_yardXOffset = yardXOffsets[zone2]
if not zone2_yardXOffset then
return nil
end
local zone1_yardYOffset = yardYOffsets[zone1]
local zone2_yardYOffset = yardYOffsets[zone2]
 
local zone1_continent = continents[zone1]
local zone2_continent = continents[zone2]
if (zone1_continent == Outland) ~= (zone2_continent == Outland) then
return nil
end
 
local zone1_yardWidth = yardWidths[zone1]
local zone1_yardHeight = yardHeights[zone1]
local zone2_yardWidth = yardWidths[zone2]
local zone2_yardHeight = yardHeights[zone2]
 
local x1_yard = zone1_yardWidth*x1
local y1_yard = zone1_yardHeight*y1
local x2_yard = zone2_yardWidth*x2
local y2_yard = zone2_yardHeight*y2
 
if zone1 ~= zone2 then
x1_yard = x1_yard + zone1_yardXOffset
y1_yard = y1_yard + zone1_yardYOffset
 
x2_yard = x2_yard + zone2_yardXOffset
y2_yard = y2_yard + zone2_yardYOffset
 
if zone1_continent ~= zone2_continent then
if zone1_continent == Kalimdor then
x1_yard = x1_yard + kalXOffset
y1_yard = y1_yard + kalYOffset
elseif zone1_continent == Eastern_Kingdoms then
x1_yard = x1_yard + ekXOffset
y1_yard = y1_yard + ekYOffset
end
 
if zone2_continent == Kalimdor then
x2_yard = x2_yard + kalXOffset
y2_yard = y2_yard + kalYOffset
elseif zone2_continent == Eastern_Kingdoms then
x2_yard = x2_yard + ekXOffset
y2_yard = y2_yard + ekYOffset
end
end
end
 
local x_diff = x1_yard - x2_yard
local y_diff = y1_yard - y2_yard
local dist_2 = x_diff*x_diff + y_diff*y_diff
return dist_2^0.5
end
 
function Tourist:TransposeZoneCoordinate(x, y, zone1, zone2)
if zone1 == zone2 then
return x, y
end
 
local zone1_yardXOffset = yardXOffsets[zone1]
if not zone1_yardXOffset then
return nil
end
local zone2_yardXOffset = yardXOffsets[zone2]
if not zone2_yardXOffset then
return nil
end
local zone1_yardYOffset = yardYOffsets[zone1]
local zone2_yardYOffset = yardYOffsets[zone2]
 
local zone1_continent = continents[zone1]
local zone2_continent = continents[zone2]
if (zone1_continent == Outland) ~= (zone2_continent == Outland) then
return nil
end
 
local zone1_yardWidth = yardWidths[zone1]
local zone1_yardHeight = yardHeights[zone1]
local zone2_yardWidth = yardWidths[zone2]
local zone2_yardHeight = yardHeights[zone2]
 
local x_yard = zone1_yardWidth*x
local y_yard = zone1_yardHeight*y
 
x_yard = x_yard + zone1_yardXOffset
y_yard = y_yard + zone1_yardYOffset
 
if zone1_continent ~= zone2_continent then
if zone1_continent == Kalimdor then
x_yard = x_yard + kalXOffset
y_yard = y_yard + kalYOffset
elseif zone1_continent == Eastern_Kingdoms then
x_yard = x_yard + ekXOffset
y_yard = y_yard + ekYOffset
end
 
if zone2_continent == Kalimdor then
x_yard = x_yard - kalXOffset
y_yard = y_yard - kalYOffset
elseif zone2_continent == Eastern_Kingdoms then
x_yard = x_yard - ekXOffset
y_yard = y_yard - ekYOffset
end
end
 
x_yard = x_yard - zone2_yardXOffset
y_yard = y_yard - zone2_yardYOffset
 
x = x_yard / zone2_yardWidth
y = y_yard / zone2_yardHeight
 
return x, y
end
 
local zonesToIterate = setmetatable({}, {__index = function(self, key)
local t = {}
self[key] = t
for k,v in pairs(continents) do
if v == key and v ~= k and yardXOffsets[k] then
t[#t+1] = k
end
end
return t
end})
 
local kal_yardWidth
local kal_yardHeight
local ek_yardWidth
local ek_yardHeight
 
function Tourist:GetBestZoneCoordinate(x, y, zone)
if not kal_yardWidth then
kal_yardWidth = yardWidths[Kalimdor]
kal_yardHeight = yardHeights[Kalimdor]
ek_yardWidth = yardWidths[Eastern_Kingdoms]
ek_yardHeight = yardHeights[Eastern_Kingdoms]
end
 
local zone_yardXOffset = yardXOffsets[zone]
if not zone_yardXOffset then
return x, y, zone
end
local zone_yardYOffset = yardYOffsets[zone]
 
local zone_yardWidth = yardWidths[zone]
local zone_yardHeight = yardHeights[zone]
 
local x_yard = zone_yardWidth*x
local y_yard = zone_yardHeight*y
 
x_yard = x_yard + zone_yardXOffset
y_yard = y_yard + zone_yardYOffset
 
local zone_continent = continents[zone]
local azeroth = false
if zone_continent == Kalimdor then
if x_yard < 0 or y_yard < 0 or x_yard > kal_yardWidth or y_yard > kal_yardHeight then
x_yard = x_yard + kalXOffset
y_yard = y_yard + kalYOffset
azeroth = true
end
elseif zone_continent == Eastern_Kingdoms then
if x_yard < 0 or y_yard < 0 or x_yard > ek_yardWidth or y_yard > ek_yardHeight then
x_yard = x_yard + ekXOffset
y_yard = y_yard + ekYOffset
azeroth = true
end
end
if azeroth then
local kal, ek = zone_continent ~= Kalimdor, zone_continent ~= Eastern_Kingdoms
if kal and (x_yard < kalXOffset or y_yard < kalYOffset or x_yard > kalXOffset + kal_yardWidth or y_yard > kalYOffset + kal_yardWidth) then
kal = false
end
if ek and (x_yard < ekXOffset or y_yard < ekYOffset or x_yard > ekXOffset + ek_yardWidth or y_yard > ekYOffset + ek_yardWidth) then
ek = false
end
if kal then
x_yard = x_yard - kalXOffset
y_yard = y_yard - kalYOffset
zone_continent = Kalimdor
elseif ek then
x_yard = x_yard - ekXOffset
y_yard = y_yard - ekYOffset
zone_continent = Eastern_Kingdoms
else
return x_yard / yardWidths[Azeroth], y_yard / yardHeights[Azeroth], Azeroth
end
end
 
local best_zone, best_x, best_y, best_value
 
for _,z in ipairs(zonesToIterate[zone_continent]) do
local z_yardXOffset = yardXOffsets[z]
local z_yardYOffset = yardYOffsets[z]
local z_yardWidth = yardWidths[z]
local z_yardHeight = yardHeights[z]
 
local x_yd = x_yard - z_yardXOffset
local y_yd = y_yard - z_yardYOffset
 
if x_yd >= 0 and y_yd >= 0 and x_yd <= z_yardWidth and y_yd <= z_yardHeight then
if types[z] == "City" then
return x_yd/z_yardWidth, y_yd/z_yardHeight, z
end
local x_tmp = x_yd - z_yardWidth / 2
local y_tmp = y_yd - z_yardHeight / 2
local value = x_tmp*x_tmp + y_tmp*y_tmp
if not best_value or value < best_value then
best_zone = z
best_value = value
best_x = x_yd/z_yardWidth
best_y = y_yd/z_yardHeight
end
end
end
if not best_zone then
return x_yard / yardWidths[zone_continent], y_yard / yardHeights[zone_continent], zone_continent
end
return best_x, best_y, best_zone
end
 
local function retNil() return nil end
local function retOne(object, state)
if state == object then
return nil
else
return object
end
end
 
local function retNormal(t, position)
return (next(t, position))
end
 
local function mysort(a,b)
if not lows[a] then
return false
elseif not lows[b] then
return true
else
local aval, bval = groupSizes[a], groupSizes[b]
if aval ~= bval then
return aval < bval
end
aval, bval = lows[a], lows[b]
if aval ~= bval then
return aval < bval
end
aval, bval = highs[a], highs[b]
if aval ~= bval then
return aval < bval
end
return a < b
end
end
local t = {}
local function myiter(t)
local n = t.n
n = n + 1
local v = t[n]
if v then
t[n] = nil
t.n = n
return v
else
t.n = nil
end
end
function Tourist:IterateZoneInstances(zone)
local inst = instances[zone]
 
if not inst then
return retNil
elseif type(inst) == "table" then
for k in pairs(t) do
t[k] = nil
end
for k in pairs(inst) do
t[#t+1] = k
end
table.sort(t, mysort)
t.n = 0
return myiter, t, nil
else
return retOne, inst, nil
end
end
 
function Tourist:GetInstanceZone(instance)
for k, v in pairs(instances) do
if v then
if type(v) == "string" then
if v == instance then
return k
end
else -- table
for l in pairs(v) do
if l == instance then
return k
end
end
end
end
end
end
 
function Tourist:DoesZoneHaveInstances(zone)
return not not instances[zone]
end
 
local zonesInstances
local function initZonesInstances()
if not zonesInstances then
zonesInstances = {}
for zone, v in pairs(lows) do
if types[zone] ~= "Transport" then
zonesInstances[zone] = true
end
end
end
initZonesInstances = nil
end
 
function Tourist:IterateZonesAndInstances()
if initZonesInstances then
initZonesInstances()
end
return retNormal, zonesInstances, nil
end
 
local function zoneIter(_, position)
local k = next(zonesInstances, position)
while k ~= nil and (types[k] == "Instance" or types[k] == "Battleground") do
k = next(zonesInstances, k)
end
return k
end
function Tourist:IterateZones()
if initZonesInstances then
initZonesInstances()
end
return zoneIter, nil, nil
end
 
local function instanceIter(_, position)
local k = next(zonesInstances, position)
while k ~= nil and (types[k] ~= "Instance" and types[k] ~= "Battleground") do
k = next(zonesInstances, k)
end
return k
end
function Tourist:IterateInstances()
if initZonesInstances then
initZonesInstances()
end
return instanceIter, nil, nil
end
 
local function bgIter(_, position)
local k = next(zonesInstances, position)
while k ~= nil and types[k] ~= "Battleground" do
k = next(zonesInstances, k)
end
return k
end
function Tourist:IterateBattlegrounds()
if initZonesInstances then
initZonesInstances()
end
return bgIter, nil, nil
end
 
local function pvpIter(_, position)
local k = next(zonesInstances, position)
while k ~= nil and types[k] ~= "PvP Zone" do
k = next(zonesInstances, k)
end
return k
end
function Tourist:IteratePvPZones()
if initZonesInstances then
initZonesInstances()
end
return pvpIter, nil, nil
end
 
local function allianceIter(_, position)
local k = next(zonesInstances, position)
while k ~= nil and factions[k] ~= "Alliance" do
k = next(zonesInstances, k)
end
return k
end
function Tourist:IterateAlliance()
if initZonesInstances then
initZonesInstances()
end
return allianceIter, nil, nil
end
 
local function hordeIter(_, position)
local k = next(zonesInstances, position)
while k ~= nil and factions[k] ~= "Horde" do
k = next(zonesInstances, k)
end
return k
end
function Tourist:IterateHorde()
if initZonesInstances then
initZonesInstances()
end
return hordeIter, nil, nil
end
 
if isHorde then
Tourist.IterateFriendly = Tourist.IterateHorde
Tourist.IterateHostile = Tourist.IterateAlliance
else
Tourist.IterateFriendly = Tourist.IterateAlliance
Tourist.IterateHostile = Tourist.IterateHorde
end
 
local function contestedIter(_, position)
local k = next(zonesInstances, position)
while k ~= nil and factions[k] do
k = next(zonesInstances, k)
end
return k
end
function Tourist:IterateContested()
if initZonesInstances then
initZonesInstances()
end
return contestedIter, nil, nil
end
 
local function kalimdorIter(_, position)
local k = next(zonesInstances, position)
while k ~= nil and continents[k] ~= Kalimdor do
k = next(zonesInstances, k)
end
return k
end
function Tourist:IterateKalimdor()
if initZonesInstances then
initZonesInstances()
end
return kalimdorIter, nil, nil
end
 
local function easternKingdomsIter(_, position)
local k = next(zonesInstances, position)
while k ~= nil and continents[k] ~= Eastern_Kingdoms do
k = next(zonesInstances, k)
end
return k
end
function Tourist:IterateEasternKingdoms()
if initZonesInstances then
initZonesInstances()
end
return easternKingdomsIter, nil, nil
end
 
local function outlandIter(_, position)
local k = next(zonesInstances, position)
while k ~= nil and continents[k] ~= Outland do
k = next(zonesInstances, k)
end
return k
end
function Tourist:IterateOutland()
if initZonesInstances then
initZonesInstances()
end
return outlandIter, nil, nil
end
 
local function northrendIter(_, position)
local k = next(zonesInstances, position)
while k ~= nil and continents[k] ~= Northrend do
k = next(zonesInstances, k)
end
return k
end
function Tourist:IterateNorthrend()
if initZonesInstances then
initZonesInstances()
end
return northrendIter, nil, nil
end
 
function Tourist:IterateRecommendedZones()
return retNormal, recZones, nil
end
 
function Tourist:IterateRecommendedInstances()
return retNormal, recInstances, nil
end
 
function Tourist:HasRecommendedInstances()
return next(recInstances) ~= nil
end
 
function Tourist:IsInstance(zone)
local t = types[zone]
return t == "Instance" or t == "Battleground"
end
 
function Tourist:IsZone(zone)
local t = types[zone]
return t ~= "Instance" and t ~= "Battleground" and t ~= "Transport"
end
 
function Tourist:GetComplex(zone)
return complexes[zone]
end
 
function Tourist:IsZoneOrInstance(zone)
local t = types[zone]
return t and t ~= "Transport"
end
 
function Tourist:IsBattleground(zone)
local t = types[zone]
return t == "Battleground"
end
 
function Tourist:IsArena(zone)
local t = types[zone]
return t == "Arena"
end
 
function Tourist:IsPvPZone(zone)
local t = types[zone]
return t == "PvP Zone"
end
 
function Tourist:IsCity(zone)
local t = types[zone]
return t == "City"
end
 
function Tourist:IsAlliance(zone)
return factions[zone] == "Alliance"
end
 
function Tourist:IsHorde(zone)
return factions[zone] == "Horde"
end
 
if isHorde then
Tourist.IsFriendly = Tourist.IsHorde
Tourist.IsHostile = Tourist.IsAlliance
else
Tourist.IsFriendly = Tourist.IsAlliance
Tourist.IsHostile = Tourist.IsHorde
end
 
function Tourist:IsContested(zone)
return not factions[zone]
end
 
function Tourist:GetContinent(zone)
return continents[zone] or UNKNOWN
end
 
function Tourist:IsInKalimdor(zone)
return continents[zone] == Kalimdor
end
 
function Tourist:IsInEasternKingdoms(zone)
return continents[zone] == Eastern_Kingdoms
end
 
function Tourist:IsInOutland(zone)
return continents[zone] == Outland
end
 
function Tourist:IsInNorthrend(zone)
return continents[zone] == Northrend
end
 
function Tourist:GetInstanceGroupSize(instance)
return groupSizes[instance] or 0
end
 
function Tourist:GetInstanceAltGroupSize(instance)
return groupAltSizes[instance] or 0
end
 
function Tourist:GetTexture(zone)
return textures[zone]
end
 
function Tourist:GetZoneFromTexture(texture)
if not texture then
return BZ["Azeroth"]
end
return textures_rev[texture]
end
 
function Tourist:GetEnglishZoneFromTexture(texture)
if not texture then
return "Azeroth"
end
local zone = textures_rev[texture]
if zone then
return BZR[zone]
end
return nil
end
 
function Tourist:GetEntrancePortalLocation(instance)
return entrancePortals_zone[instance], entrancePortals_x[instance], entrancePortals_y[instance]
end
 
local inf = 1/0
local stack = setmetatable({}, {__mode='k'})
local function iterator(S)
local position = S['#'] - 1
S['#'] = position
local x = S[position]
if not x then
for k in pairs(S) do
S[k] = nil
end
stack[S] = true
return nil
end
return x
end
 
setmetatable(cost, {
__index = function(self, vertex)
local price = 1
 
if lows[vertex] > playerLevel then
price = price * (1 + math.ceil((lows[vertex] - playerLevel) / 6))
end
 
if factions[vertex] == (isHorde and "Horde" or "Alliance") then
price = price / 2
elseif factions[vertex] == (isHorde and "Alliance" or "Horde") then
if types[vertex] == "City" then
price = price * 10
else
price = price * 3
end
end
 
if types[x] == "Transport" then
price = price * 2
end
 
self[vertex] = price
return price
end
})
 
function Tourist:IteratePath(alpha, bravo)
if paths[alpha] == nil or paths[bravo] == nil then
return retNil
end
 
local d = next(stack) or {}
stack[d] = nil
local Q = next(stack) or {}
stack[Q] = nil
local S = next(stack) or {}
stack[S] = nil
local pi = next(stack) or {}
stack[pi] = nil
 
for vertex, v in pairs(paths) do
d[vertex] = inf
Q[vertex] = v
end
d[alpha] = 0
 
while next(Q) do
local u
local min = inf
for z in pairs(Q) do
local value = d[z]
if value < min then
min = value
u = z
end
end
if min == inf then
return retNil
end
Q[u] = nil
if u == bravo then
break
end
 
local adj = paths[u]
if type(adj) == "table" then
local d_u = d[u]
for v in pairs(adj) do
local c = d_u + cost[v]
if d[v] > c then
d[v] = c
pi[v] = u
end
end
elseif adj ~= false then
local c = d[u] + cost[adj]
if d[adj] > c then
d[adj] = c
pi[adj] = u
end
end
end
 
local i = 1
local last = bravo
while last do
S[i] = last
i = i + 1
last = pi[last]
end
 
for k in pairs(pi) do
pi[k] = nil
end
for k in pairs(Q) do
Q[k] = nil
end
for k in pairs(d) do
d[k] = nil
end
stack[pi] = true
stack[Q] = true
stack[d] = true
 
S['#'] = i
 
return iterator, S
end
 
local function retWithOffset(t, key)
while true do
key = next(t, key)
if not key then
return nil
end
if yardYOffsets[key] then
return key
end
end
end
 
function Tourist:IterateBorderZones(zone, zonesOnly)
local path = paths[zone]
if not path then
return retNil
elseif type(path) == "table" then
return zonesOnly and retWithOffset or retNormal, path
else
if zonesOnly and not yardYOffsets[path] then
return retNil
end
return retOne, path
end
end
 
do
Tourist.frame = oldLib and oldLib.frame or CreateFrame("Frame", MAJOR_VERSION .. "Frame", UIParent)
Tourist.frame:UnregisterAllEvents()
Tourist.frame:RegisterEvent("PLAYER_LEVEL_UP")
Tourist.frame:RegisterEvent("PLAYER_ENTERING_WORLD")
Tourist.frame:SetScript("OnEvent", function(frame, event, ...)
PLAYER_LEVEL_UP(Tourist, ...)
end)
 
local BOOTYBAY_RATCHET_BOAT = string.format(X_Y_BOAT, BZ["Booty Bay"], BZ["Ratchet"])
local MENETHIL_THERAMORE_BOAT = string.format(X_Y_BOAT, BZ["Menethil Harbor"], BZ["Theramore Isle"])
local MENETHIL_HOWLINGFJORD_BOAT = string.format(X_Y_BOAT, BZ["Menethil Harbor"], BZ["Howling Fjord"])
local AUBERDINE_DARNASSUS_BOAT = string.format(X_Y_BOAT, BZ["Auberdine"], BZ["Darnassus"])
local AUBERDINE_AZUREMYST_BOAT = string.format(X_Y_BOAT, BZ["Auberdine"], BZ["Azuremyst Isle"])
local STORMWIND_AUBERDINE_BOAT = string.format(X_Y_BOAT, BZ["Stormwind City"], BZ["Auberdine"])
local STORMWIND_BOREANTUNDRA_BOAT = string.format(X_Y_BOAT, BZ["Stormwind City"], BZ["Borean Tundra"])
local ORGRIMMAR_BOREANTUNDRA_ZEPPELIN = string.format(X_Y_ZEPPELIN, BZ["Orgrimmar"], BZ["Borean Tundra"])
local UNDERCITY_HOWLINGFJORD_ZEPPELIN = string.format(X_Y_ZEPPELIN, BZ["Undercity"], BZ["Howling Fjord"])
local ORGRIMMAR_UNDERCITY_ZEPPELIN = string.format(X_Y_ZEPPELIN, BZ["Orgrimmar"], BZ["Undercity"])
local ORGRIMMAR_GROMGOL_ZEPPELIN = string.format(X_Y_ZEPPELIN, BZ["Orgrimmar"], BZ["Grom'gol Base Camp"])
local UNDERCITY_GROMGOL_ZEPPELIN = string.format(X_Y_ZEPPELIN, BZ["Undercity"], BZ["Grom'gol Base Camp"])
local SHATTRATH_IRONFORGE_PORTAL = string.format(X_Y_PORTAL, BZ["Shattrath City"], BZ["Ironforge"])
local SHATTRATH_STORMWIND_PORTAL = string.format(X_Y_PORTAL, BZ["Shattrath City"], BZ["Stormwind City"])
local SHATTRATH_DARNASSUS_PORTAL = string.format(X_Y_PORTAL, BZ["Shattrath City"], BZ["Darnassus"])
local SHATTRATH_ORGRIMMAR_PORTAL = string.format(X_Y_PORTAL, BZ["Shattrath City"], BZ["Orgrimmar"])
local SHATTRATH_THUNDERBLUFF_PORTAL = string.format(X_Y_PORTAL, BZ["Shattrath City"], BZ["Thunder Bluff"])
local SHATTRATH_UNDERCITY_PORTAL = string.format(X_Y_PORTAL, BZ["Shattrath City"], BZ["Undercity"])
local SHATTRATH_EXODAR_PORTAL = string.format(X_Y_PORTAL, BZ["Shattrath City"], BZ["The Exodar"])
local SHATTRATH_SILVERMOON_PORTAL = string.format(X_Y_PORTAL, BZ["Shattrath City"], BZ["Silvermoon City"])
local SHATTRATH_QUELDANAS_PORTAL = string.format(X_Y_PORTAL, BZ["Shattrath City"], BZ["Isle of Quel'Danas"])
local SHATTRATH_COT_PORTAL = string.format(X_Y_PORTAL, BZ["Shattrath City"], BZ["Caverns of Time"])
local MOAKI_UNUPE_BOAT = string.format(X_Y_BOAT, BZ["Dragonblight"], BZ["Borean Tundra"]) -- TODO localize these to the village names
local MOAKI_KAMAGUA_BOAT = string.format(X_Y_BOAT, BZ["Dragonblight"], BZ["Howling Fjord"]) -- TODO localize these to the village names
local DALARAN_IRONFORGE_PORTAL = string.format(X_Y_PORTAL, BZ["Dalaran"], BZ["Ironforge"])
local DALARAN_STORMWIND_PORTAL = string.format(X_Y_PORTAL, BZ["Dalaran"], BZ["Stormwind City"])
local DALARAN_DARNASSUS_PORTAL = string.format(X_Y_PORTAL, BZ["Dalaran"], BZ["Darnassus"])
local DALARAN_ORGRIMMAR_PORTAL = string.format(X_Y_PORTAL, BZ["Dalaran"], BZ["Orgrimmar"])
local DALARAN_THUNDERBLUFF_PORTAL = string.format(X_Y_PORTAL, BZ["Dalaran"], BZ["Thunder Bluff"])
local DALARAN_UNDERCITY_PORTAL = string.format(X_Y_PORTAL, BZ["Dalaran"], BZ["Undercity"])
local DALARAN_EXODAR_PORTAL = string.format(X_Y_PORTAL, BZ["Dalaran"], BZ["The Exodar"])
local DALARAN_SILVERMOON_PORTAL = string.format(X_Y_PORTAL, BZ["Dalaran"], BZ["Silvermoon City"])
local DALARAN_SHATTRATH_PORTAL = string.format(X_Y_PORTAL, BZ["Dalaran"], BZ["Shattrath City"])
local DALARAN_COT_PORTAL = string.format(X_Y_PORTAL, BZ["Dalaran"], BZ["Caverns of Time"])
 
local zones = {}
 
zones[BZ["Eastern Kingdoms"]] = {
type = "Continent",
yards = 47714.278579261,
x_offset = 0,
y_offset = 0,
continent = Eastern_Kingdoms,
}
 
zones[BZ["Kalimdor"]] = {
type = "Continent",
yards = 36800.210572494,
x_offset = 0,
y_offset = 0,
continent = Kalimdor,
}
 
zones[BZ["Outland"]] = {
type = "Continent",
yards = 17463.5328406368,
x_offset = 0,
y_offset = 0,
continent = Outland,
}
 
zones[BZ["Northrend"]] = {
type = "Continent",
yards = 17751.3962441049,
x_offset = 0,
y_offset = 0,
continent = Northrend,
}
 
zones[BZ["Azeroth"]] = {
type = "Continent",
yards = 44531.82907938571,
x_offset = 0,
y_offset = 0,
}
 
zones[STORMWIND_AUBERDINE_BOAT] = {
paths = {
[BZ["Stormwind City"]] = true,
[BZ["Darkshore"]] = true,
},
faction = "Alliance",
type = "Transport",
}
 
zones[STORMWIND_BOREANTUNDRA_BOAT] = {
paths = {
[BZ["Stormwind City"]] = true,
[BZ["Borean Tundra"]] = true,
},
faction = "Alliance",
type = "Transport",
}
 
zones[ORGRIMMAR_BOREANTUNDRA_ZEPPELIN] = {
paths = {
[BZ["Durotar"]] = true,
[BZ["Borean Tundra"]] = true,
},
faction = "Horde",
type = "Transport",
}
 
zones[UNDERCITY_HOWLINGFJORD_ZEPPELIN] = {
paths = {
[BZ["Tirisfal Glades"]] = true,
[BZ["Howling Fjord"]] = true,
},
faction = "Horde",
type = "Transport",
}
 
zones[AUBERDINE_AZUREMYST_BOAT] = {
paths = {
[BZ["Darkshore"]] = true,
[BZ["Azuremyst Isle"]] = true,
},
faction = "Alliance",
type = "Transport",
}
 
zones[AUBERDINE_DARNASSUS_BOAT] = {
paths = {
[BZ["Darkshore"]] = true,
[BZ["Darnassus"]] = true,
},
faction = "Alliance",
type = "Transport",
}
 
zones[BOOTYBAY_RATCHET_BOAT] = {
paths = {
[BZ["Stranglethorn Vale"]] = true,
[BZ["The Barrens"]] = true,
},
type = "Transport",
}
 
zones[MENETHIL_HOWLINGFJORD_BOAT] = {
paths = {
[BZ["Wetlands"]] = true,
[BZ["Howling Fjord"]] = true,
},
faction = "Alliance",
type = "Transport",
}
 
zones[MENETHIL_THERAMORE_BOAT] = {
paths = {
[BZ["Wetlands"]] = true,
[BZ["Dustwallow Marsh"]] = true,
},
faction = "Alliance",
type = "Transport",
}
 
zones[ORGRIMMAR_GROMGOL_ZEPPELIN] = {
paths = {
[BZ["Durotar"]] = true,
[BZ["Stranglethorn Vale"]] = true,
},
faction = "Horde",
type = "Transport",
}
 
zones[ORGRIMMAR_UNDERCITY_ZEPPELIN] = {
paths = {
[BZ["Durotar"]] = true,
[BZ["Tirisfal Glades"]] = true,
},
faction = "Horde",
type = "Transport",
}
 
zones[SHATTRATH_DARNASSUS_PORTAL] = {
paths = BZ["Darnassus"],
type = "Transport",
}
 
zones[SHATTRATH_EXODAR_PORTAL] = {
paths = BZ["The Exodar"],
type = "Transport",
}
 
zones[SHATTRATH_IRONFORGE_PORTAL] = {
paths = BZ["Ironforge"],
type = "Transport",
}
 
zones[SHATTRATH_ORGRIMMAR_PORTAL] = {
paths = BZ["Orgrimmar"],
type = "Transport",
}
 
zones[SHATTRATH_SILVERMOON_PORTAL] = {
paths = BZ["Silvermoon City"],
type = "Transport",
}
 
zones[SHATTRATH_STORMWIND_PORTAL] = {
paths = BZ["Stormwind City"],
type = "Transport",
}
 
zones[SHATTRATH_THUNDERBLUFF_PORTAL] = {
paths = BZ["Thunder Bluff"],
type = "Transport",
}
 
zones[SHATTRATH_UNDERCITY_PORTAL] = {
paths = BZ["Undercity"],
type = "Transport",
}
 
zones[SHATTRATH_QUELDANAS_PORTAL] = {
paths = BZ["Isle of Quel'Danas"],
type = "Transport",
}
 
zones[SHATTRATH_COT_PORTAL] = {
paths = BZ["Caverns of Time"],
type = "Transport",
}
 
zones[MOAKI_UNUPE_BOAT] = {
paths = {
[BZ["Dragonblight"]] = true,
[BZ["Borean Tundra"]] = true,
},
type = "Transport",
}
 
zones[MOAKI_KAMAGUA_BOAT] = {
paths = {
[BZ["Dragonblight"]] = true,
[BZ["Howling Fjord"]] = true,
},
type = "Transport",
}
 
zones[BZ["The Dark Portal"]] = {
paths = {
[BZ["Blasted Lands"]] = true,
[BZ["Hellfire Peninsula"]] = true,
},
type = "Transport",
}
 
zones[UNDERCITY_GROMGOL_ZEPPELIN] = {
paths = {
[BZ["Stranglethorn Vale"]] = true,
[BZ["Tirisfal Glades"]] = true,
},
faction = "Horde",
type = "Transport",
}
 
zones[DALARAN_IRONFORGE_PORTAL] = {
paths = BZ["Ironforge"],
type = "Transport",
}
 
zones[DALARAN_STORMWIND_PORTAL] = {
paths = BZ["Stormwind City"],
type = "Transport",
}
 
zones[DALARAN_DARNASSUS_PORTAL] = {
paths = BZ["Darnassus"],
type = "Transport",
}
 
zones[DALARAN_ORGRIMMAR_PORTAL] = {
paths = BZ["Orgrimmar"],
type = "Transport",
}
 
zones[DALARAN_THUNDERBLUFF_PORTAL] = {
paths = BZ["Thunder Bluff"],
type = "Transport",
}
 
zones[DALARAN_UNDERCITY_PORTAL] = {
paths = BZ["Undercity"],
type = "Transport",
}
 
zones[DALARAN_EXODAR_PORTAL] = {
paths = BZ["The Exodar"],
type = "Transport",
}
 
zones[DALARAN_SILVERMOON_PORTAL] = {
paths = BZ["Silvermoon City"],
type = "Transport",
}
 
zones[DALARAN_SHATTRATH_PORTAL] = {
paths = BZ["Shattrath City"],
type = "Transport",
}
 
zones[DALARAN_COT_PORTAL] = {
paths = BZ["Caverns of Time"],
type = "Transport",
}
 
zones[BZ["Alterac Valley"]] = {
continent = Eastern_Kingdoms,
paths = BZ["Alterac Mountains"],
groupSize = 40,
type = "Battleground",
texture = "AlteracValley",
}
 
zones[BZ["Arathi Basin"]] = {
continent = Eastern_Kingdoms,
paths = BZ["Arathi Highlands"],
groupSize = 15,
type = "Battleground",
texture = "ArathiBasin",
}
 
zones[BZ["Warsong Gulch"]] = {
continent = Kalimdor,
paths = isHorde and BZ["The Barrens"] or BZ["Ashenvale"],
groupSize = 10,
type = "Battleground",
texture = "WarsongGulch",
}
 
zones[BZ["Deeprun Tram"]] = {
continent = Eastern_Kingdoms,
paths = {
[BZ["Stormwind City"]] = true,
[BZ["Ironforge"]] = true,
},
faction = "Alliance",
}
 
zones[BZ["Ironforge"]] = {
continent = Eastern_Kingdoms,
instances = BZ["Gnomeregan"],
paths = {
[BZ["Dun Morogh"]] = true,
[BZ["Deeprun Tram"]] = true,
},
faction = "Alliance",
type = "City",
fishing_min = 1,
}
 
zones[BZ["Silvermoon City"]] = {
continent = Eastern_Kingdoms,
paths = {
[BZ["Eversong Woods"]] = true,
[BZ["Undercity"]] = true,
},
faction = "Horde",
type = "City",
fishing_min = 1,
}
 
zones[BZ["Stormwind City"]] = {
continent = Eastern_Kingdoms,
instances = BZ["The Stockade"],
paths = {
[BZ["Deeprun Tram"]] = true,
[BZ["The Stockade"]] = true,
[BZ["Elwynn Forest"]] = true,
[STORMWIND_AUBERDINE_BOAT] = true,
[STORMWIND_BOREANTUNDRA_BOAT] = true,
},
faction = "Alliance",
type = "City",
fishing_min = 1,
}
 
zones[BZ["Undercity"]] = {
continent = Eastern_Kingdoms,
instances = {
[BZ["Armory"]] = true,
[BZ["Library"]] = true,
[BZ["Graveyard"]] = true,
[BZ["Cathedral"]] = true,
},
paths = {
[BZ["Silvermoon City"]] = true,
[BZ["Tirisfal Glades"]] = true,
},
faction = "Horde",
type = "City",
}
 
zones[BZ["Dun Morogh"]] = {
low = 1,
high = 10,
continent = Eastern_Kingdoms,
instances = BZ["Gnomeregan"],
paths = {
[BZ["Wetlands"]] = true,
[BZ["Gnomeregan"]] = true,
[BZ["Ironforge"]] = true,
[BZ["Loch Modan"]] = true,
},
faction = "Alliance",
fishing_min = 1,
}
 
zones[BZ["Elwynn Forest"]] = {
low = 1,
high = 10,
continent = Eastern_Kingdoms,
instances = BZ["The Stockade"],
paths = {
[BZ["Westfall"]] = true,
[BZ["Redridge Mountains"]] = true,
[BZ["Stormwind City"]] = true,
[BZ["Duskwood"]] = true,
},
faction = "Alliance",
fishing_min = 1,
}
 
zones[BZ["Eversong Woods"]] = {
low = 1,
high = 10,
continent = Eastern_Kingdoms,
paths = {
[BZ["Silvermoon City"]] = true,
[BZ["Ghostlands"]] = true,
},
faction = "Horde",
fishing_min = 20,
}
 
zones[BZ["Tirisfal Glades"]] = {
low = 1,
high = 10,
continent = Eastern_Kingdoms,
instances = {
[BZ["Armory"]] = true,
[BZ["Library"]] = true,
[BZ["Graveyard"]] = true,
[BZ["Cathedral"]] = true,
},
paths = {
[BZ["Western Plaguelands"]] = true,
[BZ["Undercity"]] = true,
[BZ["Scarlet Monastery"]] = true,
[UNDERCITY_GROMGOL_ZEPPELIN] = true,
[ORGRIMMAR_UNDERCITY_ZEPPELIN] = true,
[UNDERCITY_HOWLINGFJORD_ZEPPELIN] = true,
[BZ["Silverpine Forest"]] = true,
},
faction = "Horde",
fishing_min = 1,
}
 
zones[BZ["Amani Pass"]] = {
continent = Eastern_Kingdoms,
}
 
zones[BZ["Ghostlands"]] = {
low = 10,
high = 20,
continent = Eastern_Kingdoms,
instances = BZ["Zul'Aman"],
paths = {
[BZ["Eastern Plaguelands"]] = true,
[BZ["Zul'Aman"]] = true,
[BZ["Eversong Woods"]] = true,
},
faction = "Horde",
fishing_min = 20,
}
 
zones[BZ["Loch Modan"]] = {
low = 10,
high = 20,
continent = Eastern_Kingdoms,
paths = {
[BZ["Wetlands"]] = true,
[BZ["Badlands"]] = true,
[BZ["Dun Morogh"]] = true,
[BZ["Searing Gorge"]] = not isHorde and true or nil,
},
faction = "Alliance",
fishing_min = 20,
}
 
zones[BZ["Silverpine Forest"]] = {
low = 10,
high = 20,
continent = Eastern_Kingdoms,
instances = BZ["Shadowfang Keep"],
paths = {
[BZ["Tirisfal Glades"]] = true,
[BZ["Hillsbrad Foothills"]] = true,
[BZ["Shadowfang Keep"]] = true,
},
faction = "Horde",
fishing_min = 20,
}
 
zones[BZ["Westfall"]] = {
low = 10,
high = 20,
continent = Eastern_Kingdoms,
instances = BZ["The Deadmines"],
paths = {
[BZ["Duskwood"]] = true,
[BZ["Elwynn Forest"]] = true,
[BZ["The Deadmines"]] = true,
},
faction = "Alliance",
fishing_min = 55,
}
 
zones[BZ["Redridge Mountains"]] = {
low = 15,
high = 25,
continent = Eastern_Kingdoms,
paths = {
[BZ["Burning Steppes"]] = true,
[BZ["Elwynn Forest"]] = true,
[BZ["Duskwood"]] = true,
},
fishing_min = 55,
}
 
zones[BZ["Duskwood"]] = {
low = 18,
high = 30,
continent = Eastern_Kingdoms,
paths = {
[BZ["Redridge Mountains"]] = true,
[BZ["Stranglethorn Vale"]] = true,
[BZ["Westfall"]] = true,
[BZ["Deadwind Pass"]] = true,
[BZ["Elwynn Forest"]] = true,
},
fishing_min = 55,
}
 
zones[BZ["Hillsbrad Foothills"]] = {
low = 20,
high = 30,
continent = Eastern_Kingdoms,
paths = {
[BZ["Alterac Mountains"]] = true,
[BZ["The Hinterlands"]] = true,
[BZ["Arathi Highlands"]] = true,
[BZ["Silverpine Forest"]] = true,
},
fishing_min = 55,
}
 
zones[BZ["Wetlands"]] = {
low = 20,
high = 30,
continent = Eastern_Kingdoms,
paths = {
[BZ["Arathi Highlands"]] = true,
[MENETHIL_THERAMORE_BOAT] = true,
[MENETHIL_HOWLINGFJORD_BOAT] = true,
[BZ["Dun Morogh"]] = true,
[BZ["Loch Modan"]] = true,
},
fishing_min = 55,
}
 
zones[BZ["Alterac Mountains"]] = {
low = 30,
high = 40,
continent = Eastern_Kingdoms,
instances = BZ["Alterac Valley"],
paths = {
[BZ["Western Plaguelands"]] = true,
[BZ["Alterac Valley"]] = true,
[BZ["Hillsbrad Foothills"]] = true,
},
fishing_min = 130,
}
 
zones[BZ["Arathi Highlands"]] = {
low = 30,
high = 40,
continent = Eastern_Kingdoms,
instances = BZ["Arathi Basin"],
paths = {
[BZ["Wetlands"]] = true,
[BZ["Hillsbrad Foothills"]] = true,
[BZ["Arathi Basin"]] = true,
},
fishing_min = 130,
}
 
zones[BZ["Stranglethorn Vale"]] = {
low = 30,
high = 45,
continent = Eastern_Kingdoms,
instances = BZ["Zul'Gurub"],
paths = {
[BZ["Zul'Gurub"]] = true,
[BOOTYBAY_RATCHET_BOAT] = true,
[BZ["Duskwood"]] = true,
[ORGRIMMAR_GROMGOL_ZEPPELIN] = true,
[UNDERCITY_GROMGOL_ZEPPELIN] = true,
},
fishing_min = 130,
}
 
zones[BZ["Badlands"]] = {
low = 35,
high = 45,
continent = Eastern_Kingdoms,
instances = BZ["Uldaman"],
paths = {
[BZ["Uldaman"]] = true,
[BZ["Searing Gorge"]] = true,
[BZ["Loch Modan"]] = true,
},
}
 
zones[BZ["Swamp of Sorrows"]] = {
low = 35,
high = 45,
continent = Eastern_Kingdoms,
instances = BZ["The Temple of Atal'Hakkar"],
paths = {
[BZ["Blasted Lands"]] = true,
[BZ["Deadwind Pass"]] = true,
[BZ["The Temple of Atal'Hakkar"]] = true,
},
fishing_min = 130,
}
 
zones[BZ["The Hinterlands"]] = {
low = 45,
high = 50,
continent = Eastern_Kingdoms,
paths = {
[BZ["Hillsbrad Foothills"]] = true,
[BZ["Western Plaguelands"]] = true,
},
fishing_min = 205,
}
 
zones[BZ["Searing Gorge"]] = {
low = 43,
high = 50,
continent = Eastern_Kingdoms,
instances = {
[BZ["Blackrock Depths"]] = true,
[BZ["Blackwing Lair"]] = true,
[BZ["Molten Core"]] = true,
[BZ["Blackrock Spire"]] = true,
},
paths = {
[BZ["Blackrock Mountain"]] = true,
[BZ["Badlands"]] = true,
[BZ["Loch Modan"]] = not isHorde and true or nil,
},
}
 
zones[BZ["Blackrock Mountain"]] = {
low = 42,
high = 54,
continent = Eastern_Kingdoms,
instances = {
[BZ["Blackrock Depths"]] = true,
[BZ["Blackwing Lair"]] = true,
[BZ["Molten Core"]] = true,
[BZ["Blackrock Spire"]] = true,
},
paths = {
[BZ["Burning Steppes"]] = true,
[BZ["Blackwing Lair"]] = true,
[BZ["Molten Core"]] = true,
[BZ["Blackrock Depths"]] = true,
[BZ["Searing Gorge"]] = true,
[BZ["Blackrock Spire"]] = true,
},
}
 
zones[BZ["Deadwind Pass"]] = {
low = 55,
high = 60,
continent = Eastern_Kingdoms,
instances = BZ["Karazhan"],
paths = {
[BZ["Duskwood"]] = true,
[BZ["Swamp of Sorrows"]] = true,
[BZ["Karazhan"]] = true,
},
fishing_min = 330,
}
 
zones[BZ["Blasted Lands"]] = {
low = 45,
high = 55,
continent = Eastern_Kingdoms,
paths = {
[BZ["The Dark Portal"]] = true,
[BZ["Swamp of Sorrows"]] = true,
},
}
 
zones[BZ["Burning Steppes"]] = {
low = 50,
high = 58,
continent = Eastern_Kingdoms,
instances = {
[BZ["Blackrock Depths"]] = true,
[BZ["Blackwing Lair"]] = true,
[BZ["Molten Core"]] = true,
[BZ["Blackrock Spire"]] = true,
},
paths = {
[BZ["Blackrock Mountain"]] = true,
[BZ["Redridge Mountains"]] = true,
},
fishing_min = 330,
}
 
zones[BZ["Western Plaguelands"]] = {
low = 51,
high = 58,
continent = Eastern_Kingdoms,
instances = BZ["Scholomance"],
paths = {
[BZ["The Hinterlands"]] = true,
[BZ["Eastern Plaguelands"]] = true,
[BZ["Tirisfal Glades"]] = true,
[BZ["Scholomance"]] = true,
[BZ["Alterac Mountains"]] = true,
},
fishing_min = 205,
}
 
zones[BZ["Eastern Plaguelands"]] = {
low = 53,
high = 60,
continent = Eastern_Kingdoms,
instances = BZ["Stratholme"],
paths = {
[BZ["Western Plaguelands"]] = true,
[BZ["Stratholme"]] = true,
[BZ["Ghostlands"]] = true,
},
type = "PvP Zone",
fishing_min = 330,
}
 
zones[BZ["The Deadmines"]] = {
low = 16,
high = 24,
continent = Eastern_Kingdoms,
paths = BZ["Westfall"],
groupSize = 5,
faction = "Alliance",
type = "Instance",
fishing_min = 20,
entrancePortal = { BZ["Westfall"], 42.6, 72.2 },
}
 
zones[BZ["Shadowfang Keep"]] = {
low = 17,
high = 25,
continent = Eastern_Kingdoms,
paths = BZ["Silverpine Forest"],
groupSize = 5,
faction = "Horde",
type = "Instance",
entrancePortal = { BZ["Silverpine Forest"], 43, 67 },
}
 
zones[BZ["The Stockade"]] = {
low = 21,
high = 29,
continent = Eastern_Kingdoms,
paths = BZ["Stormwind City"],
groupSize = 5,
faction = "Alliance",
type = "Instance",
entrancePortal = { BZ["Stormwind City"], 40.6, 55.8 },
}
 
zones[BZ["Gnomeregan"]] = {
low = 24,
high = 40,
continent = Eastern_Kingdoms,
paths = BZ["Dun Morogh"],
groupSize = 5,
faction = "Alliance",
type = "Instance",
entrancePortal = { BZ["Dun Morogh"], 24, 38.9 },
}
 
zones[BZ["Scarlet Monastery"]] = {
low = 28,
high = 44,
continent = Eastern_Kingdoms,
instances = {
[BZ["Armory"]] = true,
[BZ["Library"]] = true,
[BZ["Graveyard"]] = true,
[BZ["Cathedral"]] = true,
},
paths = {
[BZ["Tirisfal Glades"]] = true,
[BZ["Armory"]] = true,
[BZ["Library"]] = true,
[BZ["Graveyard"]] = true,
[BZ["Cathedral"]] = true,
},
faction = "Horde",
type = "Instance",
entrancePortal = { BZ["Tirisfal Glades"], 84.4, 32.9 },
}
 
zones[BZ["Graveyard"]] = {
low = 28,
high = 44,
continent = Eastern_Kingdoms,
paths = BZ["Scarlet Monastery"],
groupSize = 5,
type = "Instance",
complex = BZ["Scarlet Monastery"],
entrancePortal = { BZ["Tirisfal Glades"], 84.4, 32.9 },
}
 
zones[BZ["Library"]] = {
low = 28,
high = 44,
continent = Eastern_Kingdoms,
paths = BZ["Scarlet Monastery"],
groupSize = 5,
type = "Instance",
complex = BZ["Scarlet Monastery"],
entrancePortal = { BZ["Tirisfal Glades"], 84.4, 32.9 },
}
 
zones[BZ["Armory"]] = {
low = 28,
high = 44,
continent = Eastern_Kingdoms,
paths = BZ["Scarlet Monastery"],
groupSize = 5,
type = "Instance",
complex = BZ["Scarlet Monastery"],
entrancePortal = { BZ["Tirisfal Glades"], 84.4, 32.9 },
}
 
zones[BZ["Cathedral"]] = {
low = 28,
high = 44,
continent = Eastern_Kingdoms,
paths = BZ["Scarlet Monastery"],
groupSize = 5,
type = "Instance",
complex = BZ["Scarlet Monastery"],
entrancePortal = { BZ["Tirisfal Glades"], 84.4, 32.9 },
}
 
zones[BZ["Uldaman"]] = {
low = 36,
high = 44,
continent = Eastern_Kingdoms,
paths = BZ["Badlands"],
groupSize = 5,
type = "Instance",
entrancePortal = { BZ["Badlands"], 42.4, 18.6 },
}
 
zones[BZ["The Temple of Atal'Hakkar"]] = {
low = 45,
high = 54,
continent = Eastern_Kingdoms,
paths = BZ["Swamp of Sorrows"],
groupSize = 5,
type = "Instance",
fishing_min = 205,
entrancePortal = { BZ["Swamp of Sorrows"], 70, 54 },
}
 
zones[BZ["Blackrock Depths"]] = {
low = 48,
high = 60,
continent = Eastern_Kingdoms,
paths = {
[BZ["Molten Core"]] = true,
[BZ["Blackrock Mountain"]] = true,
},
groupSize = 5,
type = "Instance",
entrancePortal = { BZ["Searing Gorge"], 35.4, 84.4 },
}
 
zones[BZ["Blackrock Spire"]] = {
low = 53,
high = 61,
continent = Eastern_Kingdoms,
paths = {
[BZ["Blackrock Mountain"]] = true,
[BZ["Blackwing Lair"]] = true,
},
groupSize = 10,
type = "Instance",
entrancePortal = { BZ["Burning Steppes"], 29.7, 37.5 },
}
 
zones[BZ["Scholomance"]] = {
low = 56,
high = 61,
continent = Eastern_Kingdoms,
paths = BZ["Western Plaguelands"],
groupSize = 5,
type = "Instance",
fishing_min = 330,
entrancePortal = { BZ["Western Plaguelands"], 69.4, 72.8 },
}
 
zones[BZ["Stratholme"]] = {
low = 56,
high = 61,
continent = Eastern_Kingdoms,
paths = BZ["Eastern Plaguelands"],
groupSize = 5,
type = "Instance",
fishing_min = 330,
entrancePortal = { BZ["Eastern Plaguelands"], 30.8, 14.4 },
}
 
zones[BZ["Blackwing Lair"]] = {
low = 60,
high = 62,
continent = Eastern_Kingdoms,
paths = BZ["Blackrock Mountain"],
groupSize = 40,
type = "Instance",
entrancePortal = { BZ["Burning Steppes"], 29.7, 37.5 },
}
 
zones[BZ["Molten Core"]] = {
low = 60,
high = 62,
continent = Eastern_Kingdoms,
paths = BZ["Blackrock Mountain"],
groupSize = 40,
type = "Instance",
entrancePortal = { BZ["Searing Gorge"], 35.4, 84.4 },
}
 
zones[BZ["Zul'Gurub"]] = {
low = 60,
high = 62,
continent = Eastern_Kingdoms,
paths = BZ["Stranglethorn Vale"],
groupSize = 20,
type = "Instance",
fishing_min = 330,
entrancePortal = { BZ["Stranglethorn Vale"], 52.2, 17.1 },
}
 
zones[BZ["Karazhan"]] = {
low = 70,
high = 72,
continent = Eastern_Kingdoms,
paths = BZ["Deadwind Pass"],
groupSize = 10,
type = "Instance",
entrancePortal = { BZ["Deadwind Pass"], 40.9, 73.2 },
}
 
zones[BZ["Zul'Aman"]] = {
low = 70,
high = 72,
continent = Eastern_Kingdoms,
paths = BZ["Ghostlands"],
groupSize = 10,
type = "Instance",
entrancePortal = { BZ["Ghostlands"], 77.7, 63.2 },
}
 
zones[BZ["Darnassus"]] = {
continent = Kalimdor,
paths = {
[BZ["Teldrassil"]] = true,
[AUBERDINE_DARNASSUS_BOAT] = true,
},
faction = "Alliance",
type = "City",
fishing_min = 1,
}
 
zones[BZ["Hyjal"]] = {
continent = Kalimdor,
}
 
zones[BZ["Moonglade"]] = {
continent = Kalimdor,
paths = {
[BZ["Felwood"]] = true,
[BZ["Winterspring"]] = true,
},
fishing_min = 205,
}
 
zones[BZ["Orgrimmar"]] = {
continent = Kalimdor,
instances = BZ["Ragefire Chasm"],
paths = {
[BZ["Durotar"]] = true,
[BZ["Ragefire Chasm"]] = true,
},
faction = "Horde",
type = "City",
fishing_min = 1,
}
 
zones[BZ["The Exodar"]] = {
continent = Kalimdor,
paths = BZ["Azuremyst Isle"],
faction = "Alliance",
type = "City",
fishing_min = 1,
}
 
zones[BZ["Thunder Bluff"]] = {
continent = Kalimdor,
paths = BZ["Mulgore"],
faction = "Horde",
type = "City",
}
 
zones[BZ["Azuremyst Isle"]] = {
low = 1,
high = 10,
continent = Kalimdor,
paths = {
[BZ["The Exodar"]] = true,
[BZ["Bloodmyst Isle"]] = true,
[AUBERDINE_AZUREMYST_BOAT] = true,
},
faction = "Alliance",
fishing_min = 20,
}
 
zones[BZ["Durotar"]] = {
low = 1,
high = 10,
continent = Kalimdor,
instances = BZ["Ragefire Chasm"],
paths = {
[ORGRIMMAR_UNDERCITY_ZEPPELIN] = true,
[ORGRIMMAR_GROMGOL_ZEPPELIN] = true,
[ORGRIMMAR_BOREANTUNDRA_ZEPPELIN] = true,
[BZ["The Barrens"]] = true,
[BZ["Orgrimmar"]] = true,
},
faction = "Horde",
fishing_min = 1,
}
 
zones[BZ["Mulgore"]] = {
low = 1,
high = 10,
continent = Kalimdor,
paths = {
[BZ["Thunder Bluff"]] = true,
[BZ["The Barrens"]] = true,
},
faction = "Horde",
fishing_min = 1,
}
 
zones[BZ["Teldrassil"]] = {
low = 1,
high = 10,
continent = Kalimdor,
paths = BZ["Darnassus"],
faction = "Alliance",
fishing_min = 1,
}
 
zones[BZ["Bloodmyst Isle"]] = {
low = 10,
high = 20,
continent = Kalimdor,
paths = BZ["Azuremyst Isle"],
faction = "Alliance",
fishing_min = 1,
}
 
zones[BZ["Darkshore"]] = {
low = 10,
high = 20,
continent = Kalimdor,
paths = {
[AUBERDINE_DARNASSUS_BOAT] = true,
[AUBERDINE_AZUREMYST_BOAT] = true,
[STORMWIND_AUBERDINE_BOAT] = true,
[BZ["Ashenvale"]] = true,
},
faction = "Alliance",
fishing_min = 20,
}
 
zones[BZ["The Barrens"]] = {
low = 10,
high = 25,
continent = Kalimdor,
instances = {
[BZ["Razorfen Kraul"]] = true,
[BZ["Wailing Caverns"]] = true,
[BZ["Razorfen Downs"]] = true,
[BZ["Warsong Gulch"]] = isHorde and true or nil,
},
paths = {
[BZ["Thousand Needles"]] = true,
[BZ["Razorfen Kraul"]] = true,
[BZ["Ashenvale"]] = true,
[BZ["Durotar"]] = true,
[BZ["Wailing Caverns"]] = true,
[BOOTYBAY_RATCHET_BOAT] = true,
[BZ["Dustwallow Marsh"]] = true,
[BZ["Razorfen Downs"]] = true,
[BZ["Stonetalon Mountains"]] = true,
[BZ["Mulgore"]] = true,
[BZ["Warsong Gulch"]] = isHorde and true or nil,
},
faction = "Horde",
fishing_min = 20,
}
 
zones[BZ["Stonetalon Mountains"]] = {
low = 15,
high = 27,
continent = Kalimdor,
paths = {
[BZ["Desolace"]] = true,
[BZ["The Barrens"]] = true,
[BZ["Ashenvale"]] = true,
},
fishing_min = 55,
}
 
zones[BZ["Ashenvale"]] = {
low = 18,
high = 30,
continent = Kalimdor,
instances = {
[BZ["Blackfathom Deeps"]] = true,
[BZ["Warsong Gulch"]] = not isHorde and true or nil,
},
paths = {
[BZ["Azshara"]] = true,
[BZ["The Barrens"]] = true,
[BZ["Blackfathom Deeps"]] = true,
[BZ["Warsong Gulch"]] = not isHorde and true or nil,
[BZ["Felwood"]] = true,
[BZ["Darkshore"]] = true,
[BZ["Stonetalon Mountains"]] = true,
},
fishing_min = 55,
}
 
zones[BZ["Thousand Needles"]] = {
low = 25,
high = 35,
continent = Kalimdor,
paths = {
[BZ["Feralas"]] = true,
[BZ["The Barrens"]] = true,
[BZ["Tanaris"]] = true,
},
fishing_min = 130,
}
 
zones[BZ["Desolace"]] = {
low = 30,
high = 40,
continent = Kalimdor,
instances = BZ["Maraudon"],
paths = {
[BZ["Feralas"]] = true,
[BZ["Stonetalon Mountains"]] = true,
[BZ["Maraudon"]] = true,
},
fishing_min = 130,
}
 
zones[BZ["Dustwallow Marsh"]] = {
low = 35,
high = 45,
continent = Kalimdor,
instances = BZ["Onyxia's Lair"],
paths = {
[BZ["Onyxia's Lair"]] = true,
[BZ["The Barrens"]] = true,
[MENETHIL_THERAMORE_BOAT] = true,
},
fishing_min = 130,
}
 
zones[BZ["Feralas"]] = {
low = 40,
high = 50,
continent = Kalimdor,
instances = BZ["Dire Maul"],
paths = {
[BZ["Thousand Needles"]] = true,
[BZ["Desolace"]] = true,
[BZ["Dire Maul"]] = true,
},
fishing_min = 205,
}
 
zones[BZ["Tanaris"]] = {
low = 40,
high = 50,
continent = Kalimdor,
instances = {
[BZ["Zul'Farrak"]] = true,
[BZ["Old Hillsbrad Foothills"]] = true,
[BZ["The Black Morass"]] = true,
[BZ["Hyjal Summit"]] = true,
[BZ["The Culling of Stratholme"]] = true,
},
paths = {
[BZ["Thousand Needles"]] = true,
[BZ["Un'Goro Crater"]] = true,
[BZ["Zul'Farrak"]] = true,
[BZ["Caverns of Time"]] = true,
},
fishing_min = 205,
}
 
zones[BZ["Azshara"]] = {
low = 45,
high = 55,
continent = Kalimdor,
paths = BZ["Ashenvale"],
fishing_min = 205,
}
 
zones[BZ["Felwood"]] = {
low = 48,
high = 55,
continent = Kalimdor,
paths = {
[BZ["Winterspring"]] = true,
[BZ["Moonglade"]] = true,
[BZ["Ashenvale"]] = true,
},
fishing_min = 205,
}
 
zones[BZ["Un'Goro Crater"]] = {
low = 48,
high = 55,
continent = Kalimdor,
paths = {
[BZ["Silithus"]] = true,
[BZ["Tanaris"]] = true,
},
fishing_min = 205,
}
 
zones[BZ["Silithus"]] = {
low = 55,
high = 60,
continent = Kalimdor,
instances = {
[BZ["Ahn'Qiraj"]] = true,
[BZ["Ruins of Ahn'Qiraj"]] = true,
},
paths = {
[BZ["Ruins of Ahn'Qiraj"]] = true,
[BZ["Un'Goro Crater"]] = true,
[BZ["Ahn'Qiraj"]] = true,
},
type = "PvP Zone",
fishing_min = 330,
}
 
zones[BZ["Winterspring"]] = {
low = 53,
high = 60,
continent = Kalimdor,
paths = {
[BZ["Felwood"]] = true,
[BZ["Moonglade"]] = true,
},
fishing_min = 330,
}
 
zones[BZ["Ragefire Chasm"]] = {
low = 13,
high = 20,
continent = Kalimdor,
paths = BZ["Orgrimmar"],
groupSize = 5,
faction = "Horde",
type = "Instance",
entrancePortal = { BZ["Orgrimmar"], 52.8, 49 },
}
 
zones[BZ["Wailing Caverns"]] = {
low = 16,
high = 24,
continent = Kalimdor,
paths = BZ["The Barrens"],
groupSize = 5,
faction = "Horde",
type = "Instance",
fishing_min = 20,
entrancePortal = { BZ["The Barrens"], 47.3, 35 },
}
 
zones[BZ["Blackfathom Deeps"]] = {
low = 20,
high = 28,
continent = Kalimdor,
paths = BZ["Ashenvale"],
groupSize = 5,
type = "Instance",
fishing_min = 20,
entrancePortal = { BZ["Ashenvale"], 14.6, 15.3 },
}
 
zones[BZ["Razorfen Kraul"]] = {
low = 23,
high = 31,
continent = Kalimdor,
paths = BZ["The Barrens"],
groupSize = 5,
type = "Instance",
entrancePortal = { BZ["The Barrens"], 40.6, 89.6 },
}
 
zones[BZ["Razorfen Downs"]] = {
low = 33,
high = 41,
continent = Kalimdor,
paths = BZ["The Barrens"],
groupSize = 5,
type = "Instance",
entrancePortal = { BZ["The Barrens"], 47, 88.1 },
}
 
zones[BZ["Zul'Farrak"]] = {
low = 42,
high = 50,
continent = Kalimdor,
paths = BZ["Tanaris"],
groupSize = 5,
type = "Instance",
entrancePortal = { BZ["Tanaris"], 36, 11.7 },
}
 
zones[BZ["Maraudon"]] = {
low = 40,
high = 52,
continent = Kalimdor,
paths = BZ["Desolace"],
groupSize = 5,
type = "Instance",
fishing_min = 205,
entrancePortal = { BZ["Desolace"], 29, 62.4 },
}
 
zones[BZ["Dire Maul"]] = {
low = 54,
high = 61,
continent = Kalimdor,
paths = BZ["Feralas"],
groupSize = 5,
type = "Instance",
entrancePortal = { BZ["Feralas"], 58.5, 44.1 },
}
 
zones[BZ["Onyxia's Lair"]] = {
low = 60,
high = 62,
continent = Kalimdor,
paths = BZ["Dustwallow Marsh"],
groupSize = 40,
type = "Instance",
entrancePortal = { BZ["Dustwallow Marsh"], 52, 76 },
}
 
zones[BZ["Ahn'Qiraj"]] = {
low = 60,
high = 62,
continent = Kalimdor,
paths = BZ["Silithus"],
groupSize = 40,
type = "Instance",
entrancePortal = { BZ["Silithus"], 29.3, 94 },
}
 
zones[BZ["Ruins of Ahn'Qiraj"]] = {
low = 60,
high = 62,
continent = Kalimdor,
paths = BZ["Silithus"],
groupSize = 20,
type = "Instance",
entrancePortal = { BZ["Silithus"], 29.3, 94 },
}
 
zones[BZ["Caverns of Time"]] = {
continent = Kalimdor,
instances = {
[BZ["Old Hillsbrad Foothills"]] = true,
[BZ["The Black Morass"]] = true,
[BZ["Hyjal Summit"]] = true,
[BZ["The Culling of Stratholme"]] = true,
},
paths = {
[BZ["Tanaris"]] = true,
[BZ["Old Hillsbrad Foothills"]] = true,
[BZ["The Black Morass"]] = true,
[BZ["Hyjal Summit"]] = true,
[BZ["The Culling of Stratholme"]] = true,
},
entrancePortal = { BZ["Tanaris"], 66.2, 49.3 },
}
 
zones[BZ["Old Hillsbrad Foothills"]] = {
low = 66,
high = 68,
continent = Kalimdor,
paths = BZ["Caverns of Time"],
groupSize = 5,
type = "Instance",
complex = BZ["Caverns of Time"],
entrancePortal = { BZ["Tanaris"], 66.2, 49.3 },
}
 
zones[BZ["The Black Morass"]] = {
low = 69,
high = 72,
continent = Kalimdor,
paths = BZ["Caverns of Time"],
groupSize = 5,
type = "Instance",
complex = BZ["Caverns of Time"],
entrancePortal = { BZ["Tanaris"], 66.2, 49.3 },
}
 
zones[BZ["The Culling of Stratholme"]] = {
low = 80,
high = 80,
continent = Kalimdor,
paths = BZ["Caverns of Time"],
groupSize = 5,
type = "Instance",
complex = BZ["Caverns of Time"],
entrancePortal = { BZ["Tanaris"], 66.2, 49.3 },
}
 
zones[BZ["Hyjal Summit"]] = {
low = 70,
high = 72,
continent = Kalimdor,
paths = BZ["Caverns of Time"],
groupSize = 25,
type = "Instance",
complex = BZ["Caverns of Time"],
entrancePortal = { BZ["Tanaris"], 66.2, 49.3 },
}
 
zones[BZ["Shattrath City"]] = {
continent = Outland,
paths = {
[SHATTRATH_THUNDERBLUFF_PORTAL] = true,
[SHATTRATH_STORMWIND_PORTAL] = true,
[SHATTRATH_UNDERCITY_PORTAL] = true,
[BZ["Terokkar Forest"]] = true,
[SHATTRATH_SILVERMOON_PORTAL] = true,
[SHATTRATH_EXODAR_PORTAL] = true,
[SHATTRATH_DARNASSUS_PORTAL] = true,
[SHATTRATH_ORGRIMMAR_PORTAL] = true,
[SHATTRATH_IRONFORGE_PORTAL] = true,
[BZ["Nagrand"]] = true,
[SHATTRATH_QUELDANAS_PORTAL] = true,
--[SHATTRATH_COT_PORTAL] = true,
},
type = "City",
}
 
zones[BZ["Hellfire Citadel"]] = {
continent = Outland,
instances = {
[BZ["The Blood Furnace"]] = true,
[BZ["Hellfire Ramparts"]] = true,
[BZ["Magtheridon's Lair"]] = true,
[BZ["The Shattered Halls"]] = true,
},
paths = {
[BZ["Hellfire Peninsula"]] = true,
[BZ["The Blood Furnace"]] = true,
[BZ["Hellfire Ramparts"]] = true,
[BZ["Magtheridon's Lair"]] = true,
[BZ["The Shattered Halls"]] = true,
},
entrancePortal = { BZ["Hellfire Peninsula"], 46.8, 54.9 },
}
 
zones[BZ["Hellfire Peninsula"]] = {
low = 58,
high = 63,
continent = Outland,
instances = {
[BZ["The Blood Furnace"]] = true,
[BZ["Hellfire Ramparts"]] = true,
[BZ["Magtheridon's Lair"]] = true,
[BZ["The Shattered Halls"]] = true,
},
paths = {
[BZ["Zangarmarsh"]] = true,
[BZ["The Dark Portal"]] = true,
[BZ["Terokkar Forest"]] = true,
[BZ["Hellfire Citadel"]] = true,
},
type = "PvP Zone",
}
 
zones[BZ["Coilfang Reservoir"]] = {
continent = Outland,
instances = {
[BZ["The Underbog"]] = true,
[BZ["Serpentshrine Cavern"]] = true,
[BZ["The Steamvault"]] = true,
[BZ["The Slave Pens"]] = true,
},
paths = {
[BZ["Zangarmarsh"]] = true,
[BZ["The Underbog"]] = true,
[BZ["Serpentshrine Cavern"]] = true,
[BZ["The Steamvault"]] = true,
[BZ["The Slave Pens"]] = true,
},
entrancePortal = { BZ["Zangarmarsh"], 50.2, 40.8 },
}
 
zones[BZ["Zangarmarsh"]] = {
low = 60,
high = 64,
continent = Outland,
instances = {
[BZ["The Underbog"]] = true,
[BZ["Serpentshrine Cavern"]] = true,
[BZ["The Steamvault"]] = true,
[BZ["The Slave Pens"]] = true,
},
paths = {
[BZ["Coilfang Reservoir"]] = true,
[BZ["Blade's Edge Mountains"]] = true,
[BZ["Terokkar Forest"]] = true,
[BZ["Nagrand"]] = true,
[BZ["Hellfire Peninsula"]] = true,
},
type = "PvP Zone",
fishing_min = 305,
}
 
zones[BZ["Ring of Observance"]] = {
continent = Outland,
instances = {
[BZ["Mana-Tombs"]] = true,
[BZ["Sethekk Halls"]] = true,
[BZ["Shadow Labyrinth"]] = true,
[BZ["Auchenai Crypts"]] = true,
},
paths = {
[BZ["Terokkar Forest"]] = true,
[BZ["Mana-Tombs"]] = true,
[BZ["Sethekk Halls"]] = true,
[BZ["Shadow Labyrinth"]] = true,
[BZ["Auchenai Crypts"]] = true,
},
entrancePortal = { BZ["Terokkar Forest"], 39.6, 65.5 },
}
 
zones[BZ["Terokkar Forest"]] = {
low = 62,
high = 65,
continent = Outland,
instances = {
[BZ["Mana-Tombs"]] = true,
[BZ["Sethekk Halls"]] = true,
[BZ["Shadow Labyrinth"]] = true,
[BZ["Auchenai Crypts"]] = true,
},
paths = {
[BZ["Ring of Observance"]] = true,
[BZ["Shadowmoon Valley"]] = true,
[BZ["Zangarmarsh"]] = true,
[BZ["Shattrath City"]] = true,
[BZ["Hellfire Peninsula"]] = true,
[BZ["Nagrand"]] = true,
},
type = "PvP Zone",
fishing_min = 355,
}
 
zones[BZ["Nagrand"]] = {
low = 64,
high = 67,
continent = Outland,
paths = {
[BZ["Zangarmarsh"]] = true,
[BZ["Shattrath City"]] = true,
[BZ["Terokkar Forest"]] = true,
},
type = "PvP Zone",
fishing_min = 380,
}
 
zones[BZ["Blade's Edge Mountains"]] = {
low = 65,
high = 68,
continent = Outland,
instances = BZ["Gruul's Lair"],
paths = {
[BZ["Netherstorm"]] = true,
[BZ["Zangarmarsh"]] = true,
[BZ["Gruul's Lair"]] = true,
},
}
 
zones[BZ["Tempest Keep"]] = {
continent = Outland,
instances = {
[BZ["The Mechanar"]] = true,
[BZ["The Eye"]] = true,
[BZ["The Botanica"]] = true,
[BZ["The Arcatraz"]] = true,
},
paths = {
[BZ["Netherstorm"]] = true,
[BZ["The Mechanar"]] = true,
[BZ["The Eye"]] = true,
[BZ["The Botanica"]] = true,
[BZ["The Arcatraz"]] = true,
},
entrancePortal = { BZ["Netherstorm"], 76.5, 65.1 },
}
 
zones[BZ["Netherstorm"]] = {
low = 67,
high = 70,
continent = Outland,
instances = {
[BZ["The Mechanar"]] = true,
[BZ["The Botanica"]] = true,
[BZ["The Arcatraz"]] = true,
[BZ["The Eye"]] = true,
},
paths = {
[BZ["Tempest Keep"]] = true,
[BZ["Blade's Edge Mountains"]] = true,
},
fishing_min = 380,
}
 
zones[BZ["Shadowmoon Valley"]] = {
low = 67,
high = 70,
continent = Outland,
instances = BZ["Black Temple"],
paths = {
[BZ["Terokkar Forest"]] = true,
[BZ["Black Temple"]] = true,
},
}
 
zones[BZ["Black Temple"]] = {
low = 70,
high = 72,
continent = Outland,
paths = BZ["Shadowmoon Valley"],
groupSize = 25,
type = "Instance",
entrancePortal = { BZ["Shadowmoon Valley"], 77.7, 43.7 },
}
 
zones[BZ["Auchenai Crypts"]] = {
low = 65,
high = 67,
continent = Outland,
paths = BZ["Ring of Observance"],
groupSize = 5,
type = "Instance",
complex = BZ["Auchindoun"],
entrancePortal = { BZ["Terokkar Forest"], 39.6, 65.5 },
}
 
zones[BZ["Shadow Labyrinth"]] = {
low = 70,
high = 72,
continent = Outland,
paths = BZ["Ring of Observance"],
groupSize = 5,
type = "Instance",
complex = BZ["Auchindoun"],
entrancePortal = { BZ["Terokkar Forest"], 39.6, 65.5 },
}
 
zones[BZ["Sethekk Halls"]] = {
low = 67,
high = 69,
continent = Outland,
paths = BZ["Ring of Observance"],
groupSize = 5,
type = "Instance",
complex = BZ["Auchindoun"],
entrancePortal = { BZ["Terokkar Forest"], 39.6, 65.5 },
}
 
zones[BZ["Mana-Tombs"]] = {
low = 64,
high = 66,
continent = Outland,
paths = BZ["Ring of Observance"],
groupSize = 5,
type = "Instance",
complex = BZ["Auchindoun"],
entrancePortal = { BZ["Terokkar Forest"], 39.6, 65.5 },
}
 
zones[BZ["Hellfire Ramparts"]] = {
low = 60,
high = 62,
continent = Outland,
paths = BZ["Hellfire Citadel"],
groupSize = 5,
type = "Instance",
complex = BZ["Hellfire Citadel"],
entrancePortal = { BZ["Hellfire Peninsula"], 46.8, 54.9 },
}
 
zones[BZ["The Blood Furnace"]] = {
low = 61,
high = 63,
continent = Outland,
paths = BZ["Hellfire Citadel"],
groupSize = 5,
type = "Instance",
complex = BZ["Hellfire Citadel"],
entrancePortal = { BZ["Hellfire Peninsula"], 46.8, 54.9 },
}
 
zones[BZ["The Shattered Halls"]] = {
low = 70,
high = 72,
continent = Outland,
paths = BZ["Hellfire Citadel"],
groupSize = 5,
type = "Instance",
complex = BZ["Hellfire Citadel"],
entrancePortal = { BZ["Hellfire Peninsula"], 46.8, 54.9 },
}
 
zones[BZ["Magtheridon's Lair"]] = {
low = 70,
high = 72,
continent = Outland,
paths = BZ["Hellfire Citadel"],
groupSize = 25,
type = "Instance",
complex = BZ["Hellfire Citadel"],
entrancePortal = { BZ["Hellfire Peninsula"], 46.8, 54.9 },
}
 
zones[BZ["The Slave Pens"]] = {
low = 62,
high = 64,
continent = Outland,
paths = BZ["Coilfang Reservoir"],
groupSize = 5,
type = "Instance",
complex = BZ["Coilfang Reservoir"],
entrancePortal = { BZ["Zangarmarsh"], 50.2, 40.8 },
}
 
zones[BZ["The Underbog"]] = {
low = 63,
high = 65,
continent = Outland,
paths = BZ["Coilfang Reservoir"],
groupSize = 5,
type = "Instance",
complex = BZ["Coilfang Reservoir"],
entrancePortal = { BZ["Zangarmarsh"], 50.2, 40.8 },
}
 
zones[BZ["The Steamvault"]] = {
low = 70,
high = 72,
continent = Outland,
paths = BZ["Coilfang Reservoir"],
groupSize = 5,
type = "Instance",
complex = BZ["Coilfang Reservoir"],
entrancePortal = { BZ["Zangarmarsh"], 50.2, 40.8 },
}
 
zones[BZ["Serpentshrine Cavern"]] = {
low = 70,
high = 72,
continent = Outland,
paths = BZ["Coilfang Reservoir"],
groupSize = 25,
type = "Instance",
complex = BZ["Coilfang Reservoir"],
entrancePortal = { BZ["Zangarmarsh"], 50.2, 40.8 },
}
 
zones[BZ["Gruul's Lair"]] = {
low = 70,
high = 72,
continent = Outland,
paths = BZ["Blade's Edge Mountains"],
groupSize = 25,
type = "Instance",
entrancePortal = { BZ["Blade's Edge Mountains"], 68, 24 },
}
 
zones[BZ["The Mechanar"]] = {
low = 69,
high = 72,
continent = Outland,
paths = BZ["Tempest Keep"],
groupSize = 5,
type = "Instance",
complex = BZ["Tempest Keep"],
entrancePortal = { BZ["Netherstorm"], 76.5, 65.1 },
}
 
zones[BZ["The Botanica"]] = {
low = 70,
high = 72,
continent = Outland,
paths = BZ["Tempest Keep"],
groupSize = 5,
type = "Instance",
complex = BZ["Tempest Keep"],
entrancePortal = { BZ["Netherstorm"], 76.5, 65.1 },
}
 
zones[BZ["The Arcatraz"]] = {
low = 70,
high = 72,
continent = Outland,
paths = BZ["Tempest Keep"],
groupSize = 5,
type = "Instance",
complex = BZ["Tempest Keep"],
entrancePortal = { BZ["Netherstorm"], 76.5, 65.1 },
}
 
zones[BZ["The Eye"]] = {
low = 70,
high = 72,
continent = Outland,
paths = BZ["Tempest Keep"],
groupSize = 25,
type = "Instance",
complex = BZ["Tempest Keep"],
entrancePortal = { BZ["Netherstorm"], 76.5, 65.1 },
}
 
zones[BZ["Eye of the Storm"]] = {
low = 61,
high = 70,
continent = Outland,
groupSize = 25,
type = "Battleground",
texture = "NetherstormArena",
}
 
-- arenas
zones[BZ["Blade's Edge Arena"]] = {
low = 70,
high = 70,
continent = Outland,
type = "Arena",
}
 
zones[BZ["Nagrand Arena"]] = {
low = 70,
high = 70,
continent = Outland,
type = "Arena",
}
 
zones[BZ["Ruins of Lordaeron"]] = {
low = 70,
high = 70,
continent = Kalimdor,
type = "Arena",
}
 
-- 2.4 zones
zones[BZ["Isle of Quel'Danas"]] = {
continent = Eastern_Kingdoms,
low = 70,
high = 70,
paths = {
[BZ["Magisters' Terrace"]] = true,
[BZ["Sunwell Plateau"]] = true,
},
instances = {
[BZ["Magisters' Terrace"]] = true,
[BZ["Sunwell Plateau"]] = true,
},
fishing_min = 380, --TODO: validate
}
 
zones[BZ["Magisters' Terrace"]] = {
low = 70,
high = 72,
continent = Eastern_Kingdoms,
paths = BZ["Isle of Quel'Danas"],
groupSize = 5,
type = "Instance",
entrancePortal = { BZ["Isle of Quel'Danas"], 61.3, 30.9 },
}
 
zones[BZ["Sunwell Plateau"]] = {
low = 70,
high = 72,
continent = Eastern_Kingdoms,
paths = BZ["Isle of Quel'Danas"],
groupSize = 25,
type = "Instance",
entrancePortal = { BZ["Isle of Quel'Danas"], 44.3, 45.7 },
}
 
-- WOTLK Zones
 
zones[BZ["Dalaran"]] = {
continent = Northrend,
paths = {
[BZ["Crystalsong Forest"]] = true,
[BZ["The Violet Hold"]] = true,
[DALARAN_IRONFORGE_PORTAL] = true,
[DALARAN_STORMWIND_PORTAL] = true,
[DALARAN_DARNASSUS_PORTAL] = true,
[DALARAN_ORGRIMMAR_PORTAL] = true,
[DALARAN_THUNDERBLUFF_PORTAL] = true,
[DALARAN_UNDERCITY_PORTAL] = true,
[DALARAN_EXODAR_PORTAL] = true,
[DALARAN_SILVERMOON_PORTAL] = true,
[DALARAN_SHATTRATH_PORTAL] = true,
[DALARAN_COT_PORTAL] = true,
},
instances = BZ["The Violet Hold"],
type = "City",
texture = "Dalaran",
}
 
zones[BZ["Plaguelands: The Scarlet Enclave"]] = {
low = 55,
high = 58,
continent = Eastern_Kingdoms,
yards = 3162.5,
x_offset = 0,
y_offset = 0,
texture = "ScarletEnclave",
}
 
zones[BZ["Borean Tundra"]] = {
low = 68,
high = 72,
continent = Northrend,
paths = {
[BZ["Coldarra"]] = true,
[BZ["Dragonblight"]] = true,
[BZ["Sholazar Basin"]] = true,
[STORMWIND_BOREANTUNDRA_BOAT] = true,
[ORGRIMMAR_BOREANTUNDRA_ZEPPELIN] = true,
[MOAKI_UNUPE_BOAT] = true,
},
instances = {
[BZ["The Nexus"]] = true,
[BZ["The Oculus"]] = true,
[BZ["The Eye of Eternity"]] = true,
},
}
 
zones[BZ["Coldarra"]] = {
continent = Northrend,
paths = {
[BZ["Coldarra"]] = true,
[BZ["The Nexus"]] = true,
[BZ["The Oculus"]] = true,
[BZ["The Eye of Eternity"]] = true,
},
instances = {
[BZ["The Nexus"]] = true,
[BZ["The Oculus"]] = true,
[BZ["The Eye of Eternity"]] = true,
},
}
 
zones[BZ["Howling Fjord"]] = {
low = 68,
high = 72,
continent = Northrend,
paths = {
[BZ["Grizzly Hills"]] = true,
[MENETHIL_HOWLINGFJORD_BOAT] = true,
[UNDERCITY_HOWLINGFJORD_ZEPPELIN] = true,
[MOAKI_KAMAGUA_BOAT] = true,
[BZ["Utgarde Keep"]] = true,
[BZ["Utgarde Pinnacle"]] = true,
},
instances = {
[BZ["Utgarde Keep"]] = true,
[BZ["Utgarde Pinnacle"]] = true,
},
}
 
zones[BZ["Dragonblight"]] = {
low = 71,
high = 74,
continent = Northrend,
paths = {
[BZ["Borean Tundra"]] = true,
[BZ["Grizzly Hills"]] = true,
[BZ["Zul'Drak"]] = true,
[BZ["Crystalsong Forest"]] = true,
[MOAKI_UNUPE_BOAT] = true,
[MOAKI_KAMAGUA_BOAT] = true,
[BZ["Azjol-Nerub"]] = true,
[BZ["Ahn'kahet: The Old Kingdom"]] = true,
[BZ["Naxxramas"]] = true,
[BZ["The Obsidian Sanctum"]] = true,
},
instances = {
[BZ["Azjol-Nerub"]] = true,
[BZ["Ahn'kahet: The Old Kingdom"]] = true,
[BZ["Naxxramas"]] = true,
[BZ["The Obsidian Sanctum"]] = true,
},
}
 
zones[BZ["Grizzly Hills"]] = {
low = 73,
high = 75,
continent = Northrend,
paths = {
[BZ["Howling Fjord"]] = true,
[BZ["Dragonblight"]] = true,
[BZ["Zul'Drak"]] = true,
[BZ["Drak'Tharon Keep"]] = true,
},
instances = BZ["Drak'Tharon Keep"],
}
 
zones[BZ["Zul'Drak"]] = {
low = 74,
high = 77,
continent = Northrend,
paths = {
[BZ["Dragonblight"]] = true,
[BZ["Grizzly Hills"]] = true,
[BZ["Crystalsong Forest"]] = true,
[BZ["Gundrak"]] = true,
},
instances = BZ["Gundrak"],
}
 
zones[BZ["Sholazar Basin"]] = {
low = 76,
high = 78,
continent = Northrend,
paths = BZ["Borean Tundra"],
}
 
zones[BZ["Crystalsong Forest"]] = {
low = 77,
high = 80,
continent = Northrend,
paths = {
--[BZ["Dalaran"]] = true,
[BZ["Dragonblight"]] = true,
[BZ["Zul'Drak"]] = true,
[BZ["The Storm Peaks"]] = true,
},
}
 
zones[BZ["The Storm Peaks"]] = {
low = 77,
high = 80,
continent = Northrend,
paths = {
[BZ["Crystalsong Forest"]] = true,
[BZ["Halls of Stone"]] = true,
[BZ["Halls of Lightning"]] = true,
[BZ["Ulduar"]] = true,
},
instances = {
[BZ["Halls of Stone"]] = true,
[BZ["Halls of Lightning"]] = true,
[BZ["Ulduar"]] = true,
},
}
 
zones[BZ["Icecrown"]] = {
low = 77,
high = 80,
continent = Northrend,
--paths = {
-- [BZ["Icecrown Citadel"]] = true,
--},
--instances = {
-- [BZ["Icecrown Citadel"]] = true,
--},
}
 
zones[BZ["Wintergrasp"]] = {
low = 77,
high = 80,
continent = Northrend,
paths = BZ["Vault of Archavon"],
instances = BZ["Vault of Archavon"],
type = "PvP Zone",
}
 
-- WOTLK Dungeons
zones[BZ["Utgarde Keep"]] = {
low = 70,
high = 72,
continent = Northrend,
paths = BZ["Howling Fjord"],
groupSize = 5,
type = "Instance",
entrancePortal = { BZ["Howling Fjord"], 58, 45 }, -- TODO: Validate
}
 
zones[BZ["Utgarde Pinnacle"]] = {
low = 80,
high = 80,
continent = Northrend,
paths = BZ["Howling Fjord"],
groupSize = 5,
type = "Instance",
entrancePortal = { BZ["Howling Fjord"], 58, 45 }, -- TODO: Validate
}
 
zones[BZ["The Nexus"]] = {
low = 71,
high = 73,
continent = Northrend,
paths = BZ["Coldarra"],
groupSize = 5,
type = "Instance",
--entrancePortal = { BZ["Borean Tundra"], 58, 45 }, -- TODO
}
 
zones[BZ["The Oculus"]] = {
low = 80,
high = 80,
continent = Northrend,
paths = BZ["Coldarra"],
groupSize = 5,
type = "Instance",
--entrancePortal = { BZ["Borean Tundra"], 58, 45 }, -- TODO
}
 
zones[BZ["The Eye of Eternity"]] = {
low = 80,
high = 80,
continent = Northrend,
paths = BZ["Coldarra"],
groupSize = 10,
altGroupSize = 25,
type = "Instance",
--entrancePortal = { BZ["Borean Tundra"], 58, 45 }, -- TODO
}
 
zones[BZ["Azjol-Nerub"]] = {
low = 72,
high = 74,
continent = Northrend,
paths = BZ["Dragonblight"],
groupSize = 5,
type = "Instance",
--entrancePortal = { BZ["Dragonblight"], 58, 45 }, -- TODO
}
 
zones[BZ["Ahn'kahet: The Old Kingdom"]] = {
low = 73,
high = 75,
continent = Northrend,
paths = BZ["Dragonblight"],
groupSize = 5,
type = "Instance",
--entrancePortal = { BZ["Dragonblight"], 58, 45 }, -- TODO
}
 
zones[BZ["Naxxramas"]] = {
low = 80,
high = 80,
continent = Northrend,
paths = BZ["Dragonblight"],
groupSize = 10,
altGroupSize = 25,
type = "Instance",
entrancePortal = { BZ["Dragonblight"], 90, 46 }, -- TODO
}
 
zones[BZ["The Obsidian Sanctum"]] = {
low = 80,
high = 80,
continent = Northrend,
paths = BZ["Dragonblight"],
groupSize = 10,
altGroupSize = 25,
type = "Instance",
entrancePortal = { BZ["Dragonblight"], 60, 54 }, -- TODO
}
 
zones[BZ["Drak'Tharon Keep"]] = {
low = 74,
high = 76,
continent = Northrend,
paths = BZ["Grizzly Hills"],
groupSize = 5,
type = "Instance",
--entrancePortal = { BZ["Grizzly Hills"], 58, 45 }, -- TODO
}
 
zones[BZ["Gundrak"]] = {
low = 76,
high = 78,
continent = Northrend,
paths = BZ["Zul'Drak"],
groupSize = 5,
type = "Instance",
--entrancePortal = { BZ["Zul'Drak"], 58, 45 }, -- TODO
}
 
zones[BZ["Halls of Stone"]] = {
low = 77,
high = 79,
continent = Northrend,
paths = BZ["The Storm Peaks"],
groupSize = 5,
type = "Instance",
--entrancePortal = { BZ["The Storm Peaks"], 58, 45 }, -- TODO
}
 
zones[BZ["Halls of Lightning"]] = {
low = 80,
high = 80,
continent = Northrend,
paths = BZ["The Storm Peaks"],
groupSize = 5,
type = "Instance",
--entrancePortal = { BZ["The Storm Peaks"], 58, 45 }, -- TODO
}
 
zones[BZ["Ulduar"]] = {
low = 80,
high = 80,
continent = Northrend,
paths = BZ["The Storm Peaks"],
groupSize = 10,
altGroupSize = 25,
type = "Instance",
--entrancePortal = { BZ["The Storm Peaks"], 58, 45 }, -- TODO
}
 
zones[BZ["The Violet Hold"]] = {
low = 80,
high = 80,
continent = Northrend,
paths = BZ["Dalaran"],
groupSize = 5,
type = "Instance",
--entrancePortal = { BZ["The Storm Peaks"], 58, 45 }, -- TODO
}
 
--zones[BZ["Icecrown Citadel"]] = {
-- low = 80,
-- high = 80,
-- continent = Northrend,
-- paths = BZ["Icecrown"],
-- groupSize = 25,
-- type = "Instance",
--entrancePortal = { BZ["Icecrown"], 58, 45 }, -- TODO
--}
 
zones[BZ["Vault of Archavon"]] = {
low = 80,
high = 80,
continent = Northrend,
paths = BZ["Wintergrasp"],
groupSize = 10,
altGroupSize = 25,
type = "Instance",
}
 
local continentNames = { GetMapContinents() }
local doneZones = {}
for continentID, continentName in ipairs(continentNames) do
SetMapZoom(continentID)
if zones[continentName] then
zones[continentName].texture = GetMapInfo()
end
local zoneNames = { GetMapZones(continentID) }
local continentYards = zones[continentName].yards
for _ = 1, #zoneNames do
local x, y
local name, fileName, texPctX, texPctY, texX, texY, scrollX, scrollY
local finish = GetTime() + 0.1
repeat
if finish < GetTime() then
name = nil
break
end
x, y = math.random(), math.random()
name, fileName, texPctX, texPctY, texX, texY, scrollX, scrollY = UpdateMapHighlight(x, y)
until name and not doneZones[name]
if name == nil then
break
end
doneZones[name] = true
 
if fileName == "EversongWoods" or fileName == "Ghostlands" or fileName == "Sunwell" or fileName == "SilvermoonCity" then
scrollX = scrollX - 0.00168
scrollY = scrollY + 0.01
end
 
if zones[name] then
zones[name].yards = texX * continentYards
zones[name].x_offset = scrollX * continentYards
zones[name].y_offset = scrollY * continentYards * 2/3
zones[name].texture = fileName
end
end
end
SetMapToCurrentZone()
 
for k,v in pairs(zones) do
lows[k] = v.low or 0
highs[k] = v.high or 0
continents[k] = v.continent or UNKNOWN
instances[k] = v.instances
paths[k] = v.paths or false
types[k] = v.type or "Zone"
groupSizes[k] = v.groupSize
groupAltSizes[k] = v.altGroupSize
factions[k] = v.faction
yardWidths[k] = v.yards
yardHeights[k] = v.yards and v.yards * 2/3 or nil
yardXOffsets[k] = v.x_offset
yardYOffsets[k] = v.y_offset
fishing[k] = v.fishing_min
textures[k] = v.texture
complexes[k] = v.complex
if v.texture then
textures_rev[v.texture] = k
end
if v.entrancePortal then
entrancePortals_zone[k] = v.entrancePortal[1]
entrancePortals_x[k] = v.entrancePortal[2]
entrancePortals_y[k] = v.entrancePortal[3]
end
end
zones = nil
 
PLAYER_LEVEL_UP(Tourist)
end
EasyDaily/libs/LibDataBroker-1.1/README.textile New file
0,0 → 1,13
LibDataBroker is a small WoW addon library designed to provide a "MVC":http://en.wikipedia.org/wiki/Model-view-controller interface for use in various addons.
LDB's primary goal is to "detach" plugins for TitanPanel and FuBar from the display addon.
Plugins can provide data into a simple table, and display addons can receive callbacks to refresh their display of this data.
LDB also provides a place for addons to register "quicklaunch" functions, removing the need for authors to embed many large libraries to create minimap buttons.
Users who do not wish to be "plagued" by these buttons simply do not install an addon to render them.
 
Due to it's simple generic design, LDB can be used for any design where you wish to have an addon notified of changes to a table.
 
h2. Links
 
* "API documentation":http://github.com/tekkub/libdatabroker-1-1/wikis/api
* "Data specifications":http://github.com/tekkub/libdatabroker-1-1/wikis/data-specifications
* "Addons using LDB":http://github.com/tekkub/libdatabroker-1-1/wikis/addons-using-ldb
EasyDaily/libs/LibDataBroker-1.1/LibDataBroker-1.1.lua New file
0,0 → 1,90
 
assert(LibStub, "LibDataBroker-1.1 requires LibStub")
assert(LibStub:GetLibrary("CallbackHandler-1.0", true), "LibDataBroker-1.1 requires CallbackHandler-1.0")
 
local lib, oldminor = LibStub:NewLibrary("LibDataBroker-1.1", 4)
if not lib then return end
oldminor = oldminor or 0
 
 
lib.callbacks = lib.callbacks or LibStub:GetLibrary("CallbackHandler-1.0"):New(lib)
lib.attributestorage, lib.namestorage, lib.proxystorage = lib.attributestorage or {}, lib.namestorage or {}, lib.proxystorage or {}
local attributestorage, namestorage, callbacks = lib.attributestorage, lib.namestorage, lib.callbacks
 
if oldminor < 2 then
lib.domt = {
__metatable = "access denied",
__index = function(self, key) return attributestorage[self] and attributestorage[self][key] end,
}
end
 
if oldminor < 3 then
lib.domt.__newindex = function(self, key, value)
if not attributestorage[self] then attributestorage[self] = {} end
if attributestorage[self][key] == value then return end
attributestorage[self][key] = value
local name = namestorage[self]
if not name then return end
callbacks:Fire("LibDataBroker_AttributeChanged", name, key, value, self)
callbacks:Fire("LibDataBroker_AttributeChanged_"..name, name, key, value, self)
callbacks:Fire("LibDataBroker_AttributeChanged_"..name.."_"..key, name, key, value, self)
callbacks:Fire("LibDataBroker_AttributeChanged__"..key, name, key, value, self)
end
end
 
if oldminor < 2 then
function lib:NewDataObject(name, dataobj)
if self.proxystorage[name] then return end
 
if dataobj then
assert(type(dataobj) == "table", "Invalid dataobj, must be nil or a table")
self.attributestorage[dataobj] = {}
for i,v in pairs(dataobj) do
self.attributestorage[dataobj][i] = v
dataobj[i] = nil
end
end
dataobj = setmetatable(dataobj or {}, self.domt)
self.proxystorage[name], self.namestorage[dataobj] = dataobj, name
self.callbacks:Fire("LibDataBroker_DataObjectCreated", name, dataobj)
return dataobj
end
end
 
if oldminor < 1 then
function lib:DataObjectIterator()
return pairs(self.proxystorage)
end
 
function lib:GetDataObjectByName(dataobjectname)
return self.proxystorage[dataobjectname]
end
 
function lib:GetNameByDataObject(dataobject)
return self.namestorage[dataobject]
end
end
 
if oldminor < 4 then
local next = pairs(attributestorage)
function lib:pairs(dataobject_or_name)
local t = type(dataobject_or_name)
assert(t == "string" or t == "table", "Usage: ldb:pairs('dataobjectname') or ldb:pairs(dataobject)")
 
local dataobj = self.proxystorage[dataobject_or_name] or dataobject_or_name
assert(attributestorage[dataobj], "Data object not found")
 
return next, attributestorage[dataobj], nil
end
 
local ipairs_iter = ipairs(attributestorage)
function lib:ipairs(dataobject_or_name)
local t = type(dataobject_or_name)
assert(t == "string" or t == "table", "Usage: ldb:ipairs('dataobjectname') or ldb:ipairs(dataobject)")
 
local dataobj = self.proxystorage[dataobject_or_name] or dataobject_or_name
assert(attributestorage[dataobj], "Data object not found")
 
return ipairs_iter, attributestorage[dataobj], 0
end
end
EasyDaily/libs/LibStub/LibStub.lua New file
0,0 → 1,30
-- LibStub is a simple versioning stub meant for use in Libraries. http://www.wowace.com/wiki/LibStub for more info
-- LibStub is hereby placed in the Public Domain Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke
local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2 -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS!
local LibStub = _G[LIBSTUB_MAJOR]
 
if not LibStub or LibStub.minor < LIBSTUB_MINOR then
LibStub = LibStub or {libs = {}, minors = {} }
_G[LIBSTUB_MAJOR] = LibStub
LibStub.minor = LIBSTUB_MINOR
 
function LibStub:NewLibrary(major, minor)
assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)")
minor = assert(tonumber(strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.")
 
local oldminor = self.minors[major]
if oldminor and oldminor >= minor then return nil end
self.minors[major], self.libs[major] = minor, self.libs[major] or {}
return self.libs[major], oldminor
end
 
function LibStub:GetLibrary(major, silent)
if not self.libs[major] and not silent then
error(("Cannot find a library instance of %q."):format(tostring(major)), 2)
end
return self.libs[major], self.minors[major]
end
 
function LibStub:IterateLibraries() return pairs(self.libs) end
setmetatable(LibStub, { __call = LibStub.GetLibrary })
end
EasyDaily/libs/LibStub/LibStub.toc New file
0,0 → 1,13
## Interface: 20400
## Title: Lib: LibStub
## Notes: Universal Library Stub
## Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel
## X-Website: http://jira.wowace.com/browse/LS
## X-Category: Library
## X-License: Public Domain
## X-Curse-Packaged-Version: 1.0
## X-Curse-Project-Name: LibStub
## X-Curse-Project-ID: libstub
## X-Curse-Repository-ID: wow/libstub/mainline
 
LibStub.lua
EasyDaily/libs/LibBabble-Zone-3.0/LibStub/LibStub.lua New file
0,0 → 1,30
-- LibStub is a simple versioning stub meant for use in Libraries. http://www.wowace.com/wiki/LibStub for more info
-- LibStub is hereby placed in the Public Domain Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke
local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2 -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS!
local LibStub = _G[LIBSTUB_MAJOR]
 
if not LibStub or LibStub.minor < LIBSTUB_MINOR then
LibStub = LibStub or {libs = {}, minors = {} }
_G[LIBSTUB_MAJOR] = LibStub
LibStub.minor = LIBSTUB_MINOR
 
function LibStub:NewLibrary(major, minor)
assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)")
minor = assert(tonumber(strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.")
 
local oldminor = self.minors[major]
if oldminor and oldminor >= minor then return nil end
self.minors[major], self.libs[major] = minor, self.libs[major] or {}
return self.libs[major], oldminor
end
 
function LibStub:GetLibrary(major, silent)
if not self.libs[major] and not silent then
error(("Cannot find a library instance of %q."):format(tostring(major)), 2)
end
return self.libs[major], self.minors[major]
end
 
function LibStub:IterateLibraries() return pairs(self.libs) end
setmetatable(LibStub, { __call = LibStub.GetLibrary })
end
EasyDaily/libs/LibBabble-Zone-3.0/LibBabble-Zone-3.0.lua New file
0,0 → 1,2140
--[[
Name: LibBabble-Zone-3.0
Revision: $Rev: 207 $
Maintainers: ckknight, nevcairiel, Ackis
Website: http://www.wowace.com/projects/libbabble-zone-3-0/
Dependencies: None
License: MIT
]]
 
local MAJOR_VERSION = "LibBabble-Zone-3.0"
local MINOR_VERSION = 90000 + tonumber(("$Rev: 207 $"):match("%d+"))
 
if not LibStub then error(MAJOR_VERSION .. " requires LibStub.") end
local lib = LibStub("LibBabble-3.0"):New(MAJOR_VERSION, MINOR_VERSION)
if not lib then return end
 
local GAME_LOCALE = GetLocale()
 
lib:SetBaseTranslations {
["Ahn'kahet: The Old Kingdom"] = "Ahn'kahet: The Old Kingdom",
["Ahn'Qiraj"] = "Ahn'Qiraj",
["Alliance Base"] = "Alliance Base",
["Alterac Mountains"] = "Alterac Mountains",
["Alterac Valley"] = "Alterac Valley",
["Amani Pass"] = "Amani Pass",
["Arathi Basin"] = "Arathi Basin",
["Arathi Highlands"] = "Arathi Highlands",
Armory = "Armory",
Ashenvale = "Ashenvale",
Auberdine = "Auberdine",
["Auchenai Crypts"] = "Auchenai Crypts",
Auchindoun = "Auchindoun",
Azeroth = "Azeroth",
["Azjol-Nerub"] = "Azjol-Nerub",
Azshara = "Azshara",
["Azuremyst Isle"] = "Azuremyst Isle",
Badlands = "Badlands",
["Bash'ir Landing"] = "Bash'ir Landing",
["Blackfathom Deeps"] = "Blackfathom Deeps",
["Blackrock Depths"] = "Blackrock Depths",
["Blackrock Mountain"] = "Blackrock Mountain",
["Blackrock Spire"] = "Blackrock Spire",
["Black Temple"] = "Black Temple",
["Blackwing Lair"] = "Blackwing Lair",
["Blade's Edge Arena"] = "Blade's Edge Arena",
["Blade's Edge Mountains"] = "Blade's Edge Mountains",
["Blasted Lands"] = "Blasted Lands",
["Bloodmyst Isle"] = "Bloodmyst Isle",
["Booty Bay"] = "Booty Bay",
["Borean Tundra"] = "Borean Tundra",
["Burning Steppes"] = "Burning Steppes",
Cathedral = "Cathedral",
["Caverns of Time"] = "Caverns of Time",
["Champions' Hall"] = "Champions' Hall",
["Coilfang Reservoir"] = "Coilfang Reservoir",
Coldarra = "Coldarra",
["Cosmic map"] = "Cosmic map",
["Crystalsong Forest"] = "Crystalsong Forest",
["Crystal Spine"] = "Crystal Spine",
Dalaran = "Dalaran",
["Dalaran Arena"] = "Dalaran Arena",
["Dalaran Sewers"] = "Dalaran Sewers",
["Darkmoon Faire"] = "Darkmoon Faire",
Darkshore = "Darkshore",
Darnassus = "Darnassus",
["Deadwind Pass"] = "Deadwind Pass",
["Deeprun Tram"] = "Deeprun Tram",
Desolace = "Desolace",
["Dire Maul"] = "Dire Maul",
["Dire Maul (East)"] = "Dire Maul (East)",
["Dire Maul (North)"] = "Dire Maul (North)",
["Dire Maul (West)"] = "Dire Maul (West)",
Dragonblight = "Dragonblight",
["Drak'Tharon Keep"] = "Drak'Tharon Keep",
["Dun Morogh"] = "Dun Morogh",
Durotar = "Durotar",
Duskwood = "Duskwood",
["Dustwallow Marsh"] = "Dustwallow Marsh",
["Eastern Kingdoms"] = "Eastern Kingdoms",
["Eastern Plaguelands"] = "Eastern Plaguelands",
["Elwynn Forest"] = "Elwynn Forest",
Everlook = "Everlook",
["Eversong Woods"] = "Eversong Woods",
["Eye of the Storm"] = "Eye of the Storm",
Felwood = "Felwood",
Feralas = "Feralas",
["Forge Camp: Terror"] = "Forge Camp: Terror",
["Forge Camp: Wrath"] = "Forge Camp: Wrath",
["Frostwyrm Lair"] = "Frostwyrm Lair",
["Furywing's Perch"] = "Furywing's Perch",
Gadgetzan = "Gadgetzan",
["Gates of Ahn'Qiraj"] = "Gates of Ahn'Qiraj",
Ghostlands = "Ghostlands",
Gnomeregan = "Gnomeregan",
Graveyard = "Graveyard",
["Grizzly Hills"] = "Grizzly Hills",
["Grom'gol Base Camp"] = "Grom'gol Base Camp",
["Gruul's Lair"] = "Gruul's Lair",
Gundrak = "Gundrak",
["Hall of Champions"] = "Hall of Champions",
["Hall of Legends"] = "Hall of Legends",
["Halls of Lightning"] = "Halls of Lightning",
["Halls of Stone"] = "Halls of Stone",
["Hellfire Citadel"] = "Hellfire Citadel",
["Hellfire Peninsula"] = "Hellfire Peninsula",
["Hellfire Ramparts"] = "Hellfire Ramparts",
["Hillsbrad Foothills"] = "Hillsbrad Foothills",
["Horde Encampment"] = "Horde Encampment",
["Howling Fjord"] = "Howling Fjord",
Hyjal = "Hyjal",
["Hyjal Summit"] = "Hyjal Summit",
Icecrown = "Icecrown",
["Icecrown Citadel"] = "Icecrown Citadel",
["Insidion's Perch"] = "Insidion's Perch",
Ironforge = "Ironforge",
["Isle of Quel'Danas"] = "Isle of Quel'Danas",
Kalimdor = "Kalimdor",
Karazhan = "Karazhan",
["Krasus' Landing"] = "Krasus' Landing",
Library = "Library",
["Loch Modan"] = "Loch Modan",
["Lower Blackrock Spire"] = "Lower Blackrock Spire",
["Magisters' Terrace"] = "Magisters' Terrace",
["Magtheridon's Lair"] = "Magtheridon's Lair",
["Mana-Tombs"] = "Mana-Tombs",
Maraudon = "Maraudon",
["Menethil Harbor"] = "Menethil Harbor",
["Molten Core"] = "Molten Core",
Moonglade = "Moonglade",
Mulgore = "Mulgore",
Nagrand = "Nagrand",
["Nagrand Arena"] = "Nagrand Arena",
Naxxramas = "Naxxramas",
Netherstorm = "Netherstorm",
["Night Elf Village"] = "Night Elf Village",
Northrend = "Northrend",
["Obsidia's Perch"] = "Obsidia's Perch",
["Ogri'la"] = "Ogri'la",
["Old Hillsbrad Foothills"] = "Old Hillsbrad Foothills",
["Old Stratholme"] = "Old Stratholme",
["Onyxia's Lair"] = "Onyxia's Lair",
Orgrimmar = "Orgrimmar",
Outland = "Outland",
["Plaguelands: The Scarlet Enclave"] = "Plaguelands: The Scarlet Enclave",
Plaguewood = "Plaguewood",
["Quel'thalas"] = "Quel'thalas",
["Ragefire Chasm"] = "Ragefire Chasm",
Ratchet = "Ratchet",
["Razorfen Downs"] = "Razorfen Downs",
["Razorfen Kraul"] = "Razorfen Kraul",
["Redridge Mountains"] = "Redridge Mountains",
["Ring of Observance"] = "Ring of Observance",
["Rivendark's Perch"] = "Rivendark's Perch",
["Ruins of Ahn'Qiraj"] = "Ruins of Ahn'Qiraj",
["Ruins of Lordaeron"] = "Ruins of Lordaeron",
["Scarlet Monastery"] = "Scarlet Monastery",
Scholomance = "Scholomance",
["Searing Gorge"] = "Searing Gorge",
["Serpentshrine Cavern"] = "Serpentshrine Cavern",
["Sethekk Halls"] = "Sethekk Halls",
["Shadowfang Keep"] = "Shadowfang Keep",
["Shadow Labyrinth"] = "Shadow Labyrinth",
["Shadowmoon Valley"] = "Shadowmoon Valley",
["Shartuul's Transporter"] = "Shartuul's Transporter",
Shattrath = "Shattrath",
["Shattrath City"] = "Shattrath City",
["Sholazar Basin"] = "Sholazar Basin",
Silithus = "Silithus",
["Silvermoon City"] = "Silvermoon City",
["Silverpine Forest"] = "Silverpine Forest",
["Skyguard Outpost"] = "Skyguard Outpost",
Stonard = "Stonard",
["Stonetalon Mountains"] = "Stonetalon Mountains",
Stormwind = "Stormwind",
["Stormwind City"] = "Stormwind City",
["Strand of the Ancients"] = "Strand of the Ancients",
["Stranglethorn Vale"] = "Stranglethorn Vale",
Stratholme = "Stratholme",
["Sunken Temple"] = "Sunken Temple",
["Sunwell Plateau"] = "Sunwell Plateau",
["Swamp of Sorrows"] = "Swamp of Sorrows",
Tanaris = "Tanaris",
Teldrassil = "Teldrassil",
["Tempest Keep"] = "Tempest Keep",
["Temple of Ahn'Qiraj"] = "Temple of Ahn'Qiraj",
["Terokkar Forest"] = "Terokkar Forest",
["The Arachnid Quarter"] = "The Arachnid Quarter",
["The Arcatraz"] = "The Arcatraz",
["The Barrens"] = "The Barrens",
["The Black Morass"] = "The Black Morass",
["The Blood Furnace"] = "The Blood Furnace",
["The Bone Wastes"] = "The Bone Wastes",
["The Botanica"] = "The Botanica",
["The Construct Quarter"] = "The Construct Quarter",
["The Culling of Stratholme"] = "The Culling of Stratholme",
["The Dark Portal"] = "The Dark Portal",
["The Deadmines"] = "The Deadmines",
["The Descent into Madness"] = "The Descent into Madness",
["The Exodar"] = "The Exodar",
["The Eye"] = "The Eye",
["The Eye of Eternity"] = "The Eye of Eternity",
["The Forbidding Sea"] = "The Forbidding Sea",
["The Frozen Sea"] = "The Frozen Sea",
["The Great Sea"] = "The Great Sea",
["The Hinterlands"] = "The Hinterlands",
["The Mechanar"] = "The Mechanar",
["The Military Quarter"] = "The Military Quarter",
["The Nexus"] = "The Nexus",
["The North Sea"] = "The North Sea",
["The Obsidian Sanctum"] = "The Obsidian Sanctum",
["The Oculus"] = "The Oculus",
["The Plague Quarter"] = "The Plague Quarter",
["Theramore Isle"] = "Theramore Isle",
["The Ring of Valor"] = "The Ring of Valor",
["The Shattered Halls"] = "The Shattered Halls",
["The Slave Pens"] = "The Slave Pens",
["The Spark of Imagination"] = "The Spark of Imagination",
["The Steamvault"] = "The Steamvault",
["The Stockade"] = "The Stockade",
["The Storm Peaks"] = "The Storm Peaks",
["The Temple of Atal'Hakkar"] = "The Temple of Atal'Hakkar",
["The Underbog"] = "The Underbog",
["The Veiled Sea"] = "The Veiled Sea",
["The Violet Hold"] = "The Violet Hold",
["Thousand Needles"] = "Thousand Needles",
["Thunder Bluff"] = "Thunder Bluff",
Tirisfal = "Tirisfal",
["Tirisfal Glades"] = "Tirisfal Glades",
["Twisting Nether"] = "Twisting Nether",
Uldaman = "Uldaman",
Ulduar = "Ulduar",
Undercity = "Undercity",
["Un'Goro Crater"] = "Un'Goro Crater",
["Upper Blackrock Spire"] = "Upper Blackrock Spire",
["Utgarde Keep"] = "Utgarde Keep",
["Utgarde Pinnacle"] = "Utgarde Pinnacle",
["Vault of Archavon"] = "Vault of Archavon",
["Vortex Pinnacle"] = "Vortex Pinnacle",
["Wailing Caverns"] = "Wailing Caverns",
["Warsong Gulch"] = "Warsong Gulch",
["Western Plaguelands"] = "Western Plaguelands",
Westfall = "Westfall",
Wetlands = "Wetlands",
Wintergrasp = "Wintergrasp",
Winterspring = "Winterspring",
["Wyrmrest Temple"] = "Wyrmrest Temple",
Zangarmarsh = "Zangarmarsh",
["Zul'Aman"] = "Zul'Aman",
["Zul'Drak"] = "Zul'Drak",
["Zul'Farrak"] = "Zul'Farrak",
["Zul'Gurub"] = "Zul'Gurub",
}
 
 
if GAME_LOCALE == "enUS" then
lib:SetCurrentTranslations(true)
elseif GAME_LOCALE == "deDE" then
lib:SetCurrentTranslations {
["Ahn'kahet: The Old Kingdom"] = "Ahn'kahet: Das Alte Königreich",
["Ahn'Qiraj"] = "Ahn'Qiraj",
["Alliance Base"] = "Basis der Allianz",
["Alterac Mountains"] = "Alteracgebirge",
["Alterac Valley"] = "Alteractal",
["Amani Pass"] = "Amanipass",
["Arathi Basin"] = "Arathibecken",
["Arathi Highlands"] = "Arathihochland",
Armory = "Waffenkammer",
Ashenvale = "Eschental",
Auberdine = "Auberdine",
["Auchenai Crypts"] = "Auchenaikrypta",
Auchindoun = "Auchindoun",
Azeroth = "Azeroth",
["Azjol-Nerub"] = "Azjol-Nerub",
Azshara = "Azshara",
["Azuremyst Isle"] = "Azurmythosinsel",
Badlands = "Ödland",
["Bash'ir Landing"] = "Landeplatz von Bash'ir",
["Blackfathom Deeps"] = "Tiefschwarze Grotte",
["Blackrock Depths"] = "Schwarzfelstiefen",
["Blackrock Mountain"] = "Der Schwarzfels",
["Blackrock Spire"] = "Schwarzfelsspitze",
["Black Temple"] = "Der Schwarze Tempel",
["Blackwing Lair"] = "Pechschwingenhort",
["Blade's Edge Arena"] = "Arena des Schergrats",
["Blade's Edge Mountains"] = "Schergrat",
["Blasted Lands"] = "Verwüstete Lande",
["Bloodmyst Isle"] = "Blutmythosinsel",
["Booty Bay"] = "Beutebucht",
["Borean Tundra"] = "Boreanische Tundra",
["Burning Steppes"] = "Brennende Steppe",
Cathedral = "Kathedrale",
["Caverns of Time"] = "Die Höhlen der Zeit",
["Champions' Hall"] = "Halle der Champions",
["Coilfang Reservoir"] = "Der Echsenkessel",
Coldarra = "Kaltarra",
["Cosmic map"] = "Kosmische Karte",
["Crystalsong Forest"] = "Kristallsangwald",
["Crystal Spine"] = "Kristallrücken",
Dalaran = "Dalaran",
["Dalaran Arena"] = "Arena von Dalaran",
["Dalaran Sewers"] = "Arena von Dalaran",
["Darkmoon Faire"] = "Dunkelmond-Jahrmarkt",
Darkshore = "Dunkelküste",
Darnassus = "Darnassus",
["Deadwind Pass"] = "Gebirgspass der Totenwinde",
["Deeprun Tram"] = "Die Tiefenbahn",
Desolace = "Desolace",
["Dire Maul"] = "Düsterbruch",
["Dire Maul (East)"] = "Düsterbruch (Ost)",
["Dire Maul (North)"] = "Düsterbruch (Nord)",
["Dire Maul (West)"] = "Düsterbruch (West)",
Dragonblight = "Drachenöde",
["Drak'Tharon Keep"] = "Feste Drak'Tharon",
["Dun Morogh"] = "Dun Morogh",
Durotar = "Durotar",
Duskwood = "Dämmerwald",
["Dustwallow Marsh"] = "Düstermarschen",
["Eastern Kingdoms"] = "Östliche Königreiche",
["Eastern Plaguelands"] = "Östliche Pestländer",
["Elwynn Forest"] = "Wald von Elwynn",
Everlook = "Ewige Warte",
["Eversong Woods"] = "Immersangwald",
["Eye of the Storm"] = "Auge des Sturms",
Felwood = "Teufelswald",
Feralas = "Feralas",
["Forge Camp: Terror"] = "Konstruktionslager: Terror",
["Forge Camp: Wrath"] = "Konstruktionslager: Wut",
["Frostwyrm Lair"] = "Frostwyrm Lair", -- Needs review
["Furywing's Perch"] = "Isidions Hort",
Gadgetzan = "Gadgetzan",
["Gates of Ahn'Qiraj"] = "Tore von Ahn'Qiraj",
Ghostlands = "Geisterlande",
Gnomeregan = "Gnomeregan",
Graveyard = "Friedhof",
["Grizzly Hills"] = "Grizzlyhügel",
["Grom'gol Base Camp"] = "Basislager von Grom'gol",
["Gruul's Lair"] = "Gruuls Unterschlupf",
Gundrak = "Gundrak",
["Hall of Champions"] = "Halle der Champions",
["Hall of Legends"] = "Halle der Legenden",
["Halls of Lightning"] = "Die Hallen der Blitze",
["Halls of Stone"] = "Die Hallen des Steins",
["Hellfire Citadel"] = "Höllenfeuerzitadelle",
["Hellfire Peninsula"] = "Höllenfeuerhalbinsel",
["Hellfire Ramparts"] = "Höllenfeuerbollwerk",
["Hillsbrad Foothills"] = "Vorgebirge des Hügellands",
["Horde Encampment"] = "Lager der Horde",
["Howling Fjord"] = "Der heulende Fjord",
Hyjal = "Hyjal",
["Hyjal Summit"] = "Hyjalgipfel",
Icecrown = "Eiskrone",
["Icecrown Citadel"] = "Eiskronenzitadelle",
["Insidion's Perch"] = "Isidions Hort",
Ironforge = "Eisenschmiede",
["Isle of Quel'Danas"] = "Insel von Quel'Danas",
Kalimdor = "Kalimdor",
Karazhan = "Karazhan",
["Krasus' Landing"] = "Krasus' Landeplatz",
Library = "Bibliothek",
["Loch Modan"] = "Loch Modan",
["Lower Blackrock Spire"] = "Untere Schwarzfelsspitze",
["Magisters' Terrace"] = "Terrasse der Magister",
["Magtheridon's Lair"] = "Magtheridons Kammer",
["Mana-Tombs"] = "Managruft",
Maraudon = "Maraudon",
["Menethil Harbor"] = "Hafen von Menethil",
["Molten Core"] = "Geschmolzener Kern",
Moonglade = "Mondlichtung",
Mulgore = "Mulgore",
Nagrand = "Nagrand",
["Nagrand Arena"] = "Arena von Nagrand",
Naxxramas = "Naxxramas",
Netherstorm = "Nethersturm",
["Night Elf Village"] = "Nachtelfen Dorf",
Northrend = "Nordend",
["Obsidia's Perch"] = "Obsidias Hort",
["Ogri'la"] = "Ogri'la",
["Old Hillsbrad Foothills"] = "Vorgebirge des Alten Hügellands",
["Old Stratholme"] = "Alt-Stratholme",
["Onyxia's Lair"] = "Onyxias Hort",
Orgrimmar = "Orgrimmar",
Outland = "Scherbenwelt",
["Plaguelands: The Scarlet Enclave"] = "Pestländer: Die Scharlachrote Enklave",
Plaguewood = "Seuchenwald",
["Quel'thalas"] = "Quel'Thalas",
["Ragefire Chasm"] = "Der Flammenschlund",
Ratchet = "Ratschet",
["Razorfen Downs"] = "Hügel der Klingenhauer",
["Razorfen Kraul"] = "Kral der Klingenhauer",
["Redridge Mountains"] = "Rotkammgebirge",
["Ring of Observance"] = "Ring der Beobachtung",
["Rivendark's Perch"] = "Nachtreißers Hort",
["Ruins of Ahn'Qiraj"] = "Ruinen von Ahn'Qiraj",
["Ruins of Lordaeron"] = "Ruinen von Lordaeron",
["Scarlet Monastery"] = "Das Scharlachrote Kloster",
Scholomance = "Scholomance",
["Searing Gorge"] = "Sengende Schlucht",
["Serpentshrine Cavern"] = "Höhle des Schlangenschreins",
["Sethekk Halls"] = "Sethekkhallen",
["Shadowfang Keep"] = "Burg Schattenfang",
["Shadow Labyrinth"] = "Schattenlabyrinth",
["Shadowmoon Valley"] = "Schattenmondtal",
["Shartuul's Transporter"] = "Shartuuls Transporter",
Shattrath = "Shattrath",
["Shattrath City"] = "Shattrath",
["Sholazar Basin"] = "Sholazarbecken",
Silithus = "Silithus",
["Silvermoon City"] = "Silbermond",
["Silverpine Forest"] = "Silberwald",
["Skyguard Outpost"] = "Außenposten der Himmelswache",
Stonard = "Steinard",
["Stonetalon Mountains"] = "Steinkrallengebirge",
Stormwind = "Sturmwind",
["Stormwind City"] = "Sturmwind",
["Strand of the Ancients"] = "Strand der Uralten",
["Stranglethorn Vale"] = "Schlingendorntal",
Stratholme = "Stratholme",
["Sunken Temple"] = "Versunkener Tempel",
["Sunwell Plateau"] = "Sonnenbrunnenplateau",
["Swamp of Sorrows"] = "Sümpfe des Elends",
Tanaris = "Tanaris",
Teldrassil = "Teldrassil",
["Tempest Keep"] = "Festung der Stürme",
["Temple of Ahn'Qiraj"] = "Tempel von Ahn'Qiraj",
["Terokkar Forest"] = "Wälder von Terokkar",
["The Arachnid Quarter"] = "Das Arachnidenviertel",
["The Arcatraz"] = "Die Arkatraz",
["The Barrens"] = "Brachland",
["The Black Morass"] = "Der schwarze Morast",
["The Blood Furnace"] = "Der Blutkessel",
["The Bone Wastes"] = "Die Knochenwüste",
["The Botanica"] = "Die Botanika",
["The Construct Quarter"] = "Das Konstruktviertel",
["The Culling of Stratholme"] = "Das Ausmerzen von Stratholme",
["The Dark Portal"] = "Das Dunkle Portal",
["The Deadmines"] = "Die Todesminen",
["The Descent into Madness"] = "Der Abstieg in den Wahnsinn",
["The Exodar"] = "Die Exodar",
["The Eye"] = "Das Auge",
["The Eye of Eternity"] = "Das Auge der Ewigkeit",
["The Forbidding Sea"] = "Das verbotene Meer",
["The Frozen Sea"] = "Die gefrorene See",
["The Great Sea"] = "Das große Meer",
["The Hinterlands"] = "Hinterland",
["The Mechanar"] = "Die Mechanar",
["The Military Quarter"] = "Das Militärviertel",
["The Nexus"] = "Der Nexus",
["The North Sea"] = "Das nördliche Meer",
["The Obsidian Sanctum"] = "Das Obsidiansanktum",
["The Oculus"] = "Das Oculus",
["The Plague Quarter"] = "Das Seuchenviertel",
["Theramore Isle"] = "Insel Theramore",
["The Ring of Valor"] = "Der Ring der Ehre",
["The Shattered Halls"] = "Die zerschmetterten Hallen",
["The Slave Pens"] = "Die Sklavenunterkünfte",
["The Spark of Imagination"] = "Der Funke der Imagination",
["The Steamvault"] = "Die Dampfkammer",
["The Stockade"] = "Das Verlies",
["The Storm Peaks"] = "Die Sturmgipfel",
["The Temple of Atal'Hakkar"] = "Der Tempel von Atal'Hakkar",
["The Underbog"] = "Der Tiefensumpf",
["The Veiled Sea"] = "Das verhüllte Meer",
["The Violet Hold"] = "Die Violette Festung",
["Thousand Needles"] = "Tausend Nadeln",
["Thunder Bluff"] = "Donnerfels",
Tirisfal = "Tirisfal",
["Tirisfal Glades"] = "Tirisfal",
["Twisting Nether"] = "Wirbelnder Nether",
Uldaman = "Uldaman",
Ulduar = "Ulduar",
Undercity = "Unterstadt",
["Un'Goro Crater"] = "Krater von Un'Goro",
["Upper Blackrock Spire"] = "Obere Schwarzfelsspitze",
["Utgarde Keep"] = "Burg Utgarde",
["Utgarde Pinnacle"] = "Turm Utgarde",
["Vault of Archavon"] = "Archavons Kammer",
["Vortex Pinnacle"] = "Vortexgipfel",
["Wailing Caverns"] = "Die Höhlen des Wehklagens",
["Warsong Gulch"] = "Kriegshymnenschlucht",
["Western Plaguelands"] = "Westliche Pestländer",
Westfall = "Westfall",
Wetlands = "Sumpfland",
Wintergrasp = "Tausendwintersee",
Winterspring = "Winterquell",
["Wyrmrest Temple"] = "Wyrmruhtempel",
Zangarmarsh = "Zangarmarschen",
["Zul'Aman"] = "Zul'Aman",
["Zul'Drak"] = "Zul'Drak",
["Zul'Farrak"] = "Zul'Farrak",
["Zul'Gurub"] = "Zul'Gurub",
}
elseif GAME_LOCALE == "frFR" then
lib:SetCurrentTranslations {
["Ahn'kahet: The Old Kingdom"] = "Ahn'kahet : l'Ancien royaume",
["Ahn'Qiraj"] = "Ahn'Qiraj",
["Alliance Base"] = "Base de l'Alliance",
["Alterac Mountains"] = "Montagnes d'Alterac",
["Alterac Valley"] = "Vallée d'Alterac",
["Amani Pass"] = "Passage des Amani",
["Arathi Basin"] = "Bassin d'Arathi",
["Arathi Highlands"] = "Hautes-terres d'Arathi",
Armory = "Armurerie",
Ashenvale = "Orneval",
Auberdine = "Auberdine",
["Auchenai Crypts"] = "Cryptes Auchenaï",
Auchindoun = "Auchindoun",
Azeroth = "Azeroth",
["Azjol-Nerub"] = "Azjol-Nérub",
Azshara = "Azshara",
["Azuremyst Isle"] = "Île de Brume-azur",
Badlands = "Terres ingrates",
["Bash'ir Landing"] = "Point d'ancrage de Bash'ir",
["Blackfathom Deeps"] = "Profondeurs de Brassenoire",
["Blackrock Depths"] = "Profondeurs de Rochenoire",
["Blackrock Mountain"] = "Mont Rochenoire",
["Blackrock Spire"] = "Pic Rochenoire",
["Black Temple"] = "Temple noir",
["Blackwing Lair"] = "Repaire de l'Aile noire",
["Blade's Edge Arena"] = "Arène des Tranchantes",
["Blade's Edge Mountains"] = "Les Tranchantes",
["Blasted Lands"] = "Terres foudroyées",
["Bloodmyst Isle"] = "Île de Brume-sang",
["Booty Bay"] = "Baie-du-Butin",
["Borean Tundra"] = "Toundra Boréenne",
["Burning Steppes"] = "Steppes ardentes",
Cathedral = "Cathédrale",
["Caverns of Time"] = "Grottes du temps",
["Champions' Hall"] = "Hall des Champions",
["Coilfang Reservoir"] = "Réservoir de Glissecroc",
Coldarra = "Frimarra",
["Cosmic map"] = "Carte cosmique",
["Crystalsong Forest"] = "Forêt du Chant de cristal",
["Crystal Spine"] = "Éperon de cristal",
Dalaran = "Dalaran",
["Dalaran Arena"] = "Arène de Dalaran",
["Dalaran Sewers"] = "Égouts de Dalaran",
["Darkmoon Faire"] = "Foire de Sombrelune",
Darkshore = "Sombrivage",
Darnassus = "Darnassus",
["Deadwind Pass"] = "Défilé de Deuillevent",
["Deeprun Tram"] = "Tram des profondeurs",
Desolace = "Désolace",
["Dire Maul"] = "Hache-tripes",
["Dire Maul (East)"] = "Hache-tripes (Est)",
["Dire Maul (North)"] = "Hache-tripes (Nord)",
["Dire Maul (West)"] = "Hache-tripes (Ouest)",
Dragonblight = "Désolation des dragons",
["Drak'Tharon Keep"] = "Donjon de Drak'Tharon",
["Dun Morogh"] = "Dun Morogh",
Durotar = "Durotar",
Duskwood = "Bois de la Pénombre",
["Dustwallow Marsh"] = "Marécage d'Âprefange",
["Eastern Kingdoms"] = "Royaumes de l'est",
["Eastern Plaguelands"] = "Maleterres de l'est",
["Elwynn Forest"] = "Forêt d'Elwynn",
Everlook = "Long-guet",
["Eversong Woods"] = "Bois des Chants éternels",
["Eye of the Storm"] = "L'Œil du cyclone",
Felwood = "Gangrebois",
Feralas = "Féralas",
["Forge Camp: Terror"] = "Camp de forge : Terreur",
["Forge Camp: Wrath"] = "Camp de forge : Courroux",
["Frostwyrm Lair"] = "Repaire du wyrm de givre",
["Furywing's Perch"] = "Perchoir d'Aile-furie",
Gadgetzan = "Gadgetzan",
["Gates of Ahn'Qiraj"] = "Portes d'Ahn'Qiraj",
Ghostlands = "Les Terres fantômes",
Gnomeregan = "Gnomeregan",
Graveyard = "Cimetière",
["Grizzly Hills"] = "Les Grisonnes",
["Grom'gol Base Camp"] = "Campement Grom'gol",
["Gruul's Lair"] = "Repaire de Gruul",
Gundrak = "Gundrak",
["Hall of Champions"] = "Hall des Champions",
["Hall of Legends"] = "Hall des Légendes",
["Halls of Lightning"] = "Les salles de Foudre",
["Halls of Stone"] = "Les salles de Pierre",
["Hellfire Citadel"] = "Citadelle des Flammes infernales",
["Hellfire Peninsula"] = "Péninsule des Flammes infernales",
["Hellfire Ramparts"] = "Remparts des Flammes infernales",
["Hillsbrad Foothills"] = "Contreforts de Hautebrande",
["Horde Encampment"] = "Campement de la Horde",
["Howling Fjord"] = "Fjord Hurlant",
Hyjal = "Hyjal",
["Hyjal Summit"] = "Sommet d'Hyjal",
Icecrown = "La Couronne de glace",
["Icecrown Citadel"] = "Citadelle de la Couronne de glace",
["Insidion's Perch"] = "Perchoir d'Insidion",
Ironforge = "Forgefer",
["Isle of Quel'Danas"] = "Île de Quel'Danas",
Kalimdor = "Kalimdor",
Karazhan = "Karazhan",
["Krasus' Landing"] = "Aire de Krasus",
Library = "Bibliothèque",
["Loch Modan"] = "Loch Modan",
["Lower Blackrock Spire"] = "Pic de Rochenoire inférieur",
["Magisters' Terrace"] = "Terrasse des Magistères",
["Magtheridon's Lair"] = "Le repaire de Magtheridon",
["Mana-Tombs"] = "Tombes-mana",
Maraudon = "Maraudon",
["Menethil Harbor"] = "Port de Menethil",
["Molten Core"] = "Cœur du Magma",
Moonglade = "Reflet-de-Lune",
Mulgore = "Mulgore",
Nagrand = "Nagrand",
["Nagrand Arena"] = "Arène de Nagrand",
Naxxramas = "Naxxramas",
Netherstorm = "Raz-de-Néant",
["Night Elf Village"] = "Village elfe de la nuit",
Northrend = "Norfendre",
["Obsidia's Perch"] = "Perchoir d'Obsidia",
["Ogri'la"] = "Ogri'la",
["Old Hillsbrad Foothills"] = "Contreforts de Hautebrande d'antan",
["Old Stratholme"] = "L'Épuration de Stratholme",
["Onyxia's Lair"] = "Repaire d'Onyxia",
Orgrimmar = "Orgrimmar",
Outland = "Outreterre",
["Plaguelands: The Scarlet Enclave"] = "Maleterres : l'enclave Écarlate",
Plaguewood = "Pestebois",
["Quel'thalas"] = "Quel'thalas",
["Ragefire Chasm"] = "Gouffre de Ragefeu",
Ratchet = "Cabestan",
["Razorfen Downs"] = "Souilles de Tranchebauge",
["Razorfen Kraul"] = "Kraal de Tranchebauge",
["Redridge Mountains"] = "Les Carmines",
["Ring of Observance"] = "Cercle d'observance",
["Rivendark's Perch"] = "Perchoir de Clivenuit",
["Ruins of Ahn'Qiraj"] = "Ruines d'Ahn'Qiraj",
["Ruins of Lordaeron"] = "Ruines de Lordaeron",
["Scarlet Monastery"] = "Monastère écarlate",
Scholomance = "Scholomance",
["Searing Gorge"] = "Gorge des Vents brûlants",
["Serpentshrine Cavern"] = "Caverne du sanctuaire du Serpent",
["Sethekk Halls"] = "Les salles des Sethekk",
["Shadowfang Keep"] = "Donjon d'Ombrecroc",
["Shadow Labyrinth"] = "Labyrinthe des ombres",
["Shadowmoon Valley"] = "Vallée d'Ombrelune",
["Shartuul's Transporter"] = "Transporteur de Shartuul",
Shattrath = "Shattrath",
["Shattrath City"] = "Shattrath",
["Sholazar Basin"] = "Bassin de Sholazar",
Silithus = "Silithus",
["Silvermoon City"] = "Lune-d'argent",
["Silverpine Forest"] = "Forêt des Pins argentés",
["Skyguard Outpost"] = "Avant-poste de la Garde-ciel",
Stonard = "Pierrêche",
["Stonetalon Mountains"] = "Les Serres-Rocheuses",
Stormwind = "Hurlevent",
["Stormwind City"] = "Hurlevent",
["Strand of the Ancients"] = "Rivage des anciens",
["Stranglethorn Vale"] = "Vallée de Strangleronce",
Stratholme = "Stratholme",
["Sunken Temple"] = "Temple englouti",
["Sunwell Plateau"] = "Plateau du Puits de soleil",
["Swamp of Sorrows"] = "Marais des Chagrins",
Tanaris = "Tanaris",
Teldrassil = "Teldrassil",
["Tempest Keep"] = "Donjon de la Tempête",
["Temple of Ahn'Qiraj"] = "Le temple d'Ahn'Qiraj",
["Terokkar Forest"] = "Forêt de Terokkar",
["The Arachnid Quarter"] = "Le quartier des Arachnides",
["The Arcatraz"] = "L'Arcatraz",
["The Barrens"] = "Les Tarides",
["The Black Morass"] = "Le Noir Marécage",
["The Blood Furnace"] = "La Fournaise du sang",
["The Bone Wastes"] = "Le désert des Ossements",
["The Botanica"] = "La Botanica",
["The Construct Quarter"] = "Le quartier des Assemblages",
["The Culling of Stratholme"] = "L'Épuration de Stratholme",
["The Dark Portal"] = "La Porte des ténèbres",
["The Deadmines"] = "Les Mortemines",
["The Descent into Madness"] = "La Descente dans la folie",
["The Exodar"] = "L'Exodar",
["The Eye"] = "L'Œil",
["The Eye of Eternity"] = "L'Œil de l'éternité",
["The Forbidding Sea"] = "La Mer interdite",
["The Frozen Sea"] = "La mer Gelée",
["The Great Sea"] = "La Grande mer",
["The Hinterlands"] = "Les Hinterlands",
["The Mechanar"] = "Le Méchanar",
["The Military Quarter"] = "Le quartier Militaire",
["The Nexus"] = "Le Nexus",
["The North Sea"] = "La mer Boréale",
["The Obsidian Sanctum"] = "Le sanctum Obsidien",
["The Oculus"] = "L'Oculus",
["The Plague Quarter"] = "Le quartier de la Peste",
["Theramore Isle"] = "Ile de Theramore",
["The Ring of Valor"] = "L'Arène des valeureux",
["The Shattered Halls"] = "Les Salles brisées",
["The Slave Pens"] = "Les enclos aux esclaves",
["The Spark of Imagination"] = "L'Étincelle d'imagination",
["The Steamvault"] = "Le Caveau de la vapeur",
["The Stockade"] = "La Prison",
["The Storm Peaks"] = "Les pics Foudroyés",
["The Temple of Atal'Hakkar"] = "Le temple d'Atal'Hakkar",
["The Underbog"] = "La Basse-tourbière",
["The Veiled Sea"] = "La Mer voilée",
["The Violet Hold"] = "Le fort Pourpre",
["Thousand Needles"] = "Mille pointes",
["Thunder Bluff"] = "Les Pitons du Tonnerre",
Tirisfal = "Tirisfal",
["Tirisfal Glades"] = "Clairières de Tirisfal",
["Twisting Nether"] = "Le Néant distordu",
Uldaman = "Uldaman",
Ulduar = "Ulduar",
Undercity = "Fossoyeuse",
["Un'Goro Crater"] = "Cratère d'Un'Goro",
["Upper Blackrock Spire"] = "Pic de Rochenoire supérieur",
["Utgarde Keep"] = "Donjon d'Utgarde",
["Utgarde Pinnacle"] = "Cime d'Utgarde",
["Vault of Archavon"] = "Caveau d'Archavon",
["Vortex Pinnacle"] = "Cime du vortex",
["Wailing Caverns"] = "Cavernes des lamentations",
["Warsong Gulch"] = "Goulet des Chanteguerres",
["Western Plaguelands"] = "Maleterres de l'ouest",
Westfall = "Marche de l'Ouest",
Wetlands = "Les Paluns",
Wintergrasp = "Joug-d'hiver",
Winterspring = "Berceau-de-l'Hiver",
["Wyrmrest Temple"] = "Temple du Repos du ver",
Zangarmarsh = "Marécage de Zangar",
["Zul'Aman"] = "Zul'Aman",
["Zul'Drak"] = "Zul'Drak",
["Zul'Farrak"] = "Zul'Farrak",
["Zul'Gurub"] = "Zul'Gurub",
}
elseif GAME_LOCALE == "koKR" then
lib:SetCurrentTranslations {
["Ahn'kahet: The Old Kingdom"] = "안카헤트: 고대 왕국",
["Ahn'Qiraj"] = "안퀴라즈",
["Alliance Base"] = "얼라이언스 주둔지",
["Alterac Mountains"] = "알터랙 산맥",
["Alterac Valley"] = "알터랙 계곡",
["Amani Pass"] = "아마니 고개",
["Arathi Basin"] = "아라시 분지",
["Arathi Highlands"] = "아라시 고원",
Armory = "무기고",
Ashenvale = "잿빛 골짜기",
Auberdine = "아우버다인",
["Auchenai Crypts"] = "아키나이 납골당",
Auchindoun = "아킨둔",
Azeroth = "아제로스",
["Azjol-Nerub"] = "아졸네룹",
Azshara = "아즈샤라",
["Azuremyst Isle"] = "하늘안개 섬",
Badlands = "황야의 땅",
["Bash'ir Landing"] = "바쉬르 영지",
["Blackfathom Deeps"] = "검은심연의 나락",
["Blackrock Depths"] = "검은바위 나락",
["Blackrock Mountain"] = "검은바위 산",
["Blackrock Spire"] = "검은바위 첨탑",
["Black Temple"] = "검은 사원",
["Blackwing Lair"] = "검은날개 둥지",
["Blade's Edge Arena"] = "칼날 투기장",
["Blade's Edge Mountains"] = "칼날 산맥",
["Blasted Lands"] = "저주받은 땅",
["Bloodmyst Isle"] = "핏빛안개 섬",
["Booty Bay"] = "무법항",
["Borean Tundra"] = "북풍의 땅",
["Burning Steppes"] = "불타는 평원",
Cathedral = "대성당",
["Caverns of Time"] = "시간의 동굴",
["Champions' Hall"] = "용사의 전당",
["Coilfang Reservoir"] = "갈퀴송곳니 저수지",
Coldarra = "콜다라",
["Cosmic map"] = "세계 지도",
["Crystalsong Forest"] = "수정노래 숲",
["Crystal Spine"] = "수정 돌기",
Dalaran = "달라란",
["Dalaran Arena"] = "달라란 투기장",
["Dalaran Sewers"] = "달라란 하수도",
["Darkmoon Faire"] = "다크문 축제",
Darkshore = "어둠의 해안",
Darnassus = "다르나서스",
["Deadwind Pass"] = "죽음의 고개",
["Deeprun Tram"] = "깊은굴 지하철",
Desolace = "잊혀진 땅",
["Dire Maul"] = "혈투의 전장",
["Dire Maul (East)"] = "혈투의 전장 동부",
["Dire Maul (North)"] = "혈투의 전장 북부",
["Dire Maul (West)"] = "혈투의 전장 서부",
Dragonblight = "용의 안식처",
["Drak'Tharon Keep"] = "드락타론 성채",
["Dun Morogh"] = "던 모로",
Durotar = "듀로타",
Duskwood = "그늘숲",
["Dustwallow Marsh"] = "먼지진흙 습지대",
["Eastern Kingdoms"] = "동부 왕국",
["Eastern Plaguelands"] = "동부 역병지대",
["Elwynn Forest"] = "엘윈 숲",
Everlook = "눈망루 마을",
["Eversong Woods"] = "영원노래 숲",
["Eye of the Storm"] = "폭풍의 눈",
Felwood = "악령의 숲",
Feralas = "페랄라스",
["Forge Camp: Terror"] = "공포의 괴철로 기지",
["Forge Camp: Wrath"] = "격노의 괴철로 기지",
["Frostwyrm Lair"] = "서리고룡의 방",
["Furywing's Perch"] = "퓨리윙의 둥지",
Gadgetzan = "가젯잔",
["Gates of Ahn'Qiraj"] = "안퀴라즈 성문",
Ghostlands = "유령의 땅",
Gnomeregan = "놈리건",
Graveyard = "묘지",
["Grizzly Hills"] = "회색 구릉지",
["Grom'gol Base Camp"] = "그롬골 주둔지",
["Gruul's Lair"] = "그룰의 둥지",
Gundrak = "군드락",
["Hall of Champions"] = "용사의 전당",
["Hall of Legends"] = "전설의 전당",
["Halls of Lightning"] = "번개의 전당",
["Halls of Stone"] = "돌의 전당",
["Hellfire Citadel"] = "지옥불 성채",
["Hellfire Peninsula"] = "지옥불 반도",
["Hellfire Ramparts"] = "지옥불 성루",
["Hillsbrad Foothills"] = "힐스브래드 구릉지",
["Horde Encampment"] = "호드 야영지",
["Howling Fjord"] = "울부짖는 협만",
Hyjal = "하이잘",
["Hyjal Summit"] = "하이잘 정상",
Icecrown = "얼음왕관",
["Icecrown Citadel"] = "얼음왕관 요새",
["Insidion's Perch"] = "인시디온의 둥지",
Ironforge = "아이언포지",
["Isle of Quel'Danas"] = "쿠엘다나스 섬",
Kalimdor = "칼림도어",
Karazhan = "카라잔",
["Krasus' Landing"] = "크라서스 착륙장",
Library = "도서관",
["Loch Modan"] = "모단 호수",
["Lower Blackrock Spire"] = "검은바위 첨탑 하층",
["Magisters' Terrace"] = "마법학자의 정원",
["Magtheridon's Lair"] = "마그테리돈의 둥지",
["Mana-Tombs"] = "마나 무덤",
Maraudon = "마라우돈",
["Menethil Harbor"] = "메네실 항구",
["Molten Core"] = "화산 심장부",
Moonglade = "달의 숲",
Mulgore = "멀고어",
Nagrand = "나그란드",
["Nagrand Arena"] = "나그란드 투기장",
Naxxramas = "낙스라마스",
Netherstorm = "황천의 폭풍",
["Night Elf Village"] = "나이트 엘프 마을",
Northrend = "노스렌드",
["Obsidia's Perch"] = "옵시디아의 둥지",
["Ogri'la"] = "오그릴라",
["Old Hillsbrad Foothills"] = "옛 힐스브래드 구릉지",
["Old Stratholme"] = "옛 스트라솔름",
["Onyxia's Lair"] = "오닉시아의 둥지",
Orgrimmar = "오그리마",
Outland = "아웃랜드",
["Plaguelands: The Scarlet Enclave"] = "동부 역병지대: 붉은십자군 초소",
Plaguewood = "역병의 숲",
["Quel'thalas"] = "쿠엘탈라스",
["Ragefire Chasm"] = "성난불길 협곡",
Ratchet = "톱니항",
["Razorfen Downs"] = "가시덩굴 구릉",
["Razorfen Kraul"] = "가시덩굴 우리",
["Redridge Mountains"] = "붉은마루 산맥",
["Ring of Observance"] = "규율의 광장",
["Rivendark's Perch"] = "리븐다크의 둥지",
["Ruins of Ahn'Qiraj"] = "안퀴라즈 폐허",
["Ruins of Lordaeron"] = "로데론의 폐허",
["Scarlet Monastery"] = "붉은십자군 수도원",
Scholomance = "스칼로맨스",
["Searing Gorge"] = "이글거리는 협곡",
["Serpentshrine Cavern"] = "불뱀 제단",
["Sethekk Halls"] = "세데크 전당",
["Shadowfang Keep"] = "그림자송곳니 성채",
["Shadow Labyrinth"] = "어둠의 미궁",
["Shadowmoon Valley"] = "어둠달 골짜기",
["Shartuul's Transporter"] = "샤툴의 순간이동기",
Shattrath = "샤트라스",
["Shattrath City"] = "샤트라스",
["Sholazar Basin"] = "숄라자르 분지",
Silithus = "실리더스",
["Silvermoon City"] = "실버문",
["Silverpine Forest"] = "은빛소나무 숲",
["Skyguard Outpost"] = "하늘경비대 전초기지",
Stonard = "스토나드",
["Stonetalon Mountains"] = "돌발톱 산맥",
Stormwind = "스톰윈드",
["Stormwind City"] = "스톰윈드",
["Strand of the Ancients"] = "고대의 해안",
["Stranglethorn Vale"] = "가시덤불 골짜기",
Stratholme = "스트라솔름",
["Sunken Temple"] = "가라앉은 사원",
["Sunwell Plateau"] = "태양샘 고원",
["Swamp of Sorrows"] = "슬픔의 늪",
Tanaris = "타나리스",
Teldrassil = "텔드랏실",
["Tempest Keep"] = "폭풍우 요새",
["Temple of Ahn'Qiraj"] = "안퀴라즈 사원",
["Terokkar Forest"] = "테로카르 숲",
["The Arachnid Quarter"] = "거미 지구",
["The Arcatraz"] = "알카트라즈",
["The Barrens"] = "불모의 땅",
["The Black Morass"] = "검은늪",
["The Blood Furnace"] = "피의 용광로",
["The Bone Wastes"] = "해골 무덤",
["The Botanica"] = "신록의 정원",
["The Construct Quarter"] = "피조물 지구",
["The Culling of Stratholme"] = "옛 스트라솔름",
["The Dark Portal"] = "어둠의 문",
["The Deadmines"] = "죽음의 폐광",
["The Descent into Madness"] = "광기의 내리막길",
["The Exodar"] = "엑소다르",
["The Eye"] = "눈",
["The Eye of Eternity"] = "영원의 눈",
["The Forbidding Sea"] = "성난폭풍 해안",
["The Frozen Sea"] = "얼어붙은 바다",
["The Great Sea"] = "대해",
["The Hinterlands"] = "동부 내륙지",
["The Mechanar"] = "메카나르",
["The Military Quarter"] = "군사 지구",
["The Nexus"] = "마력의 탑",
["The North Sea"] = "북해",
["The Obsidian Sanctum"] = "흑요석 성소",
["The Oculus"] = "마력의 눈",
["The Plague Quarter"] = "역병 지구",
["Theramore Isle"] = "테라모어 섬",
["The Ring of Valor"] = "용맹의 투기장",
["The Shattered Halls"] = "으스러진 손의 전당",
["The Slave Pens"] = "강제 노역소",
["The Spark of Imagination"] = "상상의 흔적",
["The Steamvault"] = "증기 저장고",
["The Stockade"] = "스톰윈드 지하감옥",
["The Storm Peaks"] = "폭풍우 봉우리",
["The Temple of Atal'Hakkar"] = "아탈학카르 신전",
["The Underbog"] = "지하수렁",
["The Veiled Sea"] = "장막의 바다",
["The Violet Hold"] = "보랏빛 요새",
["Thousand Needles"] = "버섯구름 봉우리",
["Thunder Bluff"] = "썬더 블러프",
Tirisfal = "티리스팔",
["Tirisfal Glades"] = "티리스팔 숲",
["Twisting Nether"] = "뒤틀린 황천",
Uldaman = "울다만",
Ulduar = "울두아르",
Undercity = "언더시티",
["Un'Goro Crater"] = "운고로 분화구",
["Upper Blackrock Spire"] = "검은바위 첨탑 상층",
["Utgarde Keep"] = "우트가드 성채",
["Utgarde Pinnacle"] = "우트가드 첨탑",
["Vault of Archavon"] = "아카본 석실",
["Vortex Pinnacle"] = "소용돌이 고원",
["Wailing Caverns"] = "통곡의 동굴",
["Warsong Gulch"] = "전쟁노래 협곡",
["Western Plaguelands"] = "서부 역병지대",
Westfall = "서부 몰락지대",
Wetlands = "저습지",
Wintergrasp = "겨울손아귀 호수",
Winterspring = "여명의 설원",
["Wyrmrest Temple"] = "고룡쉼터 사원",
Zangarmarsh = "장가르 습지대",
["Zul'Aman"] = "줄아만",
["Zul'Drak"] = "줄드락",
["Zul'Farrak"] = "줄파락",
["Zul'Gurub"] = "줄구룹",
}
elseif GAME_LOCALE == "esES" then
lib:SetCurrentTranslations {
["Ahn'kahet: The Old Kingdom"] = "Ahn'kahet: El Antiguo Reino",
["Ahn'Qiraj"] = "Ahn'Qiraj",
["Alliance Base"] = "Base de la Alianza",
["Alterac Mountains"] = "Montañas de Alterac",
["Alterac Valley"] = "Valle de Alterac",
["Amani Pass"] = "Paso de Amani",
["Arathi Basin"] = "Cuenca de Arathi",
["Arathi Highlands"] = "Tierras Altas de Arathi",
Armory = "Armería",
Ashenvale = "Vallefresno",
Auberdine = "Auberdine",
["Auchenai Crypts"] = "Criptas Auchenai",
Auchindoun = "Auchindoun",
Azeroth = "Azeroth",
["Azjol-Nerub"] = "Azjol-Nerub",
Azshara = "Azshara",
["Azuremyst Isle"] = "Isla Bruma Azur",
Badlands = "Tierras Inhóspitas",
["Bash'ir Landing"] = "Zona de aterrizaje Bash'ir",
["Blackfathom Deeps"] = "Cavernas de Brazanegra",
["Blackrock Depths"] = "Profundidades de Roca Negra",
["Blackrock Mountain"] = "Montaña Roca Negra",
["Blackrock Spire"] = "Cumbre de Roca Negra",
["Black Temple"] = "El Templo Oscuro",
["Blackwing Lair"] = "Guarida Alanegra",
["Blade's Edge Arena"] = "Arena Filospada",
["Blade's Edge Mountains"] = "Montañas Filospada",
["Blasted Lands"] = "Las Tierras Devastadas",
["Bloodmyst Isle"] = "Isla Bruma de Sangre",
["Booty Bay"] = "Bahía del Botín",
["Borean Tundra"] = "Tundra Boreal",
["Burning Steppes"] = "Las Estepas Ardientes",
Cathedral = "Catedral",
["Caverns of Time"] = "Cavernas del Tiempo",
["Champions' Hall"] = "Sala de los Campeones",
["Coilfang Reservoir"] = "Reserva Colmillo Torcido",
Coldarra = "Gelidar",
["Cosmic map"] = "Mapa cósmico",
["Crystalsong Forest"] = "Bosque Canto de Cristal",
["Crystal Spine"] = "Espina de Cristal",
Dalaran = "Dalaran",
["Dalaran Arena"] = "Arena de Dalaran",
["Dalaran Sewers"] = "Cloacas de Dalaran",
["Darkmoon Faire"] = "Feria de la Luna Negra",
Darkshore = "Costa Oscura",
Darnassus = "Darnassus",
["Deadwind Pass"] = "Paso de la Muerte",
["Deeprun Tram"] = "Tranvía Subterráneo",
Desolace = "Desolace",
["Dire Maul"] = "La Masacre",
["Dire Maul (East)"] = "La Masacre (Este)",
["Dire Maul (North)"] = "La Masacre (Norte)",
["Dire Maul (West)"] = "La Masacre (Oeste)",
Dragonblight = "Cementerio de Dragones",
["Drak'Tharon Keep"] = "Fortaleza de Drak'Tharon",
["Dun Morogh"] = "Dun Morogh",
Durotar = "Durotar",
Duskwood = "Bosque del Ocaso",
["Dustwallow Marsh"] = "Marjal Revolcafango",
["Eastern Kingdoms"] = "Reinos del Este",
["Eastern Plaguelands"] = "Tierras de la Peste del Este",
["Elwynn Forest"] = "Bosque de Elwynn",
Everlook = "Vista Eterna",
["Eversong Woods"] = "Bosque Canción Eterna",
["Eye of the Storm"] = "Ojo de la Tormenta",
Felwood = "Frondavil",
Feralas = "Feralas",
["Forge Camp: Terror"] = "Campamento forja: Terror",
["Forge Camp: Wrath"] = "Campamento forja: Cólera",
["Frostwyrm Lair"] = "Guarida de Vermis de Escarcha",
["Furywing's Perch"] = "Nido de Alafuria",
Gadgetzan = "Gadgetzan",
["Gates of Ahn'Qiraj"] = "Puertas de Ahn'Qiraj",
Ghostlands = "Tierras Fantasma",
Gnomeregan = "Gnomeregan",
Graveyard = "Cementerio",
["Grizzly Hills"] = "Colinas Pardas",
["Grom'gol Base Camp"] = "Campamento Grom'gol",
["Gruul's Lair"] = "Guarida de Gruul",
Gundrak = "Gundrak",
["Hall of Champions"] = "Sala de los Campeones",
["Hall of Legends"] = "Sala de las Leyendas",
["Halls of Lightning"] = "Cámaras de Relámpagos",
["Halls of Stone"] = "Cámaras de Piedra",
["Hellfire Citadel"] = "Ciudadela del Fuego Infernal",
["Hellfire Peninsula"] = "Península del Fuego Infernal",
["Hellfire Ramparts"] = "Murallas del Fuego Infernal",
["Hillsbrad Foothills"] = "Laderas de Trabalomas",
["Horde Encampment"] = "Campamento Horda",
["Howling Fjord"] = "Fiordo Aquilonal",
Hyjal = "Hyjal",
["Hyjal Summit"] = "Cima Hyjal",
Icecrown = "Corona de Hielo",
["Icecrown Citadel"] = "Ciudadela Corona de Hielo",
["Insidion's Perch"] = "Nido de Insidion",
Ironforge = "Forjaz",
["Isle of Quel'Danas"] = "Isla de Quel'Danas",
Kalimdor = "Kalimdor",
Karazhan = "Karazhan",
["Krasus' Landing"] = "Krasus' Landing",
Library = "Biblioteca",
["Loch Modan"] = "Loch Modan",
["Lower Blackrock Spire"] = "Cumbre inferior de Roca Negra",
["Magisters' Terrace"] = "Bancal Del Magister",
["Magtheridon's Lair"] = "Guarida de Magtheridon",
["Mana-Tombs"] = "Tumbas de Maná",
Maraudon = "Maraudon",
["Menethil Harbor"] = "Puerto de Menethil",
["Molten Core"] = "Núcleo de Magma",
Moonglade = "Claro de la Luna",
Mulgore = "Mulgore",
Nagrand = "Nagrand",
["Nagrand Arena"] = "Arena de Nagrand",
Naxxramas = "Naxxramas",
Netherstorm = "Tormenta Abisal",
["Night Elf Village"] = "Poblado Elfo de la Noche",
Northrend = "Rasganorte",
["Obsidia's Perch"] = "Nido de Obsidia",
["Ogri'la"] = "Ogri'la",
["Old Hillsbrad Foothills"] = "Antiguas Laderas de Trabalomas",
["Old Stratholme"] = "Stratholme en el pasado",
["Onyxia's Lair"] = "Guarida de Onyxia",
Orgrimmar = "Orgrimmar",
Outland = "Terrallende",
["Plaguelands: The Scarlet Enclave"] = "Tierras de la Peste del Este: El Enclave Escarlata",
Plaguewood = "Bosque de la Plaga",
["Quel'thalas"] = "Quel'thalas",
["Ragefire Chasm"] = "Sima ígnea",
Ratchet = "Trinquete",
["Razorfen Downs"] = "Zahúrda Rajacieno",
["Razorfen Kraul"] = "Horado Rajacieno",
["Redridge Mountains"] = "Montañas Crestagrana",
["Ring of Observance"] = "Círculo de la Observancia",
["Rivendark's Perch"] = "Nido de Desgarro Oscuro",
["Ruins of Ahn'Qiraj"] = "Ruinas de Ahn'Qiraj",
["Ruins of Lordaeron"] = "Ruinas de Lordaeron",
["Scarlet Monastery"] = "Monasterio Escarlata",
Scholomance = "Scholomance",
["Searing Gorge"] = "La Garganta de Fuego",
["Serpentshrine Cavern"] = "Caverna Santuario Serpiente",
["Sethekk Halls"] = "Salas Sethekk",
["Shadowfang Keep"] = "Castillo de Colmillo Oscuro",
["Shadow Labyrinth"] = "Laberinto de las Sombras",
["Shadowmoon Valley"] = "Valle Sombraluna",
["Shartuul's Transporter"] = "Transportador de Shartuul",
Shattrath = "Shattrath",
["Shattrath City"] = "Ciudad de Shattrath",
["Sholazar Basin"] = "Cuenca de Sholazar",
Silithus = "Silithus",
["Silvermoon City"] = "Ciudad de Lunargenta",
["Silverpine Forest"] = "Bosque de Argénteos",
["Skyguard Outpost"] = "Puesto de la guardia de cielo",
Stonard = "Rocal",
["Stonetalon Mountains"] = "Sierra Espolón",
Stormwind = "Ventormenta",
["Stormwind City"] = "Ciudad de Ventormenta",
["Strand of the Ancients"] = "Playa de los Ancestros",
["Stranglethorn Vale"] = "Vega de Tuercespina",
Stratholme = "Stratholme",
["Sunken Temple"] = "El Templo Sumergido",
["Sunwell Plateau"] = "Meseta de la Fuente del Sol",
["Swamp of Sorrows"] = "Pantano de las Penas",
Tanaris = "Tanaris",
Teldrassil = "Teldrassil",
["Tempest Keep"] = "El Castillo de la Tempestad",
["Temple of Ahn'Qiraj"] = "El Templo de Ahn'Qiraj",
["Terokkar Forest"] = "Bosque de Terokkar",
["The Arachnid Quarter"] = "Ala Arácnida",
["The Arcatraz"] = "El Alcatraz",
["The Barrens"] = "Los Baldíos",
["The Black Morass"] = "La Ciénaga Negra",
["The Blood Furnace"] = "El Horno de Sangre",
["The Bone Wastes"] = "El Vertedero de Huesos",
["The Botanica"] = "El Invernáculo",
["The Construct Quarter"] = "Ala de Abominación",
["The Culling of Stratholme"] = "La Matanza de Stratholme",
["The Dark Portal"] = "El Portal Oscuro",
["The Deadmines"] = "Las Minas de la Muerte",
["The Descent into Madness"] = "Descenso a la Locura",
["The Exodar"] = "El Exodar",
["The Eye"] = "El Ojo",
["The Eye of Eternity"] = "El Ojo de la Eternidad",
["The Forbidding Sea"] = "Mar Adusto",
["The Frozen Sea"] = "El Mar Gélido",
["The Great Sea"] = "Mare Magnum",
["The Hinterlands"] = "Tierras del Interior",
["The Mechanar"] = "El Mechanar",
["The Military Quarter"] = "Ala Militar",
["The Nexus"] = "El Nexo",
["The North Sea"] = "El Mar Norte",
["The Obsidian Sanctum"] = "El Sagrario Obsidiana",
["The Oculus"] = "El Oculus",
["The Plague Quarter"] = "Ala de la Plaga",
["Theramore Isle"] = "Isla Theramore",
["The Ring of Valor"] = "El Anillo del Valor",
["The Shattered Halls"] = "Las Salas Arrasadas",
["The Slave Pens"] = "Recinto de los Esclavos",
["The Spark of Imagination"] = "Cámaras de la Invención",
["The Steamvault"] = "La Cámara de Vapor",
["The Stockade"] = "Las Mazmorras",
["The Storm Peaks"] = "Las Cumbres Tormentosas",
["The Temple of Atal'Hakkar"] = "El Templo de Atal'Hakkar",
["The Underbog"] = "La Sotiénaga",
["The Veiled Sea"] = "Mar de la Bruma",
["The Violet Hold"] = "El Bastión Violeta",
["Thousand Needles"] = "Las Mil Agujas",
["Thunder Bluff"] = "Cima del Trueno",
Tirisfal = "Tirisfal",
["Tirisfal Glades"] = "Claros de Tirisfal",
["Twisting Nether"] = "El Vacío Abisal",
Uldaman = "Uldaman",
Ulduar = "Ulduar",
Undercity = "Entrañas",
["Un'Goro Crater"] = "Cráter de Un'Goro",
["Upper Blackrock Spire"] = "Cumbre de Roca Negra",
["Utgarde Keep"] = "Fortaleza de Utgarde",
["Utgarde Pinnacle"] = "Pináculo de Utgarde",
["Vault of Archavon"] = "La Cámara de Archavon",
["Vortex Pinnacle"] = "Cumbre del Vórtice",
["Wailing Caverns"] = "Cuevas de los Lamentos",
["Warsong Gulch"] = "Garganta Grito de Guerra",
["Western Plaguelands"] = "Tierras de la Peste del Oeste",
Westfall = "Páramos de Poniente",
Wetlands = "Los Humedales",
Wintergrasp = "Conquista del Invierno",
Winterspring = "Cuna del Invierno",
["Wyrmrest Temple"] = "Templo del Reposo del Dragón",
Zangarmarsh = "Marisma de Zangar",
["Zul'Aman"] = "Zul'Aman",
["Zul'Drak"] = "Zul'Drak",
["Zul'Farrak"] = "Zul'Farrak",
["Zul'Gurub"] = "Zul'Gurub",
}
elseif GAME_LOCALE == "esMX" then
lib:SetCurrentTranslations {
["Ahn'kahet: The Old Kingdom"] = "Ahn'Kahet: El Antiguo Reino", -- Needs review
["Ahn'Qiraj"] = "Ahn'Qiraj",
["Alliance Base"] = "Alliance Base",
["Alterac Mountains"] = "Montañas de Alterac",
["Alterac Valley"] = "Valle de Alterac",
["Amani Pass"] = "Paso de Amani",
["Arathi Basin"] = "Cuenca de Arathi",
["Arathi Highlands"] = "Tierras Altas de Arathi",
Armory = "Armería",
Ashenvale = "Vallefresno",
Auberdine = "Auberdine",
["Auchenai Crypts"] = "Criptas Auchenai",
Auchindoun = "Auchindoun",
Azeroth = "Azeroth",
["Azjol-Nerub"] = "Azjol-Nerub", -- Needs review
Azshara = "Azshara",
["Azuremyst Isle"] = "Isla Bruma Azur",
Badlands = "Tierras Inhóspitas",
["Bash'ir Landing"] = "Zona de aterrizaje Bash'ir",
["Blackfathom Deeps"] = "Cavernas de Brazanegra",
["Blackrock Depths"] = "Profundidades de Roca Negra",
["Blackrock Mountain"] = "Montaña Roca Negra",
["Blackrock Spire"] = "Cumbre de Roca Negra",
["Black Temple"] = "El Templo Oscuro",
["Blackwing Lair"] = "Guarida Alanegra",
["Blade's Edge Arena"] = "Arena Filospada",
["Blade's Edge Mountains"] = "Montañas Filospada",
["Blasted Lands"] = "Las Tierras Devastadas",
["Bloodmyst Isle"] = "Isla Bruma de Sangre",
["Booty Bay"] = "Bahía del Botín",
["Borean Tundra"] = "Tundra Boreal", -- Needs review
["Burning Steppes"] = "Las Estepas Ardientes",
Cathedral = "Catedral",
["Caverns of Time"] = "Cavernas del Tiempo",
["Champions' Hall"] = "Sala de los Campeones",
["Coilfang Reservoir"] = "Reserva Colmillo Torcido",
Coldarra = "Gelidar", -- Needs review
["Cosmic map"] = "Mapa cósmico",
["Crystalsong Forest"] = "Bosque del Canto de Cristal", -- Needs review
["Crystal Spine"] = "",
Dalaran = "Dalaran", -- Needs review
-- ["Dalaran Arena"] = "",
["Dalaran Sewers"] = "Los Bajos Fondos", -- Needs review
-- ["Darkmoon Faire"] = "",
Darkshore = "Costa Oscura",
Darnassus = "Darnassus",
["Deadwind Pass"] = "Paso de la Muerte",
["Deeprun Tram"] = "Tranvía Subterráneo",
Desolace = "Desolace",
["Dire Maul"] = "La Masacre",
["Dire Maul (East)"] = "La Masacre (Este)",
["Dire Maul (North)"] = "La Masacre (Norte)",
["Dire Maul (West)"] = "La Masacre (Oeste)",
-- Dragonblight = "",
["Drak'Tharon Keep"] = "Fortaleza de Drak'Tharon", -- Needs review
["Dun Morogh"] = "Dun Morogh",
Durotar = "Durotar",
Duskwood = "Bosque del Ocaso",
["Dustwallow Marsh"] = "Marjal Revolcafango",
["Eastern Kingdoms"] = "Reinos del Este",
["Eastern Plaguelands"] = "Tierras de la Peste del Este",
["Elwynn Forest"] = "Bosque de Elwynn",
Everlook = "Vista Eterna",
["Eversong Woods"] = "Bosque Canción Eterna",
["Eye of the Storm"] = "Ojo de la Tormenta",
Felwood = "Frondavil",
Feralas = "Feralas",
["Forge Camp: Terror"] = "",
["Forge Camp: Wrath"] = "",
-- ["Frostwyrm Lair"] = "",
["Furywing's Perch"] = "",
Gadgetzan = "Gadgetzan",
["Gates of Ahn'Qiraj"] = "Puertas de Ahn'Qiraj",
Ghostlands = "Tierras Fantasma",
Gnomeregan = "Gnomeregan",
Graveyard = "Cementerio",
["Grizzly Hills"] = "Colinas Pardas",
["Grom'gol Base Camp"] = "Campamento Grom'gol",
["Gruul's Lair"] = "Guarida de Gruul",
Gundrak = "Gundrak",
["Hall of Champions"] = "Sala de los Campeones",
["Hall of Legends"] = "Sala de las Leyendas",
-- ["Halls of Lightning"] = "",
-- ["Halls of Stone"] = "",
["Hellfire Citadel"] = "Ciudadela del Fuego Infernal",
["Hellfire Peninsula"] = "Península del Fuego Infernal",
["Hellfire Ramparts"] = "Murallas del Fuego Infernal",
["Hillsbrad Foothills"] = "Laderas de Trabalomas",
["Horde Encampment"] = "Horde Encampment",
-- ["Howling Fjord"] = "",
Hyjal = "Hyjal",
["Hyjal Summit"] = "Hyjal Summit",
-- Icecrown = "",
-- ["Icecrown Citadel"] = "",
["Insidion's Perch"] = "",
Ironforge = "Forjaz",
["Isle of Quel'Danas"] = "Isla de Quel'Danas",
Kalimdor = "Kalimdor",
Karazhan = "Karazhan",
["Krasus' Landing"] = "Krasus' Landing",
Library = "Biblioteca",
["Loch Modan"] = "Loch Modan",
["Lower Blackrock Spire"] = "Cumbre inferior de Roca Negra",
["Magisters' Terrace"] = "Bancal Del Magister",
["Magtheridon's Lair"] = "Guarida de Magtheridon",
["Mana-Tombs"] = "Tumbas de Maná",
Maraudon = "Maraudon",
["Menethil Harbor"] = "Puerto de Menethil",
["Molten Core"] = "Núcleo de Magma",
Moonglade = "Claro de la Luna",
Mulgore = "Mulgore",
Nagrand = "Nagrand",
["Nagrand Arena"] = "Arena de Nagrand",
Naxxramas = "Naxxramas",
Netherstorm = "Tormenta Abisal",
["Night Elf Village"] = "Night Elf Village",
-- Northrend = "",
["Obsidia's Perch"] = "",
["Ogri'la"] = "",
["Old Hillsbrad Foothills"] = "Viejas Laderas de Trabalomas",
-- ["Old Stratholme"] = "",
["Onyxia's Lair"] = "Guarida de Onyxia",
Orgrimmar = "Orgrimmar",
Outland = "Terrallende",
-- ["Plaguelands: The Scarlet Enclave"] = "",
Plaguewood = "Bosque de la Plaga",
["Quel'thalas"] = "Quel'thalas",
["Ragefire Chasm"] = "Sima ígnea",
Ratchet = "Trinquete",
["Razorfen Downs"] = "Zahúrda Rajacieno",
["Razorfen Kraul"] = "Horado Rajacieno",
["Redridge Mountains"] = "Montañas Crestagrana",
["Ring of Observance"] = "Círculo de la Observancia",
["Rivendark's Perch"] = "",
["Ruins of Ahn'Qiraj"] = "Ruinas de Ahn'Qiraj",
["Ruins of Lordaeron"] = "Ruinas de Lordaeron",
["Scarlet Monastery"] = "Monasterio Escarlata",
Scholomance = "Scholomance",
["Searing Gorge"] = "La Garganta de Fuego",
["Serpentshrine Cavern"] = "Caverna Santuario Serpiente",
["Sethekk Halls"] = "Salas Sethekk",
["Shadowfang Keep"] = "Castillo de Colmillo Oscuro",
["Shadow Labyrinth"] = "Laberinto de las Sombras",
["Shadowmoon Valley"] = "Valle Sombraluna",
["Shartuul's Transporter"] = "",
Shattrath = "Shattrath",
["Shattrath City"] = "Ciudad de Shattrath",
["Sholazar Basin"] = "Cuenca de Sholazar", -- Needs review
Silithus = "Silithus",
["Silvermoon City"] = "Ciudad de Lunargenta",
["Silverpine Forest"] = "Bosque de Argénteos",
["Skyguard Outpost"] = "",
-- Stonard = "",
["Stonetalon Mountains"] = "Sierra Espolón",
Stormwind = "Ventormenta",
["Stormwind City"] = "Ciudad de Ventormenta",
-- ["Strand of the Ancients"] = "",
["Stranglethorn Vale"] = "Vega de Tuercespina",
Stratholme = "Stratholme",
["Sunken Temple"] = "El Templo de Sunken",
["Sunwell Plateau"] = "Meseta de la Fuente del Sol",
["Swamp of Sorrows"] = "Pantano de las Penas",
Tanaris = "Tanaris",
Teldrassil = "Teldrassil",
["Tempest Keep"] = "El Castillo de la Tempestad",
["Temple of Ahn'Qiraj"] = "El Templo de Ahn'Qiraj",
["Terokkar Forest"] = "Bosque de Terokkar",
-- ["The Arachnid Quarter"] = "",
["The Arcatraz"] = "El Alcatraz",
["The Barrens"] = "Los Baldíos",
["The Black Morass"] = "La Ciénaga Negra",
["The Blood Furnace"] = "El Horno de Sangre",
["The Bone Wastes"] = "El Vertedero de Huesos",
["The Botanica"] = "El Invernáculo",
-- ["The Construct Quarter"] = "",
-- ["The Culling of Stratholme"] = "",
["The Dark Portal"] = "El Portal Oscuro",
["The Deadmines"] = "Las Minas de la Muerte",
-- ["The Descent into Madness"] = "",
["The Exodar"] = "El Exodar",
["The Eye"] = "El Ojo",
["The Eye of Eternity"] = "El Ojo de la Eternidad", -- Needs review
["The Forbidding Sea"] = "Mar Adusto",
["The Frozen Sea"] = "El Mar Gélido", -- Needs review
["The Great Sea"] = "Mare Magnum",
["The Hinterlands"] = "Tierras del Interior",
["The Mechanar"] = "El Mechanar",
-- ["The Military Quarter"] = "",
["The Nexus"] = "El Nexo", -- Needs review
["The North Sea"] = "El Mar Norte",
["The Obsidian Sanctum"] = "El Sagrario Obsidiana", -- Needs review
["The Oculus"] = "El Óculus", -- Needs review
-- ["The Plague Quarter"] = "",
["Theramore Isle"] = "Isla Theramore",
-- ["The Ring of Valor"] = "",
["The Shattered Halls"] = "Las Salas Arrasadas",
["The Slave Pens"] = "Recinto de los Esclavos",
-- ["The Spark of Imagination"] = "",
["The Steamvault"] = "La Cámara de Vapor",
["The Stockade"] = "Las Mazmorras",
-- ["The Storm Peaks"] = "",
["The Temple of Atal'Hakkar"] = "El Templo de Atal'Hakkar",
["The Underbog"] = "La Sotiénaga",
["The Veiled Sea"] = "Mar de la Bruma",
-- ["The Violet Hold"] = "",
["Thousand Needles"] = "Las Mil Agujas",
["Thunder Bluff"] = "Cima del Trueno",
Tirisfal = "Tirisfal",
["Tirisfal Glades"] = "Claros de Tirisfal",
["Twisting Nether"] = "El Vacío Abisal",
Uldaman = "Uldaman",
-- Ulduar = "",
Undercity = "Entrañas",
["Un'Goro Crater"] = "Cráter de Un'Goro",
["Upper Blackrock Spire"] = "Cumbre de Roca Negra",
-- ["Utgarde Keep"] = "",
-- ["Utgarde Pinnacle"] = "",
-- ["Vault of Archavon"] = "",
["Vortex Pinnacle"] = "",
["Wailing Caverns"] = "Cuevas de los Lamentos",
["Warsong Gulch"] = "Garganta Grito de Guerra",
["Western Plaguelands"] = "Tierras de la Peste del Oeste",
Westfall = "Páramos de Poniente",
Wetlands = "Los Humedales",
-- Wintergrasp = "",
Winterspring = "Cuna del Invierno",
-- ["Wyrmrest Temple"] = "",
Zangarmarsh = "Marisma de Zangar",
["Zul'Aman"] = "Zul'Aman",
["Zul'Drak"] = "Zul'Drak",
["Zul'Farrak"] = "Zul'Farrak",
["Zul'Gurub"] = "Zul'Gurub",
}
elseif GAME_LOCALE == "ruRU" then
lib:SetCurrentTranslations {
["Ahn'kahet: The Old Kingdom"] = "Ан'кахет: Старое Королевство",
["Ahn'Qiraj"] = "Ан'Кираж",
["Alliance Base"] = "База Альянса",
["Alterac Mountains"] = "Альтеракские горы",
["Alterac Valley"] = "Альтеракская долина",
["Amani Pass"] = "Перевал Амани",
["Arathi Basin"] = "Низина Арати",
["Arathi Highlands"] = "Нагорье Арати",
Armory = "Оружейная",
Ashenvale = "Ясеневый лес",
Auberdine = "Аубердин",
["Auchenai Crypts"] = "Аукенайские гробницы",
Auchindoun = "Аукиндон",
Azeroth = "Азерот",
["Azjol-Nerub"] = "Азжол-Неруб",
Azshara = "Азшара",
["Azuremyst Isle"] = "Остров Лазурной Дымки",
Badlands = "Бесплодные земли",
["Bash'ir Landing"] = "Лагерь Баш'ира",
["Blackfathom Deeps"] = "Непроглядная Пучина",
["Blackrock Depths"] = "Глубины Черной горы",
["Blackrock Mountain"] = "Черная гора",
["Blackrock Spire"] = "Пик Черной горы",
["Black Temple"] = "Черный храм",
["Blackwing Lair"] = "Логово Крыла Тьмы",
["Blade's Edge Arena"] = "Арена Острогорья",
["Blade's Edge Mountains"] = "Острогорье",
["Blasted Lands"] = "Выжженные земли",
["Bloodmyst Isle"] = "Остров Кровавой Дымки",
["Booty Bay"] = "Пиратская Бухта",
["Borean Tundra"] = "Борейская тундра",
["Burning Steppes"] = "Пылающие степи",
Cathedral = "Собор",
["Caverns of Time"] = "Пещеры Времени",
["Champions' Hall"] = "Зал Защитника",
["Coilfang Reservoir"] = "Резервуар Кривого Клыка",
Coldarra = "Хладарра",
["Cosmic map"] = "Карта Вселенной",
["Crystalsong Forest"] = "Лес Хрустальной Песни",
["Crystal Spine"] = "Хрустальное поле",
Dalaran = "Даларан",
["Dalaran Arena"] = "Арена Даларана", -- Needs review
["Dalaran Sewers"] = "Арена Даларана",
["Darkmoon Faire"] = "Ярмарка Новолуния",
Darkshore = "Темные берега",
Darnassus = "Дарнас",
["Deadwind Pass"] = "Перевал Мертвого Ветра",
["Deeprun Tram"] = "Подземный поезд",
Desolace = "Пустоши",
["Dire Maul"] = "Забытый Город",
["Dire Maul (East)"] = "Забытый Город: Восток",
["Dire Maul (North)"] = "Забытый Город: Север",
["Dire Maul (West)"] = "Забытый Город: Запад",
Dragonblight = "Драконий Погост",
["Drak'Tharon Keep"] = "Крепость Драк'Тарон",
["Dun Morogh"] = "Дун Морог",
Durotar = "Дуротар",
Duskwood = "Сумеречный лес",
["Dustwallow Marsh"] = "Пылевые топи",
["Eastern Kingdoms"] = "Восточные королевства",
["Eastern Plaguelands"] = "Восточные Чумные земли",
["Elwynn Forest"] = "Элвиннский лес",
Everlook = "Круговзор",
["Eversong Woods"] = "Леса Вечной Песни",
["Eye of the Storm"] = "Око Бури",
Felwood = "Оскверненный лес",
Feralas = "Фералас",
["Forge Camp: Terror"] = "Лагерь Легиона: Ужас",
["Forge Camp: Wrath"] = "Лагерь Легиона: Гнев",
["Frostwyrm Lair"] = "Логово Ледяного змея",
["Furywing's Perch"] = "Гнездовье Ярокрыла",
Gadgetzan = "Прибамбасск",
["Gates of Ahn'Qiraj"] = "Врата Ан'Киража",
Ghostlands = "Призрачные земли",
Gnomeregan = "Гномреган",
Graveyard = "Кладбище",
["Grizzly Hills"] = "Седые холмы",
["Grom'gol Base Camp"] = "Лагерь Гром'гол",
["Gruul's Lair"] = "Логово Груула",
Gundrak = "Гундрак",
["Hall of Champions"] = "Чертог Защитников",
["Hall of Legends"] = "Зал Легенд",
["Halls of Lightning"] = "Чертоги Молний",
["Halls of Stone"] = "Чертоги Камня",
["Hellfire Citadel"] = "Цитадель Адского Пламени",
["Hellfire Peninsula"] = "Полуостров Адского Пламени",
["Hellfire Ramparts"] = "Бастионы Адского Пламени",
["Hillsbrad Foothills"] = "Предгорья Хилсбрада",
["Horde Encampment"] = "Стоянка Орды",
["Howling Fjord"] = "Ревущий фьорд",
Hyjal = "Хиджал",
["Hyjal Summit"] = "Вершина Хиджала",
Icecrown = "Ледяная Корона",
["Icecrown Citadel"] = "Цитадель Ледяной Короны",
["Insidion's Perch"] = "Гнездо Инсидиона",
Ironforge = "Стальгорн",
["Isle of Quel'Danas"] = "Остров Кель'Данас",
Kalimdor = "Калимдор",
Karazhan = "Каражан",
["Krasus' Landing"] = "Площадка Красуса",
Library = "Библиотека",
["Loch Modan"] = "Лок Модан",
["Lower Blackrock Spire"] = "Нижний ярус Черной горы",
["Magisters' Terrace"] = "Терраса Магистров",
["Magtheridon's Lair"] = "Логово Магтеридона",
["Mana-Tombs"] = "Гробницы Маны",
Maraudon = "Мародон",
["Menethil Harbor"] = "Гавань Менетилов",
["Molten Core"] = "Огненные Недра",
Moonglade = "Лунная поляна",
Mulgore = "Мулгор",
Nagrand = "Награнд",
["Nagrand Arena"] = "Арена Награнда",
Naxxramas = "Наксрамас",
Netherstorm = "Пустоверть",
["Night Elf Village"] = "Деревня ночных эльфов",
Northrend = "Нордскол",
["Obsidia's Perch"] = "Гнездо Обсидии",
["Ogri'la"] = "Огри'ла",
["Old Hillsbrad Foothills"] = "Старые предгорья Хилсбрада",
["Old Stratholme"] = "Старый Стратхольм",
["Onyxia's Lair"] = "Логово Ониксии",
Orgrimmar = "Оргриммар",
Outland = "Запределье",
["Plaguelands: The Scarlet Enclave"] = "Чумные земли: Анклав Алого ордена",
Plaguewood = "Проклятый лес",
["Quel'thalas"] = "Кель'Талас",
["Ragefire Chasm"] = "Огненная пропасть",
Ratchet = "Кабестан",
["Razorfen Downs"] = "Курганы Иглошкурых",
["Razorfen Kraul"] = "Лабиринты Иглошкурых",
["Redridge Mountains"] = "Красногорье",
["Ring of Observance"] = "Ритуальный Круг",
["Rivendark's Perch"] = "Гнездо Чернокрыла",
["Ruins of Ahn'Qiraj"] = "Руины Ан'Киража",
["Ruins of Lordaeron"] = "Руины Лордерона",
["Scarlet Monastery"] = "Монастырь Алого ордена",
Scholomance = "Некроситет",
["Searing Gorge"] = "Тлеющее ущелье",
["Serpentshrine Cavern"] = "Змеиное святилище",
["Sethekk Halls"] = "Сетеккские залы",
["Shadowfang Keep"] = "Крепость Темного Клыка",
["Shadow Labyrinth"] = "Темный лабиринт",
["Shadowmoon Valley"] = "Долина Призрачной Луны",
["Shartuul's Transporter"] = "Транспортер Шартуула",
Shattrath = "Шаттрат",
["Shattrath City"] = "Шаттрат",
["Sholazar Basin"] = "Низина Шолазар",
Silithus = "Силитус",
["Silvermoon City"] = "Луносвет",
["Silverpine Forest"] = "Серебряный бор",
["Skyguard Outpost"] = "Застава Стражи Небес",
Stonard = "Каменор",
["Stonetalon Mountains"] = "Когтистые горы",
Stormwind = "Штормград",
["Stormwind City"] = "Штормград",
["Strand of the Ancients"] = "Берег Древних",
["Stranglethorn Vale"] = "Тернистая долина",
Stratholme = "Стратхольм",
["Sunken Temple"] = "Затонувший храм",
["Sunwell Plateau"] = "Плато Солнечного Колодца",
["Swamp of Sorrows"] = "Болото Печали",
Tanaris = "Танарис",
Teldrassil = "Тельдрассил",
["Tempest Keep"] = "Крепость Бурь",
["Temple of Ahn'Qiraj"] = "Храм Ан'Кираж",
["Terokkar Forest"] = "Лес Тероккар",
["The Arachnid Quarter"] = "Паучий квартал",
["The Arcatraz"] = "Аркатрац",
["The Barrens"] = "Степи",
["The Black Morass"] = "Черные топи",
["The Blood Furnace"] = "Кузня Крови",
["The Bone Wastes"] = "Костяные пустоши",
["The Botanica"] = "Ботаника",
["The Construct Quarter"] = "Квартал Мерзости",
["The Culling of Stratholme"] = "Очищение Стратхольма",
["The Dark Portal"] = "Темный портал",
["The Deadmines"] = "Мертвые копи",
["The Descent into Madness"] = "Провал Безумия", -- Needs review
["The Exodar"] = "Экзодар",
["The Eye"] = "Око",
["The Eye of Eternity"] = "Око Вечности",
["The Forbidding Sea"] = "Зловещее море",
["The Frozen Sea"] = "Ледяное море",
["The Great Sea"] = "Великое море",
["The Hinterlands"] = "Внутренние земли",
["The Mechanar"] = "Механар",
["The Military Quarter"] = "Военный квартал",
["The Nexus"] = "Нексус",
["The North Sea"] = "Северное море",
["The Obsidian Sanctum"] = "Обсидиановое святилище",
["The Oculus"] = "Окулус",
["The Plague Quarter"] = "Чумной квартал",
["Theramore Isle"] = "Остров Терамор",
["The Ring of Valor"] = "Круг Доблести",
["The Shattered Halls"] = "Разрушенные залы",
["The Slave Pens"] = "Узилище",
["The Spark of Imagination"] = "Искра Воображения", -- Needs review
["The Steamvault"] = "Паровое подземелье",
["The Stockade"] = "Тюрьма",
["The Storm Peaks"] = "Грозовая Гряда",
["The Temple of Atal'Hakkar"] = "Храм Атал'Хаккара",
["The Underbog"] = "Нижетопь",
["The Veiled Sea"] = "Сокрытое Море",
["The Violet Hold"] = "Аметистовая крепость",
["Thousand Needles"] = "Тысяча Игл",
["Thunder Bluff"] = "Громовой Утес",
Tirisfal = "Тирисфальские леса",
["Tirisfal Glades"] = "Тирисфальские леса",
["Twisting Nether"] = "Круговерть Пустоты",
Uldaman = "Ульдаман",
Ulduar = "Ульдуар",
Undercity = "Подгород",
["Un'Goro Crater"] = "Кратер Ун'Горо",
["Upper Blackrock Spire"] = "Верхний ярус Черной горы",
["Utgarde Keep"] = "Крепость Утгард",
["Utgarde Pinnacle"] = "Вершина Утгард",
["Vault of Archavon"] = "Склеп Аркавона",
["Vortex Pinnacle"] = "Нагорье Смерчей",
["Wailing Caverns"] = "Пещеры Стенаний",
["Warsong Gulch"] = "Ущелье Песни Войны",
["Western Plaguelands"] = "Западные Чумные земли",
Westfall = "Западный Край",
Wetlands = "Болотина",
Wintergrasp = "Озеро Ледяных Оков",
Winterspring = "Зимние Ключи",
["Wyrmrest Temple"] = "Храм Драконьего Покоя",
Zangarmarsh = "Зангартопь",
["Zul'Aman"] = "Зул'Аман",
["Zul'Drak"] = "Зул'Драк",
["Zul'Farrak"] = "Зул'Фаррак",
["Zul'Gurub"] = "Зул'Гуруб",
}
elseif GAME_LOCALE == "zhCN" then
lib:SetCurrentTranslations {
["Ahn'kahet: The Old Kingdom"] = "安卡雷:古代王国",
["Ahn'Qiraj"] = "安其拉",
["Alliance Base"] = "联盟基地",
["Alterac Mountains"] = "奥特兰克山脉",
["Alterac Valley"] = "奥特兰克山谷",
["Amani Pass"] = "阿曼尼小径",
["Arathi Basin"] = "阿拉希盆地",
["Arathi Highlands"] = "阿拉希高地",
Armory = "军械库",
Ashenvale = "灰谷",
Auberdine = "奥伯丁",
["Auchenai Crypts"] = "奥金尼地穴",
Auchindoun = "奥金顿",
Azeroth = "艾泽拉斯",
["Azjol-Nerub"] = "艾卓-尼鲁布",
Azshara = "艾萨拉",
["Azuremyst Isle"] = "秘蓝岛",
Badlands = "荒芜之地",
["Bash'ir Landing"] = "巴什伊尔码头",
["Blackfathom Deeps"] = "黑暗深渊",
["Blackrock Depths"] = "黑石深渊",
["Blackrock Mountain"] = "黑石山",
["Blackrock Spire"] = "黑石塔",
["Black Temple"] = "黑暗神殿",
["Blackwing Lair"] = "黑翼之巢",
["Blade's Edge Arena"] = "刀锋山竞技场",
["Blade's Edge Mountains"] = "刀锋山",
["Blasted Lands"] = "诅咒之地",
["Bloodmyst Isle"] = "秘血岛",
["Booty Bay"] = "藏宝海湾",
["Borean Tundra"] = "北风苔原",
["Burning Steppes"] = "燃烧平原",
Cathedral = "教堂",
["Caverns of Time"] = "时光之穴",
["Champions' Hall"] = "勇士大厅",
["Coilfang Reservoir"] = "盘牙水库",
Coldarra = "考达拉",
["Cosmic map"] = "全部地图",
["Crystalsong Forest"] = "晶歌森林",
["Crystal Spine"] = "水晶之脊",
Dalaran = "达拉然",
["Dalaran Arena"] = "达拉然竞技场",
["Dalaran Sewers"] = "达拉然下水道",
["Darkmoon Faire"] = "暗月马戏团",
Darkshore = "黑海岸",
Darnassus = "达纳苏斯",
["Deadwind Pass"] = "逆风小径",
["Deeprun Tram"] = "矿道地铁",
Desolace = "凄凉之地",
["Dire Maul"] = "厄运之槌",
["Dire Maul (East)"] = "厄运之槌 (东)",
["Dire Maul (North)"] = "厄运之槌 (北)",
["Dire Maul (West)"] = "厄运之槌 (西)",
Dragonblight = "龙骨荒野",
["Drak'Tharon Keep"] = "达克萨隆要塞",
["Dun Morogh"] = "丹莫罗",
Durotar = "杜隆塔尔",
Duskwood = "暮色森林",
["Dustwallow Marsh"] = "尘泥沼泽",
["Eastern Kingdoms"] = "东部王国",
["Eastern Plaguelands"] = "东瘟疫之地",
["Elwynn Forest"] = "艾尔文森林",
Everlook = "永望镇",
["Eversong Woods"] = "永歌森林",
["Eye of the Storm"] = "风暴之眼",
Felwood = "费伍德森林",
Feralas = "菲拉斯",
["Forge Camp: Terror"] = "铸魔营地:恐怖",
["Forge Camp: Wrath"] = "铸魔营地:天罚",
["Frostwyrm Lair"] = "冰霜巨龙的巢穴", -- Needs review
["Furywing's Perch"] = "弗雷文栖木",
Gadgetzan = "加基森",
["Gates of Ahn'Qiraj"] = "安其拉之门",
Ghostlands = "幽魂之地",
Gnomeregan = "诺莫瑞根",
Graveyard = "墓地",
["Grizzly Hills"] = "灰熊丘陵",
["Grom'gol Base Camp"] = "格罗姆高营地",
["Gruul's Lair"] = "格鲁尔的巢穴",
Gundrak = "古达克",
["Hall of Champions"] = "勇士大厅",
["Hall of Legends"] = "传说大厅",
["Halls of Lightning"] = "闪电大厅",
["Halls of Stone"] = "岩石大厅",
["Hellfire Citadel"] = "地狱火堡垒",
["Hellfire Peninsula"] = "地狱火半岛",
["Hellfire Ramparts"] = "地狱火城墙",
["Hillsbrad Foothills"] = "希尔斯布莱德丘陵",
["Horde Encampment"] = "部落营地",
["Howling Fjord"] = "嚎风峡湾",
Hyjal = "海加尔山",
["Hyjal Summit"] = "海加尔峰",
Icecrown = "冰冠冰川",
["Icecrown Citadel"] = "冰冠堡垒",
["Insidion's Perch"] = "因斯迪安栖木",
Ironforge = "铁炉堡",
["Isle of Quel'Danas"] = "奎尔丹纳斯岛",
Kalimdor = "卡利姆多",
Karazhan = "卡拉赞",
["Krasus' Landing"] = "克拉苏斯平台",
Library = "图书馆",
["Loch Modan"] = "洛克莫丹",
["Lower Blackrock Spire"] = "黑石塔 (下层)",
["Magisters' Terrace"] = "魔导师平台",
["Magtheridon's Lair"] = "玛瑟里顿的巢穴",
["Mana-Tombs"] = "法力陵墓",
Maraudon = "玛拉顿",
["Menethil Harbor"] = "米奈希尔港",
["Molten Core"] = "熔火之心",
Moonglade = "月光林地",
Mulgore = "莫高雷",
Nagrand = "纳格兰",
["Nagrand Arena"] = "纳格兰竞技场",
Naxxramas = "纳克萨玛斯",
Netherstorm = "虚空风暴",
["Night Elf Village"] = "暗夜精灵村庄",
Northrend = "诺森德",
["Obsidia's Perch"] = "欧比斯迪栖木",
["Ogri'la"] = "奥格瑞拉",
["Old Hillsbrad Foothills"] = "旧希尔斯布莱德丘陵",
["Old Stratholme"] = "旧斯坦索姆",
["Onyxia's Lair"] = "奥妮克希亚的巢穴",
Orgrimmar = "奥格瑞玛",
Outland = "外域",
["Plaguelands: The Scarlet Enclave"] = "东瘟疫之地:血色领地",
Plaguewood = "病木林",
["Quel'thalas"] = "奎尔萨拉斯",
["Ragefire Chasm"] = "怒焰裂谷",
Ratchet = "棘齿城",
["Razorfen Downs"] = "剃刀高地",
["Razorfen Kraul"] = "剃刀沼泽",
["Redridge Mountains"] = "赤脊山",
["Ring of Observance"] = "仪式广场",
["Rivendark's Perch"] = "雷文达克栖木",
["Ruins of Ahn'Qiraj"] = "安其拉废墟",
["Ruins of Lordaeron"] = "洛丹伦废墟",
["Scarlet Monastery"] = "血色修道院",
Scholomance = "通灵学院",
["Searing Gorge"] = "灼热峡谷",
["Serpentshrine Cavern"] = "毒蛇神殿",
["Sethekk Halls"] = "塞泰克大厅",
["Shadowfang Keep"] = "影牙城堡",
["Shadow Labyrinth"] = "暗影迷宫",
["Shadowmoon Valley"] = "影月谷",
["Shartuul's Transporter"] = "沙图尔的传送器",
Shattrath = "沙塔斯",
["Shattrath City"] = "沙塔斯城",
["Sholazar Basin"] = "索拉查盆地",
Silithus = "希利苏斯",
["Silvermoon City"] = "银月城",
["Silverpine Forest"] = "银松森林",
["Skyguard Outpost"] = "天空卫队哨站",
Stonard = "斯通纳德",
["Stonetalon Mountains"] = "石爪山脉",
Stormwind = "暴风城",
["Stormwind City"] = "暴风城",
["Strand of the Ancients"] = "远古海滩",
["Stranglethorn Vale"] = "荆棘谷",
Stratholme = "斯坦索姆",
["Sunken Temple"] = "沉没的神庙",
["Sunwell Plateau"] = "太阳之井高地",
["Swamp of Sorrows"] = "悲伤沼泽",
Tanaris = "塔纳利斯",
Teldrassil = "泰达希尔",
["Tempest Keep"] = "风暴要塞",
["Temple of Ahn'Qiraj"] = "安其拉神殿",
["Terokkar Forest"] = "泰罗卡森林",
["The Arachnid Quarter"] = "蜘蛛区",
["The Arcatraz"] = "禁魔监狱",
["The Barrens"] = "贫瘠之地",
["The Black Morass"] = "黑色沼泽",
["The Blood Furnace"] = "鲜血熔炉",
["The Bone Wastes"] = "白骨荒野",
["The Botanica"] = "生态船",
["The Construct Quarter"] = "建筑区",
["The Culling of Stratholme"] = "净化斯坦索姆",
["The Dark Portal"] = "黑暗之门",
["The Deadmines"] = "死亡矿井",
["The Descent into Madness"] = "The Descent into Madness", -- Needs review
["The Exodar"] = "埃索达",
["The Eye"] = "风暴要塞",
["The Eye of Eternity"] = "永恒之眼",
["The Forbidding Sea"] = "禁忌之海",
["The Frozen Sea"] = "冰冻之海",
["The Great Sea"] = "无尽之海",
["The Hinterlands"] = "辛特兰",
["The Mechanar"] = "能源舰",
["The Military Quarter"] = "军事区",
["The Nexus"] = "魔枢",
["The North Sea"] = "北海",
["The Obsidian Sanctum"] = "黑曜石圣殿",
["The Oculus"] = "魔环",
["The Plague Quarter"] = "瘟疫区",
["Theramore Isle"] = "塞拉摩岛",
["The Ring of Valor"] = "勇气竞技场",
["The Shattered Halls"] = "破碎大厅",
["The Slave Pens"] = "奴隶围栏",
["The Spark of Imagination"] = "The Spark of Imagination", -- Needs review
["The Steamvault"] = "蒸汽地窟",
["The Stockade"] = "监狱",
["The Storm Peaks"] = "风暴峭壁",
["The Temple of Atal'Hakkar"] = "阿塔哈卡神庙",
["The Underbog"] = "幽暗沼泽",
["The Veiled Sea"] = "迷雾之海",
["The Violet Hold"] = "紫罗兰监狱",
["Thousand Needles"] = "千针石林",
["Thunder Bluff"] = "雷霆崖",
Tirisfal = "提里斯法林地",
["Tirisfal Glades"] = "提瑞斯法林地",
["Twisting Nether"] = "扭曲虚空",
Uldaman = "奥达曼",
Ulduar = "奥杜尔",
Undercity = "幽暗城",
["Un'Goro Crater"] = "安戈洛环形山",
["Upper Blackrock Spire"] = "黑石塔 (上层)",
["Utgarde Keep"] = "乌特加德城堡",
["Utgarde Pinnacle"] = "乌特加德之巅",
["Vault of Archavon"] = "阿尔卡冯的宝库",
["Vortex Pinnacle"] = "漩涡峰",
["Wailing Caverns"] = "哀嚎洞穴",
["Warsong Gulch"] = "战歌峡谷",
["Western Plaguelands"] = "西瘟疫之地",
Westfall = "西部荒野",
Wetlands = "湿地",
Wintergrasp = "冬拥湖",
Winterspring = "冬泉谷",
["Wyrmrest Temple"] = "龙眠神殿",
Zangarmarsh = "赞加沼泽",
["Zul'Aman"] = "祖阿曼",
["Zul'Drak"] = "祖达克",
["Zul'Farrak"] = "祖尔法拉克",
["Zul'Gurub"] = "祖尔格拉布",
}
elseif GAME_LOCALE == "zhTW" then
lib:SetCurrentTranslations {
["Ahn'kahet: The Old Kingdom"] = "安卡罕特:古王國",
["Ahn'Qiraj"] = "安其拉",
["Alliance Base"] = "聯盟營地",
["Alterac Mountains"] = "奧特蘭克山脈",
["Alterac Valley"] = "奧特蘭克山谷",
["Amani Pass"] = "阿曼尼小俓",
["Arathi Basin"] = "阿拉希盆地",
["Arathi Highlands"] = "阿拉希高地",
Armory = "軍械庫",
Ashenvale = "梣谷",
Auberdine = "奧伯丁",
["Auchenai Crypts"] = "奧奇奈地穴",
Auchindoun = "奧齊頓",
Azeroth = "艾澤拉斯",
["Azjol-Nerub"] = "阿茲歐-奈幽",
Azshara = "艾薩拉",
["Azuremyst Isle"] = "藍謎島",
Badlands = "荒蕪之地",
["Bash'ir Landing"] = "貝許爾平臺",
["Blackfathom Deeps"] = "黑暗深淵",
["Blackrock Depths"] = "黑石深淵",
["Blackrock Mountain"] = "黑石山",
["Blackrock Spire"] = "黑石塔",
["Black Temple"] = "黑暗神廟",
["Blackwing Lair"] = "黑翼之巢",
["Blade's Edge Arena"] = "劍刃競技場",
["Blade's Edge Mountains"] = "劍刃山脈",
["Blasted Lands"] = "詛咒之地",
["Bloodmyst Isle"] = "血謎島",
["Booty Bay"] = "藏寶海灣",
["Borean Tundra"] = "北風凍原",
["Burning Steppes"] = "燃燒平原",
Cathedral = "教堂",
["Caverns of Time"] = "時光之穴",
["Champions' Hall"] = "勇士大廳",
["Coilfang Reservoir"] = "盤牙洞穴",
Coldarra = "凜懼島",
["Cosmic map"] = "宇宙地圖",
["Crystalsong Forest"] = "水晶之歌森林",
["Crystal Spine"] = "水晶背脊",
Dalaran = "達拉然",
["Dalaran Arena"] = "達拉然競技場",
["Dalaran Sewers"] = "達拉然下水道",
["Darkmoon Faire"] = "暗月馬戲團",
Darkshore = "黑海岸",
Darnassus = "達納蘇斯",
["Deadwind Pass"] = "逆風小徑",
["Deeprun Tram"] = "礦道地鐵",
Desolace = "淒涼之地",
["Dire Maul"] = "厄運之槌",
["Dire Maul (East)"] = "厄運之槌 - 東",
["Dire Maul (North)"] = "厄運之槌 - 北",
["Dire Maul (West)"] = "厄運之槌 - 西",
Dragonblight = "龍骨荒野",
["Drak'Tharon Keep"] = "德拉克薩隆要塞",
["Dun Morogh"] = "丹莫洛",
Durotar = "杜洛塔",
Duskwood = "暮色森林",
["Dustwallow Marsh"] = "塵泥沼澤",
["Eastern Kingdoms"] = "東部王國",
["Eastern Plaguelands"] = "東瘟疫之地",
["Elwynn Forest"] = "艾爾文森林",
Everlook = "永望鎮",
["Eversong Woods"] = "永歌森林",
["Eye of the Storm"] = "暴風之眼",
Felwood = "費伍德森林",
Feralas = "菲拉斯",
["Forge Camp: Terror"] = "煉冶場:驚駭",
["Forge Camp: Wrath"] = "煉冶場:憤怒",
["Frostwyrm Lair"] = "冰霜巨龍的巢穴",
["Furywing's Perch"] = "狂怒之翼棲所",
Gadgetzan = "加基森",
["Gates of Ahn'Qiraj"] = "安其拉之門",
Ghostlands = "鬼魂之地",
Gnomeregan = "諾姆瑞根",
Graveyard = "墓地",
["Grizzly Hills"] = "灰白之丘",
["Grom'gol Base Camp"] = "格羅姆高營地",
["Gruul's Lair"] = "戈魯爾之巢",
Gundrak = "剛德拉克",
["Hall of Champions"] = "勇士大廳",
["Hall of Legends"] = "傳說大廳",
["Halls of Lightning"] = "雷光大廳",
["Halls of Stone"] = "石之大廳",
["Hellfire Citadel"] = "地獄火堡壘",
["Hellfire Peninsula"] = "地獄火半島",
["Hellfire Ramparts"] = "地獄火壁壘",
["Hillsbrad Foothills"] = "希爾斯布萊德丘陵",
["Horde Encampment"] = "部落營地",
["Howling Fjord"] = "凜風峽灣",
Hyjal = "海加爾山",
["Hyjal Summit"] = "海加爾山",
Icecrown = "寒冰皇冠",
["Icecrown Citadel"] = "冰冠城塞",
["Insidion's Perch"] = "印希迪恩棲所",
Ironforge = "鐵爐堡",
["Isle of Quel'Danas"] = "奎爾達納斯之島",
Kalimdor = "卡林多",
Karazhan = "卡拉贊",
["Krasus' Landing"] = "卡薩斯平臺",
Library = "圖書館",
["Loch Modan"] = "洛克莫丹",
["Lower Blackrock Spire"] = "低階黑石塔",
["Magisters' Terrace"] = "博學者殿堂",
["Magtheridon's Lair"] = "瑪瑟里頓的巢穴",
["Mana-Tombs"] = "法力墓地",
Maraudon = "瑪拉頓",
["Menethil Harbor"] = "米奈希爾港",
["Molten Core"] = "熔火之心",
Moonglade = "月光林地",
Mulgore = "莫高雷",
Nagrand = "納葛蘭",
["Nagrand Arena"] = "納葛蘭競技場",
Naxxramas = "納克薩瑪斯",
Netherstorm = "虛空風暴",
["Night Elf Village"] = "夜精靈村",
Northrend = "北裂境",
["Obsidia's Perch"] = "歐比希迪亞棲所",
["Ogri'la"] = "歐格利拉",
["Old Hillsbrad Foothills"] = "希爾斯布萊德丘陵舊址",
["Old Stratholme"] = "舊斯坦索姆",
["Onyxia's Lair"] = "奧妮克希亞的巢穴",
Orgrimmar = "奧格瑪",
Outland = "外域",
["Plaguelands: The Scarlet Enclave"] = "東瘟疫之地: 血色領區",
Plaguewood = "病木林",
["Quel'thalas"] = "奎爾薩拉斯",
["Ragefire Chasm"] = "怒焰裂谷",
Ratchet = "棘齒城",
["Razorfen Downs"] = "剃刀高地",
["Razorfen Kraul"] = "剃刀沼澤",
["Redridge Mountains"] = "赤脊山",
["Ring of Observance"] = "儀式競技場",
["Rivendark's Perch"] = "瑞文達科棲所",
["Ruins of Ahn'Qiraj"] = "安其拉廢墟",
["Ruins of Lordaeron"] = "羅德隆廢墟",
["Scarlet Monastery"] = "血色修道院",
Scholomance = "通靈學院",
["Searing Gorge"] = "灼熱峽谷",
["Serpentshrine Cavern"] = "毒蛇神殿洞穴",
["Sethekk Halls"] = "塞司克大廳",
["Shadowfang Keep"] = "影牙城堡",
["Shadow Labyrinth"] = "暗影迷宮",
["Shadowmoon Valley"] = "影月谷",
["Shartuul's Transporter"] = "夏圖歐的傳送門",
Shattrath = "撒塔斯城",
["Shattrath City"] = "撒塔斯城",
["Sholazar Basin"] = "休拉薩盆地",
Silithus = "希利蘇斯",
["Silvermoon City"] = "銀月城",
["Silverpine Forest"] = "銀松森林",
["Skyguard Outpost"] = "禦天者崗哨",
Stonard = "斯通納德",
["Stonetalon Mountains"] = "石爪山脈",
Stormwind = "暴風城",
["Stormwind City"] = "暴風城",
["Strand of the Ancients"] = "遠祖灘頭",
["Stranglethorn Vale"] = "荊棘谷",
Stratholme = "斯坦索姆",
["Sunken Temple"] = "沉沒的神廟",
["Sunwell Plateau"] = "太陽之井高地",
["Swamp of Sorrows"] = "悲傷沼澤",
Tanaris = "塔納利斯",
Teldrassil = "泰達希爾",
["Tempest Keep"] = "風暴要塞",
["Temple of Ahn'Qiraj"] = "安其拉神廟",
["Terokkar Forest"] = "泰洛卡森林",
["The Arachnid Quarter"] = "蜘蛛區",
["The Arcatraz"] = "亞克崔茲",
["The Barrens"] = "貧瘠之地",
["The Black Morass"] = "黑色沼澤",
["The Blood Furnace"] = "血熔爐",
["The Bone Wastes"] = "白骨荒野",
["The Botanica"] = "波塔尼卡",
["The Construct Quarter"] = "傀儡區",
["The Culling of Stratholme"] = "斯坦索姆的抉擇",
["The Dark Portal"] = "黑暗之門",
["The Deadmines"] = "死亡礦坑",
["The Descent into Madness"] = "驟狂斜廊",
["The Exodar"] = "艾克索達",
["The Eye"] = "風暴要塞",
["The Eye of Eternity"] = "永恆之眼",
["The Forbidding Sea"] = "禁忌之海",
["The Frozen Sea"] = "冰凍之海",
["The Great Sea"] = "無盡之海",
["The Hinterlands"] = "辛特蘭",
["The Mechanar"] = "麥克納爾",
["The Military Quarter"] = "軍事區",
["The Nexus"] = "奧核之心",
["The North Sea"] = "北方海岸",
["The Obsidian Sanctum"] = "黑曜聖所",
["The Oculus"] = "奧核之眼",
["The Plague Quarter"] = "瘟疫區",
["Theramore Isle"] = "塞拉摩島",
["The Ring of Valor"] = "勇武之環",
["The Shattered Halls"] = "破碎大廳",
["The Slave Pens"] = "奴隸監獄",
["The Spark of Imagination"] = "創思之廳",
["The Steamvault"] = "蒸汽洞窟",
["The Stockade"] = "監獄",
["The Storm Peaks"] = "風暴群山",
["The Temple of Atal'Hakkar"] = "阿塔哈卡神廟",
["The Underbog"] = "深幽泥沼",
["The Veiled Sea"] = "迷霧之海",
["The Violet Hold"] = "紫羅蘭堡",
["Thousand Needles"] = "千針石林",
["Thunder Bluff"] = "雷霆崖",
Tirisfal = "提里斯法林地",
["Tirisfal Glades"] = "提里斯法林地",
["Twisting Nether"] = "扭曲虛空",
Uldaman = "奧達曼",
Ulduar = "奧杜亞",
Undercity = "幽暗城",
["Un'Goro Crater"] = "安戈洛環形山",
["Upper Blackrock Spire"] = "高階黑石塔",
["Utgarde Keep"] = "俄特加德要塞",
["Utgarde Pinnacle"] = "俄特加德之巔",
["Vault of Archavon"] = "亞夏梵穹殿",
["Vortex Pinnacle"] = "漩渦尖塔",
["Wailing Caverns"] = "哀嚎洞穴",
["Warsong Gulch"] = "戰歌峽谷",
["Western Plaguelands"] = "西瘟疫之地",
Westfall = "西部荒野",
Wetlands = "濕地",
Wintergrasp = "冬握湖",
Winterspring = "冬泉谷",
["Wyrmrest Temple"] = "龍族神殿",
Zangarmarsh = "贊格沼澤",
["Zul'Aman"] = "祖阿曼",
["Zul'Drak"] = "祖爾德拉克",
["Zul'Farrak"] = "祖爾法拉克",
["Zul'Gurub"] = "祖爾格拉布",
}
 
else
error(("%s: Locale %q not supported"):format(MAJOR_VERSION, GAME_LOCALE))
end
EasyDaily/libs/LibBabble-Zone-3.0/lib.xml New file
0,0 → 1,5
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="LibBabble-3.0.lua" />
<Script file="LibBabble-Zone-3.0.lua" />
</Ui>
\ No newline at end of file
EasyDaily/libs/LibBabble-Zone-3.0/LibBabble-Zone-3.0.toc New file
0,0 → 1,18
## Interface: 30100
## LoadOnDemand: 1
## Title: Lib: Babble-Zone-3.0
## Notes: A library to help with localization of Zones.
## Notes-deDE: BabbleLib ist eine Bibliothek, die bei der Lokalisierung helfen soll.
## Notes-frFR: Une bibliothèque d'aide à la localisation.
## Notes-esES: Una biblioteca para ayudar con las localizaciones.
## Author: ckknight
## X-eMail: ckknight@gmail.com
## X-Category: Library
## X-License: MIT
## X-Curse-Packaged-Version: r207
## X-Curse-Project-Name: LibBabble-Zone-3.0
## X-Curse-Project-ID: libbabble-zone-3-0
## X-Curse-Repository-ID: wow/libbabble-zone-3-0/mainline
 
LibStub\LibStub.lua
lib.xml
EasyDaily/libs/LibBabble-Zone-3.0/LibBabble-3.0.lua New file
0,0 → 1,292
-- LibBabble-3.0 is hereby placed in the Public Domain
-- Credits: ckknight
local LIBBABBLE_MAJOR, LIBBABBLE_MINOR = "LibBabble-3.0", 2
 
local LibBabble = LibStub:NewLibrary(LIBBABBLE_MAJOR, LIBBABBLE_MINOR)
if not LibBabble then
return
end
 
local data = LibBabble.data or {}
for k,v in pairs(LibBabble) do
LibBabble[k] = nil
end
LibBabble.data = data
 
local tablesToDB = {}
for namespace, db in pairs(data) do
for k,v in pairs(db) do
tablesToDB[v] = db
end
end
 
local function warn(message)
local _, ret = pcall(error, message, 3)
geterrorhandler()(ret)
end
 
local lookup_mt = { __index = function(self, key)
local db = tablesToDB[self]
local current_key = db.current[key]
if current_key then
self[key] = current_key
return current_key
end
local base_key = db.base[key]
local real_MAJOR_VERSION
for k,v in pairs(data) do
if v == db then
real_MAJOR_VERSION = k
break
end
end
if not real_MAJOR_VERSION then
real_MAJOR_VERSION = LIBBABBLE_MAJOR
end
if base_key then
warn(("%s: Translation %q not found for locale %q"):format(real_MAJOR_VERSION, key, GetLocale()))
rawset(self, key, base_key)
return base_key
end
warn(("%s: Translation %q not found."):format(real_MAJOR_VERSION, key))
rawset(self, key, key)
return key
end }
 
local function initLookup(module, lookup)
local db = tablesToDB[module]
for k in pairs(lookup) do
lookup[k] = nil
end
setmetatable(lookup, lookup_mt)
tablesToDB[lookup] = db
db.lookup = lookup
return lookup
end
 
local function initReverse(module, reverse)
local db = tablesToDB[module]
for k in pairs(reverse) do
reverse[k] = nil
end
for k,v in pairs(db.current) do
reverse[v] = k
end
tablesToDB[reverse] = db
db.reverse = reverse
db.reverseIterators = nil
return reverse
end
 
local prototype = {}
local prototype_mt = {__index = prototype}
 
--[[---------------------------------------------------------------------------
Notes:
* If you try to access a nonexistent key, it will warn but allow the code to pass through.
Returns:
A lookup table for english to localized words.
Example:
local B = LibStub("LibBabble-Module-3.0") -- where Module is what you want.
local BL = B:GetLookupTable()
assert(BL["Some english word"] == "Some localized word")
DoSomething(BL["Some english word that doesn't exist"]) -- warning!
-----------------------------------------------------------------------------]]
function prototype:GetLookupTable()
local db = tablesToDB[self]
 
local lookup = db.lookup
if lookup then
return lookup
end
return initLookup(self, {})
end
--[[---------------------------------------------------------------------------
Notes:
* If you try to access a nonexistent key, it will return nil.
Returns:
A lookup table for english to localized words.
Example:
local B = LibStub("LibBabble-Module-3.0") -- where Module is what you want.
local B_has = B:GetUnstrictLookupTable()
assert(B_has["Some english word"] == "Some localized word")
assert(B_has["Some english word that doesn't exist"] == nil)
-----------------------------------------------------------------------------]]
function prototype:GetUnstrictLookupTable()
local db = tablesToDB[self]
 
return db.current
end
--[[---------------------------------------------------------------------------
Notes:
* If you try to access a nonexistent key, it will return nil.
* This is useful for checking if the base (English) table has a key, even if the localized one does not have it registered.
Returns:
A lookup table for english to localized words.
Example:
local B = LibStub("LibBabble-Module-3.0") -- where Module is what you want.
local B_hasBase = B:GetBaseLookupTable()
assert(B_hasBase["Some english word"] == "Some english word")
assert(B_hasBase["Some english word that doesn't exist"] == nil)
-----------------------------------------------------------------------------]]
function prototype:GetBaseLookupTable()
local db = tablesToDB[self]
 
return db.base
end
--[[---------------------------------------------------------------------------
Notes:
* If you try to access a nonexistent key, it will return nil.
* This will return only one English word that it maps to, if there are more than one to check, see :GetReverseIterator("word")
Returns:
A lookup table for localized to english words.
Example:
local B = LibStub("LibBabble-Module-3.0") -- where Module is what you want.
local BR = B:GetReverseLookupTable()
assert(BR["Some localized word"] == "Some english word")
assert(BR["Some localized word that doesn't exist"] == nil)
-----------------------------------------------------------------------------]]
function prototype:GetReverseLookupTable()
local db = tablesToDB[self]
 
local reverse = db.reverse
if reverse then
return reverse
end
return initReverse(self, {})
end
local blank = {}
local weakVal = {__mode='v'}
--[[---------------------------------------------------------------------------
Arguments:
string - the localized word to chek for.
Returns:
An iterator to traverse all English words that map to the given key
Example:
local B = LibStub("LibBabble-Module-3.0") -- where Module is what you want.
for word in B:GetReverseIterator("Some localized word") do
DoSomething(word)
end
-----------------------------------------------------------------------------]]
function prototype:GetReverseIterator(key)
local db = tablesToDB[self]
local reverseIterators = db.reverseIterators
if not reverseIterators then
reverseIterators = setmetatable({}, weakVal)
db.reverseIterators = reverseIterators
elseif reverseIterators[key] then
return pairs(reverseIterators[key])
end
local t
for k,v in pairs(db.current) do
if v == key then
if not t then
t = {}
end
t[k] = true
end
end
reverseIterators[key] = t or blank
return pairs(reverseIterators[key])
end
--[[---------------------------------------------------------------------------
Returns:
An iterator to traverse all translations English to localized.
Example:
local B = LibStub("LibBabble-Module-3.0") -- where Module is what you want.
for english, localized in B:Iterate() do
DoSomething(english, localized)
end
-----------------------------------------------------------------------------]]
function prototype:Iterate()
local db = tablesToDB[self]
 
return pairs(db.current)
end
 
-- #NODOC
-- modules need to call this to set the base table
function prototype:SetBaseTranslations(base)
local db = tablesToDB[self]
local oldBase = db.base
if oldBase then
for k in pairs(oldBase) do
oldBase[k] = nil
end
for k, v in pairs(base) do
oldBase[k] = v
end
base = oldBase
else
db.base = base
end
for k,v in pairs(base) do
if v == true then
base[k] = k
end
end
end
 
local function init(module)
local db = tablesToDB[module]
if db.lookup then
initLookup(module, db.lookup)
end
if db.reverse then
initReverse(module, db.reverse)
end
db.reverseIterators = nil
end
 
-- #NODOC
-- modules need to call this to set the current table. if current is true, use the base table.
function prototype:SetCurrentTranslations(current)
local db = tablesToDB[self]
if current == true then
db.current = db.base
else
local oldCurrent = db.current
if oldCurrent then
for k in pairs(oldCurrent) do
oldCurrent[k] = nil
end
for k, v in pairs(current) do
oldCurrent[k] = v
end
current = oldCurrent
else
db.current = current
end
end
init(self)
end
 
for namespace, db in pairs(data) do
setmetatable(db.module, prototype_mt)
init(db.module)
end
 
-- #NODOC
-- modules need to call this to create a new namespace.
function LibBabble:New(namespace, minor)
local module, oldminor = LibStub:NewLibrary(namespace, minor)
if not module then
return
end
 
if not oldminor then
local db = {
module = module,
}
data[namespace] = db
tablesToDB[module] = db
else
for k,v in pairs(module) do
module[k] = nil
end
end
 
setmetatable(module, prototype_mt)
 
return module
end
EasyDaily/libs/AceLocale-3.0/AceLocale-3.0.lua New file
0,0 → 1,128
--- **AceLocale-3.0** manages localization in addons, allowing for multiple locale to be registered with fallback to the base locale for untranslated strings.
-- @class file
-- @name AceLocale-3.0
-- @release $Id: AceLocale-3.0.lua 766 2009-04-04 08:26:05Z nevcairiel $
local MAJOR,MINOR = "AceLocale-3.0", 2
 
local AceLocale, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
 
if not AceLocale then return end -- no upgrade needed
 
local gameLocale = GetLocale()
if gameLocale == "enGB" then
gameLocale = "enUS"
end
 
AceLocale.apps = AceLocale.apps or {} -- array of ["AppName"]=localetableref
AceLocale.appnames = AceLocale.appnames or {} -- array of [localetableref]="AppName"
 
-- This metatable is used on all tables returned from GetLocale
local readmeta = {
__index = function(self, key) -- requesting totally unknown entries: fire off a nonbreaking error and return key
rawset(self, key, key) -- only need to see the warning once, really
geterrorhandler()(MAJOR..": "..tostring(AceLocale.appnames[self])..": Missing entry for '"..tostring(key).."'")
return key
end
}
 
-- This metatable is used on all tables returned from GetLocale if the silent flag is true, it does not issue a warning on unknown keys
local readmetasilent = {
__index = function(self, key) -- requesting totally unknown entries: return key
rawset(self, key, key) -- only need to invoke this function once
return key
end
}
 
-- Remember the locale table being registered right now (it gets set by :NewLocale())
-- NOTE: Do never try to register 2 locale tables at once and mix their definition.
local registering
 
-- local assert false function
local assertfalse = function() assert(false) end
 
-- This metatable proxy is used when registering nondefault locales
local writeproxy = setmetatable({}, {
__newindex = function(self, key, value)
rawset(registering, key, value == true and key or value) -- assigning values: replace 'true' with key string
end,
__index = assertfalse
})
 
-- This metatable proxy is used when registering the default locale.
-- It refuses to overwrite existing values
-- Reason 1: Allows loading locales in any order
-- Reason 2: If 2 modules have the same string, but only the first one to be
-- loaded has a translation for the current locale, the translation
-- doesn't get overwritten.
--
local writedefaultproxy = setmetatable({}, {
__newindex = function(self, key, value)
if not rawget(registering, key) then
rawset(registering, key, value == true and key or value)
end
end,
__index = assertfalse
})
 
--- Register a new locale (or extend an existing one) for the specified application.
-- :NewLocale will return a table you can fill your locale into, or nil if the locale isn't needed for the players
-- game locale.
-- @paramsig application, locale[, isDefault[, silent]]
-- @param application Unique name of addon / module
-- @param locale Name of the locale to register, e.g. "enUS", "deDE", etc.
-- @param isDefault If this is the default locale being registered (your addon is written in this language, generally enUS)
-- @param silent If true, the locale will not issue warnings for missing keys. Can only be set on the default locale.
-- @usage
-- -- enUS.lua
-- local L = LibStub("AceLocale-3.0"):NewLocale("TestLocale", "enUS", true)
-- L["string1"] = true
--
-- -- deDE.lua
-- local L = LibStub("AceLocale-3.0"):NewLocale("TestLocale", "deDE")
-- if not L then return end
-- L["string1"] = "Zeichenkette1"
-- @return Locale Table to add localizations to, or nil if the current locale is not required.
function AceLocale:NewLocale(application, locale, isDefault, silent)
 
if silent and not isDefault then
error("Usage: NewLocale(application, locale[, isDefault[, silent]]): 'silent' can only be specified for the default locale", 2)
end
 
-- GAME_LOCALE allows translators to test translations of addons without having that wow client installed
-- Ammo: I still think this is a bad idea, for instance an addon that checks for some ingame string will fail, just because some other addon
-- gives the user the illusion that they can run in a different locale? Ditch this whole thing or allow a setting per 'application'. I'm of the
-- opinion to remove this.
local gameLocale = GAME_LOCALE or gameLocale
 
if locale ~= gameLocale and not isDefault then
return -- nop, we don't need these translations
end
 
local app = AceLocale.apps[application]
 
if not app then
app = setmetatable({}, silent and readmetasilent or readmeta)
AceLocale.apps[application] = app
AceLocale.appnames[app] = application
end
 
registering = app -- remember globally for writeproxy and writedefaultproxy
 
if isDefault then
return writedefaultproxy
end
 
return writeproxy
end
 
--- Returns localizations for the current locale (or default locale if translations are missing).
-- Errors if nothing is registered (spank developer, not just a missing translation)
-- @param application Unique name of addon / module
-- @param silent If true, the locale is optional, silently return nil if it's not found (defaults to false, optional)
-- @return The locale table for the current language.
function AceLocale:GetLocale(application, silent)
if not silent and not AceLocale.apps[application] then
error("Usage: GetLocale(application[, silent]): 'application' - No locales registered for '"..tostring(application).."'", 2)
end
return AceLocale.apps[application]
end
EasyDaily/libs/AceLocale-3.0/AceLocale-3.0.xml New file
0,0 → 1,4
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="AceLocale-3.0.lua"/>
</Ui>
\ No newline at end of file
EasyDaily/libs/AceHook-3.0/AceHook-3.0.xml New file
0,0 → 1,4
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="AceHook-3.0.lua"/>
</Ui>
\ No newline at end of file
EasyDaily/libs/AceHook-3.0/AceHook-3.0.lua New file
0,0 → 1,511
--- **AceHook-3.0** offers safe Hooking/Unhooking of functions, methods and frame scripts.
-- Using AceHook-3.0 is recommended when you need to unhook your hooks again, so the hook chain isn't broken
-- when you manually restore the original function.
--
-- **AceHook-3.0** can be embeded into your addon, either explicitly by calling AceHook:Embed(MyAddon) or by
-- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
-- and can be accessed directly, without having to explicitly call AceHook itself.\\
-- It is recommended to embed AceHook, otherwise you'll have to specify a custom `self` on all calls you
-- make into AceHook.
-- @class file
-- @name AceHook-3.0
-- @release $Id: AceHook-3.0.lua 766 2009-04-04 08:26:05Z nevcairiel $
local ACEHOOK_MAJOR, ACEHOOK_MINOR = "AceHook-3.0", 5
local AceHook, oldminor = LibStub:NewLibrary(ACEHOOK_MAJOR, ACEHOOK_MINOR)
 
if not AceHook then return end -- No upgrade needed
 
AceHook.embeded = AceHook.embeded or {}
AceHook.registry = AceHook.registry or setmetatable({}, {__index = function(tbl, key) tbl[key] = {} return tbl[key] end })
AceHook.handlers = AceHook.handlers or {}
AceHook.actives = AceHook.actives or {}
AceHook.scripts = AceHook.scripts or {}
AceHook.onceSecure = AceHook.onceSecure or {}
AceHook.hooks = AceHook.hooks or {}
 
-- local upvalues
local registry = AceHook.registry
local handlers = AceHook.handlers
local actives = AceHook.actives
local scripts = AceHook.scripts
local onceSecure = AceHook.onceSecure
 
local _G = _G
local format = string.format
local next = next
local pairs = pairs
local type = type
 
-- functions for later definition
local donothing, createHook, hook
 
local protectedScripts = {
OnClick = true,
}
 
-- upgrading of embeded is done at the bottom of the file
 
local mixins = {
"Hook", "SecureHook",
"HookScript", "SecureHookScript",
"Unhook", "UnhookAll",
"IsHooked",
"RawHook", "RawHookScript"
}
 
-- AceHook:Embed( target )
-- target (object) - target object to embed AceHook in
--
-- Embeds AceEevent into the target object making the functions from the mixins list available on target:..
function AceHook:Embed( target )
for k, v in pairs( mixins ) do
target[v] = self[v]
end
self.embeded[target] = true
-- inject the hooks table safely
target.hooks = target.hooks or {}
return target
end
 
-- AceHook:OnEmbedDisable( target )
-- target (object) - target object that is being disabled
--
-- Unhooks all hooks when the target disables.
-- this method should be called by the target manually or by an addon framework
function AceHook:OnEmbedDisable( target )
target:UnhookAll()
end
 
function createHook(self, handler, orig, secure, failsafe)
local uid
local method = type(handler) == "string"
if failsafe and not secure then
-- failsafe hook creation
uid = function(...)
if actives[uid] then
if method then
self[handler](self, ...)
else
handler(...)
end
end
return orig(...)
end
-- /failsafe hook
else
-- all other hooks
uid = function(...)
if actives[uid] then
if method then
return self[handler](self, ...)
else
return handler(...)
end
elseif not secure then -- backup on non secure
return orig(...)
end
end
-- /hook
end
return uid
end
 
function donothing() end
 
function hook(self, obj, method, handler, script, secure, raw, forceSecure, usage)
if not handler then handler = method end
 
-- These asserts make sure AceHooks's devs play by the rules.
assert(not script or type(script) == "boolean")
assert(not secure or type(secure) == "boolean")
assert(not raw or type(raw) == "boolean")
assert(not forceSecure or type(forceSecure) == "boolean")
assert(usage)
 
-- Error checking Battery!
if obj and type(obj) ~= "table" then
error(format("%s: 'object' - nil or table expected got %s", usage, type(obj)), 3)
end
if type(method) ~= "string" then
error(format("%s: 'method' - string expected got %s", usage, type(method)), 3)
end
if type(handler) ~= "string" and type(handler) ~= "function" then
error(format("%s: 'handler' - nil, string, or function expected got %s", usage, type(handler)), 3)
end
if type(handler) == "string" and type(self[handler]) ~= "function" then
error(format("%s: 'handler' - Handler specified does not exist at self[handler]", usage), 3)
end
if script then
if not secure and obj:IsProtected() and protectedScripts[method] then
error(format("Cannot hook secure script %q; Use SecureHookScript(obj, method, [handler]) instead.", method), 3)
end
if not obj or not obj.GetScript or not obj:HasScript(method) then
error(format("%s: You can only hook a script on a frame object", usage), 3)
end
else
local issecure
if obj then
issecure = onceSecure[obj] and onceSecure[obj][method] or issecurevariable(obj, method)
else
issecure = onceSecure[method] or issecurevariable(method)
end
if issecure then
if forceSecure then
if obj then
onceSecure[obj] = onceSecure[obj] or {}
onceSecure[obj][method] = true
else
onceSecure[method] = true
end
elseif not secure then
error(format("%s: Attempt to hook secure function %s. Use `SecureHook' or add `true' to the argument list to override.", usage, method), 3)
end
end
end
 
local uid
if obj then
uid = registry[self][obj] and registry[self][obj][method]
else
uid = registry[self][method]
end
 
if uid then
if actives[uid] then
-- Only two sane choices exist here. We either a) error 100% of the time or b) always unhook and then hook
-- choice b would likely lead to odd debuging conditions or other mysteries so we're going with a.
error(format("Attempting to rehook already active hook %s.", method))
end
 
if handlers[uid] == handler then -- turn on a decative hook, note enclosures break this ability, small memory leak
actives[uid] = true
return
elseif obj then -- is there any reason not to call unhook instead of doing the following several lines?
if self.hooks and self.hooks[obj] then
self.hooks[obj][method] = nil
end
registry[self][obj][method] = nil
else
if self.hooks then
self.hooks[method] = nil
end
registry[self][method] = nil
end
handlers[uid], actives[uid], scripts[uid] = nil, nil, nil
uid = nil
end
 
local orig
if script then
orig = obj:GetScript(method) or donothing
elseif obj then
orig = obj[method]
else
orig = _G[method]
end
 
if not orig then
error(format("%s: Attempting to hook a non existing target", usage), 3)
end
 
uid = createHook(self, handler, orig, secure, not (raw or secure))
 
if obj then
self.hooks[obj] = self.hooks[obj] or {}
registry[self][obj] = registry[self][obj] or {}
registry[self][obj][method] = uid
 
if not secure then
self.hooks[obj][method] = orig
end
 
if script then
-- If the script is empty before, HookScript will not work, so use SetScript instead
-- This will make the hook insecure, but shouldnt matter, since it was empty before.
-- It does not taint the full frame.
if not secure or orig == donothing then
obj:SetScript(method, uid)
elseif secure then
obj:HookScript(method, uid)
end
else
if not secure then
obj[method] = uid
else
hooksecurefunc(obj, method, uid)
end
end
else
registry[self][method] = uid
 
if not secure then
_G[method] = uid
self.hooks[method] = orig
else
hooksecurefunc(method, uid)
end
end
 
actives[uid], handlers[uid], scripts[uid] = true, handler, script and true or nil
end
 
--- Hook a function or a method on an object.
-- The hook created will be a "safe hook", that means that your handler will be called
-- before the hooked function ("Pre-Hook"), and you don't have to call the original function yourself,
-- however you cannot stop the execution of the function, or modify any of the arguments/return values.\\
-- This type of hook is typically used if you need to know if some function got called, and don't want to modify it.
-- @paramsig [object], method, [handler], [hookSecure]
-- @param object The object to hook a method from
-- @param method If object was specified, the name of the method, or the name of the function to hook.
-- @param handler The handler for the hook, a funcref or a method name. (Defaults to the name of the hooked function)
-- @param hookSecure If true, AceHook will allow hooking of secure functions.
-- @usage
-- -- create an addon with AceHook embeded
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("HookDemo", "AceHook-3.0")
--
-- function MyAddon:OnEnable()
-- -- Hook ActionButton_UpdateHotkeys, overwriting the secure status
-- self:Hook("ActionButton_UpdateHotkeys", true)
-- end
--
-- function MyAddon:ActionButton_UpdateHotkeys(button, type)
-- print(button:GetName() .. " is updating its HotKey")
-- end
function AceHook:Hook(object, method, handler, hookSecure)
if type(object) == "string" then
method, handler, hookSecure, object = object, method, handler, nil
end
 
if handler == true then
handler, hookSecure = nil, true
end
 
hook(self, object, method, handler, false, false, false, hookSecure or false, "Usage: Hook([object], method, [handler], [hookSecure])")
end
 
--- RawHook a function or a method on an object.
-- The hook created will be a "raw hook", that means that your handler will completly replace
-- the original function, and your handler has to call the original function (or not, depending on your intentions).\\
-- The original function will be stored in `self.hooks[object][method]` or `self.hooks[functionName]` respectively.\\
-- This type of hook can be used for all purposes, and is usually the most common case when you need to modify arguments
-- or want to control execution of the original function.
-- @paramsig [object], method, [handler], [hookSecure]
-- @param object The object to hook a method from
-- @param method If object was specified, the name of the method, or the name of the function to hook.
-- @param handler The handler for the hook, a funcref or a method name. (Defaults to the name of the hooked function)
-- @param hookSecure If true, AceHook will allow hooking of secure functions.
-- @usage
-- -- create an addon with AceHook embeded
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("HookDemo", "AceHook-3.0")
--
-- function MyAddon:OnEnable()
-- -- Hook ActionButton_UpdateHotkeys, overwriting the secure status
-- self:RawHook("ActionButton_UpdateHotkeys", true)
-- end
--
-- function MyAddon:ActionButton_UpdateHotkeys(button, type)
-- if button:GetName() == "MyButton" then
-- -- do stuff here
-- else
-- self.hooks.ActionButton_UpdateHotkeys(button, type)
-- end
-- end
function AceHook:RawHook(object, method, handler, hookSecure)
if type(object) == "string" then
method, handler, hookSecure, object = object, method, handler, nil
end
 
if handler == true then
handler, hookSecure = nil, true
end
 
hook(self, object, method, handler, false, false, true, hookSecure or false, "Usage: RawHook([object], method, [handler], [hookSecure])")
end
 
--- SecureHook a function or a method on an object.
-- This function is a wrapper around the `hooksecurefunc` function in the WoW API. Using AceHook
-- extends the functionality of secure hooks, and adds the ability to unhook once the hook isn't
-- required anymore, or the addon is being disabled.\\
-- Secure Hooks should be used if the secure-status of the function is vital to its function,
-- and taint would block execution. Secure Hooks are always called after the original function was called
-- ("Post Hook"), and you cannot modify the arguments, return values or control the execution.
-- @paramsig [object], method, [handler]
-- @param object The object to hook a method from
-- @param method If object was specified, the name of the method, or the name of the function to hook.
-- @param handler The handler for the hook, a funcref or a method name. (Defaults to the name of the hooked function)
function AceHook:SecureHook(object, method, handler)
if type(object) == "string" then
method, handler, object = object, method, nil
end
 
hook(self, object, method, handler, false, true, false, false, "Usage: SecureHook([object], method, [handler])")
end
 
--- Hook a script handler on a frame.
-- The hook created will be a "safe hook", that means that your handler will be called
-- before the hooked script ("Pre-Hook"), and you don't have to call the original function yourself,
-- however you cannot stop the execution of the function, or modify any of the arguments/return values.\\
-- This is the frame script equivalent of the :Hook safe-hook. It would typically be used to be notified
-- when a certain event happens to a frame.
-- @paramsig frame, script, [handler]
-- @param frame The Frame to hook the script on
-- @param script The script to hook
-- @param handler The handler for the hook, a funcref or a method name. (Defaults to the name of the hooked script)
-- @usage
-- -- create an addon with AceHook embeded
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("HookDemo", "AceHook-3.0")
--
-- function MyAddon:OnEnable()
-- -- Hook the OnShow of FriendsFrame
-- self:HookScript(FriendsFrame, "OnShow", "FriendsFrameOnShow")
-- end
--
-- function MyAddon:FriendsFrameOnShow(frame)
-- print("The FriendsFrame was shown!")
-- end
function AceHook:HookScript(frame, script, handler)
hook(self, frame, script, handler, true, false, false, false, "Usage: HookScript(object, method, [handler])")
end
 
--- RawHook a script handler on a frame.
-- The hook created will be a "raw hook", that means that your handler will completly replace
-- the original script, and your handler has to call the original script (or not, depending on your intentions).\\
-- The original script will be stored in `self.hooks[frame][script]`.\\
-- This type of hook can be used for all purposes, and is usually the most common case when you need to modify arguments
-- or want to control execution of the original script.
-- @paramsig frame, script, [handler]
-- @param frame The Frame to hook the script on
-- @param script The script to hook
-- @param handler The handler for the hook, a funcref or a method name. (Defaults to the name of the hooked script)
-- @usage
-- -- create an addon with AceHook embeded
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("HookDemo", "AceHook-3.0")
--
-- function MyAddon:OnEnable()
-- -- Hook the OnShow of FriendsFrame
-- self:RawHookScript(FriendsFrame, "OnShow", "FriendsFrameOnShow")
-- end
--
-- function MyAddon:FriendsFrameOnShow(frame)
-- -- Call the original function
-- self.hooks[frame].OnShow(frame)
-- -- Do our processing
-- -- .. stuff
-- end
function AceHook:RawHookScript(frame, script, handler)
hook(self, frame, script, handler, true, false, true, false, "Usage: RawHookScript(object, method, [handler])")
end
 
--- SecureHook a script handler on a frame.
-- This function is a wrapper around the `frame:HookScript` function in the WoW API. Using AceHook
-- extends the functionality of secure hooks, and adds the ability to unhook once the hook isn't
-- required anymore, or the addon is being disabled.\\
-- Secure Hooks should be used if the secure-status of the function is vital to its function,
-- and taint would block execution. Secure Hooks are always called after the original function was called
-- ("Post Hook"), and you cannot modify the arguments, return values or control the execution.
-- @paramsig frame, script, [handler]
-- @param frame The Frame to hook the script on
-- @param script The script to hook
-- @param handler The handler for the hook, a funcref or a method name. (Defaults to the name of the hooked script)
function AceHook:SecureHookScript(frame, script, handler)
hook(self, frame, script, handler, true, true, false, false, "Usage: SecureHookScript(object, method, [handler])")
end
 
--- Unhook from the specified function, method or script.
-- @paramsig [obj], method
-- @param obj The object or frame to unhook from
-- @param method The name of the method, function or script to unhook from.
function AceHook:Unhook(obj, method)
local usage = "Usage: Unhook([obj], method)"
if type(obj) == "string" then
method, obj = obj, nil
end
 
if obj and type(obj) ~= "table" then
error(format("%s: 'obj' - expecting nil or table got %s", usage, type(obj)), 2)
end
if type(method) ~= "string" then
error(format("%s: 'method' - expeting string got %s", usage, type(method)), 2)
end
 
local uid
if obj then
uid = registry[self][obj] and registry[self][obj][method]
else
uid = registry[self][method]
end
 
if not uid or not actives[uid] then
-- Declining to error on an unneeded unhook since the end effect is the same and this would just be annoying.
return false
end
 
actives[uid], handlers[uid] = nil, nil
 
if obj then
registry[self][obj][method] = nil
registry[self][obj] = next(registry[self][obj]) and registry[self][obj] or nil
 
-- if the hook reference doesnt exist, then its a secure hook, just bail out and dont do any unhooking
if not self.hooks[obj] or not self.hooks[obj][method] then return true end
 
if scripts[uid] and obj:GetScript(method) == uid then -- unhooks scripts
obj:SetScript(method, self.hooks[obj][method] ~= donothing and self.hooks[obj][method] or nil)
scripts[uid] = nil
elseif obj and self.hooks[obj] and self.hooks[obj][method] and obj[method] == uid then -- unhooks methods
obj[method] = self.hooks[obj][method]
end
 
self.hooks[obj][method] = nil
self.hooks[obj] = next(self.hooks[obj]) and self.hooks[obj] or nil
else
registry[self][method] = nil
 
-- if self.hooks[method] doesn't exist, then this is a SecureHook, just bail out
if not self.hooks[method] then return true end
 
if self.hooks[method] and _G[method] == uid then -- unhooks functions
_G[method] = self.hooks[method]
end
 
self.hooks[method] = nil
end
return true
end
 
--- Unhook all existing hooks for this addon.
function AceHook:UnhookAll()
for key, value in pairs(registry[self]) do
if type(key) == "table" then
for method in pairs(value) do
self:Unhook(key, method)
end
else
self:Unhook(key)
end
end
end
 
--- Check if the specific function, method or script is already hooked.
-- @paramsig [obj], method
-- @param obj The object or frame to unhook from
-- @param method The name of the method, function or script to unhook from.
function AceHook:IsHooked(obj, method)
-- we don't check if registry[self] exists, this is done by evil magicks in the metatable
if type(obj) == "string" then
if registry[self][obj] and actives[registry[self][obj]] then
return true, handlers[registry[self][obj]]
end
else
if registry[self][obj] and registry[self][obj][method] and actives[registry[self][obj][method]] then
return true, handlers[registry[self][obj][method]]
end
end
 
return false, nil
end
 
--- Upgrade our old embeded
for target, v in pairs( AceHook.embeded ) do
AceHook:Embed( target )
end
EasyDaily/libs/AceDBOptions-3.0/AceDBOptions-3.0.xml New file
0,0 → 1,4
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="AceDBOptions-3.0.lua"/>
</Ui>
\ No newline at end of file
EasyDaily/libs/AceDBOptions-3.0/AceDBOptions-3.0.lua New file
0,0 → 1,396
--- AceDBOptions-3.0 provides a universal AceConfig options screen for managing AceDB-3.0 profiles.
-- @class file
-- @name AceDBOptions-3.0
-- @release $Id: AceDBOptions-3.0.lua 765 2009-04-03 19:14:41Z nevcairiel $
local ACEDBO_MAJOR, ACEDBO_MINOR = "AceDBOptions-3.0", 10
local AceDBOptions, oldminor = LibStub:NewLibrary(ACEDBO_MAJOR, ACEDBO_MINOR)
 
if not AceDBOptions then return end -- No upgrade needed
 
AceDBOptions.optionTables = AceDBOptions.optionTables or {}
AceDBOptions.handlers = AceDBOptions.handlers or {}
 
--[[
Localization of AceDBOptions-3.0
]]
 
local L = {
default = "Default",
intro = "You can change the active database profile, so you can have different settings for every character.",
reset_desc = "Reset the current profile back to its default values, in case your configuration is broken, or you simply want to start over.",
reset = "Reset Profile",
reset_sub = "Reset the current profile to the default",
choose_desc = "You can either create a new profile by entering a name in the editbox, or choose one of the already exisiting profiles.",
new = "New",
new_sub = "Create a new empty profile.",
choose = "Existing Profiles",
choose_sub = "Select one of your currently available profiles.",
copy_desc = "Copy the settings from one existing profile into the currently active profile.",
copy = "Copy From",
delete_desc = "Delete existing and unused profiles from the database to save space, and cleanup the SavedVariables file.",
delete = "Delete a Profile",
delete_sub = "Deletes a profile from the database.",
delete_confirm = "Are you sure you want to delete the selected profile?",
profiles = "Profiles",
profiles_sub = "Manage Profiles",
}
 
local LOCALE = GetLocale()
if LOCALE == "deDE" then
L["default"] = "Standard"
L["intro"] = "Hier kannst du das aktive Datenbankprofile \195\164ndern, damit du verschiedene Einstellungen f\195\188r jeden Charakter erstellen kannst, wodurch eine sehr flexible Konfiguration m\195\182glich wird."
L["reset_desc"] = "Setzt das momentane Profil auf Standardwerte zur\195\188ck, f\195\188r den Fall das mit der Konfiguration etwas schief lief oder weil du einfach neu starten willst."
L["reset"] = "Profil zur\195\188cksetzen"
L["reset_sub"] = "Das aktuelle Profil auf Standard zur\195\188cksetzen."
L["choose_desc"] = "Du kannst ein neues Profil erstellen, indem du einen neuen Namen in der Eingabebox 'Neu' eingibst, oder w\195\164hle eines der vorhandenen Profile aus."
L["new"] = "Neu"
L["new_sub"] = "Ein neues Profil erstellen."
L["choose"] = "Vorhandene Profile"
L["choose_sub"] = "W\195\164hlt ein bereits vorhandenes Profil aus."
L["copy_desc"] = "Kopiere die Einstellungen von einem vorhandenen Profil in das aktive Profil."
L["copy"] = "Kopieren von..."
L["delete_desc"] = "L\195\182sche vorhandene oder unbenutzte Profile aus der Datenbank um Platz zu sparen und um die SavedVariables Datei 'sauber' zu halten."
L["delete"] = "Profil l\195\182schen"
L["delete_sub"] = "L\195\182scht ein Profil aus der Datenbank."
L["delete_confirm"] = "Willst du das ausgew\195\164hlte Profil wirklich l\195\182schen?"
L["profiles"] = "Profile"
L["profiles_sub"] = "Profile verwalten"
elseif LOCALE == "frFR" then
L["default"] = "D\195\169faut"
L["intro"] = "Vous pouvez changer le profil actuel afin d'avoir des param\195\168tres diff\195\169rents pour chaque personnage, permettant ainsi d'avoir une configuration tr\195\168s flexible."
L["reset_desc"] = "R\195\169initialise le profil actuel au cas o\195\185 votre configuration est corrompue ou si vous voulez tout simplement faire table rase."
L["reset"] = "R\195\169initialiser le profil"
L["reset_sub"] = "R\195\169initialise le profil actuel avec les param\195\168tres par d\195\169faut."
L["choose_desc"] = "Vous pouvez cr\195\169er un nouveau profil en entrant un nouveau nom dans la bo\195\174te de saisie, ou en choississant un des profils d\195\169j\195\160 existants."
L["new"] = "Nouveau"
L["new_sub"] = "Cr\195\169\195\169e un nouveau profil vierge."
L["choose"] = "Profils existants"
L["choose_sub"] = "Permet de choisir un des profils d\195\169j\195\160 disponibles."
L["copy_desc"] = "Copie les param\195\168tres d'un profil d\195\169j\195\160 existant dans le profil actuellement actif."
L["copy"] = "Copier \195\160 partir de"
L["delete_desc"] = "Supprime les profils existants inutilis\195\169s de la base de donn\195\169es afin de gagner de la place et de nettoyer le fichier SavedVariables."
L["delete"] = "Supprimer un profil"
L["delete_sub"] = "Supprime un profil de la base de donn\195\169es."
L["delete_confirm"] = "Etes-vous s\195\187r de vouloir supprimer le profil s\195\169lectionn\195\169 ?"
L["profiles"] = "Profils"
L["profiles_sub"] = "Gestion des profils"
elseif LOCALE == "koKR" then
L["default"] = "기본값"
L["intro"] = "모든 캐릭터의 다양한 설정과 사용중인 데이터베이스 프로필, 어느것이던지 매우 다루기 쉽게 바꿀수 있습니다."
L["reset_desc"] = "단순히 다시 새롭게 구성을 원하는 경우, 현재 프로필을 기본값으로 초기화 합니다."
L["reset"] = "프로필 초기화"
L["reset_sub"] = "현재의 프로필을 기본값으로 초기화 합니다"
L["choose_desc"] = "새로운 이름을 입력하거나, 이미 있는 프로필중 하나를 선택하여 새로운 프로필을 만들 수 있습니다."
L["new"] = "새로운 프로필"
L["new_sub"] = "새로운 프로필을 만듭니다."
L["choose"] = "프로필 선택"
L["choose_sub"] = "당신이 현재 이용할수 있는 프로필을 선택합니다."
L["copy_desc"] = "현재 사용중인 프로필에, 선택한 프로필의 설정을 복사합니다."
L["copy"] = "복사"
L["delete_desc"] = "데이터베이스에 사용중이거나 저장된 프로파일 삭제로 SavedVariables 파일의 정리와 공간 절약이 됩니다."
L["delete"] = "프로필 삭제"
L["delete_sub"] = "데이터베이스의 프로필을 삭제합니다."
L["delete_confirm"] = "정말로 선택한 프로필의 삭제를 원하십니까?"
L["profiles"] = "프로필"
L["profiles_sub"] = "프로필 설정"
elseif LOCALE == "esES" then
L["default"] = "Por defecto"
L["intro"] = "Puedes cambiar el perfil activo de tal manera que cada personaje tenga diferentes configuraciones."
L["reset_desc"] = "Reinicia el perfil actual a los valores por defectos, en caso de que se haya estropeado la configuración o quieras volver a empezar de nuevo."
L["reset"] = "Reiniciar Perfil"
L["reset_sub"] = "Reinicar el perfil actual al de por defecto"
L["choose_desc"] = "Puedes crear un nuevo perfil introduciendo un nombre en el recuadro o puedes seleccionar un perfil de los ya existentes."
L["new"] = "Nuevo"
L["new_sub"] = "Crear un nuevo perfil vacio."
L["choose"] = "Perfiles existentes"
L["choose_sub"] = "Selecciona uno de los perfiles disponibles."
L["copy_desc"] = "Copia los ajustes de un perfil existente al perfil actual."
L["copy"] = "Copiar de"
L["delete_desc"] = "Borra los perfiles existentes y sin uso de la base de datos para ganar espacio y limpiar el archivo SavedVariables."
L["delete"] = "Borrar un Perfil"
L["delete_sub"] = "Borra un perfil de la base de datos."
L["delete_confirm"] = "¿Estas seguro que quieres borrar el perfil seleccionado?"
L["profiles"] = "Perfiles"
L["profiles_sub"] = "Manejar Perfiles"
elseif LOCALE == "zhTW" then
L["default"] = "預設"
L["intro"] = "你可以選擇一個活動的資料設定檔,這樣你的每個角色就可以擁有不同的設定值,可以給你的插件設定帶來極大的靈活性。"
L["reset_desc"] = "將當前的設定檔恢復到它的預設值,用於你的設定檔損壞,或者你只是想重來的情況。"
L["reset"] = "重置設定檔"
L["reset_sub"] = "將當前的設定檔恢復為預設值"
L["choose_desc"] = "你可以通過在文本框內輸入一個名字創立一個新的設定檔,也可以選擇一個已經存在的設定檔。"
L["new"] = "新建"
L["new_sub"] = "新建一個空的設定檔。"
L["choose"] = "現有的設定檔"
L["choose_sub"] = "從當前可用的設定檔裏面選擇一個。"
L["copy_desc"] = "從當前某個已保存的設定檔複製到當前正使用的設定檔。"
L["copy"] = "複製自"
L["delete_desc"] = "從資料庫裏刪除不再使用的設定檔,以節省空間,並且清理SavedVariables檔。"
L["delete"] = "刪除一個設定檔"
L["delete_sub"] = "從資料庫裏刪除一個設定檔。"
L["delete_confirm"] = "你確定要刪除所選擇的設定檔嗎?"
L["profiles"] = "設定檔"
L["profiles_sub"] = "管理設定檔"
elseif LOCALE == "zhCN" then
L["default"] = "默认"
L["intro"] = "你可以选择一个活动的数据配置文件,这样你的每个角色就可以拥有不同的设置值,可以给你的插件配置带来极大的灵活性。"
L["reset_desc"] = "将当前的配置文件恢复到它的默认值,用于你的配置文件损坏,或者你只是想重来的情况。"
L["reset"] = "重置配置文件"
L["reset_sub"] = "将当前的配置文件恢复为默认值"
L["choose_desc"] = "你可以通过在文本框内输入一个名字创立一个新的配置文件,也可以选择一个已经存在的配置文件。"
L["new"] = "新建"
L["new_sub"] = "新建一个空的配置文件。"
L["choose"] = "现有的配置文件"
L["choose_sub"] = "从当前可用的配置文件里面选择一个。"
L["copy_desc"] = "从当前某个已保存的配置文件复制到当前正使用的配置文件。"
L["copy"] = "复制自"
L["delete_desc"] = "从数据库里删除不再使用的配置文件,以节省空间,并且清理SavedVariables文件。"
L["delete"] = "删除一个配置文件"
L["delete_sub"] = "从数据库里删除一个配置文件。"
L["delete_confirm"] = "你确定要删除所选择的配置文件么?"
L["profiles"] = "配置文件"
L["profiles_sub"] = "管理配置文件"
elseif LOCALE == "ruRU" then
L["default"] = "По умолчанию"
L["intro"] = "Изменяя активный профиль, вы можете задать различные настройки модификаций для каждого персонажа."
L["reset_desc"] = "Если ваша конфигурации испорчена или если вы хотите настроить всё заново - сбросьте текущий профиль на стандартные значения."
L["reset"] = "Сброс профиля"
L["reset_sub"] = "Сброс текущего профиля на стандартный"
L["choose_desc"] = "Вы можете создать новый профиль, введя название в поле ввода, или выбрать один из уже существующих профилей."
L["new"] = "Новый"
L["new_sub"] = "Создать новый чистый профиль"
L["choose"] = "Существующие профили"
L["choose_sub"] = "Выбор одиного из уже доступных профилей"
L["copy_desc"] = "Скопировать настройки из выбранного профиля в активный."
L["copy"] = "Скопировать из"
L["delete_desc"] = "Удалить существующий и неиспользуемый профиль из БД для сохранения места, и очистить SavedVariables файл."
L["delete"] = "Удалить профиль"
L["delete_sub"] = "Удаление профиля из БД"
L["delete_confirm"] = "Вы уверены, что вы хотите удалить выбранный профиль?"
L["profiles"] = "Профили"
L["profiles_sub"] = "Управление профилями"
end
 
local defaultProfiles
local tmpprofiles = {}
 
-- Get a list of available profiles for the specified database.
-- You can specify which profiles to include/exclude in the list using the two boolean parameters listed below.
-- @param db The db object to retrieve the profiles from
-- @param common If true, getProfileList will add the default profiles to the return list, even if they have not been created yet
-- @param nocurrent If true, then getProfileList will not display the current profile in the list
-- @return Hashtable of all profiles with the internal name as keys and the display name as value.
local function getProfileList(db, common, nocurrent)
local profiles = {}
 
-- copy existing profiles into the table
local currentProfile = db:GetCurrentProfile()
for i,v in pairs(db:GetProfiles(tmpprofiles)) do
if not (nocurrent and v == currentProfile) then
profiles[v] = v
end
end
 
-- add our default profiles to choose from ( or rename existing profiles)
for k,v in pairs(defaultProfiles) do
if (common or profiles[k]) and not (nocurrent and k == currentProfile) then
profiles[k] = v
end
end
 
return profiles
end
 
--[[
OptionsHandlerPrototype
prototype class for handling the options in a sane way
]]
local OptionsHandlerPrototype = {}
 
--[[ Reset the profile ]]
function OptionsHandlerPrototype:Reset()
self.db:ResetProfile()
end
 
--[[ Set the profile to value ]]
function OptionsHandlerPrototype:SetProfile(info, value)
self.db:SetProfile(value)
end
 
--[[ returns the currently active profile ]]
function OptionsHandlerPrototype:GetCurrentProfile()
return self.db:GetCurrentProfile()
end
 
--[[
List all active profiles
you can control the output with the .arg variable
currently four modes are supported
 
(empty) - return all available profiles
"nocurrent" - returns all available profiles except the currently active profile
"common" - returns all avaialble profiles + some commonly used profiles ("char - realm", "realm", "class", "Default")
"both" - common except the active profile
]]
function OptionsHandlerPrototype:ListProfiles(info)
local arg = info.arg
local profiles
if arg == "common" and not self.noDefaultProfiles then
profiles = getProfileList(self.db, true, nil)
elseif arg == "nocurrent" then
profiles = getProfileList(self.db, nil, true)
elseif arg == "both" then -- currently not used
profiles = getProfileList(self.db, (not self.noDefaultProfiles) and true, true)
else
profiles = getProfileList(self.db)
end
 
return profiles
end
 
function OptionsHandlerPrototype:HasNoProfiles(info)
local profiles = self:ListProfiles(info)
return ((not next(profiles)) and true or false)
end
 
--[[ Copy a profile ]]
function OptionsHandlerPrototype:CopyProfile(info, value)
self.db:CopyProfile(value)
end
 
--[[ Delete a profile from the db ]]
function OptionsHandlerPrototype:DeleteProfile(info, value)
self.db:DeleteProfile(value)
end
 
--[[ fill defaultProfiles with some generic values ]]
local function generateDefaultProfiles(db)
defaultProfiles = {
["Default"] = L["default"],
[db.keys.char] = db.keys.char,
[db.keys.realm] = db.keys.realm,
[db.keys.class] = UnitClass("player")
}
end
 
--[[ create and return a handler object for the db, or upgrade it if it already existed ]]
local function getOptionsHandler(db, noDefaultProfiles)
if not defaultProfiles then
generateDefaultProfiles(db)
end
 
local handler = AceDBOptions.handlers[db] or { db = db, noDefaultProfiles = noDefaultProfiles }
 
for k,v in pairs(OptionsHandlerPrototype) do
handler[k] = v
end
 
AceDBOptions.handlers[db] = handler
return handler
end
 
--[[
the real options table
]]
local optionsTable = {
desc = {
order = 1,
type = "description",
name = L["intro"] .. "\n",
},
descreset = {
order = 9,
type = "description",
name = L["reset_desc"],
},
reset = {
order = 10,
type = "execute",
name = L["reset"],
desc = L["reset_sub"],
func = "Reset",
},
choosedesc = {
order = 20,
type = "description",
name = "\n" .. L["choose_desc"],
},
new = {
name = L["new"],
desc = L["new_sub"],
type = "input",
order = 30,
get = false,
set = "SetProfile",
},
choose = {
name = L["choose"],
desc = L["choose_sub"],
type = "select",
order = 40,
get = "GetCurrentProfile",
set = "SetProfile",
values = "ListProfiles",
arg = "common",
},
copydesc = {
order = 50,
type = "description",
name = "\n" .. L["copy_desc"],
},
copyfrom = {
order = 60,
type = "select",
name = L["copy"],
desc = L["copy_desc"],
get = false,
set = "CopyProfile",
values = "ListProfiles",
disabled = "HasNoProfiles",
arg = "nocurrent",
},
deldesc = {
order = 70,
type = "description",
name = "\n" .. L["delete_desc"],
},
delete = {
order = 80,
type = "select",
name = L["delete"],
desc = L["delete_sub"],
get = false,
set = "DeleteProfile",
values = "ListProfiles",
disabled = "HasNoProfiles",
arg = "nocurrent",
confirm = true,
confirmText = L["delete_confirm"],
},
}
 
--- Get/Create a option table that you can use in your addon to control the profiles of AceDB-3.0.
-- @param db The database object to create the options table for.
-- @return The options table to be used in AceConfig-3.0
-- @usage
-- -- Assuming `options` is your top-level options table and `self.db` is your database:
-- options.args.profiles = LibStub("AceDBOptions-3.0"):GetOptionsTable(self.db)
function AceDBOptions:GetOptionsTable(db, noDefaultProfiles)
local tbl = AceDBOptions.optionTables[db] or {
type = "group",
name = L["profiles"],
desc = L["profiles_sub"],
}
 
tbl.handler = getOptionsHandler(db, noDefaultProfiles)
tbl.args = optionsTable
 
AceDBOptions.optionTables[db] = tbl
return tbl
end
 
-- upgrade existing tables
for db,tbl in pairs(AceDBOptions.optionTables) do
tbl.handler = getOptionsHandler(db)
tbl.args = optionsTable
end
EasyDaily/libs/AceConsole-3.0/AceConsole-3.0.xml New file
0,0 → 1,4
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="AceConsole-3.0.lua"/>
</Ui>
\ No newline at end of file
EasyDaily/libs/AceConsole-3.0/AceConsole-3.0.lua New file
0,0 → 1,223
--- **AceConsole-3.0** provides registration facilities for slash commands.
-- You can register slash commands to your custom functions and use the `GetArgs` function to parse them
-- to your addons individual needs.
--
-- **AceConsole-3.0** can be embeded into your addon, either explicitly by calling AceConsole:Embed(MyAddon) or by
-- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
-- and can be accessed directly, without having to explicitly call AceConsole itself.\\
-- It is recommended to embed AceConsole, otherwise you'll have to specify a custom `self` on all calls you
-- make into AceConsole.
-- @class file
-- @name AceConsole-3.0
-- @release $Id: AceConsole-3.0.lua 779 2009-04-05 08:52:46Z nevcairiel $
local MAJOR,MINOR = "AceConsole-3.0", 6
 
local AceConsole, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
 
if not AceConsole then return end -- No upgrade needed
 
AceConsole.embeds = AceConsole.embeds or {} -- table containing objects AceConsole is embedded in.
AceConsole.commands = AceConsole.commands or {} -- table containing commands registered
AceConsole.weakcommands = AceConsole.weakcommands or {} -- table containing self, command => func references for weak commands that don't persist through enable/disable
 
-- local upvalues
local _G = _G
local pairs = pairs
local select = select
local type = type
local tostring = tostring
local strfind = string.find
local strsub = string.sub
local max = math.max
 
--- Print to DEFAULT_CHAT_FRAME or given ChatFrame (anything with an .AddMessage function)
-- @paramsig [chatframe ,] ...
-- @param chatframe Custom ChatFrame to print to (or any frame with an .AddMessage function)
-- @param ... List of any values to be printed
function AceConsole:Print(...)
local text = ""
if self ~= AceConsole then
text = "|cff33ff99"..tostring( self ).."|r: "
end
 
local frame = select(1, ...)
if not ( type(frame) == "table" and frame.AddMessage ) then -- Is first argument something with an .AddMessage member?
frame=nil
end
 
for i=(frame and 2 or 1), select("#", ...) do
text = text .. tostring( select( i, ...) ) .." "
end
(frame or DEFAULT_CHAT_FRAME):AddMessage( text )
end
 
 
--- Register a simple chat command
-- @param command Chat command to be registered WITHOUT leading "/"
-- @param func Function to call when the slash command is being used (funcref or methodname)
-- @param persist if false, the command will be soft disabled/enabled when aceconsole is used as a mixin (default: true)
function AceConsole:RegisterChatCommand( command, func, persist )
if type(command)~="string" then error([[Usage: AceConsole:RegisterChatCommand( "command", func[, persist ]): 'command' - expected a string]], 2) end
 
if persist==nil then persist=true end -- I'd rather have my addon's "/addon enable" around if the author screws up. Having some extra slash regged when it shouldnt be isn't as destructive. True is a better default. /Mikk
 
local name = "ACECONSOLE_"..command:upper()
 
if type( func ) == "string" then
SlashCmdList[name] = function(input, editBox)
self[func](self, input, editBox)
end
else
SlashCmdList[name] = func
end
_G["SLASH_"..name.."1"] = "/"..command:lower()
AceConsole.commands[command] = name
-- non-persisting commands are registered for enabling disabling
if not persist then
if not AceConsole.weakcommands[self] then AceConsole.weakcommands[self] = {} end
AceConsole.weakcommands[self][command] = func
end
return true
end
 
--- Unregister a chatcommand
-- @param command Chat command to be unregistered WITHOUT leading "/"
function AceConsole:UnregisterChatCommand( command )
local name = AceConsole.commands[command]
if name then
SlashCmdList[name] = nil
_G["SLASH_" .. name .. "1"] = nil
hash_SlashCmdList["/" .. command:upper()] = nil
AceConsole.commands[command] = nil
end
end
 
--- Get an iterator over all Chat Commands registered with AceConsole
-- @return Iterator (pairs) over all commands
function AceConsole:IterateChatCommands() return pairs(AceConsole.commands) end
 
 
local function nils(n, ...)
if n>1 then
return nil, nils(n-1, ...)
elseif n==1 then
return nil, ...
else
return ...
end
end
 
 
--- Retreive one or more space-separated arguments from a string.
-- Treats quoted strings and itemlinks as non-spaced.
-- @param string The raw argument string
-- @param numargs How many arguments to get (default 1)
-- @param startpos Where in the string to start scanning (default 1)
-- @return Returns arg1, arg2, ..., nextposition\\
-- Missing arguments will be returned as nils. 'nextposition' is returned as 1e9 at the end of the string.
function AceConsole:GetArgs(str, numargs, startpos)
numargs = numargs or 1
startpos = max(startpos or 1, 1)
 
local pos=startpos
 
-- find start of new arg
pos = strfind(str, "[^ ]", pos)
if not pos then -- whoops, end of string
return nils(numargs, 1e9)
end
 
if numargs<1 then
return pos
end
 
-- quoted or space separated? find out which pattern to use
local delim_or_pipe
local ch = strsub(str, pos, pos)
if ch=='"' then
pos = pos + 1
delim_or_pipe='([|"])'
elseif ch=="'" then
pos = pos + 1
delim_or_pipe="([|'])"
else
delim_or_pipe="([| ])"
end
 
startpos = pos
 
while true do
-- find delimiter or hyperlink
local ch,_
pos,_,ch = strfind(str, delim_or_pipe, pos)
 
if not pos then break end
 
if ch=="|" then
-- some kind of escape
 
if strsub(str,pos,pos+1)=="|H" then
-- It's a |H....|hhyper link!|h
pos=strfind(str, "|h", pos+2) -- first |h
if not pos then break end
 
pos=strfind(str, "|h", pos+2) -- second |h
if not pos then break end
elseif strsub(str,pos, pos+1) == "|T" then
-- It's a |T....|t texture
pos=strfind(str, "|t", pos+2)
if not pos then break end
end
 
pos=pos+2 -- skip past this escape (last |h if it was a hyperlink)
 
else
-- found delimiter, done with this arg
return strsub(str, startpos, pos-1), AceConsole:GetArgs(str, numargs-1, pos+1)
end
 
end
 
-- search aborted, we hit end of string. return it all as one argument. (yes, even if it's an unterminated quote or hyperlink)
return strsub(str, startpos), nils(numargs-1, 1e9)
end
 
 
--- embedding and embed handling
 
local mixins = {
"Print",
"RegisterChatCommand",
"UnregisterChatCommand",
"GetArgs",
}
 
-- Embeds AceConsole into the target object making the functions from the mixins list available on target:..
-- @param target target object to embed AceBucket in
function AceConsole:Embed( target )
for k, v in pairs( mixins ) do
target[v] = self[v]
end
self.embeds[target] = true
return target
end
 
function AceConsole:OnEmbedEnable( target )
if AceConsole.weakcommands[target] then
for command, func in pairs( AceConsole.weakcommands[target] ) do
target:RegisterChatCommand( command, func, false, true ) -- nonpersisting and silent registry
end
end
end
 
function AceConsole:OnEmbedDisable( target )
if AceConsole.weakcommands[target] then
for command, func in pairs( AceConsole.weakcommands[target] ) do
target:UnregisterChatCommand( command ) -- TODO: this could potentially unregister a command from another application in case of command conflicts. Do we care?
end
end
end
 
for addon in pairs(AceConsole.embeds) do
AceConsole:Embed(addon)
end
EasyDaily/libs/AceConfig-3.0/AceConfig-3.0.xml New file
0,0 → 1,8
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Include file="AceConfigRegistry-3.0\AceConfigRegistry-3.0.xml"/>
<Include file="AceConfigCmd-3.0\AceConfigCmd-3.0.xml"/>
<Include file="AceConfigDialog-3.0\AceConfigDialog-3.0.xml"/>
<!--<Include file="AceConfigDropdown-3.0\AceConfigDropdown-3.0.xml"/>-->
<Script file="AceConfig-3.0.lua"/>
</Ui>
\ No newline at end of file
EasyDaily/libs/AceConfig-3.0/AceConfig-3.0.lua New file
0,0 → 1,56
--- AceConfig-3.0 wrapper library.
-- Provides an API to register an options table with the config registry,
-- as well as associate it with a slash command.
-- @class file
-- @name AceConfig-3.0
-- @release $Id: AceConfig-3.0.lua 802 2009-04-11 12:12:37Z nevcairiel $
 
--[[
AceConfig-3.0
 
Very light wrapper library that combines all the AceConfig subcomponents into one more easily used whole.
 
]]
 
local MAJOR, MINOR = "AceConfig-3.0", 2
local AceConfig = LibStub:NewLibrary(MAJOR, MINOR)
 
if not AceConfig then return end
 
 
local cfgreg = LibStub("AceConfigRegistry-3.0")
local cfgcmd = LibStub("AceConfigCmd-3.0")
local cfgdlg = LibStub("AceConfigDialog-3.0")
--TODO: local cfgdrp = LibStub("AceConfigDropdown-3.0")
 
 
-- -------------------------------------------------------------------
-- :RegisterOptionsTable(appName, options, slashcmd, persist)
--
-- - appName - (string) application name
-- - options - table or function ref, see AceConfigRegistry
-- - slashcmd - slash command (string) or table with commands, or nil to NOT create a slash command
 
--- Register a option table with the AceConfig registry.
-- You can supply a slash command (or a table of slash commands) to register with AceConfigCmd directly.
-- @paramsig appName, options [, slashcmd]
-- @param appName The application name for the config table.
-- @param options The option table (or a function to generate one on demand)
-- @param slashcmd A slash command to register for the option table, or a table of slash commands.
-- @usage
-- local AceConfig = LibStub("AceConfig-3.0")
-- AceConfig:RegisterOptionsTable("MyAddon", myOptions, {"/myslash", "/my"})
function AceConfig:RegisterOptionsTable(appName, options, slashcmd)
local ok,msg = pcall(cfgreg.RegisterOptionsTable, self, appName, options)
if not ok then error(msg, 2) end
 
if slashcmd then
if type(slashcmd) == "table" then
for _,cmd in pairs(slashcmd) do
cfgcmd:CreateChatCommand(cmd, appName)
end
else
cfgcmd:CreateChatCommand(slashcmd, appName)
end
end
end
EasyDaily/libs/AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.xml New file
0,0 → 1,4
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="AceConfigDialog-3.0.lua"/>
</Ui>
\ No newline at end of file
EasyDaily/libs/AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.lua New file
0,0 → 1,1839
--- AceConfigDialog-3.0 generates AceGUI-3.0 based windows based on option tables.
-- @class file
-- @name AceConfigDialog-3.0
-- @release $Id: AceConfigDialog-3.0.lua 796 2009-04-07 15:48:54Z nevcairiel $
 
local LibStub = LibStub
local MAJOR, MINOR = "AceConfigDialog-3.0", 34
local AceConfigDialog = LibStub:NewLibrary(MAJOR, MINOR)
 
if not AceConfigDialog then return end
 
AceConfigDialog.OpenFrames = AceConfigDialog.OpenFrames or {}
AceConfigDialog.Status = AceConfigDialog.Status or {}
AceConfigDialog.frame = AceConfigDialog.frame or CreateFrame("Frame")
 
AceConfigDialog.frame.apps = AceConfigDialog.frame.apps or {}
AceConfigDialog.frame.closing = AceConfigDialog.frame.closing or {}
 
local gui = LibStub("AceGUI-3.0")
local reg = LibStub("AceConfigRegistry-3.0")
 
local select = select
local pairs = pairs
local type = type
local assert = assert
local tinsert = tinsert
local tremove = tremove
local error = error
local table = table
local unpack = unpack
local string = string
local next = next
local math = math
local _
 
--[[
xpcall safecall implementation
]]
local xpcall = xpcall
 
local function errorhandler(err)
return geterrorhandler()(err)
end
 
local function CreateDispatcher(argCount)
local code = [[
local xpcall, eh = ...
local method, ARGS
local function call() return method(ARGS) end
 
local function dispatch(func, ...)
method = func
if not method then return end
ARGS = ...
return xpcall(call, eh)
end
 
return dispatch
]]
 
local ARGS = {}
for i = 1, argCount do ARGS[i] = "arg"..i end
code = code:gsub("ARGS", table.concat(ARGS, ", "))
return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(xpcall, errorhandler)
end
 
local Dispatchers = setmetatable({}, {__index=function(self, argCount)
local dispatcher = CreateDispatcher(argCount)
rawset(self, argCount, dispatcher)
return dispatcher
end})
Dispatchers[0] = function(func)
return xpcall(func, errorhandler)
end
 
local function safecall(func, ...)
return Dispatchers[select('#', ...)](func, ...)
end
 
local width_multiplier = 170
 
--[[
Group Types
Tree - All Descendant Groups will all become nodes on the tree, direct child options will appear above the tree
- Descendant Groups with inline=true and thier children will not become nodes
 
Tab - Direct Child Groups will become tabs, direct child options will appear above the tab control
- Grandchild groups will default to inline unless specified otherwise
 
Select- Same as Tab but with entries in a dropdown rather than tabs
 
 
Inline Groups
- Will not become nodes of a select group, they will be effectivly part of thier parent group seperated by a border
- If declared on a direct child of a root node of a select group, they will appear above the group container control
- When a group is displayed inline, all descendants will also be inline members of the group
 
]]
 
-- Recycling functions
local new, del, copy
--newcount, delcount,createdcount,cached = 0,0,0
do
local pool = setmetatable({},{__mode='k'})
function new()
--newcount = newcount + 1
local t = next(pool)
if t then
pool[t] = nil
return t
else
--createdcount = createdcount + 1
return {}
end
end
function copy(t)
local c = new()
for k, v in pairs(t) do
c[k] = v
end
return c
end
function del(t)
--delcount = delcount + 1
for k in pairs(t) do
t[k] = nil
end
pool[t] = true
end
-- function cached()
-- local n = 0
-- for k in pairs(pool) do
-- n = n + 1
-- end
-- return n
-- end
end
 
-- picks the first non-nil value and returns it
local function pickfirstset(...)
for i=1,select("#",...) do
if select(i,...)~=nil then
return select(i,...)
end
end
end
 
--gets an option from a given group, checking plugins
local function GetSubOption(group, key)
if group.plugins then
for plugin, t in pairs(group.plugins) do
if t[key] then
return t[key]
end
end
end
 
return group.args[key]
end
 
--Option member type definitions, used to decide how to access it
 
--Is the member Inherited from parent options
local isInherited = {
set = true,
get = true,
func = true,
confirm = true,
validate = true,
disabled = true,
hidden = true
}
 
--Does a string type mean a literal value, instead of the default of a method of the handler
local stringIsLiteral = {
name = true,
desc = true,
icon = true,
usage = true,
width = true,
image = true,
fontSize = true,
}
 
--Is Never a function or method
local allIsLiteral = {
type = true,
imageWidth = true,
imageHeight = true,
}
 
--gets the value for a member that could be a function
--function refs are called with an info arg
--every other type is returned
local function GetOptionsMemberValue(membername, option, options, path, appName, ...)
--get definition for the member
local inherits = isInherited[membername]
 
 
--get the member of the option, traversing the tree if it can be inherited
local member
 
if inherits then
local group = options
if group[membername] ~= nil then
member = group[membername]
end
for i = 1, #path do
group = GetSubOption(group, path[i])
if group[membername] ~= nil then
member = group[membername]
end
end
else
member = option[membername]
end
 
--check if we need to call a functon, or if we have a literal value
if ( not allIsLiteral[membername] ) and ( type(member) == "function" or ((not stringIsLiteral[membername]) and type(member) == "string") ) then
--We have a function to call
local info = new()
--traverse the options table, picking up the handler and filling the info with the path
local handler
local group = options
handler = group.handler or handler
 
for i = 1, #path do
group = GetSubOption(group, path[i])
info[i] = path[i]
handler = group.handler or handler
end
 
info.options = options
info.appName = appName
info[0] = appName
info.arg = option.arg
info.handler = handler
info.option = option
info.type = option.type
info.uiType = 'dialog'
info.uiName = MAJOR
 
local a, b, c ,d
--using 4 returns for the get of a color type, increase if a type needs more
if type(member) == "function" then
--Call the function
a,b,c,d = member(info, ...)
else
--Call the method
if handler and handler[member] then
a,b,c,d = handler[member](handler, info, ...)
else
error(string.format("Method %s doesn't exist in handler for type %s", member, membername))
end
end
del(info)
return a,b,c,d
else
--The value isnt a function to call, return it
return member
end
end
 
--[[calls an options function that could be inherited, method name or function ref
local function CallOptionsFunction(funcname ,option, options, path, appName, ...)
local info = new()
 
local func
local group = options
local handler
 
--build the info table containing the path
-- pick up functions while traversing the tree
if group[funcname] ~= nil then
func = group[funcname]
end
handler = group.handler or handler
 
for i, v in ipairs(path) do
group = GetSubOption(group, v)
info[i] = v
if group[funcname] ~= nil then
func = group[funcname]
end
handler = group.handler or handler
end
 
info.options = options
info[0] = appName
info.arg = option.arg
 
local a, b, c ,d
if type(func) == "string" then
if handler and handler[func] then
a,b,c,d = handler[func](handler, info, ...)
else
error(string.format("Method %s doesn't exist in handler for type func", func))
end
elseif type(func) == "function" then
a,b,c,d = func(info, ...)
end
del(info)
return a,b,c,d
end
--]]
 
--tables to hold orders and names for options being sorted, will be created with new()
--prevents needing to call functions repeatedly while sorting
local tempOrders
local tempNames
 
local function compareOptions(a,b)
if not a then
return true
end
if not b then
return false
end
local OrderA, OrderB = tempOrders[a] or 100, tempOrders[b] or 100
if OrderA == OrderB then
local NameA = (type(tempNames[a] == "string") and tempNames[a]) or ""
local NameB = (type(tempNames[b] == "string") and tempNames[b]) or ""
return NameA:upper() < NameB:upper()
end
if OrderA < 0 then
if OrderB > 0 then
return false
end
else
if OrderB < 0 then
return true
end
end
return OrderA < OrderB
end
 
 
 
--builds 2 tables out of an options group
-- keySort, sorted keys
-- opts, combined options from .plugins and args
local function BuildSortedOptionsTable(group, keySort, opts, options, path, appName)
tempOrders = new()
tempNames = new()
 
if group.plugins then
for plugin, t in pairs(group.plugins) do
for k, v in pairs(t) do
if not opts[k] then
tinsert(keySort, k)
opts[k] = v
 
path[#path+1] = k
tempOrders[k] = GetOptionsMemberValue("order", v, options, path, appName)
tempNames[k] = GetOptionsMemberValue("name", v, options, path, appName)
path[#path] = nil
end
end
end
end
 
for k, v in pairs(group.args) do
if not opts[k] then
tinsert(keySort, k)
opts[k] = v
 
path[#path+1] = k
tempOrders[k] = GetOptionsMemberValue("order", v, options, path, appName)
tempNames[k] = GetOptionsMemberValue("name", v, options, path, appName)
path[#path] = nil
end
end
 
table.sort(keySort, compareOptions)
 
del(tempOrders)
del(tempNames)
end
 
local function DelTree(tree)
if tree.children then
local childs = tree.children
for i = 1, #childs do
DelTree(childs[i])
del(childs[i])
end
del(childs)
end
end
 
local function CleanUserData(widget, event)
 
local user = widget:GetUserDataTable()
 
if user.path then
del(user.path)
end
 
if widget.type == "TreeGroup" then
local tree = user.tree
widget:SetTree(nil)
if tree then
for i = 1, #tree do
DelTree(tree[i])
del(tree[i])
end
del(tree)
end
end
 
if widget.type == "TabGroup" then
widget:SetTabs(nil)
if user.tablist then
del(user.tablist)
end
end
 
if widget.type == "DropdownGroup" then
widget:SetGroupList(nil)
if user.grouplist then
del(user.grouplist)
end
end
end
 
-- - Gets a status table for the given appname and options path.
-- @param appName The application name as given to `:RegisterOptionsTable()`
-- @param path The path to the options (a table with all group keys)
-- @return
function AceConfigDialog:GetStatusTable(appName, path)
local status = self.Status
 
if not status[appName] then
status[appName] = {}
status[appName].status = {}
status[appName].children = {}
end
 
status = status[appName]
 
if path then
for i = 1, #path do
local v = path[i]
if not status.children[v] then
status.children[v] = {}
status.children[v].status = {}
status.children[v].children = {}
end
status = status.children[v]
end
end
 
return status.status
end
 
--- Selects the specified path in the options window.
-- The path specified has to match the keys of the groups in the table.
-- @param appName The application name as given to `:RegisterOptionsTable()`
-- @param ... The path to the key that should be selected
function AceConfigDialog:SelectGroup(appName, ...)
local path = new()
 
 
local app = reg:GetOptionsTable(appName)
if not app then
error(("%s isn't registed with AceConfigRegistry, unable to open config"):format(appName), 2)
end
local options = app("dialog", MAJOR)
local group = options
local status = self:GetStatusTable(appName, path)
if not status.groups then
status.groups = {}
end
status = status.groups
local treevalue
local treestatus
 
for n = 1, select('#',...) do
local key = select(n, ...)
 
if group.childGroups == "tab" or group.childGroups == "select" then
--if this is a tab or select group, select the group
status.selected = key
--children of this group are no longer extra levels of a tree
treevalue = nil
else
--tree group by default
if treevalue then
--this is an extra level of a tree group, build a uniquevalue for it
treevalue = treevalue.."\001"..key
else
--this is the top level of a tree group, the uniquevalue is the same as the key
treevalue = key
if not status.groups then
status.groups = {}
end
--save this trees status table for any extra levels or groups
treestatus = status
end
--make sure that the tree entry is open, and select it.
--the selected group will be overwritten if a child is the final target but still needs to be open
treestatus.selected = treevalue
treestatus.groups[treevalue] = true
 
end
 
--move to the next group in the path
group = GetSubOption(group, key)
if not group then
break
end
tinsert(path, key)
status = self:GetStatusTable(appName, path)
if not status.groups then
status.groups = {}
end
status = status.groups
end
 
del(path)
reg:NotifyChange(appName)
end
 
local function OptionOnMouseOver(widget, event)
--show a tooltip/set the status bar to the desc text
local user = widget:GetUserDataTable()
local opt = user.option
local options = user.options
local path = user.path
local appName = user.appName
 
GameTooltip:SetOwner(widget.frame, "ANCHOR_TOPRIGHT")
local name = GetOptionsMemberValue("name", opt, options, path, appName)
local desc = GetOptionsMemberValue("desc", opt, options, path, appName)
local usage = GetOptionsMemberValue("usage", opt, options, path, appName)
 
GameTooltip:SetText(name, 1, .82, 0, 1)
 
if opt.type == 'multiselect' then
GameTooltip:AddLine(user.text,0.5, 0.5, 0.8, 1)
end
if type(desc) == "string" then
GameTooltip:AddLine(desc, 1, 1, 1, 1)
end
if type(usage) == "string" then
GameTooltip:AddLine("Usage: "..usage, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, 1)
end
 
GameTooltip:Show()
end
 
local function OptionOnMouseLeave(widget, event)
GameTooltip:Hide()
end
 
local function GetFuncName(option)
local type = option.type
if type == 'execute' then
return 'func'
else
return 'set'
end
end
local function confirmPopup(appName, rootframe, basepath, info, message, func, ...)
if not StaticPopupDialogs["ACECONFIGDIALOG30_CONFIRM_DIALOG"] then
StaticPopupDialogs["ACECONFIGDIALOG30_CONFIRM_DIALOG"] = {}
end
local t = StaticPopupDialogs["ACECONFIGDIALOG30_CONFIRM_DIALOG"]
for k in pairs(t) do
t[k] = nil
end
t.text = message
t.button1 = ACCEPT
t.button2 = CANCEL
local dialog, oldstrata
t.OnAccept = function()
safecall(func, unpack(t))
if dialog and oldstrata then
dialog:SetFrameStrata(oldstrata)
end
AceConfigDialog:Open(appName, rootframe, basepath and unpack(basepath))
del(info)
end
t.OnCancel = function()
if dialog and oldstrata then
dialog:SetFrameStrata(oldstrata)
end
AceConfigDialog:Open(appName, rootframe, basepath and unpack(basepath))
del(info)
end
for i = 1, select('#', ...) do
t[i] = select(i, ...) or false
end
t.timeout = 0
t.whileDead = 1
t.hideOnEscape = 1
 
dialog = StaticPopup_Show("ACECONFIGDIALOG30_CONFIRM_DIALOG")
if dialog then
oldstrata = dialog:GetFrameStrata()
dialog:SetFrameStrata("TOOLTIP")
end
end
 
local function ActivateControl(widget, event, ...)
--This function will call the set / execute handler for the widget
--widget:GetUserDataTable() contains the needed info
local user = widget:GetUserDataTable()
local option = user.option
local options = user.options
local path = user.path
local info = new()
 
local func
local group = options
local funcname = GetFuncName(option)
local handler
local confirm
local validate
--build the info table containing the path
-- pick up functions while traversing the tree
if group[funcname] ~= nil then
func = group[funcname]
end
handler = group.handler or handler
confirm = group.confirm
validate = group.validate
for i = 1, #path do
local v = path[i]
group = GetSubOption(group, v)
info[i] = v
if group[funcname] ~= nil then
func = group[funcname]
end
handler = group.handler or handler
if group.confirm ~= nil then
confirm = group.confirm
end
if group.validate ~= nil then
validate = group.validate
end
end
 
info.options = options
info.appName = user.appName
info.arg = option.arg
info.handler = handler
info.option = option
info.type = option.type
info.uiType = 'dialog'
info.uiName = MAJOR
 
local name
if type(option.name) == "function" then
name = option.name(info)
elseif type(option.name) == "string" then
name = option.name
else
name = ""
end
local usage = option.usage
local pattern = option.pattern
 
local validated = true
 
if option.type == "input" then
if type(pattern)=="string" then
if not strmatch(..., pattern) then
validated = false
end
end
end
 
local success
if validated and option.type ~= "execute" then
if type(validate) == "string" then
if handler and handler[validate] then
success, validated = safecall(handler[validate], handler, info, ...)
if not success then validated = false end
else
error(string.format("Method %s doesn't exist in handler for type execute", validate))
end
elseif type(validate) == "function" then
success, validated = safecall(validate, info, ...)
if not success then validated = false end
end
end
 
local rootframe = user.rootframe
if type(validated) == "string" then
--validate function returned a message to display
if rootframe.SetStatusText then
rootframe:SetStatusText(validated)
end
PlaySound("igPlayerInviteDecline")
del(info)
return true
elseif not validated then
--validate returned false
if rootframe.SetStatusText then
if usage then
rootframe:SetStatusText(name..": "..usage)
else
if pattern then
rootframe:SetStatusText(name..": Expected "..pattern)
else
rootframe:SetStatusText(name..": Invalid Value")
end
end
end
PlaySound("igPlayerInviteDecline")
del(info)
return true
else
 
local confirmText = option.confirmText
--call confirm func/method
if type(confirm) == "string" then
if handler and handler[confirm] then
success, confirm = safecall(handler[confirm], handler, info, ...)
if success and type(confirm) == "string" then
confirmText = confirm
confirm = true
elseif not success then
confirm = false
end
else
error(string.format("Method %s doesn't exist in handler for type confirm", confirm))
end
elseif type(confirm) == "function" then
success, confirm = safecall(confirm, info, ...)
if success and type(confirm) == "string" then
confirmText = confirm
confirm = true
elseif not success then
confirm = false
end
end
 
--confirm if needed
if type(confirm) == "boolean" then
if confirm then
if not confirmText then
local name, desc = option.name, option.desc
if type(name) == "function" then
name = name(info)
end
if type(desc) == "function" then
desc = desc(info)
end
confirmText = name
if desc then
confirmText = confirmText.." - "..desc
end
end
 
local iscustom = user.rootframe:GetUserData('iscustom')
local rootframe
 
if iscustom then
rootframe = user.rootframe
end
local basepath = user.rootframe:GetUserData('basepath')
if type(func) == "string" then
if handler and handler[func] then
confirmPopup(user.appName, rootframe, basepath, info, confirmText, handler[func], handler, info, ...)
else
error(string.format("Method %s doesn't exist in handler for type func", func))
end
elseif type(func) == "function" then
confirmPopup(user.appName, rootframe, basepath, info, confirmText, func, info, ...)
end
--func will be called and info deleted when the confirm dialog is responded to
return
end
end
 
--call the function
if type(func) == "string" then
if handler and handler[func] then
safecall(handler[func],handler, info, ...)
else
error(string.format("Method %s doesn't exist in handler for type func", func))
end
elseif type(func) == "function" then
safecall(func,info, ...)
end
 
 
 
local iscustom = user.rootframe:GetUserData('iscustom')
local basepath = user.rootframe:GetUserData('basepath')
--full refresh of the frame, some controls dont cause this on all events
if option.type == "color" then
if event == "OnValueConfirmed" then
 
if iscustom then
AceConfigDialog:Open(user.appName, user.rootframe, basepath and unpack(basepath))
else
AceConfigDialog:Open(user.appName, basepath and unpack(basepath))
end
end
elseif option.type == "range" then
if event == "OnMouseUp" then
if iscustom then
AceConfigDialog:Open(user.appName, user.rootframe, basepath and unpack(basepath))
else
AceConfigDialog:Open(user.appName, basepath and unpack(basepath))
end
end
--multiselects don't cause a refresh on 'OnValueChanged' only 'OnClosed'
elseif option.type == "multiselect" then
user.valuechanged = true
else
if iscustom then
AceConfigDialog:Open(user.appName, user.rootframe, basepath and unpack(basepath))
else
AceConfigDialog:Open(user.appName, basepath and unpack(basepath))
end
end
 
end
del(info)
end
 
local function ActivateSlider(widget, event, value)
local option = widget:GetUserData('option')
local min, max, step = option.min or 0, option.max or 100, option.step
if step then
value = math.floor((value - min) / step + 0.5) * step + min
else
value = math.max(math.min(value,max),min)
end
ActivateControl(widget,event,value)
end
 
--called from a checkbox that is part of an internally created multiselect group
--this type is safe to refresh on activation of one control
local function ActivateMultiControl(widget, event, ...)
ActivateControl(widget, event, widget:GetUserData('value'), ...)
local user = widget:GetUserDataTable()
local iscustom = user.rootframe:GetUserData('iscustom')
local basepath = user.rootframe:GetUserData('basepath')
if iscustom then
AceConfigDialog:Open(user.appName, user.rootframe, basepath and unpack(basepath))
else
AceConfigDialog:Open(user.appName, basepath and unpack(basepath))
end
end
 
local function MultiControlOnClosed(widget, event, ...)
local user = widget:GetUserDataTable()
if user.valuechanged then
local iscustom = user.rootframe:GetUserData('iscustom')
local basepath = user.rootframe:GetUserData('basepath')
if iscustom then
AceConfigDialog:Open(user.appName, user.rootframe, basepath and unpack(basepath))
else
AceConfigDialog:Open(user.appName, basepath and unpack(basepath))
end
end
end
 
local function FrameOnClose(widget, event)
local appName = widget:GetUserData('appName')
AceConfigDialog.OpenFrames[appName] = nil
gui:Release(widget)
end
 
local function CheckOptionHidden(option, options, path, appName)
--check for a specific boolean option
local hidden = pickfirstset(option.dialogHidden,option.guiHidden)
if hidden ~= nil then
return hidden
end
 
return GetOptionsMemberValue("hidden", option, options, path, appName)
end
 
local function CheckOptionDisabled(option, options, path, appName)
--check for a specific boolean option
local disabled = pickfirstset(option.dialogDisabled,option.guiDisabled)
if disabled ~= nil then
return disabled
end
 
return GetOptionsMemberValue("disabled", option, options, path, appName)
end
--[[
local function BuildTabs(group, options, path, appName)
local tabs = new()
local text = new()
local keySort = new()
local opts = new()
 
BuildSortedOptionsTable(group, keySort, opts, options, path, appName)
 
for i = 1, #keySort do
local k = keySort[i]
local v = opts[k]
if v.type == "group" then
path[#path+1] = k
local inline = pickfirstset(v.dialogInline,v.guiInline,v.inline, false)
local hidden = CheckOptionHidden(v, options, path, appName)
if not inline and not hidden then
tinsert(tabs, k)
text[k] = GetOptionsMemberValue("name", v, options, path, appName)
end
path[#path] = nil
end
end
 
del(keySort)
del(opts)
 
return tabs, text
end
]]
local function BuildSelect(group, options, path, appName)
local groups = new()
local keySort = new()
local opts = new()
 
BuildSortedOptionsTable(group, keySort, opts, options, path, appName)
 
for i = 1, #keySort do
local k = keySort[i]
local v = opts[k]
if v.type == "group" then
path[#path+1] = k
local inline = pickfirstset(v.dialogInline,v.guiInline,v.inline, false)
local hidden = CheckOptionHidden(v, options, path, appName)
if not inline and not hidden then
groups[k] = GetOptionsMemberValue("name", v, options, path, appName)
end
path[#path] = nil
end
end
 
del(keySort)
del(opts)
 
return groups
end
 
local function BuildSubGroups(group, tree, options, path, appName)
local keySort = new()
local opts = new()
 
BuildSortedOptionsTable(group, keySort, opts, options, path, appName)
 
for i = 1, #keySort do
local k = keySort[i]
local v = opts[k]
if v.type == "group" then
path[#path+1] = k
local inline = pickfirstset(v.dialogInline,v.guiInline,v.inline, false)
local hidden = CheckOptionHidden(v, options, path, appName)
if not inline and not hidden then
local entry = new()
entry.value = k
entry.text = GetOptionsMemberValue("name", v, options, path, appName)
entry.icon = GetOptionsMemberValue("icon", v, options, path, appName)
entry.disabled = CheckOptionDisabled(v, options, path, appName)
if not tree.children then tree.children = new() end
tinsert(tree.children,entry)
if (v.childGroups or "tree") == "tree" then
BuildSubGroups(v,entry, options, path, appName)
end
end
path[#path] = nil
end
end
 
del(keySort)
del(opts)
end
 
local function BuildGroups(group, options, path, appName, recurse)
local tree = new()
local keySort = new()
local opts = new()
 
BuildSortedOptionsTable(group, keySort, opts, options, path, appName)
 
for i = 1, #keySort do
local k = keySort[i]
local v = opts[k]
if v.type == "group" then
path[#path+1] = k
local inline = pickfirstset(v.dialogInline,v.guiInline,v.inline, false)
local hidden = CheckOptionHidden(v, options, path, appName)
if not inline and not hidden then
local entry = new()
entry.value = k
entry.text = GetOptionsMemberValue("name", v, options, path, appName)
entry.icon = GetOptionsMemberValue("icon", v, options, path, appName)
entry.disabled = CheckOptionDisabled(v, options, path, appName)
tinsert(tree,entry)
if recurse and (v.childGroups or "tree") == "tree" then
BuildSubGroups(v,entry, options, path, appName)
end
end
path[#path] = nil
end
end
del(keySort)
del(opts)
return tree
end
 
local function InjectInfo(control, options, option, path, rootframe, appName)
local user = control:GetUserDataTable()
for i = 1, #path do
user[i] = path[i]
end
user.rootframe = rootframe
user.option = option
user.options = options
user.path = copy(path)
user.appName = appName
control:SetCallback("OnRelease", CleanUserData)
control:SetCallback("OnLeave", OptionOnMouseLeave)
control:SetCallback("OnEnter", OptionOnMouseOver)
end
 
 
--[[
options - root of the options table being fed
container - widget that controls will be placed in
rootframe - Frame object the options are in
path - table with the keys to get to the group being fed
--]]
 
local function FeedOptions(appName, options,container,rootframe,path,group,inline)
local keySort = new()
local opts = new()
 
BuildSortedOptionsTable(group, keySort, opts, options, path, appName)
 
for i = 1, #keySort do
local k = keySort[i]
local v = opts[k]
tinsert(path, k)
local hidden = CheckOptionHidden(v, options, path, appName)
local name = GetOptionsMemberValue("name", v, options, path, appName)
if not hidden then
if v.type == "group" then
if inline or pickfirstset(v.dialogInline,v.guiInline,v.inline, false) then
--Inline group
local GroupContainer
if name and name ~= "" then
GroupContainer = gui:Create("InlineGroup")
GroupContainer:SetTitle(name or "")
else
GroupContainer = gui:Create("SimpleGroup")
end
 
GroupContainer.width = "fill"
GroupContainer:SetLayout("flow")
container:AddChild(GroupContainer)
FeedOptions(appName,options,GroupContainer,rootframe,path,v,true)
end
else
--Control to feed
local control
 
local name = GetOptionsMemberValue("name", v, options, path, appName)
 
if v.type == "execute" then
 
local imageCoords = GetOptionsMemberValue("imageCoords",v, options, path, appName)
local image, width, height = GetOptionsMemberValue("image",v, options, path, appName)
 
if type(image) == 'string' then
control = gui:Create("Icon")
if not width then
width = GetOptionsMemberValue("imageWidth",v, options, path, appName)
end
if not height then
height = GetOptionsMemberValue("imageHeight",v, options, path, appName)
end
if type(imageCoords) == 'table' then
control:SetImage(image, unpack(imageCoords))
else
control:SetImage(image)
end
if type(width) ~= "number" then
width = 32
end
if type(height) ~= "number" then
height = 32
end
control:SetImageSize(width, height)
control:SetLabel(name)
else
control = gui:Create("Button")
control:SetText(name)
end
control:SetCallback("OnClick",ActivateControl)
 
elseif v.type == "input" then
local controlType = v.dialogControl or v.control or (v.multiline and "MultiLineEditBox") or "EditBox"
control = gui:Create(controlType)
if not control then
error(("Invalid Custom Control Type - %s"):format(tostring(controlType)))
end
 
if v.multiline then
local lines = 4
if type(v.multiline) == "number" then
lines = v.multiline
end
control:SetHeight(60 + (14*lines))
end
control:SetLabel(name)
control:SetCallback("OnEnterPressed",ActivateControl)
local text = GetOptionsMemberValue("get",v, options, path, appName)
if type(text) ~= "string" then
text = ""
end
control:SetText(text)
 
elseif v.type == "toggle" then
control = gui:Create("CheckBox")
control:SetLabel(name)
control:SetTriState(v.tristate)
local value = GetOptionsMemberValue("get",v, options, path, appName)
control:SetValue(value)
control:SetCallback("OnValueChanged",ActivateControl)
 
elseif v.type == "range" then
control = gui:Create("Slider")
control:SetLabel(name)
control:SetSliderValues(v.min or 0,v.max or 100, v.bigStep or v.step or 0)
control:SetIsPercent(v.isPercent)
local value = GetOptionsMemberValue("get",v, options, path, appName)
if type(value) ~= "number" then
value = 0
end
control:SetValue(value)
control:SetCallback("OnValueChanged",ActivateSlider)
control:SetCallback("OnMouseUp",ActivateSlider)
 
elseif v.type == "select" then
local values = GetOptionsMemberValue("values", v, options, path, appName)
local controlType = v.dialogControl or v.control or "Dropdown"
control = gui:Create(controlType)
if not control then
error(("Invalid Custom Control Type - %s"):format(tostring(controlType)))
end
control:SetLabel(name)
control:SetList(values)
local value = GetOptionsMemberValue("get",v, options, path, appName)
if not values[value] then
value = nil
end
control:SetValue(value)
control:SetCallback("OnValueChanged",ActivateControl)
 
elseif v.type == "multiselect" then
local values = GetOptionsMemberValue("values", v, options, path, appName)
local disabled = CheckOptionDisabled(v, options, path, appName)
 
local controlType = v.dialogControl or v.control
 
local valuesort = new()
if values then
for value, text in pairs(values) do
tinsert(valuesort, value)
end
end
table.sort(valuesort)
 
if controlType then
control = gui:Create(controlType)
if not control then
error(("Invalid Custom Control Type - %s"):format(tostring(controlType)))
end
control:SetMultiselect(true)
control:SetLabel(name)
control:SetList(values)
control:SetDisabled(disabled)
control:SetCallback("OnValueChanged",ActivateControl)
control:SetCallback("OnClosed", MultiControlOnClosed)
local width = GetOptionsMemberValue("width",v,options,path,appName)
if width == "double" then
control:SetWidth(width_multiplier * 2)
elseif width == "half" then
control:SetWidth(width_multiplier / 2)
elseif width == "full" then
control.width = "fill"
else
control:SetWidth(width_multiplier)
end
--check:SetTriState(v.tristate)
for i = 1, #valuesort do
local key = valuesort[i]
local value = GetOptionsMemberValue("get",v, options, path, appName, key)
control:SetItemValue(key,value)
end
else
control = gui:Create("InlineGroup")
control:SetLayout("Flow")
control:SetTitle(name)
control.width = "fill"
 
control:PauseLayout()
local width = GetOptionsMemberValue("width",v,options,path,appName)
for i = 1, #valuesort do
local value = valuesort[i]
local text = values[value]
local check = gui:Create("CheckBox")
check:SetLabel(text)
check:SetUserData('value', value)
check:SetUserData('text', text)
check:SetDisabled(disabled)
check:SetTriState(v.tristate)
check:SetValue(GetOptionsMemberValue("get",v, options, path, appName, value))
check:SetCallback("OnValueChanged",ActivateMultiControl)
InjectInfo(check, options, v, path, rootframe, appName)
control:AddChild(check)
if width == "double" then
check:SetWidth(width_multiplier * 2)
elseif width == "half" then
check:SetWidth(width_multiplier / 2)
elseif width == "full" then
check.width = "fill"
else
check:SetWidth(width_multiplier)
end
end
control:ResumeLayout()
control:DoLayout()
 
 
end
 
del(valuesort)
 
elseif v.type == "color" then
control = gui:Create("ColorPicker")
control:SetLabel(name)
control:SetHasAlpha(v.hasAlpha)
control:SetColor(GetOptionsMemberValue("get",v, options, path, appName))
control:SetCallback("OnValueChanged",ActivateControl)
control:SetCallback("OnValueConfirmed",ActivateControl)
 
elseif v.type == "keybinding" then
control = gui:Create("Keybinding")
control:SetLabel(name)
control:SetKey(GetOptionsMemberValue("get",v, options, path, appName))
control:SetCallback("OnKeyChanged",ActivateControl)
 
elseif v.type == "header" then
control = gui:Create("Heading")
control:SetText(name)
control.width = "fill"
 
elseif v.type == "description" then
control = gui:Create("Label")
control:SetText(name)
 
local fontSize = GetOptionsMemberValue("fontSize",v, options, path, appName)
if fontSize == "medium" then
control:SetFontObject(GameFontHighlight)
elseif fontSize == "large" then
control:SetFontObject(GameFontHighlightLarge)
else -- small or invalid
control:SetFontObject(GameFontHighlightSmall)
end
 
local imageCoords = GetOptionsMemberValue("imageCoords",v, options, path, appName)
local image, width, height = GetOptionsMemberValue("image",v, options, path, appName)
 
if type(image) == 'string' then
if not width then
width = GetOptionsMemberValue("imageWidth",v, options, path, appName)
end
if not height then
height = GetOptionsMemberValue("imageHeight",v, options, path, appName)
end
if type(imageCoords) == 'table' then
control:SetImage(image, unpack(imageCoords))
else
control:SetImage(image)
end
if type(width) ~= "number" then
width = 32
end
if type(height) ~= "number" then
height = 32
end
control:SetImageSize(width, height)
end
local width = GetOptionsMemberValue("width",v,options,path,appName)
control.width = not width and "fill"
end
 
--Common Init
if control then
if control.width ~= "fill" then
local width = GetOptionsMemberValue("width",v,options,path,appName)
if width == "double" then
control:SetWidth(width_multiplier * 2)
elseif width == "half" then
control:SetWidth(width_multiplier / 2)
elseif width == "full" then
control.width = "fill"
else
control:SetWidth(width_multiplier)
end
end
if control.SetDisabled then
local disabled = CheckOptionDisabled(v, options, path, appName)
control:SetDisabled(disabled)
end
 
InjectInfo(control, options, v, path, rootframe, appName)
container:AddChild(control)
end
 
end
end
tremove(path)
end
container:ResumeLayout()
container:DoLayout()
del(keySort)
del(opts)
end
 
local function BuildPath(path, ...)
for i = 1, select('#',...) do
tinsert(path, (select(i,...)))
end
end
 
 
local function TreeOnButtonEnter(widget, event, uniquevalue, button)
local user = widget:GetUserDataTable()
if not user then return end
local options = user.options
local option = user.option
local path = user.path
local appName = user.appName
 
local feedpath = new()
for i = 1, #path do
feedpath[i] = path[i]
end
 
BuildPath(feedpath, string.split("\001", uniquevalue))
local group = options
for i = 1, #feedpath do
if not group then return end
group = GetSubOption(group, feedpath[i])
end
 
local name = GetOptionsMemberValue("name", group, options, feedpath, appName)
local desc = GetOptionsMemberValue("desc", group, options, feedpath, appName)
 
GameTooltip:SetOwner(button, "ANCHOR_NONE")
if widget.type == "TabGroup" then
GameTooltip:SetPoint("BOTTOM",button,"TOP")
else
GameTooltip:SetPoint("LEFT",button,"RIGHT")
end
 
GameTooltip:SetText(name, 1, .82, 0, 1)
 
if type(desc) == "string" then
GameTooltip:AddLine(desc, 1, 1, 1, 1)
end
 
GameTooltip:Show()
end
 
local function TreeOnButtonLeave(widget, event, value, button)
GameTooltip:Hide()
end
 
 
local function GroupExists(appName, options, path, uniquevalue)
if not uniquevalue then return false end
 
local feedpath = new()
local temppath = new()
for i = 1, #path do
feedpath[i] = path[i]
end
 
BuildPath(feedpath, string.split("\001", uniquevalue))
 
local group = options
for i = 1, #feedpath do
local v = feedpath[i]
temppath[i] = v
group = GetSubOption(group, v)
 
if not group or group.type ~= "group" or CheckOptionHidden(group, options, temppath, appName) then
del(feedpath)
del(temppath)
return false
end
end
del(feedpath)
del(temppath)
return true
end
 
local function GroupSelected(widget, event, uniquevalue)
 
local user = widget:GetUserDataTable()
 
local options = user.options
local option = user.option
local path = user.path
local rootframe = user.rootframe
 
local feedpath = new()
for i = 1, #path do
feedpath[i] = path[i]
end
 
BuildPath(feedpath, string.split("\001", uniquevalue))
local group = options
for i = 1, #feedpath do
group = GetSubOption(group, feedpath[i])
end
widget:ReleaseChildren()
AceConfigDialog:FeedGroup(user.appName,options,widget,rootframe,feedpath)
 
del(feedpath)
end
 
 
 
--[[
-- INTERNAL --
This function will feed one group, and any inline child groups into the given container
Select Groups will only have the selection control (tree, tabs, dropdown) fed in
and have a group selected, this event will trigger the feeding of child groups
 
Rules:
If the group is Inline, FeedOptions
If the group has no child groups, FeedOptions
 
If the group is a tab or select group, FeedOptions then add the Group Control
If the group is a tree group FeedOptions then
its parent isnt a tree group: then add the tree control containing this and all child tree groups
if its parent is a tree group, its already a node on a tree
--]]
 
function AceConfigDialog:FeedGroup(appName,options,container,rootframe,path, isRoot)
local group = options
--follow the path to get to the curent group
local inline
local grouptype, parenttype = options.childGroups, "none"
 
 
--temp path table to pass to callbacks as we traverse the tree
local temppath = new()
for i = 1, #path do
local v = path[i]
temppath[i] = v
group = GetSubOption(group, v)
inline = inline or pickfirstset(v.dialogInline,v.guiInline,v.inline, false)
parenttype = grouptype
grouptype = group.childGroups
end
del(temppath)
 
if not parenttype then
parenttype = "tree"
end
 
--check if the group has child groups
local hasChildGroups
for k, v in pairs(group.args) do
if v.type == "group" and not pickfirstset(v.dialogInline,v.guiInline,v.inline, false) and not CheckOptionHidden(v, options, path, appName) then
hasChildGroups = true
end
end
if group.plugins then
for plugin, t in pairs(group.plugins) do
for k, v in pairs(t) do
if v.type == "group" and not pickfirstset(v.dialogInline,v.guiInline,v.inline, false) and not CheckOptionHidden(v, options, path, appName) then
hasChildGroups = true
end
end
end
end
 
container:SetLayout("flow")
local scroll
 
--Add a scrollframe if we are not going to add a group control, this is the inverse of the conditions for that later on
if (not (hasChildGroups and not inline)) or (grouptype ~= "tab" and grouptype ~= "select" and (parenttype == "tree" and not isRoot)) then
if container.type ~= "InlineGroup" then
scroll = gui:Create("ScrollFrame")
scroll:SetLayout("flow")
scroll.width = "fill"
scroll.height = "fill"
container:SetLayout("fill")
container:AddChild(scroll)
container = scroll
end
end
 
FeedOptions(appName,options,container,rootframe,path,group,nil)
 
if scroll then
container:PerformLayout()
local status = self:GetStatusTable(appName, path)
if not status.scroll then
status.scroll = {}
end
scroll:SetStatusTable(status.scroll)
end
 
if hasChildGroups and not inline then
 
if grouptype == "tab" then
 
local tab = gui:Create("TabGroup")
InjectInfo(tab, options, group, path, rootframe, appName)
tab:SetCallback("OnGroupSelected", GroupSelected)
tab:SetCallback("OnTabEnter", TreeOnButtonEnter)
tab:SetCallback("OnTabLeave", TreeOnButtonLeave)
 
local status = AceConfigDialog:GetStatusTable(appName, path)
if not status.groups then
status.groups = {}
end
tab:SetStatusTable(status.groups)
tab.width = "fill"
tab.height = "fill"
 
local tabs = BuildGroups(group, options, path, appName)
tab:SetTabs(tabs)
tab:SetUserData("tablist", tabs)
 
for i = 1, #tabs do
local entry = tabs[i]
if not entry.disabled then
tab:SelectTab((GroupExists(appName, options, path,status.groups.selected) and status.groups.selected) or entry.value)
break
end
end
 
container:AddChild(tab)
 
elseif grouptype == "select" then
 
local select = gui:Create("DropdownGroup")
InjectInfo(select, options, group, path, rootframe, appName)
select:SetCallback("OnGroupSelected", GroupSelected)
local status = AceConfigDialog:GetStatusTable(appName, path)
if not status.groups then
status.groups = {}
end
select:SetStatusTable(status.groups)
local grouplist = BuildSelect(group, options, path, appName)
select:SetGroupList(grouplist)
select:SetUserData("grouplist", grouplist)
local firstgroup
for k, v in pairs(grouplist) do
if not firstgroup or k < firstgroup then
firstgroup = k
end
end
 
if firstgroup then
select:SetGroup( (GroupExists(appName, options, path,status.groups.selected) and status.groups.selected) or firstgroup)
end
 
select.width = "fill"
select.height = "fill"
 
container:AddChild(select)
 
--assume tree group by default
--if parenttype is tree then this group is already a node on that tree
elseif (parenttype ~= "tree") or isRoot then
local tree = gui:Create("TreeGroup")
InjectInfo(tree, options, group, path, rootframe, appName)
tree:EnableButtonTooltips(false)
 
tree.width = "fill"
tree.height = "fill"
 
tree:SetCallback("OnGroupSelected", GroupSelected)
tree:SetCallback("OnButtonEnter", TreeOnButtonEnter)
tree:SetCallback("OnButtonLeave", TreeOnButtonLeave)
 
local status = AceConfigDialog:GetStatusTable(appName, path)
if not status.groups then
status.groups = {}
end
local treedefinition = BuildGroups(group, options, path, appName, true)
tree:SetStatusTable(status.groups)
 
tree:SetTree(treedefinition)
tree:SetUserData("tree",treedefinition)
 
for i = 1, #treedefinition do
local entry = treedefinition[i]
if not entry.disabled then
tree:SelectByValue((GroupExists(appName, options, path,status.groups.selected) and status.groups.selected) or entry.value)
break
end
end
 
container:AddChild(tree)
end
end
end
 
local old_CloseSpecialWindows
 
 
local function RefreshOnUpdate(this)
for appName in pairs(this.closing) do
if AceConfigDialog.OpenFrames[appName] then
AceConfigDialog.OpenFrames[appName]:Hide()
end
if AceConfigDialog.BlizOptions and AceConfigDialog.BlizOptions[appName] then
local widget = AceConfigDialog.BlizOptions[appName]
if not widget:IsVisible() then
widget:ReleaseChildren()
end
end
this.closing[appName] = nil
end
 
if this.closeAll then
for k, v in pairs(AceConfigDialog.OpenFrames) do
v:Hide()
end
this.closeAll = nil
end
 
for appName in pairs(this.apps) do
if AceConfigDialog.OpenFrames[appName] then
local user = AceConfigDialog.OpenFrames[appName]:GetUserDataTable()
AceConfigDialog:Open(appName, user.basepath and unpack(user.basepath))
end
if AceConfigDialog.BlizOptions and AceConfigDialog.BlizOptions[appName] then
local widget = AceConfigDialog.BlizOptions[appName]
local user = widget:GetUserDataTable()
if widget:IsVisible() then
AceConfigDialog:Open(widget:GetUserData('appName'), widget, user.basepath and unpack(user.basepath))
end
end
this.apps[appName] = nil
end
this:SetScript("OnUpdate", nil)
end
 
--- Close all open options windows
function AceConfigDialog:CloseAll()
AceConfigDialog.frame.closeAll = true
AceConfigDialog.frame:SetScript("OnUpdate", RefreshOnUpdate)
if next(self.OpenFrames) then
return true
end
end
 
--- Close a specific options window.
-- @param appName The application name as given to `:RegisterOptionsTable()`
function AceConfigDialog:Close(appName)
if self.OpenFrames[appName] then
AceConfigDialog.frame.closing[appName] = true
AceConfigDialog.frame:SetScript("OnUpdate", RefreshOnUpdate)
return true
end
end
 
-- Internal -- Called by AceConfigRegistry
function AceConfigDialog:ConfigTableChanged(event, appName)
AceConfigDialog.frame.apps[appName] = true
AceConfigDialog.frame:SetScript("OnUpdate", RefreshOnUpdate)
end
 
reg.RegisterCallback(AceConfigDialog, "ConfigTableChange", "ConfigTableChanged")
 
--- Sets the default size of the options window for a specific application.
-- @param appName The application name as given to `:RegisterOptionsTable()`
-- @param width The default width
-- @param height The default height
function AceConfigDialog:SetDefaultSize(appName, width, height)
local status = AceConfigDialog:GetStatusTable(appName)
if type(width) == "number" and type(height) == "number" then
status.width = width
status.height = height
end
end
 
--- Open an option window at the specified path (if any).
-- This function can optionally feed the group into a pre-created container
-- instead of creating a new container frame.
-- @paramsig appName [, container][, ...]
-- @param appName The application name as given to `:RegisterOptionsTable()`
-- @param container An optional container frame to feed the options into
-- @param ... The path to open after creating the options window (see `:SelectGroup` for details)
function AceConfigDialog:Open(appName, container, ...)
if not old_CloseSpecialWindows then
old_CloseSpecialWindows = CloseSpecialWindows
CloseSpecialWindows = function()
local found = old_CloseSpecialWindows()
return self:CloseAll() or found
end
end
local app = reg:GetOptionsTable(appName)
if not app then
error(("%s isn't registed with AceConfigRegistry, unable to open config"):format(appName), 2)
end
local options = app("dialog", MAJOR)
 
local f
 
local path = new()
local name = GetOptionsMemberValue("name", options, options, path, appName)
 
--If an optional path is specified add it to the path table before feeding the options
--as container is optional as well it may contain the first element of the path
if type(container) == "string" then
tinsert(path, container)
container = nil
end
for n = 1, select('#',...) do
tinsert(path, (select(n, ...)))
end
 
--if a container is given feed into that
if container then
f = container
f:ReleaseChildren()
f:SetUserData('appName', appName)
f:SetUserData('iscustom', true)
if #path > 0 then
f:SetUserData('basepath', copy(path))
end
local status = AceConfigDialog:GetStatusTable(appName)
if not status.width then
status.width = 700
end
if not status.height then
status.height = 500
end
if f.SetStatusTable then
f:SetStatusTable(status)
end
else
if not self.OpenFrames[appName] then
f = gui:Create("Frame")
self.OpenFrames[appName] = f
else
f = self.OpenFrames[appName]
end
f:ReleaseChildren()
f:SetCallback("OnClose", FrameOnClose)
f:SetUserData('appName', appName)
if #path > 0 then
f:SetUserData('basepath', copy(path))
end
f:SetTitle(name or "")
local status = AceConfigDialog:GetStatusTable(appName)
f:SetStatusTable(status)
end
 
self:FeedGroup(appName,options,f,f,path,true)
if f.Show then
f:Show()
end
del(path)
end
 
AceConfigDialog.BlizOptions = AceConfigDialog.BlizOptions or {}
 
local function FeedToBlizPanel(widget, event)
local path = widget:GetUserData('path')
AceConfigDialog:Open(widget:GetUserData('appName'), widget, path and unpack(path))
end
 
local function ClearBlizPanel(widget, event)
local appName = widget:GetUserData('appName')
AceConfigDialog.frame.closing[appName] = true
AceConfigDialog.frame:SetScript("OnUpdate", RefreshOnUpdate)
end
 
--- Add an option table into the Blizzard Interface Options panel.
-- You can optionally supply a descriptive name to use and a parent frame to use,
-- as well as a path in the options table.\\
-- If no name is specified, the appName will be used instead.
--
-- If you specify a proper `parent` (by name), the interface options will generate a
-- tree layout. Note that only one level of children is supported, so the parent always
-- has to be a head-level note.
--
-- This function returns a reference to the container frame registered with the Interface
-- Options. You can use this reference to open the options with the API function
-- `InterfaceOptionsFrame_OpenToCategory`.
-- @param appName The application name as given to `:RegisterOptionsTable()`
-- @param name A descriptive name to display in the options tree (defaults to appName)
-- @param parent The parent to use in the interface options tree.
-- @param ... The path in the options table to feed into the interface options panel.
-- @return The reference to the frame registered into the Interface Options.
function AceConfigDialog:AddToBlizOptions(appName, name, parent, ...)
local BlizOptions = AceConfigDialog.BlizOptions
 
local key = appName
for n = 1, select('#', ...) do
key = key..'\001'..select(n, ...)
end
 
if not BlizOptions[key] then
local group = gui:Create("BlizOptionsGroup")
BlizOptions[key] = group
group:SetName(name or appName, parent)
 
group:SetTitle(name or appName)
group:SetUserData('appName', appName)
if select('#', ...) > 0 then
local path = {}
for n = 1, select('#',...) do
tinsert(path, (select(n, ...)))
end
group:SetUserData('path', path)
end
group:SetCallback("OnShow", FeedToBlizPanel)
group:SetCallback("OnHide", ClearBlizPanel)
InterfaceOptions_AddCategory(group.frame)
return group.frame
else
error(("%s has already been added to the Blizzard Options Window with the given path"):format(appName), 2)
end
end
EasyDaily/libs/AceConfig-3.0/AceConfigCmd-3.0/AceConfigCmd-3.0.xml New file
0,0 → 1,4
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="AceConfigCmd-3.0.lua"/>
</Ui>
\ No newline at end of file
EasyDaily/libs/AceConfig-3.0/AceConfigCmd-3.0/AceConfigCmd-3.0.lua New file
0,0 → 1,757
--- AceConfigCmd-3.0 handles access to an options table through the "command line" interface via the ChatFrames.
-- @class file
-- @name AceConfigCmd-3.0
-- @release $Id: AceConfigCmd-3.0.lua 801 2009-04-09 20:34:28Z nevcairiel $
 
--[[
AceConfigCmd-3.0
 
Handles commandline optionstable access
 
REQUIRES: AceConsole-3.0 for command registration (loaded on demand)
 
]]
 
-- TODO: handle disabled / hidden
-- TODO: implement handlers for all types
-- TODO: plugin args
 
 
local MAJOR, MINOR = "AceConfigCmd-3.0", 9
local AceConfigCmd = LibStub:NewLibrary(MAJOR, MINOR)
 
if not AceConfigCmd then return end
 
AceConfigCmd.commands = AceConfigCmd.commands or {}
local commands = AceConfigCmd.commands
 
local cfgreg = LibStub("AceConfigRegistry-3.0")
local AceConsole -- LoD
local AceConsoleName = "AceConsole-3.0"
 
 
local L = setmetatable({}, { -- TODO: replace with proper locale
__index = function(self,k) return k end
})
 
 
 
local function print(msg)
(SELECTED_CHAT_FRAME or DEFAULT_CHAT_FRAME):AddMessage(msg)
end
 
 
-- pickfirstset() - picks the first non-nil value and returns it
 
local function pickfirstset(...)
for i=1,select("#",...) do
if select(i,...)~=nil then
return select(i,...)
end
end
end
 
 
-- err() - produce real error() regarding malformed options tables etc
 
local function err(info,inputpos,msg )
local cmdstr=" "..strsub(info.input, 1, inputpos-1)
error(MAJOR..": /" ..info[0] ..cmdstr ..": "..(msg or "malformed options table"), 2)
end
 
 
-- usererr() - produce chatframe message regarding bad slash syntax etc
 
local function usererr(info,inputpos,msg )
local cmdstr=strsub(info.input, 1, inputpos-1);
print("/" ..info[0] .. " "..cmdstr ..": "..(msg or "malformed options table"))
end
 
 
-- callmethod() - call a given named method (e.g. "get", "set") with given arguments
 
local function callmethod(info, inputpos, tab, methodtype, ...)
local method = info[methodtype]
if not method then
err(info, inputpos, "'"..methodtype.."': not set")
end
 
info.arg = tab.arg
info.option = tab
info.type = tab.type
 
if type(method)=="function" then
return method(info, ...)
elseif type(method)=="string" then
if type(info.handler[method])~="function" then
err(info, inputpos, "'"..methodtype.."': '"..method.."' is not a member function of "..tostring(info.handler))
end
return info.handler[method](info.handler, info, ...)
else
assert(false) -- type should have already been checked on read
end
end
 
-- callfunction() - call a given named function (e.g. "name", "desc") with given arguments
 
local function callfunction(info, tab, methodtype, ...)
local method = tab[methodtype]
 
info.arg = tab.arg
info.option = tab
info.type = tab.type
 
if type(method)=="function" then
return method(info, ...)
else
assert(false) -- type should have already been checked on read
end
end
 
-- do_final() - do the final step (set/execute) along with validation and confirmation
 
local function do_final(info, inputpos, tab, methodtype, ...)
if info.validate then
local res = callmethod(info,inputpos,tab,"validate",...)
if type(res)=="string" then
usererr(info, inputpos, "'"..strsub(info.input, inputpos).."' - "..res)
return
end
end
-- console ignores .confirm
 
callmethod(info,inputpos,tab,methodtype, ...)
end
 
 
-- getparam() - used by handle() to retreive and store "handler", "get", "set", etc
 
local function getparam(info, inputpos, tab, depth, paramname, types, errormsg)
local old,oldat = info[paramname], info[paramname.."_at"]
local val=tab[paramname]
if val~=nil then
if val==false then
val=nil
elseif not types[type(val)] then
err(info, inputpos, "'" .. paramname.. "' - "..errormsg)
end
info[paramname] = val
info[paramname.."_at"] = depth
end
return old,oldat
end
 
 
-- iterateargs(tab) - custom iterator that iterates both t.args and t.plugins.*
local dummytable={}
 
local function iterateargs(tab)
if not tab.plugins then
return pairs(tab.args)
end
 
local argtabkey,argtab=next(tab.plugins)
local v
 
return function(_, k)
while argtab do
k,v = next(argtab, k)
if k then return k,v end
if argtab==tab.args then
argtab=nil
else
argtabkey,argtab = next(tab.plugins, argtabkey)
if not argtabkey then
argtab=tab.args
end
end
end
end
end
 
local function showhelp(info, inputpos, tab, noHead)
if not noHead then
print("|cff33ff99"..info.appName.."|r: Arguments to |cffffff78/"..info[0].."|r "..strsub(info.input,1,inputpos-1)..":")
end
 
local sortTbl = {} -- [1..n]=name
local refTbl = {} -- [name]=tableref
 
for k,v in iterateargs(tab) do
if not refTbl[k] then -- a plugin overriding something in .args
table.insert(sortTbl, k)
refTbl[k] = v
end
end
 
table.sort(sortTbl, function(one, two)
local o1 = refTbl[one].order or 100
local o2 = refTbl[two].order or 100
if type(o1) == "function" or type(o1) == "string" then
info.order = o1
info[#info+1] = one
o1 = callmethod(info, inputpos, refTbl[one], "order")
info[#info] = nil
info.order = nil
end
if type(o2) == "function" or type(o1) == "string" then
info.order = o2
info[#info+1] = two
o2 = callmethod(info, inputpos, refTbl[two], "order")
info[#info] = nil
info.order = nil
end
if o1<0 and o2<0 then return o1<o2 end
if o2<0 then return true end
if o1<0 then return false end
if o1==o2 then return tostring(one)<tostring(two) end -- compare names
return o1<o2
end)
 
for _,k in ipairs(sortTbl) do
local v = refTbl[k]
if not pickfirstset(v.cmdHidden, v.hidden, false) then
-- recursively show all inline groups
local name, desc = v.name, v.desc
if type(name) == "function" then
name = callfunction(info, v, 'name')
end
if type(desc) == "function" then
desc = callfunction(info, v, 'desc')
end
if v.type == "group" and pickfirstset(v.cmdInline, v.inline, false) then
print(" "..(desc or name)..":")
showhelp(info, inputpos, v, true)
elseif v.type ~= "description" and v.type ~= "header" then
local key = k:gsub(" ", "_")
print(" |cffffff78"..key.."|r - "..(desc or name or ""))
end
end
end
end
 
 
local function keybindingValidateFunc(text)
if text == nil or text == "NONE" then
return nil
end
text = text:upper()
local shift, ctrl, alt
local modifier
while true do
if text == "-" then
break
end
modifier, text = strsplit('-', text, 2)
if text then
if modifier ~= "SHIFT" and modifier ~= "CTRL" and modifier ~= "ALT" then
return false
end
if modifier == "SHIFT" then
if shift then
return false
end
shift = true
end
if modifier == "CTRL" then
if ctrl then
return false
end
ctrl = true
end
if modifier == "ALT" then
if alt then
return false
end
alt = true
end
else
text = modifier
break
end
end
if text == "" then
return false
end
if not text:find("^F%d+$") and text ~= "CAPSLOCK" and text:len() ~= 1 and (text:byte() < 128 or text:len() > 4) and not _G["KEY_" .. text] then
return false
end
local s = text
if shift then
s = "SHIFT-" .. s
end
if ctrl then
s = "CTRL-" .. s
end
if alt then
s = "ALT-" .. s
end
return s
end
 
-- constants used by getparam() calls below
 
local handlertypes = {["table"]=true}
local handlermsg = "expected a table"
 
local functypes = {["function"]=true, ["string"]=true}
local funcmsg = "expected function or member name"
 
-- handle() - selfrecursing function that processes input->optiontable
-- - depth - starts at 0
-- - retfalse - return false rather than produce error if a match is not found (used by inlined groups)
 
local function handle(info, inputpos, tab, depth, retfalse)
 
if not(type(tab)=="table" and type(tab.type)=="string") then err(info,inputpos) end
 
-------------------------------------------------------------------
-- Grab hold of handler,set,get,func,etc if set (and remember old ones)
-- Note that we do NOT validate if method names are correct at this stage,
-- the handler may change before they're actually used!
 
local oldhandler,oldhandler_at = getparam(info,inputpos,tab,depth,"handler",handlertypes,handlermsg)
local oldset,oldset_at = getparam(info,inputpos,tab,depth,"set",functypes,funcmsg)
local oldget,oldget_at = getparam(info,inputpos,tab,depth,"get",functypes,funcmsg)
local oldfunc,oldfunc_at = getparam(info,inputpos,tab,depth,"func",functypes,funcmsg)
local oldvalidate,oldvalidate_at = getparam(info,inputpos,tab,depth,"validate",functypes,funcmsg)
--local oldconfirm,oldconfirm_at = getparam(info,inputpos,tab,depth,"confirm",functypes,funcmsg)
 
-------------------------------------------------------------------
-- Act according to .type of this table
 
if tab.type=="group" then
------------ group --------------------------------------------
 
if type(tab.args)~="table" then err(info, inputpos) end
if tab.plugins and type(tab.plugins)~="table" then err(info,inputpos) end
 
-- grab next arg from input
local _,nextpos,arg = string.find(info.input, " *([^ ]+) *", inputpos)
if not arg then
showhelp(info, inputpos, tab)
return
end
nextpos=nextpos+1
 
-- loop .args and try to find a key with a matching name
for k,v in iterateargs(tab) do
if not(type(k)=="string" and type(v)=="table" and type(v.type)=="string") then err(info,inputpos, "options table child '"..tostring(k).."' is malformed") end
 
-- is this child an inline group? if so, traverse into it
if v.type=="group" and pickfirstset(v.cmdInline, v.inline, false) then
info[depth+1] = k
if handle(info, inputpos, v, depth+1, true)==false then
info[depth+1] = nil
-- wasn't found in there, but that's ok, we just keep looking down here
else
return -- done, name was found in inline group
end
-- matching name and not a inline group
elseif strlower(arg)==strlower(k:gsub(" ", "_")) then
info[depth+1] = k
return handle(info,nextpos,v,depth+1)
end
end
 
-- no match
if retfalse then
-- restore old infotable members and return false to indicate failure
info.handler,info.handler_at = oldhandler,oldhandler_at
info.set,info.set_at = oldset,oldset_at
info.get,info.get_at = oldget,oldget_at
info.func,info.func_at = oldfunc,oldfunc_at
info.validate,info.validate_at = oldvalidate,oldvalidate_at
--info.confirm,info.confirm_at = oldconfirm,oldconfirm_at
return false
end
 
-- couldn't find the command, display error
usererr(info, inputpos, "'"..arg.."' - " .. L["unknown argument"])
return
end
 
local str = strsub(info.input,inputpos);
 
if tab.type=="execute" then
------------ execute --------------------------------------------
do_final(info, inputpos, tab, "func")
 
 
 
elseif tab.type=="input" then
------------ input --------------------------------------------
 
local res = true
if tab.pattern then
if not(type(tab.pattern)=="string") then err(info, inputpos, "'pattern' - expected a string") end
if not strmatch(str, tab.pattern) then
usererr(info, inputpos, "'"..str.."' - " .. L["invalid input"])
return
end
end
 
do_final(info, inputpos, tab, "set", str)
 
 
 
elseif tab.type=="toggle" then
------------ toggle --------------------------------------------
local b
local str = strtrim(strlower(str))
if str=="" then
b = callmethod(info, inputpos, tab, "get")
 
if tab.tristate then
--cycle in true, nil, false order
if b then
b = nil
elseif b == nil then
b = false
else
b = true
end
else
b = not b
end
 
elseif str==L["on"] then
b = true
elseif str==L["off"] then
b = false
elseif tab.tristate and str==L["default"] then
b = nil
else
if tab.tristate then
usererr(info, inputpos, format(L["'%s' - expected 'on', 'off' or 'default', or no argument to toggle."], str))
else
usererr(info, inputpos, format(L["'%s' - expected 'on' or 'off', or no argument to toggle."], str))
end
return
end
 
do_final(info, inputpos, tab, "set", b)
 
 
elseif tab.type=="range" then
------------ range --------------------------------------------
local val = tonumber(str)
if not val then
usererr(info, inputpos, "'"..str.."' - "..L["expected number"])
return
end
if type(info.step)=="number" then
val = val- (val % info.step)
end
if type(info.min)=="number" and val<info.min then
usererr(info, inputpos, val.." - "..format(L["must be equal to or higher than %s"], tostring(info.min)) )
return
end
if type(info.max)=="number" and val>info.max then
usererr(info, inputpos, val.." - "..format(L["must be equal to or lower than %s"], tostring(info.max)) )
return
end
 
do_final(info, inputpos, tab, "set", val)
 
 
elseif tab.type=="select" then
------------ select ------------------------------------
local str = strtrim(strlower(str))
 
local values = tab.values
if type(values) == "function" or type(values) == "string" then
info.values = values
values = callmethod(info, inputpos, tab, "values")
info.values = nil
end
 
if str == "" then
local b = callmethod(info, inputpos, tab, "get")
local fmt = "|cffffff78- [%s]|r %s"
local fmt_sel = "|cffffff78- [%s]|r %s |cffff0000*|r"
print(L["Options for |cffffff78"..info[#info].."|r:"])
for k, v in pairs(values) do
if b == k then
print(fmt_sel:format(k, v))
else
print(fmt:format(k, v))
end
end
return
end
 
local ok
for k,v in pairs(values) do
if strlower(k)==str then
str = k -- overwrite with key (in case of case mismatches)
ok = true
break
end
end
if not ok then
usererr(info, inputpos, "'"..str.."' - "..L["unknown selection"])
return
end
 
do_final(info, inputpos, tab, "set", str)
 
elseif tab.type=="multiselect" then
------------ multiselect -------------------------------------------
local str = strtrim(strlower(str))
 
local values = tab.values
if type(values) == "function" or type(values) == "string" then
info.values = values
values = callmethod(info, inputpos, tab, "values")
info.values = nil
end
 
if str == "" then
local fmt = "|cffffff78- [%s]|r %s"
local fmt_sel = "|cffffff78- [%s]|r %s |cffff0000*|r"
print(L["Options for |cffffff78"..info[#info].."|r (multiple possible):"])
for k, v in pairs(values) do
if callmethod(info, inputpos, tab, "get", k) then
print(fmt_sel:format(k, v))
else
print(fmt:format(k, v))
end
end
return
end
 
--build a table of the selections, checking that they exist
--parse for =on =off =default in the process
--table will be key = true for options that should toggle, key = [on|off|default] for options to be set
local sels = {}
for v in string.gmatch(str, "[^ ]+") do
--parse option=on etc
local opt, val = string.match(v,'(.+)=(.+)')
--get option if toggling
if not opt then
opt = v
end
 
--check that the opt is valid
local ok
for k,v in pairs(values) do
if strlower(k)==opt then
opt = k -- overwrite with key (in case of case mismatches)
ok = true
break
end
end
 
if not ok then
usererr(info, inputpos, "'"..opt.."' - "..L["unknown selection"])
return
end
 
--check that if val was supplied it is valid
if val then
if val == L["on"] or val == L["off"] or (tab.tristate and val == L["default"]) then
--val is valid insert it
sels[opt] = val
else
if tab.tristate then
usererr(info, inputpos, format(L["'%s' '%s' - expected 'on', 'off' or 'default', or no argument to toggle."], v, val))
else
usererr(info, inputpos, format(L["'%s' '%s' - expected 'on' or 'off', or no argument to toggle."], v, val))
end
return
end
else
-- no val supplied, toggle
sels[opt] = true
end
end
 
for opt, val in pairs(sels) do
local newval
 
if (val == true) then
--toggle the option
local b = callmethod(info, inputpos, tab, "get", opt)
 
if tab.tristate then
--cycle in true, nil, false order
if b then
b = nil
elseif b == nil then
b = false
else
b = true
end
else
b = not b
end
newval = b
else
--set the option as specified
if val==L["on"] then
newval = true
elseif val==L["off"] then
newval = false
elseif val==L["default"] then
newval = nil
end
end
 
do_final(info, inputpos, tab, "set", opt, newval)
end
 
 
elseif tab.type=="color" then
------------ color --------------------------------------------
local str = strtrim(strlower(str))
if str == "" then
--TODO: Show current value
return
end
 
local r, g, b, a
 
if tab.hasAlpha then
if str:len() == 8 and str:find("^%x*$") then
--parse a hex string
r,g,b,a = tonumber(str:sub(1, 2), 16) / 255, tonumber(str:sub(3, 4), 16) / 255, tonumber(str:sub(5, 6), 16) / 255, tonumber(str:sub(7, 8), 16) / 255
else
--parse seperate values
r,g,b,a = str:match("^([%d%.]+) ([%d%.]+) ([%d%.]+) ([%d%.]+)$")
r,g,b,a = tonumber(r), tonumber(g), tonumber(b), tonumber(a)
end
if not (r and g and b and a) then
usererr(info, inputpos, format(L["'%s' - expected 'RRGGBBAA' or 'r g b a'."], str))
return
end
 
if r >= 0.0 and r <= 1.0 and g >= 0.0 and g <= 1.0 and b >= 0.0 and b <= 1.0 and a >= 0.0 and a <= 1.0 then
--values are valid
elseif r >= 0 and r <= 255 and g >= 0 and g <= 255 and b >= 0 and b <= 255 and a >= 0 and a <= 255 then
--values are valid 0..255, convert to 0..1
r = r / 255
g = g / 255
b = b / 255
a = a / 255
else
--values are invalid
usererr(info, inputpos, format(L["'%s' - values must all be either in the range 0..1 or 0..255."], str))
end
else
a = 1.0
if str:len() == 6 and str:find("^%x*$") then
--parse a hex string
r,g,b = tonumber(str:sub(1, 2), 16) / 255, tonumber(str:sub(3, 4), 16) / 255, tonumber(str:sub(5, 6), 16) / 255
else
--parse seperate values
r,g,b = str:match("^([%d%.]+) ([%d%.]+) ([%d%.]+)$")
r,g,b = tonumber(r), tonumber(g), tonumber(b)
end
if not (r and g and b) then
usererr(info, inputpos, format(L["'%s' - expected 'RRGGBB' or 'r g b'."], str))
return
end
if r >= 0.0 and r <= 1.0 and g >= 0.0 and g <= 1.0 and b >= 0.0 and b <= 1.0 then
--values are valid
elseif r >= 0 and r <= 255 and g >= 0 and g <= 255 and b >= 0 and b <= 255 then
--values are valid 0..255, convert to 0..1
r = r / 255
g = g / 255
b = b / 255
else
--values are invalid
usererr(info, inputpos, format(L["'%s' - values must all be either in the range 0-1 or 0-255."], str))
end
end
 
do_final(info, inputpos, tab, "set", r,g,b,a)
 
elseif tab.type=="keybinding" then
------------ keybinding --------------------------------------------
local str = strtrim(strlower(str))
if str == "" then
--TODO: Show current value
return
end
local value = keybindingValidateFunc(str:upper())
if value == false then
usererr(info, inputpos, format(L["'%s' - Invalid Keybinding."], str))
return
end
 
do_final(info, inputpos, tab, "set", value)
 
elseif tab.type=="description" then
------------ description --------------------
-- ignore description, GUI config only
else
err(info, inputpos, "unknown options table item type '"..tostring(tab.type).."'")
end
end
 
--- Handle the chat command.
-- This is usually called from a chat command handler to parse the command input as operations on an aceoptions table.\\
-- AceConfigCmd uses this function internally when a slash command is registered with `:CreateChatCommand`
-- @param slashcmd The slash command WITHOUT leading slash (only used for error output)
-- @param appName The application name as given to `:RegisterOptionsTable()`
-- @param input The commandline input (as given by the WoW handler, i.e. without the command itself)
-- @usage
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon", "AceConsole-3.0")
-- -- Use AceConsole-3.0 to register a Chat Command
-- MyAddon:RegisterChatCommand("mychat", "ChatCommand")
--
-- -- Show the GUI if no input is supplied, otherwise handle the chat input.
-- function MyAddon:ChatCommand(input)
-- -- Assuming "MyOptions" is the appName of a valid options table
-- if not input or input:trim() == "" then
-- LibStub("AceConfigDialog-3.0"):Open("MyOptions")
-- else
-- LibStub("AceConfigCmd-3.0").HandleCommand(MyAddon, "mychat", "MyOptions", input)
-- end
-- end
function AceConfigCmd:HandleCommand(slashcmd, appName, input)
 
local optgetter = cfgreg:GetOptionsTable(appName)
if not optgetter then
error([[Usage: HandleCommand("slashcmd", "appName", "input"): 'appName' - no options table "]]..tostring(appName)..[[" has been registered]], 2)
end
local options = assert( optgetter("cmd", MAJOR) )
 
local info = { -- Don't try to recycle this, it gets handed off to callbacks and whatnot
[0] = slashcmd,
appName = appName,
options = options,
input = input,
self = self,
handler = self,
uiType = "cmd",
uiName = MAJOR,
}
 
handle(info, 1, options, 0) -- (info, inputpos, table, depth)
end
 
--- Utility function to create a slash command handler.
-- Also registers tab completion with AceTab
-- @param slashcmd The slash command WITHOUT leading slash (only used for error output)
-- @param appName The application name as given to `:RegisterOptionsTable()`
function AceConfigCmd:CreateChatCommand(slashcmd, appName)
if not AceConsole then
AceConsole = LibStub(AceConsoleName)
end
if AceConsole.RegisterChatCommand(self, slashcmd, function(input)
AceConfigCmd.HandleCommand(self, slashcmd, appName, input) -- upgradable
end,
true) then -- succesfully registered so lets get the command -> app table in
commands[slashcmd] = appName
end
end
 
--- Utility function that returns the options table that belongs to a slashcommand.
-- Designed to be used for the AceTab interface.
-- @param slashcmd The slash command WITHOUT leading slash (only used for error output)
-- @return The options table associated with the slash command (or nil if the slash command was not registered)
function AceConfigCmd:GetChatCommandOptions(slashcmd)
return commands[slashcmd]
end
EasyDaily/libs/AceConfig-3.0/AceConfigRegistry-3.0/AceConfigRegistry-3.0.lua New file
0,0 → 1,341
--- AceConfigRegistry-3.0 handles central registration of options tables in use by addons and modules.
-- Options tables can be registered as raw tables, or as function refs that return a table.\\
-- These functions receive two arguments: "uiType" and "uiName". \\
-- Valid "uiTypes": "cmd", "dropdown", "dialog". This is verified by the library at call time. \\
-- The "uiName" field is expected to contain the full name of the calling addon, including version, e.g. "FooBar-1.0". This is verified by the library at call time.\\
-- :IterateOptionsTables() and :GetOptionsTable() always return a function reference that the requesting config handling addon must call with the above arguments.
-- @class file
-- @name AceConfigRegistry-3.0
-- @release $Id: AceConfigRegistry-3.0.lua 785 2009-04-05 14:57:29Z nevcairiel $
local MAJOR, MINOR = "AceConfigRegistry-3.0", 9
local AceConfigRegistry = LibStub:NewLibrary(MAJOR, MINOR)
 
if not AceConfigRegistry then return end
 
AceConfigRegistry.tables = AceConfigRegistry.tables or {}
 
local CallbackHandler = LibStub:GetLibrary("CallbackHandler-1.0")
 
if not AceConfigRegistry.callbacks then
AceConfigRegistry.callbacks = CallbackHandler:New(AceConfigRegistry)
end
 
-----------------------------------------------------------------------
-- Validating options table consistency:
 
 
AceConfigRegistry.validated = {
-- list of options table names ran through :ValidateOptionsTable automatically.
-- CLEARED ON PURPOSE, since newer versions may have newer validators
cmd = {},
dropdown = {},
dialog = {},
}
 
 
 
local function err(msg, errlvl, ...)
local t = {}
for i=select("#",...),1,-1 do
tinsert(t, (select(i, ...)))
end
error(MAJOR..":ValidateOptionsTable(): "..table.concat(t,".")..msg, errlvl+2)
end
 
 
local isstring={["string"]=true, _="string"}
local isstringfunc={["string"]=true,["function"]=true, _="string or funcref"}
local istable={["table"]=true, _="table"}
local ismethodtable={["table"]=true,["string"]=true,["function"]=true, _="methodname, funcref or table"}
local optstring={["nil"]=true,["string"]=true, _="string"}
local optstringfunc={["nil"]=true,["string"]=true,["function"]=true, _="string or funcref"}
local optnumber={["nil"]=true,["number"]=true, _="number"}
local optmethod={["nil"]=true,["string"]=true,["function"]=true, _="methodname or funcref"}
local optmethodfalse={["nil"]=true,["string"]=true,["function"]=true,["boolean"]={[false]=true}, _="methodname, funcref or false"}
local optmethodnumber={["nil"]=true,["string"]=true,["function"]=true,["number"]=true, _="methodname, funcref or number"}
local optmethodtable={["nil"]=true,["string"]=true,["function"]=true,["table"]=true, _="methodname, funcref or table"}
local optmethodbool={["nil"]=true,["string"]=true,["function"]=true,["boolean"]=true, _="methodname, funcref or boolean"}
local opttable={["nil"]=true,["table"]=true, _="table"}
local optbool={["nil"]=true,["boolean"]=true, _="boolean"}
local optboolnumber={["nil"]=true,["boolean"]=true,["number"]=true, _="boolean or number"}
 
local basekeys={
type=isstring,
name=isstringfunc,
desc=optstringfunc,
order=optmethodnumber,
validate=optmethodfalse,
confirm=optmethodbool,
confirmText=optstring,
disabled=optmethodbool,
hidden=optmethodbool,
guiHidden=optmethodbool,
dialogHidden=optmethodbool,
dropdownHidden=optmethodbool,
cmdHidden=optmethodbool,
icon=optstringfunc,
iconCoords=optmethodtable,
handler=opttable,
get=optmethodfalse,
set=optmethodfalse,
func=optmethodfalse,
arg={["*"]=true},
width=optstring,
}
 
local typedkeys={
header={},
description={
image=optstringfunc,
imageCoords=optmethodtable,
imageHeight=optnumber,
imageWidth=optnumber,
fontSize=optstringfunc,
},
group={
args=istable,
plugins=opttable,
inline=optbool,
cmdInline=optbool,
guiInline=optbool,
dropdownInline=optbool,
dialogInline=optbool,
childGroups=optstring,
},
execute={
image=optstringfunc,
imageCoords=optmethodtable,
imageHeight=optnumber,
imageWidth=optnumber,
},
input={
pattern=optstring,
usage=optstring,
control=optstring,
dialogControl=optstring,
dropdownControl=optstring,
multiline=optboolnumber,
},
toggle={
tristate=optbool,
},
tristate={
},
range={
min=optnumber,
max=optnumber,
step=optnumber,
bigStep=optnumber,
isPercent=optbool,
},
select={
values=ismethodtable,
style={
["nil"]=true,
["string"]={dropdown=true,radio=true},
_="string: 'dropdown' or 'radio'"
},
control=optstring,
dialogControl=optstring,
dropdownControl=optstring,
},
multiselect={
values=ismethodtable,
style=optstring,
tristate=optbool,
control=optstring,
dialogControl=optstring,
dropdownControl=optstring,
},
color={
hasAlpha=optbool,
},
keybinding={
-- TODO
},
}
 
local function validateKey(k,errlvl,...)
errlvl=(errlvl or 0)+1
if type(k)~="string" then
err("["..tostring(k).."] - key is not a string", errlvl,...)
end
if strfind(k, "[%c\127]") then
err("["..tostring(k).."] - key name contained control characters", errlvl,...)
end
end
 
local function validateVal(v, oktypes, errlvl,...)
errlvl=(errlvl or 0)+1
local isok=oktypes[type(v)] or oktypes["*"]
 
if not isok then
err(": expected a "..oktypes._..", got '"..tostring(v).."'", errlvl,...)
end
if type(isok)=="table" then -- isok was a table containing specific values to be tested for!
if not isok[v] then
err(": did not expect "..type(v).." value '"..tostring(v).."'", errlvl,...)
end
end
end
 
local function validate(options,errlvl,...)
errlvl=(errlvl or 0)+1
-- basic consistency
if type(options)~="table" then
err(": expected a table, got a "..type(options), errlvl,...)
end
if type(options.type)~="string" then
err(".type: expected a string, got a "..type(options.type), errlvl,...)
end
 
-- get type and 'typedkeys' member
local tk = typedkeys[options.type]
if not tk then
err(".type: unknown type '"..options.type.."'", errlvl,...)
end
 
-- make sure that all options[] are known parameters
for k,v in pairs(options) do
if not (tk[k] or basekeys[k]) then
err(": unknown parameter", errlvl,tostring(k),...)
end
end
 
-- verify that required params are there, and that everything is the right type
for k,oktypes in pairs(basekeys) do
validateVal(options[k], oktypes, errlvl,k,...)
end
for k,oktypes in pairs(tk) do
validateVal(options[k], oktypes, errlvl,k,...)
end
 
-- extra logic for groups
if options.type=="group" then
for k,v in pairs(options.args) do
validateKey(k,errlvl,"args",...)
validate(v, errlvl,k,"args",...)
end
if options.plugins then
for plugname,plugin in pairs(options.plugins) do
if type(plugin)~="table" then
err(": expected a table, got '"..tostring(plugin).."'", errlvl,tostring(plugname),"plugins",...)
end
for k,v in pairs(plugin) do
validateKey(k,errlvl,tostring(plugname),"plugins",...)
validate(v, errlvl,k,tostring(plugname),"plugins",...)
end
end
end
end
end
 
-- -------------------------------------------------------------------
-- :ValidateOptionsTable(options,name,errlvl)
-- - options - the table
-- - name - (string) name of table, used in error reports
-- - errlvl - (optional number) error level offset, default 0
--
-- Validates basic structure and integrity of an options table
-- Does NOT verify that get/set etc actually exist, since they can be defined at any depth
function AceConfigRegistry:ValidateOptionsTable(options,name,errlvl)
errlvl=(errlvl or 0)+1
name = name or "Optionstable"
if not options.name then
options.name=name -- bit of a hack, the root level doesn't really need a .name :-/
end
validate(options,errlvl,name)
end
 
--- Fires a ConfigTableChange callback for those listening in on it, allowing config GUIs to refresh.
-- You should call this function if your options table changed from any outside event, like a game event
-- or a timer.
-- @param appName The application name as given to `:RegisterOptionsTable()`
function AceConfigRegistry:NotifyChange(appName)
if not AceConfigRegistry.tables[appName] then return end
AceConfigRegistry.callbacks:Fire("ConfigTableChange", appName)
end
 
-- -------------------------------------------------------------------
-- Registering and retreiving options tables:
 
 
-- validateGetterArgs: helper function for :GetOptionsTable (or, rather, the getter functions returned by it)
 
local function validateGetterArgs(uiType, uiName, errlvl)
errlvl=(errlvl or 0)+2
if uiType~="cmd" and uiType~="dropdown" and uiType~="dialog" then
error(MAJOR..": Requesting options table: 'uiType' - invalid configuration UI type, expected 'cmd', 'dropdown' or 'dialog'", errlvl)
end
if not strmatch(uiName, "[A-Za-z]%-[0-9]") then -- Expecting e.g. "MyLib-1.2"
error(MAJOR..": Requesting options table: 'uiName' - badly formatted or missing version number. Expected e.g. 'MyLib-1.2'", errlvl)
end
end
 
--- Register an options table with the config registry.
-- @param appName The application name as given to `:RegisterOptionsTable()`
-- @param options The options table or a function reference that generates it on demand.
function AceConfigRegistry:RegisterOptionsTable(appName, options)
if type(options)=="table" then
if options.type~="group" then -- quick sanity checker
error(MAJOR..": RegisterOptionsTable(appName, options): 'options' - missing type='group' member in root group", 2)
end
AceConfigRegistry.tables[appName] = function(uiType, uiName, errlvl)
errlvl=(errlvl or 0)+1
validateGetterArgs(uiType, uiName, errlvl)
if not AceConfigRegistry.validated[uiType][appName] then
AceConfigRegistry:ValidateOptionsTable(options, appName, errlvl) -- upgradable
AceConfigRegistry.validated[uiType][appName] = true
end
return options
end
elseif type(options)=="function" then
AceConfigRegistry.tables[appName] = function(uiType, uiName, errlvl)
errlvl=(errlvl or 0)+1
validateGetterArgs(uiType, uiName, errlvl)
local tab = assert(options(uiType, uiName))
if not AceConfigRegistry.validated[uiType][appName] then
AceConfigRegistry:ValidateOptionsTable(tab, appName, errlvl) -- upgradable
AceConfigRegistry.validated[uiType][appName] = true
end
return tab
end
else
error(MAJOR..": RegisterOptionsTable(appName, options): 'options' - expected table or function reference", 2)
end
end
 
--- Returns an iterator of ["appName"]=funcref pairs
function AceConfigRegistry:IterateOptionsTables()
return pairs(AceConfigRegistry.tables)
end
 
 
---------------------------------------------------------------------
-- :GetOptionsTable(appName)
-- - appName - which addon to retreive the options table of
-- Optional:
-- - uiType - "cmd", "dropdown", "dialog"
-- - uiName - e.g. "MyLib-1.0"
--
 
 
--- Query the registry for a specific options table.
-- If only appName is given, a function is returned which you
-- can call with (uiType,uiName) to get the table.\\
-- If uiType&uiName are given, the table is returned.
-- @param appName The application name as given to `:RegisterOptionsTable()`
-- @param uiType The type of UI to get the table for.
-- @param uiName The name of the library/addon querying the table.
function AceConfigRegistry:GetOptionsTable(appName, uiType, uiName)
local f = AceConfigRegistry.tables[appName]
if not f then
return nil
end
 
if uiType then
return f(uiType,uiName,1) -- get the table for us
else
return f -- return the function
end
end
EasyDaily/libs/AceConfig-3.0/AceConfigRegistry-3.0/AceConfigRegistry-3.0.xml New file
0,0 → 1,4
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="AceConfigRegistry-3.0.lua"/>
</Ui>
\ No newline at end of file
EasyDaily/libs/LibBabble-Faction-3.0/LibBabble-Faction-3.0.lua New file
0,0 → 1,790
--[[
Name: LibBabble-Faction-3.0
Revision: $Rev: 83 $
Maintainers: ckknight, nevcairiel, Ackis
Website: http://www.wowace.com/projects/libbabble-faction-3-0/
Dependencies: None
License: MIT
]]
 
local MAJOR_VERSION = "LibBabble-Faction-3.0"
local MINOR_VERSION = 90000 + tonumber(("$Rev: 83 $"):match("%d+"))
 
if not LibStub then error(MAJOR_VERSION .. " requires LibStub.") end
local lib = LibStub("LibBabble-3.0"):New(MAJOR_VERSION, MINOR_VERSION)
if not lib then return end
 
local GAME_LOCALE = GetLocale()
 
lib:SetBaseTranslations {
Alliance = "Alliance",
["Alliance Vanguard"] = "Alliance Vanguard",
["Argent Crusade"] = "Argent Crusade",
["Argent Dawn"] = "Argent Dawn",
["Ashtongue Deathsworn"] = "Ashtongue Deathsworn",
["Bloodsail Buccaneers"] = "Bloodsail Buccaneers",
["Booty Bay"] = "Booty Bay",
["Brood of Nozdormu"] = "Brood of Nozdormu",
["Cenarion Circle"] = "Cenarion Circle",
["Cenarion Expedition"] = "Cenarion Expedition",
["Darkmoon Faire"] = "Darkmoon Faire",
["Darkspear Trolls"] = "Darkspear Trolls",
Darnassus = "Darnassus",
Everlook = "Everlook",
Exalted = "Exalted",
Exodar = "Exodar",
["Explorers' League"] = "Explorers' League",
["Frenzyheart Tribe"] = "Frenzyheart Tribe",
Friendly = "Friendly",
["Frostwolf Clan"] = "Frostwolf Clan",
Gadgetzan = "Gadgetzan",
["Gelkis Clan Centaur"] = "Gelkis Clan Centaur",
["Gnomeregan Exiles"] = "Gnomeregan Exiles",
Honored = "Honored",
["Honor Hold"] = "Honor Hold",
Horde = "Horde",
["Horde Expedition"] = "Horde Expedition",
["Hydraxian Waterlords"] = "Hydraxian Waterlords",
Ironforge = "Ironforge",
["Keepers of Time"] = "Keepers of Time",
["Kirin Tor"] = "Kirin Tor",
["Knights of the Ebon Blade"] = "Knights of the Ebon Blade",
Kurenai = "Kurenai",
["Lower City"] = "Lower City",
["Magram Clan Centaur"] = "Magram Clan Centaur",
Netherwing = "Netherwing",
Neutral = "Neutral",
["Ogri'la"] = "Ogri'la",
Orgrimmar = "Orgrimmar",
Ratchet = "Ratchet",
Ravenholdt = "Ravenholdt",
Revered = "Revered",
["Sha'tari Skyguard"] = "Sha'tari Skyguard",
["Shattered Sun Offensive"] = "Shattered Sun Offensive",
["Shen'dralar"] = "Shen'dralar",
["Silvermoon City"] = "Silvermoon City",
["Silverwing Sentinels"] = "Silverwing Sentinels",
Sporeggar = "Sporeggar",
["Stormpike Guard"] = "Stormpike Guard",
Stormwind = "Stormwind",
Syndicate = "Syndicate",
["The Aldor"] = "The Aldor",
["The Consortium"] = "The Consortium",
["The Defilers"] = "The Defilers",
["The Frostborn"] = "The Frostborn",
["The Hand of Vengeance"] = "The Hand of Vengeance",
["The Kalu'ak"] = "The Kalu'ak",
["The League of Arathor"] = "The League of Arathor",
["The Mag'har"] = "The Mag'har",
["The Oracles"] = "The Oracles",
["The Scale of the Sands"] = "The Scale of the Sands",
["The Scryers"] = "The Scryers",
["The Sha'tar"] = "The Sha'tar",
["The Silver Covenant"] = "The Silver Covenant",
["The Sons of Hodir"] = "The Sons of Hodir",
["The Sunreavers"] = "The Sunreavers",
["The Taunka"] = "The Taunka",
["The Violet Eye"] = "The Violet Eye",
["The Wyrmrest Accord"] = "The Wyrmrest Accord",
["Thorium Brotherhood"] = "Thorium Brotherhood",
Thrallmar = "Thrallmar",
["Thunder Bluff"] = "Thunder Bluff",
["Timbermaw Hold"] = "Timbermaw Hold",
Tranquillien = "Tranquillien",
Undercity = "Undercity",
["Valiance Expedition"] = "Valiance Expedition",
["Warsong Offensive"] = "Warsong Offensive",
["Warsong Outriders"] = "Warsong Outriders",
["Wildhammer Clan"] = "Wildhammer Clan",
["Winterfin Retreat"] = "Winterfin Retreat",
["Wintersaber Trainers"] = "Wintersaber Trainers",
["Zandalar Tribe"] = "Zandalar Tribe",
}
 
 
if GAME_LOCALE == "enUS" then
lib:SetCurrentTranslations(true)
elseif GAME_LOCALE == "deDE" then
lib:SetCurrentTranslations {
Alliance = "Allianz",
["Alliance Vanguard"] = "Vorposten der Allianz",
["Argent Crusade"] = "Argentumkreuzzug",
["Argent Dawn"] = "Argentumdämmerung",
["Ashtongue Deathsworn"] = "Die Todeshörigen",
["Bloodsail Buccaneers"] = "Blutsegelbukaniere",
["Booty Bay"] = "Beutebucht",
["Brood of Nozdormu"] = "Nozdormus Brut",
["Cenarion Circle"] = "Zirkel des Cenarius",
["Cenarion Expedition"] = "Expedition des Cenarius",
["Darkmoon Faire"] = "Dunkelmond-Jahrmarkt",
["Darkspear Trolls"] = "Dunkelspeertrolle",
Darnassus = "Darnassus",
Everlook = "Ewige Warte",
Exalted = "Ehrfürchtig",
Exodar = "Die Exodar",
["Explorers' League"] = "Forscherliga",
["Frenzyheart Tribe"] = "Stamm der Wildherzen",
Friendly = "Freundlich",
["Frostwolf Clan"] = "Frostwolfklan",
Gadgetzan = "Gadgetzan",
["Gelkis Clan Centaur"] = "Gelkisklan",
["Gnomeregan Exiles"] = "Gnomeregangnome",
Honored = "Wohlwollend",
["Honor Hold"] = "Ehrenfeste",
Horde = "Horde",
["Horde Expedition"] = "Expedition der Horde",
["Hydraxian Waterlords"] = "Hydraxianer",
Ironforge = "Eisenschmiede",
["Keepers of Time"] = "Hüter der Zeit",
["Kirin Tor"] = "Kirin Tor",
["Knights of the Ebon Blade"] = "Ritter der Schwarzen Klinge",
Kurenai = "Kurenai",
["Lower City"] = "Unteres Viertel",
["Magram Clan Centaur"] = "Magramklan",
Netherwing = "Netherschwingen",
Neutral = "Neutral",
["Ogri'la"] = "Ogri'la",
Orgrimmar = "Orgrimmar",
Ratchet = "Ratschet",
Ravenholdt = "Rabenholdt",
Revered = "Respektvoll",
["Sha'tari Skyguard"] = "Himmelswache der Sha'tari",
["Shattered Sun Offensive"] = "Offensive der Zerschmetterten Sonne",
["Shen'dralar"] = "Shen'dralar",
["Silvermoon City"] = "Silbermond",
["Silverwing Sentinels"] = "Silberschwingen",
Sporeggar = "Sporeggar",
["Stormpike Guard"] = "Sturmlanzengarde",
Stormwind = "Sturmwind",
Syndicate = "Syndikat",
["The Aldor"] = "Die Aldor",
["The Consortium"] = "Das Konsortium",
["The Defilers"] = "Die Entweihten",
["The Frostborn"] = "Die Frosterben",
["The Hand of Vengeance"] = "Die Hand der Rache",
["The Kalu'ak"] = "Die Kalu'ak",
["The League of Arathor"] = "Der Bund von Arathor",
["The Mag'har"] = "Die Mag'har",
["The Oracles"] = "Die Orakel",
["The Scale of the Sands"] = "Die Wächter der Sande",
["The Scryers"] = "Die Seher",
["The Sha'tar"] = "Die Sha'tar",
["The Silver Covenant"] = "Der Silberbund",
["The Sons of Hodir"] = "Die Söhne Hodirs",
["The Sunreavers"] = "Die Sonnenhäscher",
["The Taunka"] = "Die Taunka",
["The Violet Eye"] = "Das Violette Auge",
["The Wyrmrest Accord"] = "Der Wyrmruhpakt",
["Thorium Brotherhood"] = "Thoriumbruderschaft",
Thrallmar = "Thrallmar",
["Thunder Bluff"] = "Donnerfels",
["Timbermaw Hold"] = "Holzschlundfeste",
Tranquillien = "Tristessa",
Undercity = "Unterstadt",
["Valiance Expedition"] = "Expedition Valianz",
["Warsong Offensive"] = "Kriegshymnenoffensive",
["Warsong Outriders"] = "Vorhut des Kriegshymnenklan",
["Wildhammer Clan"] = "Wildhammerklan",
["Winterfin Retreat"] = "Zuflucht der Winterflossen",
["Wintersaber Trainers"] = "Wintersäblerausbilder",
["Zandalar Tribe"] = "Stamm der Zandalar",
}
elseif GAME_LOCALE == "frFR" then
lib:SetCurrentTranslations {
Alliance = "Alliance",
["Alliance Vanguard"] = "Avant-garde de l'Alliance",
["Argent Crusade"] = "La Croisade d'argent",
["Argent Dawn"] = "Aube d'argent",
["Ashtongue Deathsworn"] = "Ligemort cendrelangue",
["Bloodsail Buccaneers"] = "La Voile sanglante",
["Booty Bay"] = "Baie-du-Butin",
["Brood of Nozdormu"] = "Progéniture de Nozdormu",
["Cenarion Circle"] = "Cercle cénarien",
["Cenarion Expedition"] = "Expédition cénarienne",
["Darkmoon Faire"] = "Foire de Sombrelune",
["Darkspear Trolls"] = "Trolls Sombrelance",
Darnassus = "Darnassus",
Everlook = "Long-guet",
Exalted = "Exalté",
Exodar = "Exodar",
["Explorers' League"] = "Ligue des explorateurs",
["Frenzyheart Tribe"] = "La tribu Frénécœur",
Friendly = "Amical",
["Frostwolf Clan"] = "Clan Loup-de-givre",
Gadgetzan = "Gadgetzan",
["Gelkis Clan Centaur"] = "Centaures (Gelkis)",
["Gnomeregan Exiles"] = "Exilés de Gnomeregan",
Honored = "Honoré",
["Honor Hold"] = "Bastion de l'Honneur",
Horde = "Horde",
["Horde Expedition"] = "Expédition de la Horde",
["Hydraxian Waterlords"] = "Les Hydraxiens",
Ironforge = "Forgefer",
["Keepers of Time"] = "Gardiens du Temps",
["Kirin Tor"] = "Kirin Tor",
["Knights of the Ebon Blade"] = "Chevaliers de la Lame d'ébène",
Kurenai = "Kurenaï",
["Lower City"] = "Ville basse",
["Magram Clan Centaur"] = "Centaures (Magram)",
Netherwing = "Aile-du-Néant",
Neutral = "Neutre",
["Ogri'la"] = "Ogri'la",
Orgrimmar = "Orgrimmar",
Ratchet = "Cabestan",
Ravenholdt = "Ravenholdt",
Revered = "Révéré",
["Sha'tari Skyguard"] = "Garde-ciel sha'tari",
["Shattered Sun Offensive"] = "Opération Soleil brisé",
["Shen'dralar"] = "Shen'dralar",
["Silvermoon City"] = "Lune-d'argent",
["Silverwing Sentinels"] = "Sentinelles d'Aile-argent",
Sporeggar = "Sporeggar",
["Stormpike Guard"] = "Garde Foudrepique",
Stormwind = "Hurlevent",
Syndicate = "Syndicat",
["The Aldor"] = "L'Aldor",
["The Consortium"] = "Le Consortium",
["The Defilers"] = "Les Profanateurs",
["The Frostborn"] = "Les Givre-nés",
["The Hand of Vengeance"] = "La Main de la vengeance",
["The Kalu'ak"] = "Les Kalu'aks",
["The League of Arathor"] = "La Ligue d'Arathor",
["The Mag'har"] = "Les Mag'har",
["The Oracles"] = "Les Oracles",
["The Scale of the Sands"] = "La Balance des sables",
["The Scryers"] = "Les Clairvoyants",
["The Sha'tar"] = "Les Sha'tar",
["The Silver Covenant"] = "Le Concordat argenté",
["The Sons of Hodir"] = "Les Fils d'Hodir",
["The Sunreavers"] = "Les Saccage-soleil",
["The Taunka"] = "Les Taunkas",
["The Violet Eye"] = "L'Œil pourpre",
["The Wyrmrest Accord"] = "L'Accord de Repos du ver",
["Thorium Brotherhood"] = "Confrérie du thorium",
Thrallmar = "Thrallmar",
["Thunder Bluff"] = "Les Pitons du Tonnerre",
["Timbermaw Hold"] = "Les Grumegueules",
Tranquillien = "Tranquillien",
Undercity = "Fossoyeuse",
["Valiance Expedition"] = "Expédition de la Bravoure",
["Warsong Offensive"] = "Offensive chanteguerre",
["Warsong Outriders"] = "Voltigeurs Chanteguerre",
["Wildhammer Clan"] = "Clan Marteau-hardi",
["Winterfin Retreat"] = "Retraite des Ailerons-d'hiver",
["Wintersaber Trainers"] = "Éleveurs de sabres-d'hiver",
["Zandalar Tribe"] = "Tribu Zandalar",
}
elseif GAME_LOCALE == "koKR" then
lib:SetCurrentTranslations {
Alliance = "얼라이언스",
["Alliance Vanguard"] = "얼라이언스 선봉대",
["Argent Crusade"] = "은빛십자군",
["Argent Dawn"] = "은빛 여명회",
["Ashtongue Deathsworn"] = "잿빛혓바닥 결사단",
["Bloodsail Buccaneers"] = "붉은 해적단",
["Booty Bay"] = "무법항",
["Brood of Nozdormu"] = "노즈도르무 혈족",
["Cenarion Circle"] = "세나리온 의회",
["Cenarion Expedition"] = "세나리온 원정대",
["Darkmoon Faire"] = "다크문 유랑단",
["Darkspear Trolls"] = "검은창 트롤",
Darnassus = "다르나서스",
Everlook = "눈망루 마을",
Exalted = "확고한 동맹",
Exodar = "엑소다르",
["Explorers' League"] = "탐험가 연맹",
["Frenzyheart Tribe"] = "광란의심장일족",
Friendly = "약간 우호적",
["Frostwolf Clan"] = "서리늑대 부족",
Gadgetzan = "가젯잔",
["Gelkis Clan Centaur"] = "겔키스 부족 켄타로우스",
["Gnomeregan Exiles"] = "놈리건",
Honored = "우호적",
["Honor Hold"] = "명예의 요새",
Horde = "호드",
["Horde Expedition"] = "호드 원정대",
["Hydraxian Waterlords"] = "히드락시안 물의 군주",
Ironforge = "아이언포지",
["Keepers of Time"] = "시간의 수호자",
["Kirin Tor"] = "키린 토",
["Knights of the Ebon Blade"] = "칠흑의 기사단",
Kurenai = "쿠레나이",
["Lower City"] = "고난의 거리",
["Magram Clan Centaur"] = "마그람 부족 켄타로우스",
Netherwing = "황천의 용군단",
Neutral = "중립적",
["Ogri'la"] = "오그릴라",
Orgrimmar = "오그리마",
Ratchet = "톱니항",
Ravenholdt = "라벤홀트",
Revered = "매우 우호적",
["Sha'tari Skyguard"] = "샤타리 하늘경비대",
["Shattered Sun Offensive"] = "무너진 태양 공격대",
["Shen'dralar"] = "센드렐라",
["Silvermoon City"] = "실버문",
["Silverwing Sentinels"] = "은빛날개 파수대",
Sporeggar = "스포어가르",
["Stormpike Guard"] = "스톰파이크 경비대",
Stormwind = "스톰윈드",
Syndicate = "비밀결사대",
["The Aldor"] = "알도르 사제회",
["The Consortium"] = "무역연합",
["The Defilers"] = "포세이큰 파멸단",
["The Frostborn"] = "서릿결부족 드워프",
["The Hand of Vengeance"] = "복수의 대리인",
["The Kalu'ak"] = "칼루아크",
["The League of Arathor"] = "아라소르 연맹",
["The Mag'har"] = "마그하르",
["The Oracles"] = "점쟁이 조합",
["The Scale of the Sands"] = "시간의 중재자",
["The Scryers"] = "점술가 길드",
["The Sha'tar"] = "샤타르",
["The Silver Covenant"] = "은빛 서약단",
["The Sons of Hodir"] = "호디르의 후예",
["The Sunreavers"] = "선리버",
["The Taunka"] = "타운카",
["The Violet Eye"] = "보랏빛 눈의 감시자",
["The Wyrmrest Accord"] = "고룡쉼터 사원 용군단",
["Thorium Brotherhood"] = "토륨 대장조합 ",
Thrallmar = "스랄마",
["Thunder Bluff"] = "썬더 블러프",
["Timbermaw Hold"] = "나무구렁 요새",
Tranquillien = "트랜퀼리엔",
Undercity = "언더시티",
["Valiance Expedition"] = "용맹의 원정대",
["Warsong Offensive"] = "전쟁노래 공격대",
["Warsong Outriders"] = "전쟁노래 정찰대",
["Wildhammer Clan"] = "와일드해머 부족",
["Winterfin Retreat"] = "겨울지느러미 은신처",
["Wintersaber Trainers"] = "눈호랑이 조련사",
["Zandalar Tribe"] = "잔달라 부족",
}
elseif GAME_LOCALE == "esES" then
lib:SetCurrentTranslations {
Alliance = "Alianza",
["Alliance Vanguard"] = "Vanguardia de la Alianza",
["Argent Crusade"] = "Cruzada Argenta",
["Argent Dawn"] = "Alba Argenta",
["Ashtongue Deathsworn"] = "Juramorte Lengua de ceniza",
["Bloodsail Buccaneers"] = "Bucaneros Velasangre",
["Booty Bay"] = "Bahía del Botín",
["Brood of Nozdormu"] = "Linaje de Nozdormu",
["Cenarion Circle"] = "Círculo Cenarion",
["Cenarion Expedition"] = "Expedición Cenarion",
["Darkmoon Faire"] = "Feria de la Luna Negra",
["Darkspear Trolls"] = "Trols Lanza Negra",
Darnassus = "Darnassus",
Everlook = "Vista Eterna",
Exalted = "Exaltado",
Exodar = "Exodar",
["Explorers' League"] = "Liga de Expedicionarios",
["Frenzyheart Tribe"] = "Tribu Corazón Frenético",
Friendly = "Amistoso",
["Frostwolf Clan"] = "Clan Lobo Gélido",
Gadgetzan = "Gadgetzan",
["Gelkis Clan Centaur"] = "Centauro del clan Gelkis",
["Gnomeregan Exiles"] = "Exiliados de Gnomeregan",
Honored = "Honorable",
["Honor Hold"] = "Bastión del Honor",
Horde = "Horda",
["Horde Expedition"] = "Expedición de la Horda",
["Hydraxian Waterlords"] = "Srs. del Agua de Hydraxis",
Ironforge = "Forjaz",
["Keepers of Time"] = "Vigilantes del tiempo",
["Kirin Tor"] = "Kirin Tor",
["Knights of the Ebon Blade"] = "Caballeros de la Espada de Ébano",
Kurenai = "Kurenai",
["Lower City"] = "Bajo Arrabal",
["Magram Clan Centaur"] = "Centauro del clan Magram",
Netherwing = "Ala Abisal",
Neutral = "Neutral",
["Ogri'la"] = "Ogri'la",
Orgrimmar = "Orgrimmar",
Ratchet = "Trinquete",
Ravenholdt = "Ravenholdt",
Revered = "Reverenciado",
["Sha'tari Skyguard"] = "Guardia del cielo Sha'tari",
["Shattered Sun Offensive"] = "Ofensiva Sol Devastado",
["Shen'dralar"] = "Shen'dralar",
["Silvermoon City"] = "Ciudad de Lunargenta",
["Silverwing Sentinels"] = "Centinelas Ala de Plata",
Sporeggar = "Esporaggar",
["Stormpike Guard"] = "Guardia Pico Tormenta",
Stormwind = "Ventormenta",
Syndicate = "La Hermandad",
["The Aldor"] = "Los Aldor",
["The Consortium"] = "El Consorcio",
["The Defilers"] = "Los Rapiñadores",
["The Frostborn"] = "Los Natoescarcha",
["The Hand of Vengeance"] = "La Mano de la Venganza",
["The Kalu'ak"] = "Los Kalu'ak",
["The League of Arathor"] = "Liga de Arathor",
["The Mag'har"] = "Los Mag'har",
["The Oracles"] = "Los Oráculos",
["The Scale of the Sands"] = "La Escama de las Arenas",
["The Scryers"] = "Los Arúspices",
["The Sha'tar"] = "Los Sha'tar",
["The Silver Covenant"] = "El Pacto de Plata",
["The Sons of Hodir"] = "Los Hijos de Hodir",
["The Sunreavers"] = "Los Atracasol",
["The Taunka"] = "Los taunka",
["The Violet Eye"] = "El Ojo Violeta",
["The Wyrmrest Accord"] = "El Acuerdo del Reposo del Dragón",
["Thorium Brotherhood"] = "Hermandad del torio",
Thrallmar = "Thrallmar",
["Thunder Bluff"] = "Cima del Trueno",
["Timbermaw Hold"] = "Bastión Fauces de Madera",
Tranquillien = "Tranquilien",
Undercity = "Entrañas",
["Valiance Expedition"] = "Expedición de Denuedo",
["Warsong Offensive"] = "Ofensiva Grito de Guerra",
["Warsong Outriders"] = "Escoltas Grito de Guerra",
["Wildhammer Clan"] = "Clan Martillo Salvaje",
["Winterfin Retreat"] = "Retiro Aleta Invernal",
["Wintersaber Trainers"] = "Instructores de Sableinvernales",
["Zandalar Tribe"] = "Tribu Zandalar",
}
elseif GAME_LOCALE == "esMX" then
lib:SetCurrentTranslations {
-- Alliance = "",
-- ["Alliance Vanguard"] = "",
-- ["Argent Crusade"] = "",
-- ["Argent Dawn"] = "",
-- ["Ashtongue Deathsworn"] = "",
-- ["Bloodsail Buccaneers"] = "",
-- ["Booty Bay"] = "",
-- ["Brood of Nozdormu"] = "",
-- ["Cenarion Circle"] = "",
-- ["Cenarion Expedition"] = "",
-- ["Darkmoon Faire"] = "",
-- ["Darkspear Trolls"] = "",
-- Darnassus = "",
-- Everlook = "",
-- Exalted = "",
-- Exodar = "",
-- ["Explorers' League"] = "",
-- ["Frenzyheart Tribe"] = "",
-- Friendly = "",
-- ["Frostwolf Clan"] = "",
-- Gadgetzan = "",
-- ["Gelkis Clan Centaur"] = "",
-- ["Gnomeregan Exiles"] = "",
-- Honored = "",
-- ["Honor Hold"] = "",
-- Horde = "",
-- ["Horde Expedition"] = "",
-- ["Hydraxian Waterlords"] = "",
-- Ironforge = "",
-- ["Keepers of Time"] = "",
-- ["Kirin Tor"] = "",
-- ["Knights of the Ebon Blade"] = "",
-- Kurenai = "",
-- ["Lower City"] = "",
-- ["Magram Clan Centaur"] = "",
-- Netherwing = "",
-- Neutral = "",
-- ["Ogri'la"] = "",
-- Orgrimmar = "",
-- Ratchet = "",
-- Ravenholdt = "",
-- Revered = "",
-- ["Sha'tari Skyguard"] = "",
-- ["Shattered Sun Offensive"] = "",
-- ["Shen'dralar"] = "",
-- ["Silvermoon City"] = "",
-- ["Silverwing Sentinels"] = "",
-- Sporeggar = "",
-- ["Stormpike Guard"] = "",
-- Stormwind = "",
-- Syndicate = "",
-- ["The Aldor"] = "",
-- ["The Consortium"] = "",
-- ["The Defilers"] = "",
-- ["The Frostborn"] = "",
-- ["The Hand of Vengeance"] = "",
-- ["The Kalu'ak"] = "",
-- ["The League of Arathor"] = "",
-- ["The Mag'har"] = "",
-- ["The Oracles"] = "",
-- ["The Scale of the Sands"] = "",
-- ["The Scryers"] = "",
-- ["The Sha'tar"] = "",
-- ["The Silver Covenant"] = "",
-- ["The Sons of Hodir"] = "",
-- ["The Sunreavers"] = "",
-- ["The Taunka"] = "",
-- ["The Violet Eye"] = "",
-- ["The Wyrmrest Accord"] = "",
-- ["Thorium Brotherhood"] = "",
-- Thrallmar = "",
-- ["Thunder Bluff"] = "",
-- ["Timbermaw Hold"] = "",
-- Tranquillien = "",
-- Undercity = "",
-- ["Valiance Expedition"] = "",
-- ["Warsong Offensive"] = "",
-- ["Warsong Outriders"] = "",
-- ["Wildhammer Clan"] = "",
-- ["Winterfin Retreat"] = "",
-- ["Wintersaber Trainers"] = "",
-- ["Zandalar Tribe"] = "",
}
elseif GAME_LOCALE == "ruRU" then
lib:SetCurrentTranslations {
Alliance = "Альянс",
["Alliance Vanguard"] = "Авангард Альянса",
["Argent Crusade"] = "Серебряный Авангард",
["Argent Dawn"] = "Серебряный Рассвет",
["Ashtongue Deathsworn"] = "Пеплоусты-служители",
["Bloodsail Buccaneers"] = "Пираты Кровавого Паруса",
["Booty Bay"] = "Пиратская бухта",
["Brood of Nozdormu"] = "Род Ноздорму",
["Cenarion Circle"] = "Круг Кенария",
["Cenarion Expedition"] = "Экспедиция Ценариона",
["Darkmoon Faire"] = "Ярмарка Новолуния",
["Darkspear Trolls"] = "Тролли Черного Копья",
Darnassus = "Дарнас",
Everlook = "Круговзор",
Exalted = "Превознесение",
Exodar = "Экзодар",
["Explorers' League"] = "Лига исследователей",
["Frenzyheart Tribe"] = "Племя Мятежного Сердца",
Friendly = "Дружелюбие",
["Frostwolf Clan"] = "Клан Северного Волка",
Gadgetzan = "Прибамбасск",
["Gelkis Clan Centaur"] = "Кентавры из племени Гелкис",
["Gnomeregan Exiles"] = "Изгнанники Гномрегана",
Honored = "Уважение",
["Honor Hold"] = "Оплот Чести",
Horde = "Орда",
["Horde Expedition"] = "Экспедиция Орды",
["Hydraxian Waterlords"] = "Гидраксианские Повелители Вод",
Ironforge = "Стальгорн",
["Keepers of Time"] = "Хранители Времени",
["Kirin Tor"] = "Кирин-Тор",
["Knights of the Ebon Blade"] = "Рыцари Черного Клинка",
Kurenai = "Куренай",
["Lower City"] = "Нижний Город",
["Magram Clan Centaur"] = "Кентавры из племени Маграм",
Netherwing = "Крылья Пустоверти",
Neutral = "Равнодушие",
["Ogri'la"] = "Огри'ла",
Orgrimmar = "Оргриммар",
Ratchet = "Кабестан",
Ravenholdt = "Черный Ворон",
Revered = "Почтение",
["Sha'tari Skyguard"] = "Стражи Небес Ша'тар",
["Shattered Sun Offensive"] = "Армия Расколотого Солнца",
["Shen'dralar"] = "Шен'дралар",
["Silvermoon City"] = "Луносвет",
["Silverwing Sentinels"] = "Среброкрылые Часовые",
Sporeggar = "Спореггар",
["Stormpike Guard"] = "Стража Грозовой Вершины",
Stormwind = "Штормград",
Syndicate = "Синдикат",
["The Aldor"] = "Алдоры",
["The Consortium"] = "Консорциум",
["The Defilers"] = "Осквернители",
["The Frostborn"] = "Зиморожденные",
["The Hand of Vengeance"] = "Карающая длань",
["The Kalu'ak"] = "Калу'ак",
["The League of Arathor"] = "Лига Аратора",
["The Mag'har"] = "Маг'хары",
["The Oracles"] = "Оракулы",
["The Scale of the Sands"] = "Песчаная Чешуя",
["The Scryers"] = "Провидцы",
["The Sha'tar"] = "Ша'тар",
["The Silver Covenant"] = "Серебряный Союз",
["The Sons of Hodir"] = "Сыновья Ходира",
["The Sunreavers"] = "Похитители солнца",
["The Taunka"] = "Таунка",
["The Violet Eye"] = "Аметистовое Око",
["The Wyrmrest Accord"] = "Драконий союз",
["Thorium Brotherhood"] = "Братство Тория",
Thrallmar = "Траллмар",
["Thunder Bluff"] = "Громовой Утес",
["Timbermaw Hold"] = "Древобрюхи",
Tranquillien = "Транквиллион",
Undercity = "Подгород",
["Valiance Expedition"] = "Экспедиция Отважных",
["Warsong Offensive"] = "Армия Песни Войны",
["Warsong Outriders"] = "Всадники Песни Войны",
["Wildhammer Clan"] = "Неистовый Молот",
["Winterfin Retreat"] = "Холодный Плавник",
["Wintersaber Trainers"] = "Укротители ледопардов",
["Zandalar Tribe"] = "Племя Зандалар",
}
elseif GAME_LOCALE == "zhCN" then
lib:SetCurrentTranslations {
Alliance = "联盟",
["Alliance Vanguard"] = "联盟先遣军",
["Argent Crusade"] = "银色北伐军",
["Argent Dawn"] = "银色黎明",
["Ashtongue Deathsworn"] = "灰舌死誓者",
["Bloodsail Buccaneers"] = "血帆海盗",
["Booty Bay"] = "藏宝海湾",
["Brood of Nozdormu"] = "诺兹多姆的子嗣",
["Cenarion Circle"] = "塞纳里奥议会",
["Cenarion Expedition"] = "塞纳里奥远征队",
["Darkmoon Faire"] = "暗月马戏团",
["Darkspear Trolls"] = "暗矛巨魔",
Darnassus = "达纳苏斯",
Everlook = "永望镇",
Exalted = "崇拜",
Exodar = "埃索达",
["Explorers' League"] = "探险者协会",
["Frenzyheart Tribe"] = "狂心氏族",
Friendly = "友善",
["Frostwolf Clan"] = "霜狼氏族",
Gadgetzan = "加基森",
["Gelkis Clan Centaur"] = "吉尔吉斯半人马",
["Gnomeregan Exiles"] = "诺莫瑞根流亡者",
Honored = "尊敬",
["Honor Hold"] = "荣耀堡",
Horde = "部落",
["Horde Expedition"] = "部落先遣军",
["Hydraxian Waterlords"] = "海达希亚水元素",
Ironforge = "铁炉堡",
["Keepers of Time"] = "时光守护者",
["Kirin Tor"] = "肯瑞托",
["Knights of the Ebon Blade"] = "黑锋骑士团",
Kurenai = "库雷尼",
["Lower City"] = "贫民窟",
["Magram Clan Centaur"] = "玛格拉姆半人马",
Netherwing = "灵翼之龙",
Neutral = "中立",
["Ogri'la"] = "奥格瑞拉",
Orgrimmar = "奥格瑞玛",
Ratchet = "棘齿城",
Ravenholdt = "拉文霍德",
Revered = "崇敬",
["Sha'tari Skyguard"] = "沙塔尔天空卫士",
["Shattered Sun Offensive"] = "破碎残阳",
["Shen'dralar"] = "辛德拉",
["Silvermoon City"] = "银月城",
["Silverwing Sentinels"] = "银翼哨兵",
Sporeggar = "孢子村",
["Stormpike Guard"] = "雷矛卫队",
Stormwind = "暴风城",
Syndicate = "辛迪加",
["The Aldor"] = "奥尔多",
["The Consortium"] = "星界财团",
["The Defilers"] = "污染者",
["The Frostborn"] = "霜脉矮人",
["The Hand of Vengeance"] = "复仇之手",
["The Kalu'ak"] = "卡鲁亚克",
["The League of Arathor"] = "阿拉索联军",
["The Mag'har"] = "玛格汉",
["The Oracles"] = "神谕者",
["The Scale of the Sands"] = "流沙之鳞",
["The Scryers"] = "占星者",
["The Sha'tar"] = "沙塔尔",
["The Silver Covenant"] = "银色盟约",
["The Sons of Hodir"] = "霍迪尔之子",
["The Sunreavers"] = "夺日者",
["The Taunka"] = "牦牛人",
["The Violet Eye"] = "紫罗兰之眼",
["The Wyrmrest Accord"] = "龙眠联军",
["Thorium Brotherhood"] = "瑟银兄弟会",
Thrallmar = "萨尔玛",
["Thunder Bluff"] = "雷霆崖",
["Timbermaw Hold"] = "木喉要塞",
Tranquillien = "塔奎林",
Undercity = "幽暗城",
["Valiance Expedition"] = "无畏远征军",
["Warsong Offensive"] = "战歌远征军",
["Warsong Outriders"] = "战歌侦察骑兵",
["Wildhammer Clan"] = "蛮锤部族",
["Winterfin Retreat"] = "冬鳞避难所",
["Wintersaber Trainers"] = "冬刃豹训练师",
["Zandalar Tribe"] = "赞达拉部族",
}
elseif GAME_LOCALE == "zhTW" then
lib:SetCurrentTranslations {
Alliance = "聯盟",
["Alliance Vanguard"] = "聯盟先鋒",
["Argent Crusade"] = "銀白十字軍",
["Argent Dawn"] = "銀色黎明",
["Ashtongue Deathsworn"] = "灰舌死亡誓言者",
["Bloodsail Buccaneers"] = "血帆海盜",
["Booty Bay"] = "藏寶海灣",
["Brood of Nozdormu"] = "諾茲多姆的子嗣",
["Cenarion Circle"] = "塞納里奧議會",
["Cenarion Expedition"] = "塞納里奧遠征隊",
["Darkmoon Faire"] = "暗月馬戲團",
["Darkspear Trolls"] = "暗矛食人妖",
Darnassus = "達納蘇斯",
Everlook = "永望鎮",
Exalted = "崇拜",
Exodar = "艾克索達",
["Explorers' League"] = "探險者協會",
["Frenzyheart Tribe"] = "狂心部族",
Friendly = "友好",
["Frostwolf Clan"] = "霜狼氏族",
Gadgetzan = "加基森",
["Gelkis Clan Centaur"] = "吉爾吉斯半人馬",
["Gnomeregan Exiles"] = "諾姆瑞根流亡者",
Honored = "尊敬",
["Honor Hold"] = "榮譽堡",
Horde = "部落",
["Horde Expedition"] = "部落遠征軍",
["Hydraxian Waterlords"] = "海達希亞水元素",
Ironforge = "鐵爐堡",
["Keepers of Time"] = "時光守望者",
["Kirin Tor"] = "祈倫托",
["Knights of the Ebon Blade"] = "黯刃騎士團",
Kurenai = "卡爾奈",
["Lower City"] = "陰鬱城",
["Magram Clan Centaur"] = "瑪格拉姆半人馬",
Netherwing = "虛空之翼",
Neutral = "中立",
["Ogri'la"] = "歐格利拉",
Orgrimmar = "奧格瑪",
Ratchet = "棘齒城",
Ravenholdt = "拉文霍德",
Revered = "崇敬",
["Sha'tari Skyguard"] = "薩塔禦天者",
["Shattered Sun Offensive"] = "破碎之日進攻部隊",
["Shen'dralar"] = "辛德拉",
["Silvermoon City"] = "銀月城",
["Silverwing Sentinels"] = "銀翼哨兵",
Sporeggar = "斯博格爾",
["Stormpike Guard"] = "雷矛衛隊",
Stormwind = "暴風城",
Syndicate = "辛迪加",
["The Aldor"] = "奧多爾",
["The Consortium"] = "聯合團",
["The Defilers"] = "污染者",
["The Frostborn"] = "霜誕矮人",
["The Hand of Vengeance"] = "復仇之手",
["The Kalu'ak"] = "卡魯耶克",
["The League of Arathor"] = "阿拉索聯軍",
["The Mag'har"] = "瑪格哈",
["The Oracles"] = "神諭者",
["The Scale of the Sands"] = "流沙之鱗",
["The Scryers"] = "占卜者",
["The Sha'tar"] = "薩塔",
["The Silver Covenant"] = "白銀誓盟",
["The Sons of Hodir"] = "霍迪爾之子",
["The Sunreavers"] = "奪日者",
["The Taunka"] = "坦卡族",
["The Violet Eye"] = "紫羅蘭之眼",
["The Wyrmrest Accord"] = "龍眠協調者",
["Thorium Brotherhood"] = "瑟銀兄弟會",
Thrallmar = "索爾瑪",
["Thunder Bluff"] = "雷霆崖",
["Timbermaw Hold"] = "木喉要塞",
Tranquillien = "安寧地",
Undercity = "幽暗城",
["Valiance Expedition"] = "驍勇遠征隊",
["Warsong Offensive"] = "戰歌進攻部隊",
["Warsong Outriders"] = "戰歌偵察騎兵",
["Wildhammer Clan"] = "蠻錘氏族",
["Winterfin Retreat"] = "冬鰭避居地",
["Wintersaber Trainers"] = "冬刃豹訓練師",
["Zandalar Tribe"] = "贊達拉部族",
}
 
else
error(("%s: Locale %q not supported"):format(MAJOR_VERSION, GAME_LOCALE))
end
EasyDaily/libs/LibBabble-Faction-3.0/LibBabble-Faction-3.0.toc New file
0,0 → 1,22
## Interface: 30100
## LoadOnDemand: 1
## Title: Lib: Babble-Faction-3.0
## Notes: A library to help with localization of factions.
## Notes-zhCN: 为本地化服务的支持库[声望阵营]
## Notes-zhTW: 為本地化服務的函式庫[聲望陣營]
## Notes-deDE: BabbleLib ist eine Bibliothek, die bei der Lokalisierung helfen soll.
## Notes-frFR: Une bibliothèque d'aide à la localisation.
## Notes-esES: Una biblioteca para ayudar con las localizaciones.
## Notes-ruRU: Библиотека для локализации аддонов.
## Author: Daviesh
## X-eMail: oma_daviesh@hotmail.com
## X-Category: Library
## X-License: MIT
## X-Curse-Packaged-Version: r87
## X-Curse-Project-Name: LibBabble-Faction-3.0
## X-Curse-Project-ID: libbabble-faction-3-0
## X-Curse-Repository-ID: wow/libbabble-faction-3-0/mainline
 
LibStub\LibStub.lua
lib.xml
 
EasyDaily/libs/LibBabble-Faction-3.0/LibStub/LibStub.lua New file
0,0 → 1,30
-- LibStub is a simple versioning stub meant for use in Libraries. http://www.wowace.com/wiki/LibStub for more info
-- LibStub is hereby placed in the Public Domain Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke
local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2 -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS!
local LibStub = _G[LIBSTUB_MAJOR]
 
if not LibStub or LibStub.minor < LIBSTUB_MINOR then
LibStub = LibStub or {libs = {}, minors = {} }
_G[LIBSTUB_MAJOR] = LibStub
LibStub.minor = LIBSTUB_MINOR
 
function LibStub:NewLibrary(major, minor)
assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)")
minor = assert(tonumber(strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.")
 
local oldminor = self.minors[major]
if oldminor and oldminor >= minor then return nil end
self.minors[major], self.libs[major] = minor, self.libs[major] or {}
return self.libs[major], oldminor
end
 
function LibStub:GetLibrary(major, silent)
if not self.libs[major] and not silent then
error(("Cannot find a library instance of %q."):format(tostring(major)), 2)
end
return self.libs[major], self.minors[major]
end
 
function LibStub:IterateLibraries() return pairs(self.libs) end
setmetatable(LibStub, { __call = LibStub.GetLibrary })
end
EasyDaily/libs/LibBabble-Faction-3.0/lib.xml New file
0,0 → 1,5
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="LibBabble-3.0.lua" />
<Script file="LibBabble-Faction-3.0.lua" />
</Ui>
EasyDaily/libs/LibBabble-Faction-3.0/LibBabble-3.0.lua New file
0,0 → 1,292
-- LibBabble-3.0 is hereby placed in the Public Domain
-- Credits: ckknight
local LIBBABBLE_MAJOR, LIBBABBLE_MINOR = "LibBabble-3.0", 2
 
local LibBabble = LibStub:NewLibrary(LIBBABBLE_MAJOR, LIBBABBLE_MINOR)
if not LibBabble then
return
end
 
local data = LibBabble.data or {}
for k,v in pairs(LibBabble) do
LibBabble[k] = nil
end
LibBabble.data = data
 
local tablesToDB = {}
for namespace, db in pairs(data) do
for k,v in pairs(db) do
tablesToDB[v] = db
end
end
 
local function warn(message)
local _, ret = pcall(error, message, 3)
geterrorhandler()(ret)
end
 
local lookup_mt = { __index = function(self, key)
local db = tablesToDB[self]
local current_key = db.current[key]
if current_key then
self[key] = current_key
return current_key
end
local base_key = db.base[key]
local real_MAJOR_VERSION
for k,v in pairs(data) do
if v == db then
real_MAJOR_VERSION = k
break
end
end
if not real_MAJOR_VERSION then
real_MAJOR_VERSION = LIBBABBLE_MAJOR
end
if base_key then
warn(("%s: Translation %q not found for locale %q"):format(real_MAJOR_VERSION, key, GetLocale()))
rawset(self, key, base_key)
return base_key
end
warn(("%s: Translation %q not found."):format(real_MAJOR_VERSION, key))
rawset(self, key, key)
return key
end }
 
local function initLookup(module, lookup)
local db = tablesToDB[module]
for k in pairs(lookup) do
lookup[k] = nil
end
setmetatable(lookup, lookup_mt)
tablesToDB[lookup] = db
db.lookup = lookup
return lookup
end
 
local function initReverse(module, reverse)
local db = tablesToDB[module]
for k in pairs(reverse) do
reverse[k] = nil
end
for k,v in pairs(db.current) do
reverse[v] = k
end
tablesToDB[reverse] = db
db.reverse = reverse
db.reverseIterators = nil
return reverse
end
 
local prototype = {}
local prototype_mt = {__index = prototype}
 
--[[---------------------------------------------------------------------------
Notes:
* If you try to access a nonexistent key, it will warn but allow the code to pass through.
Returns:
A lookup table for english to localized words.
Example:
local B = LibStub("LibBabble-Module-3.0") -- where Module is what you want.
local BL = B:GetLookupTable()
assert(BL["Some english word"] == "Some localized word")
DoSomething(BL["Some english word that doesn't exist"]) -- warning!
-----------------------------------------------------------------------------]]
function prototype:GetLookupTable()
local db = tablesToDB[self]
 
local lookup = db.lookup
if lookup then
return lookup
end
return initLookup(self, {})
end
--[[---------------------------------------------------------------------------
Notes:
* If you try to access a nonexistent key, it will return nil.
Returns:
A lookup table for english to localized words.
Example:
local B = LibStub("LibBabble-Module-3.0") -- where Module is what you want.
local B_has = B:GetUnstrictLookupTable()
assert(B_has["Some english word"] == "Some localized word")
assert(B_has["Some english word that doesn't exist"] == nil)
-----------------------------------------------------------------------------]]
function prototype:GetUnstrictLookupTable()
local db = tablesToDB[self]
 
return db.current
end
--[[---------------------------------------------------------------------------
Notes:
* If you try to access a nonexistent key, it will return nil.
* This is useful for checking if the base (English) table has a key, even if the localized one does not have it registered.
Returns:
A lookup table for english to localized words.
Example:
local B = LibStub("LibBabble-Module-3.0") -- where Module is what you want.
local B_hasBase = B:GetBaseLookupTable()
assert(B_hasBase["Some english word"] == "Some english word")
assert(B_hasBase["Some english word that doesn't exist"] == nil)
-----------------------------------------------------------------------------]]
function prototype:GetBaseLookupTable()
local db = tablesToDB[self]
 
return db.base
end
--[[---------------------------------------------------------------------------
Notes:
* If you try to access a nonexistent key, it will return nil.
* This will return only one English word that it maps to, if there are more than one to check, see :GetReverseIterator("word")
Returns:
A lookup table for localized to english words.
Example:
local B = LibStub("LibBabble-Module-3.0") -- where Module is what you want.
local BR = B:GetReverseLookupTable()
assert(BR["Some localized word"] == "Some english word")
assert(BR["Some localized word that doesn't exist"] == nil)
-----------------------------------------------------------------------------]]
function prototype:GetReverseLookupTable()
local db = tablesToDB[self]
 
local reverse = db.reverse
if reverse then
return reverse
end
return initReverse(self, {})
end
local blank = {}
local weakVal = {__mode='v'}
--[[---------------------------------------------------------------------------
Arguments:
string - the localized word to chek for.
Returns:
An iterator to traverse all English words that map to the given key
Example:
local B = LibStub("LibBabble-Module-3.0") -- where Module is what you want.
for word in B:GetReverseIterator("Some localized word") do
DoSomething(word)
end
-----------------------------------------------------------------------------]]
function prototype:GetReverseIterator(key)
local db = tablesToDB[self]
local reverseIterators = db.reverseIterators
if not reverseIterators then
reverseIterators = setmetatable({}, weakVal)
db.reverseIterators = reverseIterators
elseif reverseIterators[key] then
return pairs(reverseIterators[key])
end
local t
for k,v in pairs(db.current) do
if v == key then
if not t then
t = {}
end
t[k] = true
end
end
reverseIterators[key] = t or blank
return pairs(reverseIterators[key])
end
--[[---------------------------------------------------------------------------
Returns:
An iterator to traverse all translations English to localized.
Example:
local B = LibStub("LibBabble-Module-3.0") -- where Module is what you want.
for english, localized in B:Iterate() do
DoSomething(english, localized)
end
-----------------------------------------------------------------------------]]
function prototype:Iterate()
local db = tablesToDB[self]
 
return pairs(db.current)
end
 
-- #NODOC
-- modules need to call this to set the base table
function prototype:SetBaseTranslations(base)
local db = tablesToDB[self]
local oldBase = db.base
if oldBase then
for k in pairs(oldBase) do
oldBase[k] = nil
end
for k, v in pairs(base) do
oldBase[k] = v
end
base = oldBase
else
db.base = base
end
for k,v in pairs(base) do
if v == true then
base[k] = k
end
end
end
 
local function init(module)
local db = tablesToDB[module]
if db.lookup then
initLookup(module, db.lookup)
end
if db.reverse then
initReverse(module, db.reverse)
end
db.reverseIterators = nil
end
 
-- #NODOC
-- modules need to call this to set the current table. if current is true, use the base table.
function prototype:SetCurrentTranslations(current)
local db = tablesToDB[self]
if current == true then
db.current = db.base
else
local oldCurrent = db.current
if oldCurrent then
for k in pairs(oldCurrent) do
oldCurrent[k] = nil
end
for k, v in pairs(current) do
oldCurrent[k] = v
end
current = oldCurrent
else
db.current = current
end
end
init(self)
end
 
for namespace, db in pairs(data) do
setmetatable(db.module, prototype_mt)
init(db.module)
end
 
-- #NODOC
-- modules need to call this to create a new namespace.
function LibBabble:New(namespace, minor)
local module, oldminor = LibStub:NewLibrary(namespace, minor)
if not module then
return
end
 
if not oldminor then
local db = {
module = module,
}
data[namespace] = db
tablesToDB[module] = db
else
for k,v in pairs(module) do
module[k] = nil
end
end
 
setmetatable(module, prototype_mt)
 
return module
end
EasyDaily/libs/LibDBIcon-1.0/LibDBIcon-1.0.lua New file
0,0 → 1,242
--[[
Name: DBIcon-1.0
Revision: $Rev: 8 $
Author(s): Rabbit (rabbit.magtheridon@gmail.com)
Description: Allows addons to register to recieve a lightweight minimap icon as an alternative to more heavy LDB displays.
Dependencies: LibStub
License: GPL v2 or later.
]]
 
--[[
Copyright (C) 2008-2009 Rabbit
 
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
]]
 
-----------------------------------------------------------------------
-- DBIcon-1.0
--
-- Disclaimer: Most of this code was ripped from Barrel but fixed, streamlined
-- and cleaned up a lot so that it no longer sucks.
--
 
local DBICON10 = "LibDBIcon-1.0"
local DBICON10_MINOR = tonumber(("$Rev: 8 $"):match("(%d+)"))
if not LibStub then error(DBICON10 .. " requires LibStub.") end
local lib = LibStub:NewLibrary(DBICON10, DBICON10_MINOR)
if not lib then return end
local ldb = LibStub("LibDataBroker-1.1", true)
if not ldb then error(DBICON10 .. " requires LibDataBroker-1.1.") end
 
lib.objects = lib.objects or {}
lib.callbackRegistered = lib.callbackRegistered or nil
lib.notCreated = lib.notCreated or {}
 
function lib:IconCallback(event, name, key, value, dataobj)
if lib.objects[name] then
lib.objects[name].icon:SetTexture(dataobj.icon)
end
end
if not lib.callbackRegistered then
ldb.RegisterCallback(lib, "LibDataBroker_AttributeChanged__icon", "IconCallback")
lib.callbackRegistered = true
end
 
-- Tooltip code ripped from StatBlockCore by Funkydude
local function getAnchors(frame)
local x,y = frame:GetCenter()
if not x or not y then return "TOPLEFT", "BOTTOMLEFT" end
local hhalf = (x > UIParent:GetWidth()*2/3) and "RIGHT" or (x < UIParent:GetWidth()/3) and "LEFT" or ""
local vhalf = (y > UIParent:GetHeight()/2) and "TOP" or "BOTTOM"
return vhalf..hhalf, frame, (vhalf == "TOP" and "BOTTOM" or "TOP")..hhalf
end
 
local function onEnter(self)
local obj = self.dataObject
if not self.isMoving and obj.OnTooltipShow then
GameTooltip:SetOwner(self, "ANCHOR_NONE")
GameTooltip:SetPoint(getAnchors(self))
obj.OnTooltipShow(GameTooltip)
GameTooltip:Show()
elseif obj.OnEnter then
obj.OnEnter(self)
end
end
 
local function onLeave(self)
local obj = self.dataObject
GameTooltip:Hide()
if obj.OnLeave then obj.OnLeave(self) end
end
 
--------------------------------------------------------------------------------
 
local minimapShapes = {
["ROUND"] = {true, true, true, true},
["SQUARE"] = {false, false, false, false},
["CORNER-TOPLEFT"] = {true, false, false, false},
["CORNER-TOPRIGHT"] = {false, false, true, false},
["CORNER-BOTTOMLEFT"] = {false, true, false, false},
["CORNER-BOTTOMRIGHT"] = {false, false, false, true},
["SIDE-LEFT"] = {true, true, false, false},
["SIDE-RIGHT"] = {false, false, true, true},
["SIDE-TOP"] = {true, false, true, false},
["SIDE-BOTTOM"] = {false, true, false, true},
["TRICORNER-TOPLEFT"] = {true, true, true, false},
["TRICORNER-TOPRIGHT"] = {true, false, true, true},
["TRICORNER-BOTTOMLEFT"] = {true, true, false, true},
["TRICORNER-BOTTOMRIGHT"] = {false, true, true, true},
}
 
local function updatePosition(button)
local angle = math.rad(button.db.minimapPos or 225)
local x, y, q = math.cos(angle), math.sin(angle), 1
if x < 0 then q = q + 1 end
if y > 0 then q = q + 2 end
local minimapShape = GetMinimapShape and GetMinimapShape() or "ROUND"
local quadTable = minimapShapes[minimapShape]
if quadTable[q] then
x, y = x*80, y*80
else
local diagRadius = 103.13708498985 --math.sqrt(2*(80)^2)-10
x = math.max(-80, math.min(x*diagRadius, 80))
y = math.max(-80, math.min(y*diagRadius, 80))
end
button:SetPoint("CENTER", Minimap, "CENTER", x, y)
end
 
local function onClick(self, b) if self.dataObject.OnClick then self.dataObject.OnClick(self, b) end end
local function onMouseDown(self) self.icon:SetTexCoord(0, 1, 0, 1) end
local function onMouseUp(self) self.icon:SetTexCoord(0.05, 0.95, 0.05, 0.95) end
 
local function onUpdate(self)
local mx, my = Minimap:GetCenter()
local px, py = GetCursorPosition()
local scale = Minimap:GetEffectiveScale()
px, py = px / scale, py / scale
self.db.minimapPos = math.deg(math.atan2(py - my, px - mx)) % 360
updatePosition(self)
end
 
local function onDragStart(self)
self:LockHighlight()
self.icon:SetTexCoord(0, 1, 0, 1)
self:SetScript("OnUpdate", onUpdate)
self.isMoving = true
GameTooltip:Hide()
end
 
local function onDragStop(self)
self:SetScript("OnUpdate", nil)
self.icon:SetTexCoord(0.05, 0.95, 0.05, 0.95)
self:UnlockHighlight()
self.isMoving = nil
end
 
local function createButton(name, object, db)
local button = CreateFrame("Button", "LibDBIcon10_"..name, Minimap)
button.dataObject = object
button.db = db
button:SetFrameStrata("MEDIUM")
button:SetWidth(31); button:SetHeight(31)
button:SetFrameLevel(8)
button:RegisterForClicks("anyUp")
button:RegisterForDrag("LeftButton")
button:SetHighlightTexture("Interface\\Minimap\\UI-Minimap-ZoomButton-Highlight")
local overlay = button:CreateTexture(nil, "OVERLAY")
overlay:SetWidth(53); overlay:SetHeight(53)
overlay:SetTexture("Interface\\Minimap\\MiniMap-TrackingBorder")
overlay:SetPoint("TOPLEFT")
local icon = button:CreateTexture(nil, "BACKGROUND")
icon:SetWidth(20); icon:SetHeight(20)
icon:SetTexture(object.icon)
icon:SetTexCoord(0.05, 0.95, 0.05, 0.95)
icon:SetPoint("TOPLEFT", 7, -5)
button.icon = icon
 
button.total = 0
button:SetScript("OnEnter", onEnter)
button:SetScript("OnLeave", onLeave)
button:SetScript("OnClick", onClick)
button:SetScript("OnDragStart", onDragStart)
button:SetScript("OnDragStop", onDragStop)
button:SetScript("OnMouseDown", onMouseDown)
button:SetScript("OnMouseUp", onMouseUp)
 
lib.objects[name] = button
 
if lib.loggedIn then
updatePosition(button)
if not db.hide then button:Show()
else button:Hide() end
end
end
 
-- We could use a metatable.__index on lib.objects, but then we'd create
-- the icons when checking things like :IsRegistered, which is not necessary.
local function check(name)
if lib.notCreated[name] then
createButton(name, lib.notCreated[name][1], lib.notCreated[name][2])
lib.notCreated[name] = nil
end
end
 
lib.loggedIn = lib.loggedIn or false
-- Wait a bit with the initial positioning to let any GetMinimapShape addons
-- load up.
if not lib.loggedIn then
local f = CreateFrame("Frame")
f:SetScript("OnEvent", function()
for _, object in pairs(lib.objects) do
updatePosition(object)
if not object.db.hide then object:Show()
else object:Hide() end
end
lib.loggedIn = true
f:SetScript("OnEvent", nil)
f = nil
end)
f:RegisterEvent("PLAYER_LOGIN")
end
 
function lib:Register(name, object, db)
if not object.icon then error("Can't register LDB objects without icons set!") end
if lib.objects[name] or lib.notCreated[name] then error("Already registered, nubcake.") end
if not db or not db.hide then
createButton(name, object, db)
else
lib.notCreated[name] = {object, db}
end
end
 
function lib:Hide(name)
check(name)
lib.objects[name]:Hide()
end
function lib:Show(name)
check(name)
lib.objects[name]:Show()
updatePosition(lib.objects[name])
end
function lib:IsRegistered(name)
return (lib.objects[name] or lib.notCreated[name]) and true or false
end
function lib:Refresh(name, db)
check(name)
local button = lib.objects[name]
if db then button.db = db end
updatePosition(button)
end
 
EasyDaily/libs/LibAbacus-3.0/lib.xml New file
0,0 → 1,4
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="LibAbacus-3.0.lua" />
</Ui>
\ No newline at end of file
EasyDaily/libs/LibAbacus-3.0/LibAbacus-3.0.toc New file
0,0 → 1,16
## Interface: 20400
## LoadOnDemand: 1
## Title: Lib: Abacus-3.0
## Notes: A library to provide tools for formatting money and time.
## Author: ckknight
## X-AceLibrary-Abacus-2.0: true
## X-eMail: ckknight@gmail.com
## X-Category: Library
## X-License: LGPL v2.1
## X-Curse-Packaged-Version: r49
## X-Curse-Project-Name: LibAbacus-3.0
## X-Curse-Project-ID: libabacus-3-0
## X-Curse-Repository-ID: wow/libabacus-3-0/mainline
 
LibStub\LibStub.lua
lib.xml
EasyDaily/libs/LibAbacus-3.0/LICENSE.txt New file
0,0 → 1,15
Copyright (C) 2006-2007 ckknight
 
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
 
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
 
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
\ No newline at end of file
EasyDaily/libs/LibAbacus-3.0/LibAbacus-3.0.lua New file
0,0 → 1,547
--[[
Name: LibAbacus-3.0
Revision: $Rev: 46 $
Author(s): ckknight (ckknight@gmail.com)
Website: http://ckknight.wowinterface.com/
Documentation: http://www.wowace.com/wiki/LibAbacus-3.0
SVN: http://svn.wowace.com/wowace/trunk/LibAbacus-3.0
Description: A library to provide tools for formatting money and time.
License: LGPL v2.1
]]
 
local MAJOR_VERSION = "LibAbacus-3.0"
local MINOR_VERSION = tonumber(("$Revision: 46 $"):match("(%d+)")) + 90000
 
if not LibStub then error(MAJOR_VERSION .. " requires LibStub") end
local Abacus, oldLib = LibStub:NewLibrary(MAJOR_VERSION, MINOR_VERSION)
if not Abacus then
return
end
 
local gsub = string.gsub
 
local COPPER_ABBR
local SILVER_ABBR
local GOLD_ABBR
local GOLD, SILVER, COPPER = GOLD, SILVER, COPPER
 
if not COPPER and COPPER_AMOUNT then
GOLD = GOLD_AMOUNT:gsub("%s*%%d%s*", "")
SILVER = SILVER_AMOUNT:gsub("%s*%%d%s*", "")
COPPER = COPPER_AMOUNT:gsub("%s*%%d%s*", "")
end
 
if (COPPER:byte(1) or 128) > 127 then
-- non-western
COPPER_ABBR = COPPER
SILVER_ABBR = SILVER
GOLD_ABBR = GOLD
else
COPPER_ABBR = COPPER:sub(1, 1):lower()
SILVER_ABBR = SILVER:sub(1, 1):lower()
GOLD_ABBR = GOLD:sub(1, 1):lower()
end
 
local DAYS_ABBR_S1, HOURS_ABBR_S1, MINUTES_ABBR_S1, SECONDS_ABBR_S1
local DAYS_ABBR_P1, HOURS_ABBR_P1, MINUTES_ABBR_P1, SECONDS_ABBR_P1 = DAYS_ABBR_P1, HOURS_ABBR_P1, MINUTES_ABBR_P1, SECONDS_ABBR_P1
 
if not DAYS_ABBR_P1 then
DAYS_ABBR_S1 = gsub(DAYS_ABBR, ".*|4(.-):.-;.*", "%1")
DAYS_ABBR_P1 = gsub(DAYS_ABBR, ".*|4.-:(.-);.*", "%1")
 
HOURS_ABBR_S1 = gsub(HOURS_ABBR, ".*|4(.-):.-;.*", "%1")
HOURS_ABBR_P1 = gsub(HOURS_ABBR, ".*|4.-:(.-);.*", "%1")
 
MINUTES_ABBR_S1 = gsub(MINUTES_ABBR, ".*|4(.-):.-;.*", "%1")
MINUTES_ABBR_P1 = gsub(MINUTES_ABBR, ".*|4.-:(.-);.*", "%1")
 
SECONDS_ABBR_S1 = gsub(SECONDS_ABBR, ".*|4(.-):.-;.*", "%1")
SECONDS_ABBR_P1 = gsub(SECONDS_ABBR, ".*|4.-:(.-);.*", "%1")
else
DAYS_ABBR_S1 = DAYS_ABBR
HOURS_ABBR_S1 = HOURS_ABBR
MINUTES_ABBR_S1 = MINUTES_ABBR
SECONDS_ABBR_S1 = SECONDS_ABBR
end
 
 
local COLOR_WHITE = "ffffff"
local COLOR_GREEN = "00ff00"
local COLOR_RED = "ff0000"
local COLOR_COPPER = "eda55f"
local COLOR_SILVER = "c7c7cf"
local COLOR_GOLD = "ffd700"
 
local L_DAY_ONELETTER_ABBR = DAY_ONELETTER_ABBR:gsub("%s*%%d%s*", "")
local L_HOUR_ONELETTER_ABBR = HOUR_ONELETTER_ABBR:gsub("%s*%%d%s*", "")
local L_MINUTE_ONELETTER_ABBR = MINUTE_ONELETTER_ABBR:gsub("%s*%%d%s*", "")
local L_SECOND_ONELETTER_ABBR = SECOND_ONELETTER_ABBR:gsub("%s*%%d%s*", "")
 
local L_UNDETERMINED = "Undetermined"
 
if ( GetLocale() =="koKR" ) then
L_UNDETERMINED = "측정불가"
elseif ( GetLocale() == "zhTW" ) then
COPPER_ABBR = "銅"
SILVER_ABBR = "銀"
GOLD_ABBR = "金"
 
L_UNDETERMINED = "未定義的"
 
--***************************************
-- zhCN Chinese Simplify
-- 2007/09/19 CN3羽月 雪夜之狼
-- 请保留本翻译作者名 谢谢
-- E=mail:xionglingfeng@Gmail.com
-- Website:http://www.wowtigu.org (Chs)
--***************************************
elseif ( GetLocale() == "zhCN" ) then
COPPER_ABBR = "铜"
SILVER_ABBR = "银"
GOLD_ABBR = "金"
 
L_UNDETERMINED = "未定义的"
--***************************************
-- ruRU Russian, 2008-08-04
-- Author: SLA80, sla80x at Gmail com
--***************************************
elseif ( GetLocale() == "ruRU" ) then
GOLD, SILVER, COPPER = "золота", "серебра", "меди"
GOLD_ABBR, SILVER_ABBR, COPPER_ABBR = "з", "с", "м"
DAYS_ABBR_P1 = "дней"
HOURS_ABBR_S1, HOURS_ABBR_P1 = "ч.", "ч."
MINUTES_ABBR_S1, MINUTES_ABBR_P1 = "мин.", "мин."
SECONDS_ABBR_S1, SECONDS_ABBR_P1 = "сек.", "сек."
L_UNDETERMINED = "Неопределено"
end
 
local inf = 1/0
 
function Abacus:FormatMoneyExtended(value, colorize, textColor)
local gold = abs(value / 10000)
local silver = abs(mod(value / 100, 100))
local copper = abs(mod(value, 100))
 
local negl = ""
local color = COLOR_WHITE
if value > 0 then
if textColor then
color = COLOR_GREEN
end
elseif value < 0 then
negl = "-"
if textColor then
color = COLOR_RED
end
end
if colorize then
if value == inf or value == -inf then
return format("|cff%s%s|r", color, value)
elseif value ~= value then
return format("|cff%s0|r|cff%s %s|r", COLOR_WHITE, COLOR_COPPER, COPPER)
elseif value >= 10000 or value <= -10000 then
return format("|cff%s%s%d|r|cff%s %s|r |cff%s%d|r|cff%s %s|r |cff%s%d|r|cff%s %s|r", color, negl, gold, COLOR_GOLD, GOLD, color, silver, COLOR_SILVER, SILVER, color, copper, COLOR_COPPER, COPPER)
elseif value >= 100 or value <= -100 then
return format("|cff%s%s%d|r|cff%s %s|r |cff%s%d|r|cff%s %s|r", color, negl, silver, COLOR_SILVER, SILVER, color, copper, COLOR_COPPER, COPPER)
else
return format("|cff%s%s%d|r|cff%s %s|r", color, negl, copper, COLOR_COPPER, COPPER)
end
else
if value == inf or value == -inf then
return format("%s", value)
elseif value ~= value then
return format("0 %s", COPPER)
elseif value >= 10000 or value <= -10000 then
return format("%s%d %s %d %s %d %s", negl, gold, GOLD, silver, SILVER, copper, COPPER)
elseif value >= 100 or value <= -100 then
return format("%s%d %s %d %s", negl, silver, SILVER, copper, COPPER)
else
return format("%s%d %s", negl, copper, COPPER)
end
end
end
 
function Abacus:FormatMoneyFull(value, colorize, textColor)
local gold = abs(value / 10000)
local silver = abs(mod(value / 100, 100))
local copper = abs(mod(value, 100))
 
local negl = ""
local color = COLOR_WHITE
if value > 0 then
if textColor then
color = COLOR_GREEN
end
elseif value < 0 then
negl = "-"
if textColor then
color = COLOR_RED
end
end
if colorize then
if value == inf or value == -inf then
return format("|cff%s%s|r", color, value)
elseif value ~= value then
return format("|cff%s0|r|cff%s%s|r", COLOR_WHITE, COLOR_COPPER, COPPER_ABBR)
elseif value >= 10000 or value <= -10000 then
return format("|cff%s%s%d|r|cff%s%s|r |cff%s%d|r|cff%s%s|r |cff%s%d|r|cff%s%s|r", color, negl, gold, COLOR_GOLD, GOLD_ABBR, color, silver, COLOR_SILVER, SILVER_ABBR, color, copper, COLOR_COPPER, COPPER_ABBR)
elseif value >= 100 or value <= -100 then
return format("|cff%s%s%d|r|cff%s%s|r |cff%s%d|r|cff%s%s|r", color, negl, silver, COLOR_SILVER, SILVER_ABBR, color, copper, COLOR_COPPER, COPPER_ABBR)
else
return format("|cff%s%s%d|r|cff%s%s|r", color, negl, copper, COLOR_COPPER, COPPER_ABBR)
end
else
if value == inf or value == -inf then
return format("%s", value)
elseif value ~= value then
return format("0%s", COPPER_ABBR)
elseif value >= 10000 or value <= -10000 then
return format("%s%d%s %d%s %d%s", negl, gold, GOLD_ABBR, silver, SILVER_ABBR, copper, COPPER_ABBR)
elseif value >= 100 or value <= -100 then
return format("%s%d%s %d%s", negl, silver, SILVER_ABBR, copper, COPPER_ABBR)
else
return format("%s%d%s", negl, copper, COPPER_ABBR)
end
end
end
 
function Abacus:FormatMoneyShort(copper, colorize, textColor)
local color = COLOR_WHITE
if textColor then
if copper > 0 then
color = COLOR_GREEN
elseif copper < 0 then
color = COLOR_RED
end
end
if colorize then
if copper == inf or copper == -inf then
return format("|cff%s%s|r", color, copper)
elseif copper ~= copper then
return format("|cff%s0|r|cff%s%s|r", COLOR_WHITE, COLOR_COPPER, COPPER_ABBR)
elseif copper >= 10000 or copper <= -10000 then
return format("|cff%s%.1f|r|cff%s%s|r", color, copper / 10000, COLOR_GOLD, GOLD_ABBR)
elseif copper >= 100 or copper <= -100 then
return format("|cff%s%.1f|r|cff%s%s|r", color, copper / 100, COLOR_SILVER, SILVER_ABBR)
else
return format("|cff%s%d|r|cff%s%s|r", color, copper, COLOR_COPPER, COPPER_ABBR)
end
else
if value == copper or value == -copper then
return format("%s", copper)
elseif copper ~= copper then
return format("0%s", COPPER_ABBR)
elseif copper >= 10000 or copper <= -10000 then
return format("%.1f%s", copper / 10000, GOLD_ABBR)
elseif copper >= 100 or copper <= -100 then
return format("%.1f%s", copper / 100, SILVER_ABBR)
else
return format("%.0f%s", copper, COPPER_ABBR)
end
end
end
 
function Abacus:FormatMoneyCondensed(value, colorize, textColor)
local negl = ""
local negr = ""
if value < 0 then
if colorize and textColor then
negl = "|cffff0000-(|r"
negr = "|cffff0000)|r"
else
negl = "-("
negr = ")"
end
end
local gold = floor(math.abs(value) / 10000)
local silver = mod(floor(math.abs(value) / 100), 100)
local copper = mod(floor(math.abs(value)), 100)
if colorize then
if value == inf or value == -inf then
return format("%s|cff%s%s|r%s", negl, COLOR_COPPER, math.abs(value), negr)
elseif value ~= value then
return format("|cff%s0|r", COLOR_COPPER)
elseif gold ~= 0 then
return format("%s|cff%s%d|r.|cff%s%02d|r.|cff%s%02d|r%s", negl, COLOR_GOLD, gold, COLOR_SILVER, silver, COLOR_COPPER, copper, negr)
elseif silver ~= 0 then
return format("%s|cff%s%d|r.|cff%s%02d|r%s", negl, COLOR_SILVER, silver, COLOR_COPPER, copper, negr)
else
return format("%s|cff%s%d|r%s", negl, COLOR_COPPER, copper, negr)
end
else
if value == inf or value == -inf then
return tostring(value)
elseif value ~= value then
return "0"
elseif gold ~= 0 then
return format("%s%d.%02d.%02d%s", negl, gold, silver, copper, negr)
elseif silver ~= 0 then
return format("%s%d.%02d%s", negl, silver, copper, negr)
else
return format("%s%d%s", negl, copper, negr)
end
end
end
 
local t = {}
function Abacus:FormatDurationExtended(duration, colorize, hideSeconds)
local negative = ""
if duration ~= duration then
duration = 0
end
if duration < 0 then
negative = "-"
duration = -duration
end
local days = floor(duration / 86400)
local hours = mod(floor(duration / 3600), 24)
local mins = mod(floor(duration / 60), 60)
local secs = mod(floor(duration), 60)
for k in pairs(t) do
t[k] = nil
end
if not colorize then
if not duration or duration > 86400*36500 then -- 100 years
return L_UNDETERMINED
end
if days > 1 then
table.insert(t, format("%d %s", days, DAYS_ABBR_P1))
elseif days == 1 then
table.insert(t, format("%d %s", days, DAYS_ABBR_S1))
end
if hours > 1 then
table.insert(t, format("%d %s", hours, HOURS_ABBR_P1))
elseif hours == 1 then
table.insert(t, format("%d %s", hours, HOURS_ABBR_S1))
end
if mins > 1 then
table.insert(t, format("%d %s", mins, MINUTES_ABBR_P1))
elseif mins == 1 then
table.insert(t, format("%d %s", mins, MINUTES_ABBR_S1))
end
if not hideSeconds then
if secs > 1 then
table.insert(t, format("%d %s", secs, SECONDS_ABBR_P1))
elseif secs == 1 then
table.insert(t, format("%d %s", secs, SECONDS_ABBR_S1))
end
end
if table.getn(t) == 0 then
if not hideSeconds then
return "0 " .. SECONDS_ABBR_P1
else
return "0 " .. MINUTES_ABBR_P1
end
else
return negative .. table.concat(t, " ")
end
else
if not duration or duration > 86400*36500 then -- 100 years
return "|cffffffff"..L_UNDETERMINED.."|r"
end
if days > 1 then
table.insert(t, format("|cffffffff%d|r %s", days, DAYS_ABBR_P1))
elseif days == 1 then
table.insert(t, format("|cffffffff%d|r %s", days, DAYS_ABBR_S1))
end
if hours > 1 then
table.insert(t, format("|cffffffff%d|r %s", hours, HOURS_ABBR_P1))
elseif hours == 1 then
table.insert(t, format("|cffffffff%d|r %s", hours, HOURS_ABBR_S1))
end
if mins > 1 then
table.insert(t, format("|cffffffff%d|r %s", mins, MINUTES_ABBR_P1))
elseif mins == 1 then
table.insert(t, format("|cffffffff%d|r %s", mins, MINUTES_ABBR_S1))
end
if not hideSeconds then
if secs > 1 then
table.insert(t, format("|cffffffff%d|r %s", secs, SECONDS_ABBR_P1))
elseif secs == 1 then
table.insert(t, format("|cffffffff%d|r %s", secs, SECONDS_ABBR))
end
end
if table.getn(t) == 0 then
if not hideSeconds then
return "|cffffffff0|r " .. SECONDS_ABBR_P1
else
return "|cffffffff0|r " .. MINUTES_ABBR_P1
end
elseif negative == "-" then
return "|cffffffff-|r" .. table.concat(t, " ")
else
return table.concat(t, " ")
end
end
end
 
function Abacus:FormatDurationFull(duration, colorize, hideSeconds)
local negative = ""
if duration ~= duration then
duration = 0
end
if duration < 0 then
negative = "-"
duration = -duration
end
if not colorize then
if not hideSeconds then
if not duration or duration > 86400*36500 then -- 100 years
return L_UNDETERMINED
elseif duration >= 86400 then
return format("%s%d%s %02d%s %02d%s %02d%s", negative, duration/86400, L_DAY_ONELETTER_ABBR, mod(duration/3600, 24), L_HOUR_ONELETTER_ABBR, mod(duration/60, 60), L_MINUTE_ONELETTER_ABBR, mod(duration, 60), L_SECOND_ONELETTER_ABBR)
elseif duration >= 3600 then
return format("%s%d%s %02d%s %02d%s", negative, duration/3600, L_HOUR_ONELETTER_ABBR, mod(duration/60, 60), L_MINUTE_ONELETTER_ABBR, mod(duration, 60), L_SECOND_ONELETTER_ABBR)
elseif duration >= 120 then
return format("%s%d%s %02d%s", negative, duration/60, L_MINUTE_ONELETTER_ABBR, mod(duration, 60), L_SECOND_ONELETTER_ABBR)
else
return format("%s%d%s", negative, duration, L_SECOND_ONELETTER_ABBR)
end
else
if not duration or duration > 86400*36500 then -- 100 years
return L_UNDETERMINED
elseif duration >= 86400 then
return format("%s%d%s %02d%s %02d%s", negative, duration/86400, L_DAY_ONELETTER_ABBR, mod(duration/3600, 24), L_HOUR_ONELETTER_ABBR, mod(duration/60, 60), L_MINUTE_ONELETTER_ABBR)
elseif duration >= 3600 then
return format("%s%d%s %02d%s", negative, duration/3600, L_HOUR_ONELETTER_ABBR, mod(duration/60, 60), L_MINUTE_ONELETTER_ABBR)
else
return format("%s%d%s", negative, duration/60, L_MINUTE_ONELETTER_ABBR)
end
end
else
if not hideSeconds then
if not duration or duration > 86400*36500 then -- 100 years
return "|cffffffff"..L_UNDETERMINED.."|r"
elseif duration >= 86400 then
return format("|cffffffff%s%d|r%s |cffffffff%02d|r%s |cffffffff%02d|r%s |cffffffff%02d|r%s", negative, duration/86400, L_DAY_ONELETTER_ABBR, mod(duration/3600, 24), L_HOUR_ONELETTER_ABBR, mod(duration/60, 60), L_MINUTE_ONELETTER_ABBR, mod(duration, 60), L_SECOND_ONELETTER_ABBR)
elseif duration >= 3600 then
return format("|cffffffff%s%d|r%s |cffffffff%02d|r%s |cffffffff%02d|r%s", negative, duration/3600, L_HOUR_ONELETTER_ABBR, mod(duration/60, 60), L_MINUTE_ONELETTER_ABBR, mod(duration, 60), L_SECOND_ONELETTER_ABBR)
elseif duration >= 120 then
return format("|cffffffff%s%d|r%s |cffffffff%02d|r%s", negative, duration/60, L_MINUTE_ONELETTER_ABBR, mod(duration, 60), L_SECOND_ONELETTER_ABBR)
else
return format("|cffffffff%s%d|r%s", negative, duration, L_SECOND_ONELETTER_ABBR)
end
else
if not duration or duration > 86400*36500 then -- 100 years
return "|cffffffff"..L_UNDETERMINED.."|r"
elseif duration >= 86400 then
return format("|cffffffff%s%d|r%s |cffffffff%02d|r%s |cffffffff%02d|r%s", negative, duration/86400, L_DAY_ONELETTER_ABBR, mod(duration/3600, 24), L_HOUR_ONELETTER_ABBR, mod(duration/60, 60), L_MINUTE_ONELETTER_ABBR)
elseif duration >= 3600 then
return format("|cffffffff%s%d|r%s |cffffffff%02d|r%s", negative, duration/3600, L_HOUR_ONELETTER_ABBR, mod(duration/60, 60), L_MINUTE_ONELETTER_ABBR)
else
return format("|cffffffff%s%d|r%s", negative, duration/60, L_MINUTE_ONELETTER_ABBR)
end
end
end
end
 
function Abacus:FormatDurationShort(duration, colorize, hideSeconds)
local negative = ""
if duration ~= duration then
duration = 0
end
if duration < 0 then
negative = "-"
duration = -duration
end
if not colorize then
if not duration or duration >= 86400*36500 then -- 100 years
return "***"
elseif duration >= 172800 then
return format("%s%.1f %s", negative, duration/86400, DAYS_ABBR_P1)
elseif duration >= 7200 then
return format("%s%.1f %s", negative, duration/3600, HOURS_ABBR_P1)
elseif duration >= 120 or not hideSeconds then
return format("%s%.1f %s", negative, duration/60, MINUTES_ABBR_P1)
else
return format("%s%.0f %s", negative, duration, SECONDS_ABBR_P1)
end
else
if not duration or duration >= 86400*36500 then -- 100 years
return "|cffffffff***|r"
elseif duration >= 172800 then
return format("|cffffffff%s%.1f|r %s", negative, duration/86400, DAYS_ABBR_P1)
elseif duration >= 7200 then
return format("|cffffffff%s%.1f|r %s", negative, duration/3600, HOURS_ABBR_P1)
elseif duration >= 120 or not hideSeconds then
return format("|cffffffff%s%.1f|r %s", negative, duration/60, MINUTES_ABBR_P1)
else
return format("|cffffffff%s%.0f|r %s", negative, duration, SECONDS_ABBR_P1)
end
end
end
 
function Abacus:FormatDurationCondensed(duration, colorize, hideSeconds)
local negative = ""
if duration ~= duration then
duration = 0
end
if duration < 0 then
negative = "-"
duration = -duration
end
if not colorize then
if hideSeconds then
if not duration or duration >= 86400*36500 then -- 100 years
return format("%s**%s **:**", negative, L_DAY_ONELETTER_ABBR)
elseif duration >= 86400 then
return format("%s%d%s %d:%02d", negative, duration/86400, L_DAY_ONELETTER_ABBR, mod(duration/3600, 24), mod(duration/60, 60))
else
return format("%s%d:%02d", negative, duration/3600, mod(duration/60, 60))
end
else
if not duration or duration >= 86400*36500 then -- 100 years
return negative .. "**:**:**:**"
elseif duration >= 86400 then
return format("%s%d%s %d:%02d:%02d", negative, duration/86400, L_DAY_ONELETTER_ABBR, mod(duration/3600, 24), mod(duration/60, 60), mod(duration, 60))
elseif duration >= 3600 then
return format("%s%d:%02d:%02d", negative, duration/3600, mod(duration/60, 60), mod(duration, 60))
else
return format("%s%d:%02d", negative, duration/60, mod(duration, 60))
end
end
else
if hideSeconds then
if not duration or duration >= 86400*36500 then -- 100 years
return format("|cffffffff%s**|r%s |cffffffff**|r:|cffffffff**|r", negative, L_DAY_ONELETTER_ABBR)
elseif duration >= 86400 then
return format("|cffffffff%s%d|r%s |cffffffff%d|r:|cffffffff%02d|r", negative, duration/86400, L_DAY_ONELETTER_ABBR, mod(duration/3600, 24), mod(duration/60, 60))
else
return format("|cffffffff%s%d|r:|cffffffff%02d|r", negative, duration/3600, mod(duration/60, 60))
end
else
if not duration or duration >= 86400*36500 then -- 100 years
return format("|cffffffff%s**|r%s |cffffffff**|r:|cffffffff**|r:|cffffffff**|r", negative, L_DAY_ONELETTER_ABBR)
elseif duration >= 86400 then
return format("|cffffffff%s%d|r%s |cffffffff%d|r:|cffffffff%02d|r:|cffffffff%02d|r", negative, duration/86400, L_DAY_ONELETTER_ABBR, mod(duration/3600, 24), mod(duration/60, 60), mod(duration, 60))
elseif duration >= 3600 then
return format("|cffffffff%s%d|r:|cffffffff%02d|r:|cffffffff%02d|r", negative, duration/3600, mod(duration/60, 60), mod(duration, 60))
else
return format("|cffffffff%s%d|r:|cffffffff%02d|r", negative, duration/60, mod(duration, 60))
end
end
end
end
 
local function compat()
local Abacus20 = setmetatable({}, {__index = function(self, key)
if type(Abacus[key]) == "function" then
self[key] = function(self, ...)
return Abacus[key](Abacus, ...)
end
else
self[key] = Abacus[key]
end
return self[key]
end})
AceLibrary:Register(Abacus20, "Abacus-2.0", MINOR_VERSION*1000)
end
if AceLibrary then
compat()
elseif Rock then
function Abacus:OnLibraryLoad(major, instance)
if major == "AceLibrary" then
compat()
end
end
end
EasyDaily/libs/LibAbacus-3.0/LibStub/LibStub.lua New file
0,0 → 1,30
-- LibStub is a simple versioning stub meant for use in Libraries. http://www.wowace.com/wiki/LibStub for more info
-- LibStub is hereby placed in the Public Domain Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke
local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2 -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS!
local LibStub = _G[LIBSTUB_MAJOR]
 
if not LibStub or LibStub.minor < LIBSTUB_MINOR then
LibStub = LibStub or {libs = {}, minors = {} }
_G[LIBSTUB_MAJOR] = LibStub
LibStub.minor = LIBSTUB_MINOR
 
function LibStub:NewLibrary(major, minor)
assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)")
minor = assert(tonumber(strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.")
 
local oldminor = self.minors[major]
if oldminor and oldminor >= minor then return nil end
self.minors[major], self.libs[major] = minor, self.libs[major] or {}
return self.libs[major], oldminor
end
 
function LibStub:GetLibrary(major, silent)
if not self.libs[major] and not silent then
error(("Cannot find a library instance of %q."):format(tostring(major)), 2)
end
return self.libs[major], self.minors[major]
end
 
function LibStub:IterateLibraries() return pairs(self.libs) end
setmetatable(LibStub, { __call = LibStub.GetLibrary })
end
EasyDaily/options.lua New file
0,0 → 1,524
--[[
Desc:
Info: $Id: options.lua 17 2009-05-02 03:59:49Z draake $
]]
 
local _G = _G
local pairs, ipairs, type, select, tonumber, tostring = pairs, ipairs, type, select, tonumber, tostring
 
local tinsert, tremove, tsort = table.insert, table.remove, table.sort
local sformat = string.format
 
local L = LibStub("AceLocale-3.0"):GetLocale("EasyDaily_Base")
 
local LDBIcon = LibStub("LibDBIcon-1.0")
 
--------------------------------------------------------------------------------------------------
-- Content
--------------------------------------------------------------------------------------------------
 
do
local side = UnitFactionGroup("player")
local sideBit = ( side == "Alliance" and 1 ) or 2
function EasyDaily:GetPlayerSideBit()
return sideBit
end
end
 
-- available, complete, repeatable, normal
function EasyDaily:SetQuestOptionsTable(available, complete, repeatable)
for i, h in pairs(self.handlers) do
local name, index, questType, questTag, objective, side, enable, header = EasyDaily:GetQuestHandlerInfo(h)
if name then
local t
if ( questType == "daily" ) then
if self:QuestCompleteToday(name) then
t = complete
else
t = available
end
elseif ( questType == "repeat" ) then
t = repeatable
end
if t then
 
local cat1, cat2
if self.LibTourist:IsZone(header) then
local text = self.LibTourist:GetContinent(header)
if text == UNKNOWN then
cat1 = L["Special"]
cat2 = header
else
cat1 = text
cat2 = header
end
elseif self.LibTourist:IsBattleground(header) then
cat1 = L["Battleground"]
cat2 = header
elseif self.LibTourist:IsInstance(zone) then
if questTag == "heroic" then
cat1 = L["Heroic Dungeon"]
cat2 = header
else
cat1 = L["Normal Dungeon"]
cat2 = header
end
end
 
local idkey = sformat("id-%s", i)
local x = {
type = "toggle",
width = "double",
name = name,
desc = L["Toggle this quest's state."],
get = function(info) return enable end,
set = function(info, value) h:SetVal("enable", not enable); self:RefreshGossipOrQuestFrame(); end,
}
 
local cat1key = sformat("c1-%s", cat1)
if ( not t[cat1key] )then
t[cat1key] = {
type = "group",
name = cat1,
args = {}
}
end
 
local cat2key
if cat2 then
cat2key = sformat("c2-%s", cat2)
if ( not t[cat1key].args[cat2key] )then
t[cat1key].args[cat2key] = {
type = "group",
name = cat2,
args = {}
}
end
--~ t[cat1key].childGroups = "tab"
t[cat1key].args[cat2key].args[idkey] = x
else
t[cat1key].args[idkey] = x
end
 
end
end
end
end
 
--------------------------------------------------------------------------------------------------
-- Option Registration and Table Creation
--------------------------------------------------------------------------------------------------
 
local getFunc = function(info)
return info.arg and EasyDaily.db.profile[info.arg] or EasyDaily.db.profile[info[#info]]
end
local setFunc = function(info, value)
local key = info.arg or info[#info]
EasyDaily.db.profile[key] = value
end
 
local isDisabled = function()
return ( not EasyDaily:IsEnabled() )
end
 
local GetOptMods = function(...)
local optMods = { ["ctrl"] = L["Ctrl"], ["alt"] = L["Alt"], ["shift"] = L["Shift"], ["none"] = L["None"], ["disable"] = L["Disable"] }
for i = 1, select("#", ...), 1 do
local v = EasyDaily:GetPVar( EasyDaily:SelectOne(i, ...) )
if v and v ~= "disable" then
optMods[v] = nil
end
end
return optMods
end
 
local getOptions = function()
local self = EasyDaily
if ( not self.options ) then -- static options; run once; etc...
self.options = {
type = "group",
name = sformat("EasyDaily (%s)", self.version.text),
icon = "Interface\\Icons\\INV_Misc_TabardSummer01",
childGroups = "tree",
plugins = {},
args = {
enabled = {
order = 1,
type = "toggle",
name = L["Enabled"],
desc = L["Enable/Disable the addon."],
get = function() return self:IsEnabled() end,
set = function(info, value) self[value and "Enable" or "Disable"](self) end,
width = "half",
},
debug = {
order = 2,
type = "toggle",
name = L["Debug"],
desc = L["Enable/Disable debug mode."],
get = getFunc,
set = setFunc,
disabled = isDisabled,
},
minimapIcon = {
order = 3,
type = "toggle",
name = L["Minimap Icon"],
desc = L["Show an icon on the Minimap."],
get = function() return not self.db.profile.minimapIcon.hide end,
set = function(info, value) self.db.profile.minimapIcon.hide = not value; LDBIcon[value and "Show" or "Hide"](self, "self") end,
disabled = function() return not LDBIcon end,
},
general = {
order = 10,
type = "group",
name = L["General"],
disabled = isDisabled,
args = {
gossipdisplay = {
order = 1,
type = "group",
guiInline = true,
name = L["Gossip Window"],
args = {
stickyturnin = {
order = 1,
type = "toggle",
name = L["Sticky Turn-in"],
desc = L["Turn-in sequences will run to completion once they've been started regardless of its modifier's status."],
get = getFunc,
set = setFunc,
},
gossipicons = {
order = 2,
type = "toggle",
name = L["Replace Gossip Icons"],
desc = L["Replaces the default gossip icons with color coded versions."],
get = getFunc,
set = function(...) setFunc(...); self:RefreshGossipOrQuestFrame(); end,
},
gossipstate = {
order = 3,
type = "toggle",
name = L["Auto Turn-in Text"],
desc = L["Displays a quests auto turn-in status in text."],
get = getFunc,
set = function(...) setFunc(...); self:RefreshGossipOrQuestFrame(); end,
},
},
},
rewards = {
order = 2,
type = "group",
guiInline = true,
name = L["Quest Rewards"],
args = {
single = {
order = 1,
type = "toggle",
name = L["Single Reward"],
desc = L["Auto-Select rewards for quests with one or less reward."],
get = getFunc,
set = setFunc,
},
multiple = {
order = 2,
type = "toggle",
name = L["Multiple Rewards"],
desc = L["Auto-Select rewards for quests with more than one reward."],
get = getFunc,
set = setFunc,
},
},
},
popups = {
order = 3,
type = "group",
guiInline = true,
name = L["Quest Pop-ups"],
args = {
skipflag = {
order = 1,
type = "toggle",
name = L["Disable PvP Pop-up"],
desc = L["Disables the confirmation pop-up that appears when accepting a daily quest that flags you for pvp."],
get = getFunc,
set = setFunc,
},
skipmoney = {
order = 2,
type = "toggle",
name = L["Disable Gold Pop-up"],
desc = L["Disables the confirmation pop-up that appears when completing a daily quest that requires gold."],
get = getFunc,
set = setFunc,
},
},
},
activetags = {
order = 5,
type = "group",
guiInline = true,
name = L["Quest Tags"],
args = {
tag_normal = {
order = 1,
type = "toggle",
name = L["Normal"],
desc = sformat(L["Enables Auto Turn-in for %s tagged quests."], L["Normal"]),
get = getFunc,
set = setFunc,
},
tag_elite = {
order = 2,
type = "toggle",
name = ELITE,
desc = sformat(L["Enables Auto Turn-in for %s tagged quests."], ELITE),
get = getFunc,
set = setFunc,
},
tag_group = {
order = 3,
type = "toggle",
name = GROUP,
desc = sformat(L["Enables Auto Turn-in for %s tagged quests."], GROUP),
get = getFunc,
set = setFunc,
},
tag_dungeon = {
order = 4,
type = "toggle",
name = LFG_TYPE_DUNGEON,
desc = sformat(L["Enables Auto Turn-in for %s tagged quests."], LFG_TYPE_DUNGEON),
get = getFunc,
set = setFunc,
},
tag_heroic = {
order = 5,
type = "toggle",
name = LFG_TYPE_HEROIC_DUNGEON,
desc = sformat(L["Enables Auto Turn-in for %s tagged quests."], LFG_TYPE_HEROIC_DUNGEON),
get = getFunc,
set = setFunc,
},
tag_raid = {
order = 6,
type = "toggle",
name = RAID,
desc = sformat(L["Enables Auto Turn-in for %s tagged quests."], RAID),
get = getFunc,
set = setFunc,
},
tag_pvp = {
order = 7,
type = "toggle",
name = PVP,
desc = sformat(L["Enables Auto Turn-in for %s tagged quests."], PVP),
get = getFunc,
set = setFunc,
},
},
},
modifiers = {
order = 10,
type = "group",
guiInline = true,
name = L["Selection Modifiers"],
args = {
modifierstext = {
order = 1,
type = "description",
name = L["Note: The modifier 'None' refers to when no modifier is being held. Setting the modifier to 'Disable' disables the option."],
},
mod_normal = {
order = 2,
type = "select",
style = "dropdown",
name = L["Normal"],
desc = sformat(L["Use this modifier to Auto Turn-in %s quests."], L["Normal"]),
values = function()
return GetOptMods("override", "suspend")
end,
get = getFunc,
set = setFunc,
},
mod_daily = {
order = 3,
type = "select",
style = "dropdown",
name = L["Daily"],
desc = sformat(L["Use this modifier to Auto Turn-in %s quests."], L["Daily"]),
values = function()
return GetOptMods("override", "suspend")
end,
get = getFunc,
set = setFunc,
},
mod_repeat = {
order = 4,
type = "select",
style = "dropdown",
name = L["Repeatable"],
desc = sformat(L["Use this modifier to Auto Turn-in %s quests."], L["Repeatable"]),
values = function()
return GetOptMods("override", "suspend")
end,
get = getFunc,
set = setFunc,
},
mod_override = {
order = 5,
type = "select",
style = "dropdown",
name = L["Force"],
desc = L["Use this modifier to forcibly Auto Turn-in any quest. Overrides all settings."],
values = function()
return GetOptMods("normal", "daily", "repeat", "suspend")
end,
get = getFunc,
set = setFunc,
},
mod_suspend = {
order = 6,
type = "select",
style = "dropdown",
name = L["Suspend"],
desc = L["Use this modifier to suspend the Auto Turn-in process."],
values = function()
return GetOptMods("normal", "daily", "repeat", "override")
end,
get = getFunc,
set = setFunc,
},
},
},
},
},
quests = {
order = 20,
type = "group",
name = L["Quests"],
args = {
daily = {
order = 1,
type = "group",
name = L["Daily"],
args = {
available = {
order = 1,
type = "group",
childGroups = "tab",
name = L["Available"],
args = {},
},
complete = {
order = 1,
type = "group",
childGroups = "tab",
name = L["Complete"],
args = {},
},
},
},
repeatable = {
order = 2,
type = "group",
childGroups = "tab",
name = L["Repeatable"],
args = {},
},
--~ normal = {
--~ order = 3,
--~ type = "group",
--~ childGroups = "tab",
--~ name = L["Normal"],
--~ args = {},
--~ },
},
},
},
}
self.options.plugins.profiles = { profiles = LibStub("AceDBOptions-3.0"):GetOptionsTable(self.db) }
end
 
local available = self:CleanTable(self.options.args.quests.args.daily.args.available.args)
local complete = self:CleanTable(self.options.args.quests.args.daily.args.complete.args)
local repeatable = self:CleanTable(self.options.args.quests.args.repeatable.args)
--~ local normal = self:CleanTable(self.options.args.quests.args.normal.args)
 
self:SetQuestOptionsTable(available, complete, repeatable)
 
return self.options
end
 
function EasyDaily:SetupOptions()
 
local AceConfigDialog = LibStub("AceConfigDialog-3.0")
local AceConfig = LibStub("AceConfig-3.0")
 
-- Register Options
AceConfig:RegisterOptionsTable("EasyDaily", getOptions, "edtest")
AceConfigDialog:SetDefaultSize("EasyDaily", 790, 540)
AceConfigDialog:AddToBlizOptions("EasyDaily", "EasyDaily")
 
-- Slash Commands
local AceConsole = LibStub("AceConsole-3.0")
local optFunc = function()
AceConfigDialog:Open("EasyDaily")
end
 
local slashCom = {
"ed",
"easydaily",
"daily",
}
 
for _, slash in pairs(slashCom) do
AceConsole:RegisterChatCommand(slash, optFunc)
end
 
-- Create LDB Launcher
local LDBObj = LibStub("LibDataBroker-1.1"):NewDataObject("EasyDaily", {
type = "launcher",
label = "EasyDaily",
OnClick = function(button, click)
--~ if click == "RightButton" then
if AceConfigDialog.OpenFrames["EasyDaily"] then
AceConfigDialog:Close("EasyDaily")
else
AceConfigDialog:Open("EasyDaily")
end
--~ else
--~ AceConfigDialog:Close("EasyDaily")
--~ end
end,
icon = "Interface\\Icons\\INV_Misc_TabardSummer01",
OnTooltipShow = function(tooltip)
 
if not tooltip or not tooltip.AddLine then return end
 
tooltip:AddLine("EasyDaily")
tooltip:AddLine( self:ColorizePattern(L["[Left-Click] to toggle the quest window"], "%[(.-)%]", 1, 1, 0) )
tooltip:AddLine( self:ColorizePattern(L["[Right-Click] to toggle the options menu"], "%[(.-)%]", 1, 1, 0) )
 
tooltip:AddLine(" ")
--~ tooltip:AddLine( self:Colorize(L["Quick Info"], 1, 1, 1) )
--~ tooltip:AddLine(" ")
 
local cur, max = self:GetDailyStats()
tooltip:AddLine( self:ColorizePattern( sformat(L["Completed [%s] of [%s] dailies"], cur, max), "%[(.-)%]", 1, 1, 0 ) )
 
local reset = GetQuestResetTime()
if reset and reset > 0 then
local text = self:ColorizePattern( self.LibAbacus:FormatDurationExtended(reset, false, true), "(%d+)", 1, 1, 0 )
tooltip:AddLine( self:ColorizePattern( sformat(L["The [new day] begins in %s"], text), "%[(.-)%]", 1, 1, 0 ) )
end
 
end,
})
if LDBIcon then
LDBIcon:Register("EasyDaily", LDBObj, self.db.profile.minimapIcon)
end
 
end