/
--[[----------------------------------------------------------------------------- |
Frame Container |
-------------------------------------------------------------------------------]] |
local Type, Version = "Frame", 21 |
local AceGUI = LibStub and LibStub("AceGUI-3.0", true) |
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end |
-- Lua APIs |
local pairs, assert, type = pairs, assert, type |
local wipe = table.wipe |
-- WoW APIs |
local PlaySound = PlaySound |
local CreateFrame, UIParent = CreateFrame, UIParent |
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded |
-- List them here for Mikk's FindGlobals script |
-- GLOBALS: CLOSE |
--[[----------------------------------------------------------------------------- |
Scripts |
-------------------------------------------------------------------------------]] |
local function Button_OnClick(frame) |
PlaySound("gsTitleOptionExit") |
frame.obj:Hide() |
end |
local function Frame_OnClose(frame) |
frame.obj:Fire("OnClose") |
end |
local function Frame_OnMouseDown(frame) |
AceGUI:ClearFocus() |
end |
local function Title_OnMouseDown(frame) |
frame:GetParent():StartMoving() |
AceGUI:ClearFocus() |
end |
local function MoverSizer_OnMouseUp(mover) |
local frame = mover: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 SizerSE_OnMouseDown(frame) |
frame:GetParent():StartSizing("BOTTOMRIGHT") |
AceGUI:ClearFocus() |
end |
local function SizerS_OnMouseDown(frame) |
frame:GetParent():StartSizing("BOTTOM") |
AceGUI:ClearFocus() |
end |
local function SizerE_OnMouseDown(frame) |
frame:GetParent():StartSizing("RIGHT") |
AceGUI:ClearFocus() |
end |
local function StatusBar_OnEnter(frame) |
frame.obj:Fire("OnEnterStatusBar") |
end |
local function StatusBar_OnLeave(frame) |
frame.obj:Fire("OnLeaveStatusBar") |
end |
--[[----------------------------------------------------------------------------- |
Methods |
-------------------------------------------------------------------------------]] |
local methods = { |
["OnAcquire"] = function(self) |
self.frame:SetParent(UIParent) |
self.frame:SetFrameStrata("FULLSCREEN_DIALOG") |
self:SetTitle() |
self:SetStatusText() |
self:ApplyStatus() |
self:Show() |
end, |
["OnRelease"] = function(self) |
self.status = nil |
wipe(self.localstatus) |
end, |
["OnWidthSet"] = function(self, width) |
local content = self.content |
local contentwidth = width - 34 |
if contentwidth < 0 then |
contentwidth = 0 |
end |
content:SetWidth(contentwidth) |
content.width = contentwidth |
end, |
["OnHeightSet"] = function(self, height) |
local content = self.content |
local contentheight = height - 57 |
if contentheight < 0 then |
contentheight = 0 |
end |
content:SetHeight(contentheight) |
content.height = contentheight |
end, |
["SetTitle"] = function(self, title) |
self.titletext:SetText(title) |
end, |
["SetStatusText"] = function(self, text) |
self.statustext:SetText(text) |
end, |
["Hide"] = function(self) |
self.frame:Hide() |
end, |
["Show"] = function(self) |
self.frame:Show() |
end, |
-- called to set an external table to store status in |
["SetStatusTable"] = function(self, status) |
assert(type(status) == "table") |
self.status = status |
self:ApplyStatus() |
end, |
["ApplyStatus"] = function(self) |
local status = self.status or self.localstatus |
local frame = self.frame |
self:SetWidth(status.width or 700) |
self:SetHeight(status.height or 500) |
frame:ClearAllPoints() |
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") |
end |
end |
} |
--[[----------------------------------------------------------------------------- |
Constructor |
-------------------------------------------------------------------------------]] |
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 Constructor() |
local frame = CreateFrame("Frame", nil, UIParent) |
frame:Hide() |
frame:EnableMouse(true) |
frame:SetMovable(true) |
frame:SetResizable(true) |
frame:SetFrameStrata("FULLSCREEN_DIALOG") |
frame:SetBackdrop(FrameBackdrop) |
frame:SetBackdropColor(0, 0, 0, 1) |
frame:SetMinResize(400, 200) |
frame:SetToplevel(true) |
frame:SetScript("OnHide", Frame_OnClose) |
frame:SetScript("OnMouseDown", Frame_OnMouseDown) |
local closebutton = CreateFrame("Button", nil, frame, "UIPanelButtonTemplate") |
closebutton:SetScript("OnClick", Button_OnClick) |
closebutton:SetPoint("BOTTOMRIGHT", -27, 17) |
closebutton:SetHeight(20) |
closebutton:SetWidth(100) |
closebutton:SetText(CLOSE) |
local statusbg = CreateFrame("Button", nil, frame) |
statusbg:SetPoint("BOTTOMLEFT", 15, 15) |
statusbg:SetPoint("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) |
statusbg:SetScript("OnEnter", StatusBar_OnEnter) |
statusbg:SetScript("OnLeave", StatusBar_OnLeave) |
local statustext = statusbg:CreateFontString(nil, "OVERLAY", "GameFontNormal") |
statustext:SetPoint("TOPLEFT", 7, -2) |
statustext:SetPoint("BOTTOMRIGHT", -7, 2) |
statustext:SetHeight(20) |
statustext:SetJustifyH("LEFT") |
statustext:SetText("") |
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", 0, 12) |
titlebg:SetWidth(100) |
titlebg:SetHeight(40) |
local title = CreateFrame("Frame", nil, frame) |
title:EnableMouse(true) |
title:SetScript("OnMouseDown", Title_OnMouseDown) |
title:SetScript("OnMouseUp", MoverSizer_OnMouseUp) |
title:SetAllPoints(titlebg) |
local titletext = title:CreateFontString(nil, "OVERLAY", "GameFontNormal") |
titletext:SetPoint("TOP", titlebg, "TOP", 0, -14) |
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") |
titlebg_l:SetWidth(30) |
titlebg_l:SetHeight(40) |
local titlebg_r = frame:CreateTexture(nil, "OVERLAY") |
titlebg_r:SetTexture("Interface\\DialogFrame\\UI-DialogBox-Header") |
titlebg_r:SetTexCoord(0.67, 0.77, 0, 0.63) |
titlebg_r:SetPoint("LEFT", titlebg, "RIGHT") |
titlebg_r:SetWidth(30) |
titlebg_r:SetHeight(40) |
local sizer_se = CreateFrame("Frame", nil, frame) |
sizer_se:SetPoint("BOTTOMRIGHT") |
sizer_se:SetWidth(25) |
sizer_se:SetHeight(25) |
sizer_se:EnableMouse() |
sizer_se:SetScript("OnMouseDown",SizerSE_OnMouseDown) |
sizer_se:SetScript("OnMouseUp", MoverSizer_OnMouseUp) |
local line1 = sizer_se:CreateTexture(nil, "BACKGROUND") |
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") |
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", -25, 0) |
sizer_s:SetPoint("BOTTOMLEFT") |
sizer_s:SetHeight(25) |
sizer_s:EnableMouse(true) |
sizer_s:SetScript("OnMouseDown", SizerS_OnMouseDown) |
sizer_s:SetScript("OnMouseUp", MoverSizer_OnMouseUp) |
local sizer_e = CreateFrame("Frame", nil, frame) |
sizer_e:SetPoint("BOTTOMRIGHT", 0, 25) |
sizer_e:SetPoint("TOPRIGHT") |
sizer_e:SetWidth(25) |
sizer_e:EnableMouse(true) |
sizer_e:SetScript("OnMouseDown", SizerE_OnMouseDown) |
sizer_e:SetScript("OnMouseUp", MoverSizer_OnMouseUp) |
--Container Support |
local content = CreateFrame("Frame", nil, frame) |
content:SetPoint("TOPLEFT", 17, -27) |
content:SetPoint("BOTTOMRIGHT", -17, 40) |
local widget = { |
localstatus = {}, |
titletext = titletext, |
statustext = statustext, |
content = content, |
frame = frame, |
type = Type |
} |
for method, func in pairs(methods) do |
widget[method] = func |
end |
closebutton.obj, statusbg.obj = widget, widget |
return AceGUI:RegisterAsContainer(widget) |
end |
AceGUI:RegisterWidgetType(Type, Constructor, Version) |
--[[----------------------------------------------------------------------------- |
InlineGroup Container |
Simple container widget that creates a visible "box" with an optional title. |
-------------------------------------------------------------------------------]] |
local Type, Version = "InlineGroup", 20 |
local AceGUI = LibStub and LibStub("AceGUI-3.0", true) |
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end |
-- Lua APIs |
local pairs = pairs |
-- WoW APIs |
local CreateFrame, UIParent = CreateFrame, UIParent |
--[[----------------------------------------------------------------------------- |
Methods |
-------------------------------------------------------------------------------]] |
local methods = { |
["OnAcquire"] = function(self) |
self:SetWidth(300) |
self:SetHeight(100) |
end, |
-- ["OnRelease"] = nil, |
["SetTitle"] = function(self,title) |
self.titletext:SetText(title) |
end, |
["LayoutFinished"] = function(self, width, height) |
if self.noAutoHeight then return end |
self:SetHeight((height or 0) + 40) |
end, |
["OnWidthSet"] = function(self, width) |
local content = self.content |
local contentwidth = width - 20 |
if contentwidth < 0 then |
contentwidth = 0 |
end |
content:SetWidth(contentwidth) |
content.width = contentwidth |
end, |
["OnHeightSet"] = function(self, height) |
local content = self.content |
local contentheight = height - 20 |
if contentheight < 0 then |
contentheight = 0 |
end |
content:SetHeight(contentheight) |
content.height = contentheight |
end |
} |
--[[----------------------------------------------------------------------------- |
Constructor |
-------------------------------------------------------------------------------]] |
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 Constructor() |
local frame = CreateFrame("Frame", nil, UIParent) |
frame:SetFrameStrata("FULLSCREEN_DIALOG") |
local titletext = frame:CreateFontString(nil, "OVERLAY", "GameFontNormal") |
titletext:SetPoint("TOPLEFT", 14, 0) |
titletext:SetPoint("TOPRIGHT", -14, 0) |
titletext:SetJustifyH("LEFT") |
titletext:SetHeight(18) |
local border = CreateFrame("Frame", nil, frame) |
border:SetPoint("TOPLEFT", 0, -17) |
border:SetPoint("BOTTOMRIGHT", -1, 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) |
content:SetPoint("TOPLEFT", 10, -10) |
content:SetPoint("BOTTOMRIGHT", -10, 10) |
local widget = { |
frame = frame, |
content = content, |
titletext = titletext, |
type = Type |
} |
for method, func in pairs(methods) do |
widget[method] = func |
end |
return AceGUI:RegisterAsContainer(widget) |
end |
AceGUI:RegisterWidgetType(Type, Constructor, Version) |
--[[ $Id: AceGUIWidget-DropDown.lua 916 2010-03-15 12:24:36Z nevcairiel $ ]]-- |
local AceGUI = LibStub("AceGUI-3.0") |
-- Lua APIs |
local min, max, floor = math.min, math.max, math.floor |
local select, pairs, ipairs = select, pairs, ipairs |
local tsort = table.sort |
-- WoW APIs |
local PlaySound = PlaySound |
local UIParent, CreateFrame = UIParent, CreateFrame |
local _G = _G |
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded |
-- List them here for Mikk's FindGlobals script |
-- GLOBALS: CLOSE |
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 = 3 |
--[[ Static data ]]-- |
local backdrop = { |
bgFile = "Interface\\ChatFrame\\ChatFrameBackground", |
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 = 22 |
--[[ 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 |
PlaySound("igMainMenuOptionCheckBoxOn") -- missleading name, but the Blizzard code uses this sound |
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.pullout = nil |
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 GetValue(self) |
return self.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 |
tsort(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.GetValue = GetValue |
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 |
--[[----------------------------------------------------------------------------- |
EditBox Widget |
-------------------------------------------------------------------------------]] |
local Type, Version = "EditBox", 21 |
local AceGUI = LibStub and LibStub("AceGUI-3.0", true) |
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end |
-- Lua APIs |
local tostring, pairs = tostring, pairs |
-- WoW APIs |
local PlaySound = PlaySound |
local GetCursorInfo, ClearCursor, GetSpellName = GetCursorInfo, ClearCursor, GetSpellName |
local CreateFrame, UIParent = CreateFrame, UIParent |
local _G = _G |
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded |
-- List them here for Mikk's FindGlobals script |
-- GLOBALS: AceGUIEditBoxInsertLink, ChatFontNormal, OKAY |
--[[----------------------------------------------------------------------------- |
Support functions |
-------------------------------------------------------------------------------]] |
if not AceGUIEditBoxInsertLink then |
-- upgradeable hook |
hooksecurefunc("ChatEdit_InsertLink", function(...) return _G.AceGUIEditBoxInsertLink(...) end) |
end |
function _G.AceGUIEditBoxInsertLink(text) |
for i = 1, AceGUI:GetWidgetCount(Type) do |
local editbox = _G["AceGUI-3.0EditBox"..i] |
if editbox and editbox:IsVisible() and editbox:HasFocus() then |
editbox:Insert(text) |
return true |
end |
end |
end |
local function ShowButton(self) |
if not self.disablebutton 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 |
--[[----------------------------------------------------------------------------- |
Scripts |
-------------------------------------------------------------------------------]] |
local function Control_OnEnter(frame) |
frame.obj:Fire("OnEnter") |
end |
local function Control_OnLeave(frame) |
frame.obj:Fire("OnLeave") |
end |
local function EditBox_OnEscapePressed(frame) |
AceGUI:ClearFocus() |
end |
local function EditBox_OnEnterPressed(frame) |
local self = frame.obj |
local value = frame:GetText() |
local cancel = self:Fire("OnEnterPressed", value) |
if not cancel then |
PlaySound("igMainMenuOptionCheckBoxOn") |
HideButton(self) |
end |
end |
local function EditBox_OnReceiveDrag(frame) |
local self = frame.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(frame) |
local self = frame.obj |
local value = frame:GetText() |
if tostring(value) ~= tostring(self.lasttext) then |
self:Fire("OnTextChanged", value) |
self.lasttext = value |
ShowButton(self) |
end |
end |
local function Button_OnClick(frame) |
local editbox = frame.obj.editbox |
editbox:ClearFocus() |
EditBox_OnEnterPressed(editbox) |
end |
--[[----------------------------------------------------------------------------- |
Methods |
-------------------------------------------------------------------------------]] |
local methods = { |
["OnAcquire"] = function(self) |
-- height is controlled by SetLabel |
self:SetWidth(200) |
self:SetDisabled(false) |
self:SetLabel() |
self:SetText() |
self:DisableButton(false) |
self:SetMaxLetters(0) |
end, |
-- ["OnRelease"] = nil, |
["SetDisabled"] = function(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, |
["SetText"] = function(self, text) |
self.lasttext = text or "" |
self.editbox:SetText(text or "") |
self.editbox:SetCursorPosition(0) |
HideButton(self) |
end, |
["SetLabel"] = function(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, |
["DisableButton"] = function(self, disabled) |
self.disablebutton = disabled |
end, |
["SetMaxLetters"] = function (self, num) |
self.editbox:SetMaxLetters(num or 0) |
end |
} |
--[[----------------------------------------------------------------------------- |
Constructor |
-------------------------------------------------------------------------------]] |
local function Constructor() |
local num = AceGUI:GetNextWidgetNum(Type) |
local frame = CreateFrame("Frame", nil, UIParent) |
frame:Hide() |
local editbox = CreateFrame("EditBox", "AceGUI-3.0EditBox"..num, frame, "InputBoxTemplate") |
editbox:SetAutoFocus(false) |
editbox:SetFontObject(ChatFontNormal) |
editbox:SetScript("OnEnter", Control_OnEnter) |
editbox:SetScript("OnLeave", Control_OnLeave) |
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", 6, 0) |
editbox:SetPoint("BOTTOMRIGHT") |
editbox:SetHeight(19) |
local label = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall") |
label:SetPoint("TOPLEFT", 0, -2) |
label:SetPoint("TOPRIGHT", 0, -2) |
label:SetJustifyH("LEFT") |
label:SetHeight(18) |
local button = CreateFrame("Button", nil, editbox, "UIPanelButtonTemplate") |
button:SetWidth(40) |
button:SetHeight(20) |
button:SetPoint("RIGHT", -2, 0) |
button:SetText(OKAY) |
button:SetScript("OnClick", Button_OnClick) |
button:Hide() |
local widget = { |
alignoffset = 30, |
editbox = editbox, |
label = label, |
button = button, |
frame = frame, |
type = Type |
} |
for method, func in pairs(methods) do |
widget[method] = func |
end |
editbox.obj, button.obj = widget, widget |
return AceGUI:RegisterAsWidget(widget) |
end |
AceGUI:RegisterWidgetType(Type, Constructor, Version) |
--[[----------------------------------------------------------------------------- |
Heading Widget |
-------------------------------------------------------------------------------]] |
local Type, Version = "Heading", 20 |
local AceGUI = LibStub and LibStub("AceGUI-3.0", true) |
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end |
-- Lua APIs |
local pairs = pairs |
-- WoW APIs |
local CreateFrame, UIParent = CreateFrame, UIParent |
--[[----------------------------------------------------------------------------- |
Methods |
-------------------------------------------------------------------------------]] |
local methods = { |
["OnAcquire"] = function(self) |
self:SetText() |
self:SetFullWidth() |
self:SetHeight(18) |
end, |
-- ["OnRelease"] = nil, |
["SetText"] = function(self, text) |
self.label:SetText(text or "") |
if text and text ~= "" then |
self.left:SetPoint("RIGHT", self.label, "LEFT", -5, 0) |
self.right:Show() |
else |
self.left:SetPoint("RIGHT", -3, 0) |
self.right:Hide() |
end |
end |
} |
--[[----------------------------------------------------------------------------- |
Constructor |
-------------------------------------------------------------------------------]] |
local function Constructor() |
local frame = CreateFrame("Frame", nil, UIParent) |
frame:Hide() |
local label = frame:CreateFontString(nil, "BACKGROUND", "GameFontNormal") |
label:SetPoint("TOP") |
label:SetPoint("BOTTOM") |
label:SetJustifyH("CENTER") |
local left = frame:CreateTexture(nil, "BACKGROUND") |
left:SetHeight(8) |
left:SetPoint("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") |
right:SetHeight(8) |
right:SetPoint("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) |
local widget = { |
label = label, |
left = left, |
right = right, |
frame = frame, |
type = Type |
} |
for method, func in pairs(methods) do |
widget[method] = func |
end |
return AceGUI:RegisterAsWidget(widget) |
end |
AceGUI:RegisterWidgetType(Type, Constructor, Version) |
--[[----------------------------------------------------------------------------- |
SimpleGroup Container |
Simple container widget that just groups widgets. |
-------------------------------------------------------------------------------]] |
local Type, Version = "SimpleGroup", 20 |
local AceGUI = LibStub and LibStub("AceGUI-3.0", true) |
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end |
-- Lua APIs |
local pairs = pairs |
-- WoW APIs |
local CreateFrame, UIParent = CreateFrame, UIParent |
--[[----------------------------------------------------------------------------- |
Methods |
-------------------------------------------------------------------------------]] |
local methods = { |
["OnAcquire"] = function(self) |
self:SetWidth(300) |
self:SetHeight(100) |
end, |
-- ["OnRelease"] = nil, |
["LayoutFinished"] = function(self, width, height) |
if self.noAutoHeight then return end |
self:SetHeight(height or 0) |
end, |
["OnWidthSet"] = function(self, width) |
local content = self.content |
content:SetWidth(width) |
content.width = width |
end, |
["OnHeightSet"] = function(self, height) |
local content = self.content |
content:SetHeight(height) |
content.height = height |
end |
} |
--[[----------------------------------------------------------------------------- |
Constructor |
-------------------------------------------------------------------------------]] |
local function Constructor() |
local frame = CreateFrame("Frame", nil, UIParent) |
frame:SetFrameStrata("FULLSCREEN_DIALOG") |
--Container Support |
local content = CreateFrame("Frame", nil, frame) |
content:SetPoint("TOPLEFT") |
content:SetPoint("BOTTOMRIGHT") |
local widget = { |
frame = frame, |
content = content, |
type = Type |
} |
for method, func in pairs(methods) do |
widget[method] = func |
end |
return AceGUI:RegisterAsContainer(widget) |
end |
AceGUI:RegisterWidgetType(Type, Constructor, Version) |
local AceGUI = LibStub("AceGUI-3.0") |
-- Lua APIs |
local pairs, assert, type = pairs, assert, type |
-- WoW APIs |
local PlaySound = PlaySound |
local CreateFrame, UIParent = CreateFrame, UIParent |
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded |
-- List them here for Mikk's FindGlobals script |
-- GLOBALS: GameFontNormal |
---------------- |
-- Main Frame -- |
---------------- |
--[[ |
Events : |
OnClose |
]] |
do |
local Type = "Window" |
local Version = 4 |
local function frameOnClose(this) |
this.obj:Fire("OnClose") |
end |
local function closeOnClick(this) |
PlaySound("gsTitleOptionExit") |
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() |
self:EnableResize(true) |
self:Show() |
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 EnableResize(self, state) |
local func = state and "Show" or "Hide" |
self.sizer_se[func](self.sizer_se) |
self.sizer_s[func](self.sizer_s) |
self.sizer_e[func](self.sizer_e) |
end |
local function Constructor() |
local frame = CreateFrame("Frame",nil,UIParent) |
local self = {} |
self.type = "Window" |
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.EnableResize = EnableResize |
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:SetScript("OnHide",frameOnClose) |
frame:SetMinResize(240,240) |
frame:SetToplevel(true) |
local titlebg = frame:CreateTexture(nil, "BACKGROUND") |
titlebg:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Title-Background]]) |
titlebg:SetPoint("TOPLEFT", 9, -6) |
titlebg:SetPoint("BOTTOMRIGHT", frame, "TOPRIGHT", -28, -24) |
local dialogbg = frame:CreateTexture(nil, "BACKGROUND") |
dialogbg:SetTexture([[Interface\Tooltips\UI-Tooltip-Background]]) |
dialogbg:SetPoint("TOPLEFT", 8, -24) |
dialogbg:SetPoint("BOTTOMRIGHT", -6, 8) |
dialogbg:SetVertexColor(0, 0, 0, .75) |
local topleft = frame:CreateTexture(nil, "BORDER") |
topleft:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]]) |
topleft:SetWidth(64) |
topleft:SetHeight(64) |
topleft:SetPoint("TOPLEFT") |
topleft:SetTexCoord(0.501953125, 0.625, 0, 1) |
local topright = frame:CreateTexture(nil, "BORDER") |
topright:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]]) |
topright:SetWidth(64) |
topright:SetHeight(64) |
topright:SetPoint("TOPRIGHT") |
topright:SetTexCoord(0.625, 0.75, 0, 1) |
local top = frame:CreateTexture(nil, "BORDER") |
top:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]]) |
top:SetHeight(64) |
top:SetPoint("TOPLEFT", topleft, "TOPRIGHT") |
top:SetPoint("TOPRIGHT", topright, "TOPLEFT") |
top:SetTexCoord(0.25, 0.369140625, 0, 1) |
local bottomleft = frame:CreateTexture(nil, "BORDER") |
bottomleft:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]]) |
bottomleft:SetWidth(64) |
bottomleft:SetHeight(64) |
bottomleft:SetPoint("BOTTOMLEFT") |
bottomleft:SetTexCoord(0.751953125, 0.875, 0, 1) |
local bottomright = frame:CreateTexture(nil, "BORDER") |
bottomright:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]]) |
bottomright:SetWidth(64) |
bottomright:SetHeight(64) |
bottomright:SetPoint("BOTTOMRIGHT") |
bottomright:SetTexCoord(0.875, 1, 0, 1) |
local bottom = frame:CreateTexture(nil, "BORDER") |
bottom:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]]) |
bottom:SetHeight(64) |
bottom:SetPoint("BOTTOMLEFT", bottomleft, "BOTTOMRIGHT") |
bottom:SetPoint("BOTTOMRIGHT", bottomright, "BOTTOMLEFT") |
bottom:SetTexCoord(0.376953125, 0.498046875, 0, 1) |
local left = frame:CreateTexture(nil, "BORDER") |
left:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]]) |
left:SetWidth(64) |
left:SetPoint("TOPLEFT", topleft, "BOTTOMLEFT") |
left:SetPoint("BOTTOMLEFT", bottomleft, "TOPLEFT") |
left:SetTexCoord(0.001953125, 0.125, 0, 1) |
local right = frame:CreateTexture(nil, "BORDER") |
right:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]]) |
right:SetWidth(64) |
right:SetPoint("TOPRIGHT", topright, "BOTTOMRIGHT") |
right:SetPoint("BOTTOMRIGHT", bottomright, "TOPRIGHT") |
right:SetTexCoord(0.1171875, 0.2421875, 0, 1) |
local close = CreateFrame("Button", nil, frame, "UIPanelCloseButton") |
close:SetPoint("TOPRIGHT", 2, 1) |
close:SetScript("OnClick", closeOnClick) |
self.closebutton = close |
close.obj = self |
local titletext = frame:CreateFontString(nil, "ARTWORK") |
titletext:SetFontObject(GameFontNormal) |
titletext:SetPoint("TOPLEFT", 12, -8) |
titletext:SetPoint("TOPRIGHT", -32, -8) |
self.titletext = titletext |
local title = CreateFrame("Button", nil, frame) |
title:SetPoint("TOPLEFT", titlebg) |
title:SetPoint("BOTTOMRIGHT", titlebg) |
title:EnableMouse() |
title:SetScript("OnMouseDown",titleOnMouseDown) |
title:SetScript("OnMouseUp", frameOnMouseUp) |
self.title = title |
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",12,-32) |
content:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-12,13) |
AceGUI:RegisterAsContainer(self) |
return self |
end |
AceGUI:RegisterWidgetType(Type,Constructor,Version) |
end |
--[[----------------------------------------------------------------------------- |
DropdownGroup Container |
Container controlled by a dropdown on the top. |
-------------------------------------------------------------------------------]] |
local Type, Version = "DropdownGroup", 20 |
local AceGUI = LibStub and LibStub("AceGUI-3.0", true) |
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end |
-- Lua APIs |
local assert, pairs, type = assert, pairs, type |
-- WoW APIs |
local CreateFrame = CreateFrame |
--[[----------------------------------------------------------------------------- |
Scripts |
-------------------------------------------------------------------------------]] |
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 |
--[[----------------------------------------------------------------------------- |
Methods |
-------------------------------------------------------------------------------]] |
local methods = { |
["OnAcquire"] = function(self) |
self.dropdown:SetText("") |
self:SetDropdownWidth(200) |
self:SetTitle("") |
end, |
["OnRelease"] = function(self) |
self.dropdown.list = nil |
self.status = nil |
for k in pairs(self.localstatus) do |
self.localstatus[k] = nil |
end |
end, |
["SetTitle"] = function(self, title) |
self.titletext:SetText(title) |
self.dropdown.frame:ClearAllPoints() |
if title and title ~= "" then |
self.dropdown.frame:SetPoint("TOPRIGHT", -2, 0) |
else |
self.dropdown.frame:SetPoint("TOPLEFT", -1, 0) |
end |
end, |
["SetGroupList"] = function(self,list) |
self.dropdown:SetList(list) |
end, |
["SetStatusTable"] = function(self, status) |
assert(type(status) == "table") |
self.status = status |
end, |
["SetGroup"] = function(self,group) |
self.dropdown:SetValue(group) |
local status = self.status or self.localstatus |
status.selected = group |
self:Fire("OnGroupSelected", group) |
end, |
["OnWidthSet"] = function(self, width) |
local content = self.content |
local contentwidth = width - 26 |
if contentwidth < 0 then |
contentwidth = 0 |
end |
content:SetWidth(contentwidth) |
content.width = contentwidth |
end, |
["OnHeightSet"] = function(self, height) |
local content = self.content |
local contentheight = height - 63 |
if contentheight < 0 then |
contentheight = 0 |
end |
content:SetHeight(contentheight) |
content.height = contentheight |
end, |
["LayoutFinished"] = function(self, width, height) |
self:SetHeight((height or 0) + 63) |
end, |
["SetDropdownWidth"] = function(self, width) |
self.dropdown:SetWidth(width) |
end |
} |
--[[----------------------------------------------------------------------------- |
Constructor |
-------------------------------------------------------------------------------]] |
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 Constructor() |
local frame = CreateFrame("Frame") |
frame:SetHeight(100) |
frame:SetWidth(100) |
frame:SetFrameStrata("FULLSCREEN_DIALOG") |
local titletext = frame:CreateFontString(nil, "OVERLAY", "GameFontNormal") |
titletext:SetPoint("TOPLEFT", 4, -5) |
titletext:SetPoint("TOPRIGHT", -4, -5) |
titletext:SetJustifyH("LEFT") |
titletext:SetHeight(18) |
local dropdown = AceGUI:Create("Dropdown") |
dropdown.frame:SetParent(frame) |
dropdown.frame:SetFrameLevel(dropdown.frame:GetFrameLevel() + 2) |
dropdown:SetCallback("OnValueChanged", SelectedGroup) |
dropdown.frame:SetPoint("TOPLEFT", -1, 0) |
dropdown.frame:Show() |
dropdown:SetLabel("") |
local border = CreateFrame("Frame", nil, frame) |
border:SetPoint("TOPLEFT", 0, -26) |
border:SetPoint("BOTTOMRIGHT", 0, 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) |
content:SetPoint("TOPLEFT", 10, -10) |
content:SetPoint("BOTTOMRIGHT", -10, 10) |
local widget = { |
frame = frame, |
localstatus = {}, |
titletext = titletext, |
dropdown = dropdown, |
border = border, |
content = content, |
type = Type |
} |
for method, func in pairs(methods) do |
widget[method] = func |
end |
dropdown.parentgroup = widget |
return AceGUI:RegisterAsContainer(widget) |
end |
AceGUI:RegisterWidgetType(Type, Constructor, Version) |
--[[----------------------------------------------------------------------------- |
ScrollFrame Container |
Plain container that scrolls its content and doesn't grow in height. |
-------------------------------------------------------------------------------]] |
local Type, Version = "ScrollFrame", 20 |
local AceGUI = LibStub and LibStub("AceGUI-3.0", true) |
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end |
-- Lua APIs |
local pairs, assert, type = pairs, assert, type |
local min, max, floor = math.min, math.max, math.floor |
-- WoW APIs |
local CreateFrame, UIParent = CreateFrame, UIParent |
--[[----------------------------------------------------------------------------- |
Support functions |
-------------------------------------------------------------------------------]] |
local function FixScrollOnUpdate(frame) |
frame:SetScript("OnUpdate", nil) |
frame.obj:FixScroll() |
end |
--[[----------------------------------------------------------------------------- |
Scripts |
-------------------------------------------------------------------------------]] |
local function ScrollFrame_OnMouseWheel(frame, value) |
frame.obj:MoveScroll(value) |
end |
local function ScrollFrame_OnSizeChanged(frame) |
frame:SetScript("OnUpdate", FixScrollOnUpdate) |
end |
local function ScrollBar_OnScrollValueChanged(frame, value) |
frame.obj:SetScroll(value) |
end |
--[[----------------------------------------------------------------------------- |
Methods |
-------------------------------------------------------------------------------]] |
local methods = { |
["OnAcquire"] = function(self) |
self:SetScroll(0) |
end, |
["OnRelease"] = function(self) |
self.status = nil |
for k in pairs(self.localstatus) do |
self.localstatus[k] = nil |
end |
self.scrollframe:SetPoint("BOTTOMRIGHT") |
self.scrollbar:Hide() |
self.scrollBarShown = nil |
self.content.height, self.content.width = nil, nil |
end, |
["SetScroll"] = function(self, value) |
local status = self.status or self.localstatus |
local viewheight = self.scrollframe:GetHeight() |
local height = self.content:GetHeight() |
local offset |
if viewheight > height then |
offset = 0 |
else |
offset = floor((height - viewheight) / 1000.0 * value) |
end |
self.content:ClearAllPoints() |
self.content:SetPoint("TOPLEFT", 0, offset) |
self.content:SetPoint("TOPRIGHT", 0, offset) |
status.offset = offset |
status.scrollvalue = value |
end, |
["MoveScroll"] = function(self, value) |
local status = self.status or self.localstatus |
local height, viewheight = self.scrollframe:GetHeight(), self.content: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(min(max(status.scrollvalue + delta*(1000/(diff/45)),0), 1000)) |
end |
end, |
["FixScroll"] = function(self) |
if self.updateLock then return end |
self.updateLock = true |
local status = self.status or self.localstatus |
local height, viewheight = self.scrollframe:GetHeight(), self.content:GetHeight() |
local offset = status.offset or 0 |
local curvalue = self.scrollbar:GetValue() |
if viewheight < height then |
if self.scrollBarShown then |
self.scrollBarShown = nil |
self.scrollbar:Hide() |
self.scrollbar:SetValue(0) |
self.scrollframe:SetPoint("BOTTOMRIGHT") |
self:DoLayout() |
end |
else |
if not self.scrollBarShown then |
self.scrollBarShown = true |
self.scrollbar:Show() |
self.scrollframe:SetPoint("BOTTOMRIGHT", -20, 0) |
self:DoLayout() |
end |
local value = (offset / (viewheight - height) * 1000) |
if value > 1000 then value = 1000 end |
self.scrollbar:SetValue(value) |
self:SetScroll(value) |
if value < 1000 then |
self.content:ClearAllPoints() |
self.content:SetPoint("TOPLEFT", 0, offset) |
self.content:SetPoint("TOPRIGHT", 0, offset) |
status.offset = offset |
end |
end |
self.updateLock = nil |
end, |
["LayoutFinished"] = function(self, width, height) |
self.content:SetHeight(height or 0 + 20) |
self.scrollframe:SetScript("OnUpdate", FixScrollOnUpdate) |
end, |
["SetStatusTable"] = function(self, status) |
assert(type(status) == "table") |
self.status = status |
if not status.scrollvalue then |
status.scrollvalue = 0 |
end |
end, |
["OnWidthSet"] = function(self, width) |
local content = self.content |
content.width = width |
end, |
["OnHeightSet"] = function(self, height) |
local content = self.content |
content.height = height |
end |
} |
--[[----------------------------------------------------------------------------- |
Constructor |
-------------------------------------------------------------------------------]] |
local function Constructor() |
local frame = CreateFrame("Frame", nil, UIParent) |
local num = AceGUI:GetNextWidgetNum(Type) |
local scrollframe = CreateFrame("ScrollFrame", nil, frame) |
scrollframe:SetPoint("TOPLEFT") |
scrollframe:SetPoint("BOTTOMRIGHT") |
scrollframe:EnableMouseWheel(true) |
scrollframe:SetScript("OnMouseWheel", ScrollFrame_OnMouseWheel) |
scrollframe:SetScript("OnSizeChanged", ScrollFrame_OnSizeChanged) |
local scrollbar = CreateFrame("Slider", ("AceConfigDialogScrollFrame%dScrollBar"):format(num), scrollframe, "UIPanelScrollBarTemplate") |
scrollbar:SetPoint("TOPLEFT", scrollframe, "TOPRIGHT", 4, -16) |
scrollbar:SetPoint("BOTTOMLEFT", scrollframe, "BOTTOMRIGHT", 4, 16) |
scrollbar:SetMinMaxValues(0, 1000) |
scrollbar:SetValueStep(1) |
scrollbar:SetValue(0) |
scrollbar:SetWidth(16) |
scrollbar:Hide() |
-- set the script as the last step, so it doesn't fire yet |
scrollbar:SetScript("OnValueChanged", ScrollBar_OnScrollValueChanged) |
local scrollbg = scrollbar:CreateTexture(nil, "BACKGROUND") |
scrollbg:SetAllPoints(scrollbar) |
scrollbg:SetTexture(0, 0, 0, 0.4) |
--Container Support |
local content = CreateFrame("Frame", nil, scrollframe) |
content:SetPoint("TOPLEFT") |
content:SetPoint("TOPRIGHT") |
content:SetHeight(400) |
scrollframe:SetScrollChild(content) |
local widget = { |
localstatus = { scrollvalue = 0 }, |
scrollframe = scrollframe, |
scrollbar = scrollbar, |
content = content, |
frame = frame, |
type = Type |
} |
for method, func in pairs(methods) do |
widget[method] = func |
end |
scrollframe.obj, scrollbar.obj = widget, widget |
return AceGUI:RegisterAsContainer(widget) |
end |
AceGUI:RegisterWidgetType(Type, Constructor, Version) |
--[[----------------------------------------------------------------------------- |
TreeGroup Container |
Container that uses a tree control to switch between groups. |
-------------------------------------------------------------------------------]] |
local Type, Version = "TreeGroup", 30 |
local AceGUI = LibStub and LibStub("AceGUI-3.0", true) |
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end |
-- Lua APIs |
local next, pairs, ipairs, assert, type = next, pairs, ipairs, assert, type |
local math_min, math_max, floor = math.min, math.max, floor |
local select, tremove, unpack = select, table.remove, unpack |
-- WoW APIs |
local CreateFrame, UIParent = CreateFrame, UIParent |
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded |
-- List them here for Mikk's FindGlobals script |
-- GLOBALS: GameTooltip, FONT_COLOR_CODE_CLOSE |
-- 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 |
local DEFAULT_TREE_WIDTH = 175 |
local DEFAULT_TREE_SIZABLE = true |
--[[----------------------------------------------------------------------------- |
Support functions |
-------------------------------------------------------------------------------]] |
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 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 iconCoords = treeline.iconCoords |
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", 8 * level, (level == 1) and 0 or 1) |
else |
button.icon:SetTexture(nil) |
end |
if iconCoords then |
button.icon:SetTexCoord(unpack(iconCoords)) |
else |
button.icon:SetTexCoord(0, 1, 0, 1) |
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 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.iconCoords = v.iconCoords |
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 |
--fire an update after one frame to catch the treeframes height |
local function FirstFrameUpdate(frame) |
local self = frame.obj |
frame:SetScript("OnUpdate", nil) |
self:RefreshTree() |
end |
local function BuildUniqueValue(...) |
local n = select('#', ...) |
if n == 1 then |
return ... |
else |
return (...).."\001"..BuildUniqueValue(select(2,...)) |
end |
end |
--[[----------------------------------------------------------------------------- |
Scripts |
-------------------------------------------------------------------------------]] |
local function Expand_OnClick(frame) |
local button = frame.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 Button_OnClick(frame) |
local self = frame.obj |
self:Fire("OnClick", frame.uniquevalue, frame.selected) |
if not frame.selected then |
self:SetSelected(frame.uniquevalue) |
frame.selected = true |
frame:LockHighlight() |
self:RefreshTree() |
end |
AceGUI:ClearFocus() |
end |
local function Button_OnDoubleClick(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 Button_OnEnter(frame) |
local self = frame.obj |
self:Fire("OnButtonEnter", frame.uniquevalue, frame) |
if self.enabletooltips then |
GameTooltip:SetOwner(frame, "ANCHOR_NONE") |
GameTooltip:SetPoint("LEFT",frame,"RIGHT") |
GameTooltip:SetText(frame.text:GetText() or "", 1, .82, 0, 1) |
GameTooltip:Show() |
end |
end |
local function Button_OnLeave(frame) |
local self = frame.obj |
self:Fire("OnButtonLeave", frame.uniquevalue, frame) |
if self.enabletooltips then |
GameTooltip:Hide() |
end |
end |
local function OnScrollValueChanged(frame, value) |
if frame.obj.noupdate then return end |
local self = frame.obj |
local status = self.status or self.localstatus |
status.scrollvalue = value |
self:RefreshTree() |
AceGUI:ClearFocus() |
end |
local function Tree_OnSizeChanged(frame) |
frame.obj:RefreshTree() |
end |
local function Tree_OnMouseWheel(frame, delta) |
local self = frame.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 Dragger_OnLeave(frame) |
frame:SetBackdropColor(1, 1, 1, 0) |
end |
local function Dragger_OnEnter(frame) |
frame:SetBackdropColor(1, 1, 1, 0.8) |
end |
local function Dragger_OnMouseDown(frame) |
local treeframe = frame:GetParent() |
treeframe:StartSizing("RIGHT") |
end |
local function Dragger_OnMouseUp(frame) |
local treeframe = frame: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) |
local status = self.status or self.localstatus |
status.treewidth = treeframe:GetWidth() |
treeframe.obj:Fire("OnTreeResize",treeframe:GetWidth()) |
-- recalculate the content width |
treeframe.obj:OnWidthSet(status.fullwidth) |
-- update the layout of the content |
treeframe.obj:DoLayout() |
end |
--[[----------------------------------------------------------------------------- |
Methods |
-------------------------------------------------------------------------------]] |
local methods = { |
["OnAcquire"] = function(self) |
self:SetTreeWidth(DEFAULT_TREE_WIDTH, DEFAULT_TREE_SIZABLE) |
self:EnableButtonTooltips(true) |
end, |
["OnRelease"] = function(self) |
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, |
["EnableButtonTooltips"] = function(self, enable) |
self.enabletooltips = enable |
end, |
["CreateButton"] = function(self) |
local num = AceGUI:GetNextWidgetNum("TreeGroupButton") |
local button = CreateFrame("Button", ("AceGUI30TreeButton%d"):format(num), self.treeframe, "OptionsListButtonTemplate") |
button.obj = self |
local icon = button:CreateTexture(nil, "OVERLAY") |
icon:SetWidth(14) |
icon:SetHeight(14) |
button.icon = icon |
button:SetScript("OnClick",Button_OnClick) |
button:SetScript("OnDoubleClick", Button_OnDoubleClick) |
button:SetScript("OnEnter",Button_OnEnter) |
button:SetScript("OnLeave",Button_OnLeave) |
button.toggle.button = button |
button.toggle:SetScript("OnClick",Expand_OnClick) |
return button |
end, |
["SetStatusTable"] = function(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 |
["SetTree"] = function(self, tree, filter) |
self.filter = filter |
if tree then |
assert(type(tree) == "table") |
end |
self.tree = tree |
self:RefreshTree() |
end, |
["BuildLevel"] = function(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, |
["RefreshTree"] = function(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 = (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, |
["SetSelected"] = function(self, value) |
local status = self.status or self.localstatus |
if status.selected ~= value then |
status.selected = value |
self:Fire("OnGroupSelected", value) |
end |
end, |
["Select"] = function(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, |
["SelectByPath"] = function(self, ...) |
self:Select(BuildUniqueValue(...), ...) |
end, |
["SelectByValue"] = function(self, uniquevalue) |
self:Select(uniquevalue, ("\001"):split(uniquevalue)) |
end, |
["ShowScroll"] = function(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, |
["OnWidthSet"] = function(self, width) |
local content = self.content |
local treeframe = self.treeframe |
local status = self.status or self.localstatus |
status.fullwidth = width |
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, |
["OnHeightSet"] = function(self, height) |
local content = self.content |
local contentheight = height - 20 |
if contentheight < 0 then |
contentheight = 0 |
end |
content:SetHeight(contentheight) |
content.height = contentheight |
end, |
["SetTreeWidth"] = function(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 |
-- recalculate the content width |
if status.fullwidth then |
self:OnWidthSet(status.fullwidth) |
end |
end, |
["LayoutFinished"] = function(self, width, height) |
if self.noAutoHeight then return end |
self:SetHeight((height or 0) + 20) |
end |
} |
--[[----------------------------------------------------------------------------- |
Constructor |
-------------------------------------------------------------------------------]] |
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 Constructor() |
local num = AceGUI:GetNextWidgetNum(Type) |
local frame = CreateFrame("Frame", nil, UIParent) |
local treeframe = CreateFrame("Frame", nil, frame) |
treeframe:SetPoint("TOPLEFT") |
treeframe:SetPoint("BOTTOMLEFT") |
treeframe:SetWidth(DEFAULT_TREE_WIDTH) |
treeframe:EnableMouseWheel(true) |
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) |
treeframe:SetScript("OnUpdate", FirstFrameUpdate) |
treeframe:SetScript("OnSizeChanged", Tree_OnSizeChanged) |
treeframe:SetScript("OnMouseWheel", Tree_OnMouseWheel) |
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("OnEnter", Dragger_OnEnter) |
dragger:SetScript("OnLeave", Dragger_OnLeave) |
dragger:SetScript("OnMouseDown", Dragger_OnMouseDown) |
dragger:SetScript("OnMouseUp", Dragger_OnMouseUp) |
local scrollbar = CreateFrame("Slider", ("AceConfigDialogTreeGroup%dScrollBar"):format(num), treeframe, "UIPanelScrollBarTemplate") |
scrollbar:SetScript("OnValueChanged", nil) |
scrollbar:SetPoint("TOPRIGHT", -10, -26) |
scrollbar:SetPoint("BOTTOMRIGHT", -10, 26) |
scrollbar:SetMinMaxValues(0,0) |
scrollbar:SetValueStep(1) |
scrollbar:SetValue(0) |
scrollbar:SetWidth(16) |
scrollbar:SetScript("OnValueChanged", OnScrollValueChanged) |
local scrollbg = scrollbar:CreateTexture(nil, "BACKGROUND") |
scrollbg:SetAllPoints(scrollbar) |
scrollbg:SetTexture(0,0,0,0.4) |
local border = CreateFrame("Frame",nil,frame) |
border:SetPoint("TOPLEFT", treeframe, "TOPRIGHT") |
border:SetPoint("BOTTOMRIGHT") |
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) |
content:SetPoint("TOPLEFT", 10, -10) |
content:SetPoint("BOTTOMRIGHT", -10, 10) |
local widget = { |
frame = frame, |
lines = {}, |
levels = {}, |
buttons = {}, |
hasChildren = {}, |
localstatus = { groups = {}, scrollvalue = 0 }, |
filter = false, |
treeframe = treeframe, |
dragger = dragger, |
scrollbar = scrollbar, |
border = border, |
content = content, |
type = Type |
} |
for method, func in pairs(methods) do |
widget[method] = func |
end |
treeframe.obj, dragger.obj, scrollbar.obj = widget, widget, widget |
return AceGUI:RegisterAsContainer(widget) |
end |
AceGUI:RegisterWidgetType(Type, Constructor, Version) |
--[[----------------------------------------------------------------------------- |
Button Widget |
Graphical Button. |
-------------------------------------------------------------------------------]] |
local Type, Version = "Button", 20 |
local AceGUI = LibStub and LibStub("AceGUI-3.0", true) |
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end |
-- Lua APIs |
local pairs = pairs |
-- WoW APIs |
local _G = _G |
local PlaySound, CreateFrame, UIParent = PlaySound, CreateFrame, UIParent |
--[[----------------------------------------------------------------------------- |
Scripts |
-------------------------------------------------------------------------------]] |
local function Button_OnClick(frame, ...) |
PlaySound("igMainMenuOption") |
frame.obj:Fire("OnClick", ...) |
AceGUI:ClearFocus() |
end |
local function Control_OnEnter(frame) |
frame.obj:Fire("OnEnter") |
end |
local function Control_OnLeave(frame) |
frame.obj:Fire("OnLeave") |
end |
--[[----------------------------------------------------------------------------- |
Methods |
-------------------------------------------------------------------------------]] |
local methods = { |
["OnAcquire"] = function(self) |
-- restore default values |
self:SetHeight(24) |
self:SetWidth(200) |
self:SetDisabled(false) |
self:SetText() |
end, |
-- ["OnRelease"] = nil, |
["SetText"] = function(self, text) |
self.text:SetText(text) |
end, |
["SetDisabled"] = function(self, disabled) |
self.disabled = disabled |
if disabled then |
self.frame:Disable() |
else |
self.frame:Enable() |
end |
end |
} |
--[[----------------------------------------------------------------------------- |
Constructor |
-------------------------------------------------------------------------------]] |
local function Constructor() |
local name = "AceGUI30Button" .. AceGUI:GetNextWidgetNum(Type) |
local frame = CreateFrame("Button", name, UIParent, "UIPanelButtonTemplate2") |
frame:Hide() |
frame:EnableMouse(true) |
frame:SetScript("OnClick", Button_OnClick) |
frame:SetScript("OnEnter", Control_OnEnter) |
frame:SetScript("OnLeave", Control_OnLeave) |
local text = frame:GetFontString() |
text:ClearAllPoints() |
text:SetPoint("TOPLEFT", 15, -1) |
text:SetPoint("BOTTOMRIGHT", -15, 1) |
text:SetJustifyV("MIDDLE") |
local widget = { |
text = text, |
frame = frame, |
type = Type |
} |
for method, func in pairs(methods) do |
widget[method] = func |
end |
return AceGUI:RegisterAsWidget(widget) |
end |
AceGUI:RegisterWidgetType(Type, Constructor, Version) |
--[[ $Id: AceGUIWidget-DropDown-Items.lua 916 2010-03-15 12:24:36Z nevcairiel $ ]]-- |
local AceGUI = LibStub("AceGUI-3.0") |
-- Lua APIs |
local select, assert = select, assert |
-- WoW APIs |
local PlaySound = PlaySound |
local CreateFrame = CreateFrame |
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 = 3 |
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 |
if self.value then |
PlaySound("igMainMenuOptionCheckBoxOn") |
else |
PlaySound("igMainMenuOptionCheckBoxOff") |
end |
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 = 2 |
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 |
local function SetMenu(self, menu) |
assert(menu.type == "Dropdown-Pullout") |
self.submenu = menu |
end |
-- exported |
local 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 |
--[[----------------------------------------------------------------------------- |
ColorPicker Widget |
-------------------------------------------------------------------------------]] |
local Type, Version = "ColorPicker", 20 |
local AceGUI = LibStub and LibStub("AceGUI-3.0", true) |
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end |
-- Lua APIs |
local pairs = pairs |
-- WoW APIs |
local CreateFrame, UIParent = CreateFrame, UIParent |
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded |
-- List them here for Mikk's FindGlobals script |
-- GLOBALS: ShowUIPanel, HideUIPanel, ColorPickerFrame, OpacitySliderFrame |
--[[----------------------------------------------------------------------------- |
Support functions |
-------------------------------------------------------------------------------]] |
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 |
--[[----------------------------------------------------------------------------- |
Scripts |
-------------------------------------------------------------------------------]] |
local function Control_OnEnter(frame) |
frame.obj:Fire("OnEnter") |
end |
local function Control_OnLeave(frame) |
frame.obj:Fire("OnLeave") |
end |
local function ColorSwatch_OnClick(frame) |
HideUIPanel(ColorPickerFrame) |
local self = frame.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 |
--[[----------------------------------------------------------------------------- |
Methods |
-------------------------------------------------------------------------------]] |
local methods = { |
["OnAcquire"] = function(self) |
self:SetHeight(24) |
self:SetWidth(200) |
self:SetHasAlpha(false) |
self:SetColor(0, 0, 0, 1) |
self:SetDisabled(nil) |
self:SetLabel(nil) |
end, |
-- ["OnRelease"] = nil, |
["SetLabel"] = function(self, text) |
self.text:SetText(text) |
end, |
["SetColor"] = function(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, |
["SetHasAlpha"] = function(self, HasAlpha) |
self.HasAlpha = HasAlpha |
end, |
["SetDisabled"] = function(self, disabled) |
self.disabled = disabled |
if self.disabled then |
self.frame:Disable() |
self.text:SetTextColor(0.5, 0.5, 0.5) |
else |
self.frame:Enable() |
self.text:SetTextColor(1, 1, 1) |
end |
end |
} |
--[[----------------------------------------------------------------------------- |
Constructor |
-------------------------------------------------------------------------------]] |
local function Constructor() |
local frame = CreateFrame("Button", nil, UIParent) |
frame:Hide() |
frame:EnableMouse(true) |
frame:SetScript("OnEnter", Control_OnEnter) |
frame:SetScript("OnLeave", Control_OnLeave) |
frame:SetScript("OnClick", ColorSwatch_OnClick) |
local colorSwatch = frame:CreateTexture(nil, "OVERLAY") |
colorSwatch:SetWidth(19) |
colorSwatch:SetHeight(19) |
colorSwatch:SetTexture("Interface\\ChatFrame\\ChatFrameColorSwatch") |
colorSwatch:SetPoint("LEFT") |
local texture = frame:CreateTexture(nil, "BACKGROUND") |
texture:SetWidth(16) |
texture:SetHeight(16) |
texture:SetTexture(1, 1, 1) |
texture:SetPoint("CENTER", colorSwatch) |
texture:Show() |
local checkers = frame:CreateTexture(nil, "BACKGROUND") |
checkers:SetWidth(14) |
checkers:SetHeight(14) |
checkers:SetTexture("Tileset\\Generic\\Checkers") |
checkers:SetTexCoord(.25, 0, 0.5, .25) |
checkers:SetDesaturated(true) |
checkers:SetVertexColor(1, 1, 1, 0.75) |
checkers:SetPoint("CENTER", colorSwatch) |
checkers:Show() |
local text = frame:CreateFontString(nil,"OVERLAY","GameFontHighlight") |
text:SetHeight(24) |
text:SetJustifyH("LEFT") |
text:SetTextColor(1, 1, 1) |
text:SetPoint("LEFT", colorSwatch, "RIGHT", 2, 0) |
text:SetPoint("RIGHT") |
--local highlight = frame:CreateTexture(nil, "HIGHLIGHT") |
--highlight:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight") |
--highlight:SetBlendMode("ADD") |
--highlight:SetAllPoints(frame) |
local widget = { |
colorSwatch = colorSwatch, |
text = text, |
frame = frame, |
type = Type |
} |
for method, func in pairs(methods) do |
widget[method] = func |
end |
return AceGUI:RegisterAsWidget(widget) |
end |
AceGUI:RegisterWidgetType(Type, Constructor, Version) |
--[[----------------------------------------------------------------------------- |
InteractiveLabel Widget |
-------------------------------------------------------------------------------]] |
local Type, Version = "InteractiveLabel", 20 |
local AceGUI = LibStub and LibStub("AceGUI-3.0", true) |
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end |
-- Lua APIs |
local select, pairs = select, pairs |
-- WoW APIs |
local CreateFrame, UIParent = CreateFrame, UIParent |
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded |
-- List them here for Mikk's FindGlobals script |
-- GLOBALS: GameFontHighlightSmall |
--[[----------------------------------------------------------------------------- |
Scripts |
-------------------------------------------------------------------------------]] |
local function Control_OnEnter(frame) |
frame.obj:Fire("OnEnter") |
end |
local function Control_OnLeave(frame) |
frame.obj:Fire("OnLeave") |
end |
local function Label_OnClick(frame, button) |
frame.obj:Fire("OnClick", button) |
AceGUI:ClearFocus() |
end |
--[[----------------------------------------------------------------------------- |
Methods |
-------------------------------------------------------------------------------]] |
local methods = { |
["OnAcquire"] = function(self) |
self:LabelOnAcquire() |
self:SetHighlight() |
self:SetHighlightTexCoord() |
self:SetDisabled(false) |
end, |
-- ["OnRelease"] = nil, |
["SetHighlight"] = function(self, ...) |
self.highlight:SetTexture(...) |
end, |
["SetHighlightTexCoord"] = function(self, ...) |
local c = select("#", ...) |
if c == 4 or c == 8 then |
self.highlight:SetTexCoord(...) |
else |
self.highlight:SetTexCoord(0, 1, 0, 1) |
end |
end, |
["SetDisabled"] = function(self,disabled) |
self.disabled = disabled |
if disabled then |
self.frame:EnableMouse(false) |
self.label:SetTextColor(0.5, 0.5, 0.5) |
else |
self.frame:EnableMouse(true) |
self.label:SetTextColor(1, 1, 1) |
end |
end |
} |
--[[----------------------------------------------------------------------------- |
Constructor |
-------------------------------------------------------------------------------]] |
local function Constructor() |
-- create a Label type that we will hijack |
local label = AceGUI:Create("Label") |
local frame = label.frame |
frame:EnableMouse(true) |
frame:SetScript("OnEnter", Control_OnEnter) |
frame:SetScript("OnLeave", Control_OnLeave) |
frame:SetScript("OnMouseDown", Label_OnClick) |
local highlight = frame:CreateTexture(nil, "HIGHLIGHT") |
highlight:SetTexture(nil) |
highlight:SetAllPoints() |
highlight:SetBlendMode("ADD") |
label.highlight = highlight |
label.type = Type |
label.LabelOnAcquire = label.OnAcquire |
for method, func in pairs(methods) do |
label[method] = func |
end |
return label |
end |
AceGUI:RegisterWidgetType(Type, Constructor, Version) |
--[[----------------------------------------------------------------------------- |
Label Widget |
Displays text and optionally an icon. |
-------------------------------------------------------------------------------]] |
local Type, Version = "Label", 21 |
local AceGUI = LibStub and LibStub("AceGUI-3.0", true) |
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end |
-- Lua APIs |
local max, select, pairs = math.max, select, pairs |
-- WoW APIs |
local CreateFrame, UIParent = CreateFrame, UIParent |
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded |
-- List them here for Mikk's FindGlobals script |
-- GLOBALS: GameFontHighlightSmall |
--[[----------------------------------------------------------------------------- |
Support functions |
-------------------------------------------------------------------------------]] |
local function UpdateImageAnchor(self) |
if self.resizing then return end |
local frame = self.frame |
local width = frame.width or frame:GetWidth() or 0 |
local image = self.image |
local label = self.label |
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") |
label:SetPoint("TOP", image, "BOTTOM") |
label:SetPoint("LEFT") |
label:SetWidth(width) |
height = image:GetHeight() + label:GetHeight() |
else |
-- image on the left |
image:SetPoint("TOPLEFT") |
label:SetPoint("TOPLEFT", image, "TOPRIGHT", 4, 0) |
label:SetWidth(width - imagewidth - 4) |
height = max(image:GetHeight(), label:GetHeight()) |
end |
else |
-- no image shown |
label:SetPoint("TOPLEFT") |
label:SetWidth(width) |
height = label:GetHeight() |
end |
self.resizing = true |
frame:SetHeight(height) |
frame.height = height |
self.resizing = nil |
end |
--[[----------------------------------------------------------------------------- |
Methods |
-------------------------------------------------------------------------------]] |
local methods = { |
["OnAcquire"] = function(self) |
-- set the flag to stop constant size updates |
self.resizing = true |
-- height is set dynamically by the text and image size |
self:SetWidth(200) |
self:SetText() |
self:SetImage(nil) |
self:SetImageSize(16, 16) |
self:SetColor() |
self:SetFontObject() |
-- reset the flag |
self.resizing = nil |
-- run the update explicitly |
UpdateImageAnchor(self) |
end, |
-- ["OnRelease"] = nil, |
["OnWidthSet"] = function(self, width) |
UpdateImageAnchor(self) |
end, |
["SetText"] = function(self, text) |
self.label:SetText(text) |
UpdateImageAnchor(self) |
end, |
["SetColor"] = function(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, |
["SetImage"] = function(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(...) |
else |
image:SetTexCoord(0, 1, 0, 1) |
end |
else |
self.imageshown = nil |
end |
UpdateImageAnchor(self) |
end, |
["SetFont"] = function(self, font, height, flags) |
self.label:SetFont(font, height, flags) |
end, |
["SetFontObject"] = function(self, font) |
self:SetFont((font or GameFontHighlightSmall):GetFont()) |
end, |
["SetImageSize"] = function(self, width, height) |
self.image:SetWidth(width) |
self.image:SetHeight(height) |
UpdateImageAnchor(self) |
end, |
} |
--[[----------------------------------------------------------------------------- |
Constructor |
-------------------------------------------------------------------------------]] |
local function Constructor() |
local frame = CreateFrame("Frame", nil, UIParent) |
frame:Hide() |
local label = frame:CreateFontString(nil, "BACKGROUND", "GameFontHighlightSmall") |
label:SetJustifyH("LEFT") |
label:SetJustifyV("TOP") |
local image = frame:CreateTexture(nil, "BACKGROUND") |
-- create widget |
local widget = { |
label = label, |
image = image, |
frame = frame, |
type = Type |
} |
for method, func in pairs(methods) do |
widget[method] = func |
end |
return AceGUI:RegisterAsWidget(widget) |
end |
AceGUI:RegisterWidgetType(Type, Constructor, Version) |
local Type, Version = "MultiLineEditBox", 22 |
local AceGUI = LibStub and LibStub("AceGUI-3.0", true) |
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end |
-- Lua APIs |
local pairs = pairs |
-- WoW APIs |
local GetCursorInfo, GetSpellName, ClearCursor = GetCursorInfo, GetSpellName, ClearCursor |
local CreateFrame, UIParent = CreateFrame, UIParent |
local _G = _G |
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded |
-- List them here for Mikk's FindGlobals script |
-- GLOBALS: ACCEPT, ChatFontNormal |
--[[----------------------------------------------------------------------------- |
Scripts |
-------------------------------------------------------------------------------]] |
local function OnClick(self) -- Button |
self = self.obj |
self.editBox:ClearFocus() |
if not self:Fire("OnEnterPressed", self.editBox:GetText()) then |
self.button:Disable() |
end |
end |
local function OnCursorChanged(self, _, y, _, cursorHeight) -- EditBox |
self, y = self.obj.scrollFrame, -y |
local offset = self:GetVerticalScroll() |
if y < offset then |
self:SetVerticalScroll(y) |
else |
y = y + cursorHeight - self:GetHeight() |
if y > offset then |
self:SetVerticalScroll(y) |
end |
end |
end |
local function OnEditFocusLost(self) -- EditBox |
self:HighlightText(0, 0) |
end |
local function OnEnter(self) -- EditBox / ScrollFrame |
self = self.obj |
if not self.entered then |
self.entered = true |
self:Fire("OnEnter") |
end |
end |
local function OnLeave(self) -- EditBox / ScrollFrame |
self = self.obj |
if self.entered then |
self.entered = nil |
self:Fire("OnLeave") |
end |
end |
local function OnMouseUp(self) -- ScrollFrame |
self = self.obj.editBox |
self:SetFocus() |
self:SetCursorPosition(self:GetNumLetters()) |
end |
local function OnReceiveDrag(self) -- EditBox / ScrollFrame |
local type, id, info = GetCursorInfo() |
if type == "spell" then |
info, id = GetSpellName(id, info) |
if id and id:match("%d") then |
info = info .. "(" .. id .. ")" |
end |
elseif type ~= "item" then |
return |
end |
ClearCursor() |
self = self.obj |
local editBox = self.editBox |
if not editBox:HasFocus() then |
editBox:SetFocus() |
editBox:SetCursorPosition(editBox:GetNumLetters()) |
end |
editBox:Insert(info) |
self.button:Enable() |
end |
local function OnSizeChanged(self, width, height) -- ScrollFrame |
self.obj.editBox:SetWidth(width) |
end |
local function OnTextChanged(self, userInput) -- EditBox |
if userInput then |
self = self.obj |
self:Fire("OnTextChanged", self.editBox:GetText()) |
self.button:Enable() |
end |
end |
local function OnTextSet(self) -- EditBox |
self:HighlightText(0, 0) |
self:SetCursorPosition(self:GetNumLetters()) |
self:SetCursorPosition(0) |
self.obj.button:Disable() |
end |
local function OnVerticalScroll(self, offset) -- ScrollFrame |
local editBox = self.obj.editBox |
editBox:SetHitRectInsets(0, 0, offset, editBox:GetHeight() - offset - self:GetHeight()) |
end |
--[[----------------------------------------------------------------------------- |
Methods |
-------------------------------------------------------------------------------]] |
local methods = { |
["GetText"] = function(self) |
return self.editBox:GetText() |
end, |
["OnAcquire"] = function(self) |
self.editBox:SetText("") |
self:SetDisabled(false) |
self:SetWidth(200) |
self:SetNumLines() |
self.entered = nil |
self:SetMaxLetters(0) |
end, |
["OnRelease"] = function(self) |
self.frame:ClearAllPoints() |
self.frame:Hide() |
end, |
["SetDisabled"] = function(self, disabled) |
local editBox = self.editBox |
if disabled then |
editBox:ClearFocus() |
editBox:EnableMouse(false) |
editBox:SetTextColor(0.5, 0.5, 0.5) |
self.label:SetTextColor(0.5, 0.5, 0.5) |
self.scrollFrame:EnableMouse(false) |
self.button:Disable() |
else |
editBox:EnableMouse(true) |
editBox:SetTextColor(1, 1, 1) |
self.label:SetTextColor(1, 0.82, 0) |
self.scrollFrame:EnableMouse(true) |
end |
end, |
["SetLabel"] = function(self, text) |
if text and text ~= "" then |
self.label:SetText(text) |
if self.labelHeight ~= 10 then |
self.labelHeight = 10 |
self.scrollBar:SetPoint("TOP", self.label, "BOTTOM", 0, -19) |
self:SetHeight(self.frame.height + 10) |
self.label:Show() |
end |
elseif self.labelHeight ~= 0 then |
self.labelHeight = 0 |
self.label:Hide() |
self.scrollBar:SetPoint("TOP", self.frame, "TOP", 0, -23) |
self:SetHeight(self.frame.height - 10) |
end |
end, |
["SetNumLines"] = function(self, value) |
if not value or value < 4 then |
value = 4 |
end |
self:SetHeight(value * 14 + 41 + self.labelHeight) |
end, |
["SetText"] = function(self, text) |
self.editBox:SetText(text) |
end, |
["SetMaxLetters"] = function (self, num) |
self.editBox:SetMaxLetters(num or 0) |
end |
} |
--[[----------------------------------------------------------------------------- |
Constructor |
-------------------------------------------------------------------------------]] |
local backdrop = { |
bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], |
edgeFile = [[Interface\Tooltips\UI-Tooltip-Border]], edgeSize = 16, |
insets = { left = 4, right = 3, top = 4, bottom = 3 } |
} |
local function Constructor() |
local frame = CreateFrame("Frame", nil, UIParent) |
frame:Hide() |
local widgetNum = AceGUI:GetNextWidgetNum(Type) |
local label = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall") |
label:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, -4) |
label:SetPoint("TOPRIGHT", frame, "TOPRIGHT", 0, -4) |
label:SetJustifyH("LEFT") |
label:SetText(ACCEPT) |
label:SetHeight(10) |
local button = CreateFrame("Button", ("%s%dButton"):format(Type, widgetNum), frame, "UIPanelButtonTemplate2") |
button:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT", 0, 4) |
button:SetHeight(22) |
button:SetWidth(label:GetStringWidth() + 24) |
button:SetText(ACCEPT) |
button:SetScript("OnClick", OnClick) |
button:Disable() |
local text = button:GetFontString() |
text:ClearAllPoints() |
text:SetPoint("TOPLEFT", button, "TOPLEFT", 5, -5) |
text:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", -5, 1) |
text:SetJustifyV("MIDDLE") |
local scrollBG = CreateFrame("Frame", nil, frame) |
scrollBG:SetBackdrop(backdrop) |
scrollBG:SetBackdropColor(0, 0, 0) |
scrollBG:SetBackdropBorderColor(0.4, 0.4, 0.4) |
local scrollFrame = CreateFrame("ScrollFrame", ("%s%dScrollFrame"):format(Type, widgetNum), frame, "UIPanelScrollFrameTemplate") |
local scrollBar = _G[scrollFrame:GetName() .. "ScrollBar"] |
scrollBar:ClearAllPoints() |
scrollBar:SetPoint("TOP", label, "BOTTOM", 0, -19) |
scrollBar:SetPoint("BOTTOM", button, "TOP", 0, 18) |
scrollBar:SetPoint("RIGHT", frame, "RIGHT") |
scrollBG:SetPoint("TOPRIGHT", scrollBar, "TOPLEFT", 0, 19) |
scrollBG:SetPoint("BOTTOMLEFT", button, "TOPLEFT") |
scrollFrame:SetPoint("TOPLEFT", scrollBG, "TOPLEFT", 5, -6) |
scrollFrame:SetPoint("BOTTOMRIGHT", scrollBG, "BOTTOMRIGHT", -4, 4) |
scrollFrame:SetScript("OnEnter", OnEnter) |
scrollFrame:SetScript("OnLeave", OnLeave) |
scrollFrame:SetScript("OnMouseUp", OnMouseUp) |
scrollFrame:SetScript("OnReceiveDrag", OnReceiveDrag) |
scrollFrame:SetScript("OnSizeChanged", OnSizeChanged) |
scrollFrame:HookScript("OnVerticalScroll", OnVerticalScroll) |
local editBox = CreateFrame("EditBox", nil, scrollFrame) |
editBox:SetAllPoints() |
editBox:SetFontObject(ChatFontNormal) |
editBox:SetMultiLine(true) |
editBox:EnableMouse(true) |
editBox:SetAutoFocus(false) |
editBox:SetCountInvisibleLetters(false) |
editBox:SetScript("OnCursorChanged", OnCursorChanged) |
editBox:SetScript("OnEditFocusLost", OnEditFocusLost) |
editBox:SetScript("OnEnter", OnEnter) |
editBox:SetScript("OnEscapePressed", editBox.ClearFocus) |
editBox:SetScript("OnLeave", OnLeave) |
editBox:SetScript("OnMouseDown", OnReceiveDrag) |
editBox:SetScript("OnReceiveDrag", OnReceiveDrag) |
editBox:SetScript("OnTextChanged", OnTextChanged) |
editBox:SetScript("OnTextSet", OnTextSet) |
scrollFrame:SetScrollChild(editBox) |
local widget = { |
button = button, |
editBox = editBox, |
frame = frame, |
label = label, |
labelHeight = 10, |
scrollBar = scrollBar, |
scrollFrame = scrollFrame, |
type = Type |
} |
for method, func in pairs(methods) do |
widget[method] = func |
end |
button.obj, editBox.obj, scrollFrame.obj = widget, widget, widget |
AceGUI:RegisterAsWidget(widget) |
return widget |
end |
AceGUI:RegisterWidgetType(Type, Constructor, Version) |
--[[----------------------------------------------------------------------------- |
TabGroup Container |
Container that uses tabs on top to switch between groups. |
-------------------------------------------------------------------------------]] |
local Type, Version = "TabGroup", 30 |
local AceGUI = LibStub and LibStub("AceGUI-3.0", true) |
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end |
-- Lua APIs |
local pairs, ipairs, assert, type, wipe = pairs, ipairs, assert, type, wipe |
-- WoW APIs |
local PlaySound = PlaySound |
local CreateFrame, UIParent = CreateFrame, UIParent |
local _G = _G |
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded |
-- List them here for Mikk's FindGlobals script |
-- GLOBALS: PanelTemplates_TabResize, PanelTemplates_SetDisabledTabState, PanelTemplates_SelectTab, PanelTemplates_DeselectTab |
-- local upvalue storage used by BuildTabs |
local widths = {} |
local rowwidths = {} |
local rowends = {} |
--[[----------------------------------------------------------------------------- |
Support functions |
-------------------------------------------------------------------------------]] |
local function UpdateTabLook(frame) |
if frame.disabled then |
PanelTemplates_SetDisabledTabState(frame) |
elseif frame.selected then |
PanelTemplates_SelectTab(frame) |
else |
PanelTemplates_DeselectTab(frame) |
end |
end |
local function Tab_SetText(frame, text) |
frame:_SetText(text) |
local width = frame.obj.frame.width or frame.obj.frame:GetWidth() or 0 |
PanelTemplates_TabResize(frame, 0, nil, width) |
end |
local function Tab_SetSelected(frame, selected) |
frame.selected = selected |
UpdateTabLook(frame) |
end |
local function Tab_SetDisabled(frame, disabled) |
frame.disabled = disabled |
UpdateTabLook(frame) |
end |
local function BuildTabsOnUpdate(frame) |
local self = frame.obj |
self:BuildTabs() |
frame:SetScript("OnUpdate", nil) |
end |
--[[----------------------------------------------------------------------------- |
Scripts |
-------------------------------------------------------------------------------]] |
local function Tab_OnClick(frame) |
if not (frame.selected or frame.disabled) then |
PlaySound("igCharacterInfoTab") |
frame.obj:SelectTab(frame.value) |
end |
end |
local function Tab_OnEnter(frame) |
local self = frame.obj |
self:Fire("OnTabEnter", self.tabs[frame.id].value, frame) |
end |
local function Tab_OnLeave(frame) |
local self = frame.obj |
self:Fire("OnTabLeave", self.tabs[frame.id].value, frame) |
end |
local function Tab_OnShow(frame) |
_G[frame:GetName().."HighlightTexture"]:SetWidth(frame:GetTextWidth() + 30) |
end |
--[[----------------------------------------------------------------------------- |
Methods |
-------------------------------------------------------------------------------]] |
local methods = { |
["OnAcquire"] = function(self) |
self:SetTitle() |
end, |
["OnRelease"] = function(self) |
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, |
["CreateTab"] = function(self, id) |
local tabname = ("AceGUITabGroup%dTab%d"):format(self.num, 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", 14, -3) |
tab.text:SetPoint("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, |
["SetTitle"] = function(self, text) |
self.titletext:SetText(text or "") |
if text and text ~= "" then |
self.alignoffset = 25 |
else |
self.alignoffset = 18 |
end |
self:BuildTabs() |
end, |
["SetStatusTable"] = function(self, status) |
assert(type(status) == "table") |
self.status = status |
end, |
["SelectTab"] = function(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, |
["SetTabs"] = function(self, tabs) |
self.tablist = tabs |
self:BuildTabs() |
end, |
["BuildTabs"] = function(self) |
local hastitle = (self.titletext:GetText() and self.titletext:GetText() ~= "") |
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 |
wipe(widths) |
wipe(rowwidths) |
wipe(rowends) |
--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, -(hastitle and 14 or 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 = (hastitle and 17 or 10)+((numrows)*20) |
self.border:SetPoint("TOPLEFT", 1, -self.borderoffset) |
end, |
["OnWidthSet"] = function(self, width) |
local content = self.content |
local contentwidth = width - 60 |
if contentwidth < 0 then |
contentwidth = 0 |
end |
content:SetWidth(contentwidth) |
content.width = contentwidth |
self:BuildTabs(self) |
self.frame:SetScript("OnUpdate", BuildTabsOnUpdate) |
end, |
["OnHeightSet"] = function(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, |
["LayoutFinished"] = function(self, width, height) |
if self.noAutoHeight then return end |
self:SetHeight((height or 0) + (self.borderoffset + 23)) |
end |
} |
--[[----------------------------------------------------------------------------- |
Constructor |
-------------------------------------------------------------------------------]] |
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 Constructor() |
local num = AceGUI:GetNextWidgetNum(Type) |
local frame = CreateFrame("Frame",nil,UIParent) |
frame:SetHeight(100) |
frame:SetWidth(100) |
frame:SetFrameStrata("FULLSCREEN_DIALOG") |
local titletext = frame:CreateFontString(nil,"OVERLAY","GameFontNormal") |
titletext:SetPoint("TOPLEFT", 14, 0) |
titletext:SetPoint("TOPRIGHT", -14, 0) |
titletext:SetJustifyH("LEFT") |
titletext:SetHeight(18) |
titletext:SetText("") |
local border = CreateFrame("Frame", nil, frame) |
border:SetPoint("TOPLEFT", 1, -27) |
border:SetPoint("BOTTOMRIGHT", -1, 3) |
border:SetBackdrop(PaneBackdrop) |
border:SetBackdropColor(0.1, 0.1, 0.1, 0.5) |
border:SetBackdropBorderColor(0.4, 0.4, 0.4) |
local content = CreateFrame("Frame", nil, border) |
content:SetPoint("TOPLEFT", 10, -7) |
content:SetPoint("BOTTOMRIGHT", -10, 7) |
local widget = { |
num = num, |
frame = frame, |
localstatus = {}, |
alignoffset = 18, |
titletext = titletext, |
border = border, |
borderoffset = 27, |
tabs = {}, |
content = content, |
type = Type |
} |
for method, func in pairs(methods) do |
widget[method] = func |
end |
return AceGUI:RegisterAsContainer(widget) |
end |
AceGUI:RegisterWidgetType(Type, Constructor, Version) |
--[[----------------------------------------------------------------------------- |
Slider Widget |
Graphical Slider, like, for Range values. |
-------------------------------------------------------------------------------]] |
local Type, Version = "Slider", 20 |
local AceGUI = LibStub and LibStub("AceGUI-3.0", true) |
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end |
-- Lua APIs |
local min, max, floor = math.min, math.max, math.floor |
local tonumber, pairs = tonumber, pairs |
-- WoW APIs |
local PlaySound = PlaySound |
local CreateFrame, UIParent = CreateFrame, UIParent |
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded |
-- List them here for Mikk's FindGlobals script |
-- GLOBALS: GameFontHighlightSmall |
--[[----------------------------------------------------------------------------- |
Support functions |
-------------------------------------------------------------------------------]] |
local function UpdateText(self) |
local value = self.value or 0 |
if self.ispercent then |
self.editbox:SetText(("%s%%"):format(floor(value * 1000 + 0.5) / 10)) |
else |
self.editbox:SetText(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 |
--[[----------------------------------------------------------------------------- |
Scripts |
-------------------------------------------------------------------------------]] |
local function Control_OnEnter(frame) |
frame.obj:Fire("OnEnter") |
end |
local function Control_OnLeave(frame) |
frame.obj:Fire("OnLeave") |
end |
local function Frame_OnMouseDown(frame) |
frame.obj.slider:EnableMouseWheel(true) |
AceGUI:ClearFocus() |
end |
local function Slider_OnValueChanged(frame) |
local self = frame.obj |
if not frame.setup then |
local newvalue = frame:GetValue() |
if newvalue ~= self.value and not self.disabled then |
self.value = newvalue |
self:Fire("OnValueChanged", newvalue) |
end |
if self.value then |
UpdateText(self) |
end |
end |
end |
local function Slider_OnMouseUp(frame) |
local self = frame.obj |
self:Fire("OnMouseUp", self.value) |
end |
local function Slider_OnMouseWheel(frame, v) |
local self = frame.obj |
if not self.disabled then |
local value = self.value |
if v > 0 then |
value = min(value + (self.step or 1), self.max) |
else |
value = max(value - (self.step or 1), self.min) |
end |
self.slider:SetValue(value) |
end |
end |
local function EditBox_OnEscapePressed(frame) |
frame:ClearFocus() |
end |
local function EditBox_OnEnterPressed(frame) |
local self = frame.obj |
local value = frame:GetText() |
if self.ispercent then |
value = value:gsub('%%', '') |
value = tonumber(value) / 100 |
else |
value = tonumber(value) |
end |
if value then |
PlaySound("igMainMenuOptionCheckBoxOn") |
self.slider:SetValue(value) |
self:Fire("OnMouseUp", value) |
end |
end |
local function EditBox_OnEnter(frame) |
frame:SetBackdropBorderColor(0.5, 0.5, 0.5, 1) |
end |
local function EditBox_OnLeave(frame) |
frame:SetBackdropBorderColor(0.3, 0.3, 0.3, 0.8) |
end |
--[[----------------------------------------------------------------------------- |
Methods |
-------------------------------------------------------------------------------]] |
local methods = { |
["OnAcquire"] = function(self) |
self:SetWidth(200) |
self:SetHeight(44) |
self:SetDisabled(false) |
self:SetIsPercent(nil) |
self:SetSliderValues(0,100,1) |
self:SetValue(0) |
self.slider:EnableMouseWheel(false) |
end, |
-- ["OnRelease"] = nil, |
["SetDisabled"] = function(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, |
["SetValue"] = function(self, value) |
self.slider.setup = true |
self.slider:SetValue(value) |
self.value = value |
UpdateText(self) |
self.slider.setup = nil |
end, |
["GetValue"] = function(self) |
return self.value |
end, |
["SetLabel"] = function(self, text) |
self.label:SetText(text) |
end, |
["SetSliderValues"] = function(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) |
if self.value then |
frame:SetValue(self.value) |
end |
frame.setup = nil |
end, |
["SetIsPercent"] = function(self, value) |
self.ispercent = value |
UpdateLabels(self) |
UpdateText(self) |
end |
} |
--[[----------------------------------------------------------------------------- |
Constructor |
-------------------------------------------------------------------------------]] |
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 ManualBackdrop = { |
bgFile = "Interface\\ChatFrame\\ChatFrameBackground", |
edgeFile = "Interface\\ChatFrame\\ChatFrameBackground", |
tile = true, edgeSize = 1, tileSize = 5, |
} |
local function Constructor() |
local frame = CreateFrame("Frame", nil, UIParent) |
frame:EnableMouse(true) |
frame:SetScript("OnMouseDown", Frame_OnMouseDown) |
local label = frame:CreateFontString(nil, "OVERLAY", "GameFontNormal") |
label:SetPoint("TOPLEFT") |
label:SetPoint("TOPRIGHT") |
label:SetJustifyH("CENTER") |
label:SetHeight(15) |
local slider = CreateFrame("Slider", nil, frame) |
slider:SetOrientation("HORIZONTAL") |
slider:SetHeight(15) |
slider:SetHitRectInsets(0, 0, -10, 0) |
slider:SetBackdrop(SliderBackdrop) |
slider:SetThumbTexture("Interface\\Buttons\\UI-SliderBar-Button-Horizontal") |
slider:SetPoint("TOP", label, "BOTTOM") |
slider:SetPoint("LEFT", 3, 0) |
slider:SetPoint("RIGHT", -3, 0) |
slider:SetValue(0) |
slider:SetScript("OnValueChanged",Slider_OnValueChanged) |
slider:SetScript("OnEnter", Control_OnEnter) |
slider:SetScript("OnLeave", Control_OnLeave) |
slider:SetScript("OnMouseUp", Slider_OnMouseUp) |
slider:SetScript("OnMouseWheel", Slider_OnMouseWheel) |
local lowtext = slider:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall") |
lowtext:SetPoint("TOPLEFT", slider, "BOTTOMLEFT", 2, 3) |
local hightext = slider:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall") |
hightext:SetPoint("TOPRIGHT", slider, "BOTTOMRIGHT", -2, 3) |
local editbox = CreateFrame("EditBox", nil, frame) |
editbox:SetAutoFocus(false) |
editbox:SetFontObject(GameFontHighlightSmall) |
editbox:SetPoint("TOP", slider, "BOTTOM") |
editbox:SetHeight(14) |
editbox:SetWidth(70) |
editbox:SetJustifyH("CENTER") |
editbox:EnableMouse(true) |
editbox:SetBackdrop(ManualBackdrop) |
editbox:SetBackdropColor(0, 0, 0, 0.5) |
editbox:SetBackdropBorderColor(0.3, 0.3, 0.30, 0.80) |
editbox:SetScript("OnEnter", EditBox_OnEnter) |
editbox:SetScript("OnLeave", EditBox_OnLeave) |
editbox:SetScript("OnEnterPressed", EditBox_OnEnterPressed) |
editbox:SetScript("OnEscapePressed", EditBox_OnEscapePressed) |
local widget = { |
label = label, |
slider = slider, |
lowtext = lowtext, |
hightext = hightext, |
editbox = editbox, |
alignoffset = 25, |
frame = frame, |
type = Type |
} |
for method, func in pairs(methods) do |
widget[method] = func |
end |
slider.obj, editbox.obj = widget, widget |
return AceGUI:RegisterAsWidget(widget) |
end |
AceGUI:RegisterWidgetType(Type,Constructor,Version) |
--[[----------------------------------------------------------------------------- |
Keybinding Widget |
Set Keybindings in the Config UI. |
-------------------------------------------------------------------------------]] |
local Type, Version = "Keybinding", 21 |
local AceGUI = LibStub and LibStub("AceGUI-3.0", true) |
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end |
-- Lua APIs |
local pairs = pairs |
-- WoW APIs |
local IsShiftKeyDown, IsControlKeyDown, IsAltKeyDown = IsShiftKeyDown, IsControlKeyDown, IsAltKeyDown |
local CreateFrame, UIParent = CreateFrame, UIParent |
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded |
-- List them here for Mikk's FindGlobals script |
-- GLOBALS: NOT_BOUND |
--[[----------------------------------------------------------------------------- |
Scripts |
-------------------------------------------------------------------------------]] |
local function Control_OnEnter(frame) |
frame.obj:Fire("OnEnter") |
end |
local function Control_OnLeave(frame) |
frame.obj:Fire("OnLeave") |
end |
local function Keybinding_OnClick(frame, button) |
if button == "LeftButton" or button == "RightButton" then |
local self = frame.obj |
if self.waitingForKey then |
frame:EnableKeyboard(false) |
self.msgframe:Hide() |
frame:UnlockHighlight() |
self.waitingForKey = nil |
else |
frame:EnableKeyboard(true) |
self.msgframe:Show() |
frame:LockHighlight() |
self.waitingForKey = true |
end |
end |
AceGUI:ClearFocus() |
end |
local ignoreKeys = { |
["BUTTON1"] = true, ["BUTTON2"] = true, |
["UNKNOWN"] = true, |
["LSHIFT"] = true, ["LCTRL"] = true, ["LALT"] = true, |
["RSHIFT"] = true, ["RCTRL"] = true, ["RALT"] = true, |
} |
local function Keybinding_OnKeyDown(frame, key) |
local self = frame.obj |
if self.waitingForKey then |
local keyPressed = key |
if keyPressed == "ESCAPE" then |
keyPressed = "" |
else |
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 |
frame:EnableKeyboard(false) |
self.msgframe:Hide() |
frame:UnlockHighlight() |
self.waitingForKey = nil |
if not self.disabled then |
self:SetKey(keyPressed) |
self:Fire("OnKeyChanged", keyPressed) |
end |
end |
end |
local function Keybinding_OnMouseDown(frame, 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(frame, button) |
end |
--[[----------------------------------------------------------------------------- |
Methods |
-------------------------------------------------------------------------------]] |
local methods = { |
["OnAcquire"] = function(self) |
self:SetWidth(200) |
self:SetLabel("") |
self:SetKey("") |
self.waitingForKey = nil |
self.msgframe:Hide() |
self:SetDisabled(false) |
end, |
-- ["OnRelease"] = nil, |
["SetDisabled"] = function(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, |
["SetKey"] = function(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, |
["GetKey"] = function(self) |
local key = self.button:GetText() |
if key == NOT_BOUND then |
key = nil |
end |
return key |
end, |
["SetLabel"] = function(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, |
} |
--[[----------------------------------------------------------------------------- |
Constructor |
-------------------------------------------------------------------------------]] |
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 keybindingMsgFixWidth(frame) |
frame:SetWidth(frame.msg:GetWidth() + 10) |
frame:SetScript("OnUpdate", nil) |
end |
local function Constructor() |
local name = "AceGUI30KeybindingButton" .. AceGUI:GetNextWidgetNum(Type) |
local frame = CreateFrame("Frame", nil, UIParent) |
local button = CreateFrame("Button", name, frame, "UIPanelButtonTemplate2") |
button:EnableMouse(true) |
button:RegisterForClicks("AnyDown") |
button:SetScript("OnEnter", Control_OnEnter) |
button:SetScript("OnLeave", Control_OnLeave) |
button:SetScript("OnClick", Keybinding_OnClick) |
button:SetScript("OnKeyDown", Keybinding_OnKeyDown) |
button:SetScript("OnMouseDown", Keybinding_OnMouseDown) |
button:SetPoint("BOTTOMLEFT") |
button:SetPoint("BOTTOMRIGHT") |
button:SetHeight(24) |
local text = button:GetFontString() |
text:SetPoint("LEFT", 7, 0) |
text:SetPoint("RIGHT", -7, 0) |
local label = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlight") |
label:SetPoint("TOPLEFT") |
label:SetPoint("TOPRIGHT") |
label:SetJustifyH("CENTER") |
label:SetHeight(18) |
local msgframe = CreateFrame("Frame", nil, UIParent) |
msgframe:SetHeight(30) |
msgframe:SetBackdrop(ControlBackdrop) |
msgframe:SetBackdropColor(0,0,0) |
msgframe:SetFrameStrata("FULLSCREEN_DIALOG") |
msgframe:SetFrameLevel(1000) |
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", 5, -5) |
msgframe:SetScript("OnUpdate", keybindingMsgFixWidth) |
msgframe:SetPoint("BOTTOM", button, "TOP") |
msgframe:Hide() |
local widget = { |
button = button, |
label = label, |
msgframe = msgframe, |
frame = frame, |
alignoffset = 30, |
type = Type |
} |
for method, func in pairs(methods) do |
widget[method] = func |
end |
button.obj = widget |
return AceGUI:RegisterAsWidget(widget) |
end |
AceGUI:RegisterWidgetType(Type, Constructor, Version) |
--[[----------------------------------------------------------------------------- |
Checkbox Widget |
-------------------------------------------------------------------------------]] |
local Type, Version = "CheckBox", 21 |
local AceGUI = LibStub and LibStub("AceGUI-3.0", true) |
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end |
-- Lua APIs |
local select, pairs = select, pairs |
-- WoW APIs |
local PlaySound = PlaySound |
local CreateFrame, UIParent = CreateFrame, UIParent |
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded |
-- List them here for Mikk's FindGlobals script |
-- GLOBALS: SetDesaturation, GameFontHighlight |
--[[----------------------------------------------------------------------------- |
Support functions |
-------------------------------------------------------------------------------]] |
local function AlignImage(self) |
local img = self.image:GetTexture() |
self.text:ClearAllPoints() |
if not img then |
self.text:SetPoint("LEFT", self.checkbg, "RIGHT") |
self.text:SetPoint("RIGHT") |
else |
self.text:SetPoint("LEFT", self.image,"RIGHT", 1, 0) |
self.text:SetPoint("RIGHT") |
end |
end |
--[[----------------------------------------------------------------------------- |
Scripts |
-------------------------------------------------------------------------------]] |
local function Control_OnEnter(frame) |
frame.obj:Fire("OnEnter") |
end |
local function Control_OnLeave(frame) |
frame.obj:Fire("OnLeave") |
end |
local function CheckBox_OnMouseDown(frame) |
local self = frame.obj |
if not self.disabled then |
if self.image:GetTexture() then |
self.text:SetPoint("LEFT", self.image,"RIGHT", 2, -1) |
else |
self.text:SetPoint("LEFT", self.checkbg, "RIGHT", 1, -1) |
end |
end |
AceGUI:ClearFocus() |
end |
local function CheckBox_OnMouseUp(frame) |
local self = frame.obj |
if not self.disabled then |
self:ToggleChecked() |
if self.checked then |
PlaySound("igMainMenuOptionCheckBoxOn") |
else -- for both nil and false (tristate) |
PlaySound("igMainMenuOptionCheckBoxOff") |
end |
self:Fire("OnValueChanged", self.checked) |
AlignImage(self) |
end |
end |
--[[----------------------------------------------------------------------------- |
Methods |
-------------------------------------------------------------------------------]] |
local methods = { |
["OnAcquire"] = function(self) |
self:SetType() |
self:SetValue(false) |
self:SetTriState(nil) |
-- height is calculated from the width and required space for the description |
self:SetWidth(200) |
self:SetImage() |
self:SetDisabled(nil) |
self:SetDescription(nil) |
end, |
-- ["OnRelease"] = nil, |
["OnWidthSet"] = function(self, width) |
if self.desc then |
self.desc:SetWidth(width - 30) |
if self.desc:GetText() and self.desc:GetText() ~= "" then |
self:SetHeight(28 + self.desc:GetHeight()) |
end |
end |
end, |
["SetDisabled"] = function(self, disabled) |
self.disabled = disabled |
if disabled then |
self.frame:Disable() |
self.text:SetTextColor(0.5, 0.5, 0.5) |
SetDesaturation(self.check, true) |
else |
self.frame:Enable() |
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, |
["SetValue"] = function(self,value) |
local check = self.check |
self.checked = value |
if value then |
SetDesaturation(self.check, false) |
self.check:Show() |
else |
--Nil is the unknown tristate value |
if self.tristate and value == nil then |
SetDesaturation(self.check, true) |
self.check:Show() |
else |
SetDesaturation(self.check, false) |
self.check:Hide() |
end |
end |
self:SetDisabled(self.disabled) |
end, |
["GetValue"] = function(self) |
return self.checked |
end, |
["SetTriState"] = function(self, enabled) |
self.tristate = enabled |
self:SetValue(self:GetValue()) |
end, |
["SetType"] = function(self, type) |
local checkbg = self.checkbg |
local check = self.check |
local highlight = self.highlight |
local size |
if type == "radio" then |
size = 16 |
checkbg:SetTexture("Interface\\Buttons\\UI-RadioButton") |
checkbg:SetTexCoord(0, 0.25, 0, 1) |
check:SetTexture("Interface\\Buttons\\UI-RadioButton") |
check:SetTexCoord(0.25, 0.5, 0, 1) |
check:SetBlendMode("ADD") |
highlight:SetTexture("Interface\\Buttons\\UI-RadioButton") |
highlight:SetTexCoord(0.5, 0.75, 0, 1) |
else |
size = 24 |
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 |
checkbg:SetHeight(size) |
checkbg:SetWidth(size) |
end, |
["ToggleChecked"] = function(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, |
["SetLabel"] = function(self, label) |
self.text:SetText(label) |
end, |
["SetDescription"] = function(self, desc) |
if desc then |
if not self.desc then |
local desc = self.frame:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall") |
desc:ClearAllPoints() |
desc:SetPoint("TOPLEFT", self.checkbg, "TOPRIGHT", 5, -21) |
desc:SetWidth(self.frame.width - 30) |
desc:SetJustifyH("LEFT") |
desc:SetJustifyV("TOP") |
self.desc = desc |
end |
self.desc:Show() |
--self.text:SetFontObject(GameFontNormal) |
self.desc:SetText(desc) |
self:SetHeight(28 + self.desc:GetHeight()) |
else |
if self.desc then |
self.desc:SetText("") |
self.desc:Hide() |
end |
--self.text:SetFontObject(GameFontHighlight) |
self:SetHeight(24) |
end |
end, |
["SetImage"] = function(self, path, ...) |
local image = self.image |
image:SetTexture(path) |
if image:GetTexture() then |
local n = select("#", ...) |
if n == 4 or n == 8 then |
image:SetTexCoord(...) |
else |
image:SetTexCoord(0, 1, 0, 1) |
end |
end |
AlignImage(self) |
end |
} |
--[[----------------------------------------------------------------------------- |
Constructor |
-------------------------------------------------------------------------------]] |
local function Constructor() |
local frame = CreateFrame("Button", nil, UIParent) |
frame:Hide() |
frame:EnableMouse(true) |
frame:SetScript("OnEnter", Control_OnEnter) |
frame:SetScript("OnLeave", Control_OnLeave) |
frame:SetScript("OnMouseDown", CheckBox_OnMouseDown) |
frame:SetScript("OnMouseUp", CheckBox_OnMouseUp) |
local checkbg = frame:CreateTexture(nil, "ARTWORK") |
checkbg:SetWidth(24) |
checkbg:SetHeight(24) |
checkbg:SetPoint("TOPLEFT") |
checkbg:SetTexture("Interface\\Buttons\\UI-CheckBox-Up") |
local check = frame:CreateTexture(nil, "OVERLAY") |
check:SetAllPoints(checkbg) |
check:SetTexture("Interface\\Buttons\\UI-CheckBox-Check") |
local text = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlight") |
text:SetJustifyH("LEFT") |
text:SetHeight(18) |
text:SetPoint("LEFT", checkbg, "RIGHT") |
text:SetPoint("RIGHT") |
local highlight = frame:CreateTexture(nil, "HIGHLIGHT") |
highlight:SetTexture("Interface\\Buttons\\UI-CheckBox-Highlight") |
highlight:SetBlendMode("ADD") |
highlight:SetAllPoints(checkbg) |
local image = frame:CreateTexture(nil, "OVERLAY") |
image:SetHeight(16) |
image:SetWidth(16) |
image:SetPoint("LEFT", checkbg, "RIGHT", 1, 0) |
local widget = { |
checkbg = checkbg, |
check = check, |
text = text, |
highlight = highlight, |
image = image, |
frame = frame, |
type = Type |
} |
for method, func in pairs(methods) do |
widget[method] = func |
end |
return AceGUI:RegisterAsWidget(widget) |
end |
AceGUI:RegisterWidgetType(Type, Constructor, Version) |
--[[----------------------------------------------------------------------------- |
Icon Widget |
-------------------------------------------------------------------------------]] |
local Type, Version = "Icon", 20 |
local AceGUI = LibStub and LibStub("AceGUI-3.0", true) |
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end |
-- Lua APIs |
local select, pairs, print = select, pairs, print |
-- WoW APIs |
local CreateFrame, UIParent, GetBuildInfo = CreateFrame, UIParent, GetBuildInfo |
--[[----------------------------------------------------------------------------- |
Scripts |
-------------------------------------------------------------------------------]] |
local function Control_OnEnter(frame) |
frame.obj:Fire("OnEnter") |
end |
local function Control_OnLeave(frame) |
frame.obj:Fire("OnLeave") |
end |
local function Button_OnClick(frame, button) |
frame.obj:Fire("OnClick", button) |
AceGUI:ClearFocus() |
end |
--[[----------------------------------------------------------------------------- |
Methods |
-------------------------------------------------------------------------------]] |
local methods = { |
["OnAcquire"] = function(self) |
self:SetHeight(110) |
self:SetWidth(110) |
self:SetLabel() |
self:SetImage(nil) |
self:SetImageSize(64, 64) |
self:SetDisabled(false) |
end, |
-- ["OnRelease"] = nil, |
["SetLabel"] = function(self, text) |
if text and text ~= "" then |
self.label:Show() |
self.label:SetText(text) |
self:SetHeight(self.image:GetHeight() + 25) |
else |
self.label:Hide() |
self:SetHeight(self.image:GetHeight() + 10) |
end |
end, |
["SetImage"] = function(self, path, ...) |
local image = self.image |
image:SetTexture(path) |
if image:GetTexture() then |
local n = select("#", ...) |
if n == 4 or n == 8 then |
image:SetTexCoord(...) |
else |
image:SetTexCoord(0, 1, 0, 1) |
end |
end |
end, |
["SetImageSize"] = function(self, width, height) |
self.image:SetWidth(width) |
self.image:SetHeight(height) |
--self.frame:SetWidth(width + 30) |
if self.label:IsShown() then |
self:SetHeight(height + 25) |
else |
self:SetHeight(height + 10) |
end |
end, |
["SetDisabled"] = function(self, disabled) |
self.disabled = disabled |
if disabled then |
self.frame:Disable() |
self.label:SetTextColor(0.5, 0.5, 0.5) |
self.image:SetVertexColor(0.5, 0.5, 0.5, 0.5) |
else |
self.frame:Enable() |
self.label:SetTextColor(1, 1, 1) |
self.image:SetVertexColor(1, 1, 1) |
end |
end |
} |
--[[----------------------------------------------------------------------------- |
Constructor |
-------------------------------------------------------------------------------]] |
local function Constructor() |
local frame = CreateFrame("Button", nil, UIParent) |
frame:Hide() |
frame:EnableMouse(true) |
frame:SetScript("OnEnter", Control_OnEnter) |
frame:SetScript("OnLeave", Control_OnLeave) |
frame:SetScript("OnClick", Button_OnClick) |
local label = frame:CreateFontString(nil, "BACKGROUND", "GameFontHighlight") |
label:SetPoint("BOTTOMLEFT") |
label:SetPoint("BOTTOMRIGHT") |
label:SetJustifyH("CENTER") |
label:SetJustifyV("TOP") |
label:SetHeight(18) |
local image = frame:CreateTexture(nil, "BACKGROUND") |
image:SetWidth(64) |
image:SetHeight(64) |
image:SetPoint("TOP", 0, -5) |
local highlight = frame:CreateTexture(nil, "HIGHLIGHT") |
highlight:SetAllPoints(image) |
highlight:SetTexture("Interface\\PaperDollInfoFrame\\UI-Character-Tab-Highlight") |
highlight:SetTexCoord(0, 1, 0.23, 0.77) |
highlight:SetBlendMode("ADD") |
local widget = { |
label = label, |
image = image, |
frame = frame, |
type = Type |
} |
for method, func in pairs(methods) do |
widget[method] = func |
end |
-- SetText is deprecated, but keep it around for a while. (say, to WoW 4.0) |
if (select(4, GetBuildInfo()) < 40000) then |
widget.SetText = widget.SetLabel |
else |
widget.SetText = function(self, ...) print("AceGUI-3.0-Icon: SetText is deprecated! Use SetLabel instead!"); self:SetLabel(...) end |
end |
return AceGUI:RegisterAsWidget(widget) |
end |
AceGUI:RegisterWidgetType(Type, Constructor, Version) |
--[[----------------------------------------------------------------------------- |
BlizOptionsGroup Container |
Simple container widget for the integration of AceGUI into the Blizzard Interface Options |
-------------------------------------------------------------------------------]] |
local Type, Version = "BlizOptionsGroup", 20 |
local AceGUI = LibStub and LibStub("AceGUI-3.0", true) |
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end |
-- Lua APIs |
local pairs = pairs |
-- WoW APIs |
local CreateFrame = CreateFrame |
--[[----------------------------------------------------------------------------- |
Scripts |
-------------------------------------------------------------------------------]] |
local function OnShow(frame) |
frame.obj:Fire("OnShow") |
end |
local function OnHide(frame) |
frame.obj:Fire("OnHide") |
end |
--[[----------------------------------------------------------------------------- |
Support functions |
-------------------------------------------------------------------------------]] |
local function okay(frame) |
frame.obj:Fire("okay") |
end |
local function cancel(frame) |
frame.obj:Fire("cancel") |
end |
local function defaults(frame) |
frame.obj:Fire("defaults") |
end |
--[[----------------------------------------------------------------------------- |
Methods |
-------------------------------------------------------------------------------]] |
local methods = { |
["OnAcquire"] = function(self) |
self:SetName() |
self:SetTitle() |
end, |
-- ["OnRelease"] = nil, |
["OnWidthSet"] = function(self, width) |
local content = self.content |
local contentwidth = width - 63 |
if contentwidth < 0 then |
contentwidth = 0 |
end |
content:SetWidth(contentwidth) |
content.width = contentwidth |
end, |
["OnHeightSet"] = function(self, height) |
local content = self.content |
local contentheight = height - 26 |
if contentheight < 0 then |
contentheight = 0 |
end |
content:SetHeight(contentheight) |
content.height = contentheight |
end, |
["SetName"] = function(self, name, parent) |
self.frame.name = name |
self.frame.parent = parent |
end, |
["SetTitle"] = function(self, title) |
local content = self.content |
content:ClearAllPoints() |
if not title or title == "" then |
content:SetPoint("TOPLEFT", 10, -10) |
self.label:SetText("") |
else |
content:SetPoint("TOPLEFT", 10, -40) |
self.label:SetText(title) |
end |
content:SetPoint("BOTTOMRIGHT", -10, 10) |
end |
} |
--[[----------------------------------------------------------------------------- |
Constructor |
-------------------------------------------------------------------------------]] |
local function Constructor() |
local frame = CreateFrame("Frame") |
frame:Hide() |
-- support functions for the Blizzard Interface Options |
frame.okay = okay |
frame.cancel = cancel |
frame.defaults = defaults |
frame:SetScript("OnHide", OnHide) |
frame:SetScript("OnShow", OnShow) |
local label = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge") |
label:SetPoint("TOPLEFT", 10, -15) |
label:SetPoint("BOTTOMRIGHT", frame, "TOPRIGHT", 10, -45) |
label:SetJustifyH("LEFT") |
label:SetJustifyV("TOP") |
--Container Support |
local content = CreateFrame("Frame", nil, frame) |
content:SetPoint("TOPLEFT", 10, -10) |
content:SetPoint("BOTTOMRIGHT", -10, 10) |
local widget = { |
label = label, |
frame = frame, |
content = content, |
type = Type |
} |
for method, func in pairs(methods) do |
widget[method] = func |
end |
return AceGUI:RegisterAsContainer(widget) |
end |
AceGUI:RegisterWidgetType(Type, Constructor, Version) |
<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"/> |
<!-- Container --> |
<Script file="widgets\AceGUIContainer-BlizOptionsGroup.lua"/> |
<Script file="widgets\AceGUIContainer-DropDownGroup.lua"/> |
<Script file="widgets\AceGUIContainer-Frame.lua"/> |
<Script file="widgets\AceGUIContainer-InlineGroup.lua"/> |
<Script file="widgets\AceGUIContainer-ScrollFrame.lua"/> |
<Script file="widgets\AceGUIContainer-SimpleGroup.lua"/> |
<Script file="widgets\AceGUIContainer-TabGroup.lua"/> |
<Script file="widgets\AceGUIContainer-TreeGroup.lua"/> |
<Script file="widgets\AceGUIContainer-Window.lua"/> |
<!-- Widgets --> |
<Script file="widgets\AceGUIWidget-Button.lua"/> |
<Script file="widgets\AceGUIWidget-CheckBox.lua"/> |
<Script file="widgets\AceGUIWidget-ColorPicker.lua"/> |
<Script file="widgets\AceGUIWidget-DropDown.lua"/> |
<Script file="widgets\AceGUIWidget-DropDown-Items.lua"/> |
<Script file="widgets\AceGUIWidget-EditBox.lua"/> |
<Script file="widgets\AceGUIWidget-Heading.lua"/> |
<Script file="widgets\AceGUIWidget-Icon.lua"/> |
<Script file="widgets\AceGUIWidget-InteractiveLabel.lua"/> |
<Script file="widgets\AceGUIWidget-Keybinding.lua"/> |
<Script file="widgets\AceGUIWidget-Label.lua"/> |
<Script file="widgets\AceGUIWidget-MultiLineEditBox.lua"/> |
<Script file="widgets\AceGUIWidget-Slider.lua"/> |
</Ui> |
--- **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 924 2010-05-13 15:12:20Z nevcairiel $ |
local ACEGUI_MAJOR, ACEGUI_MINOR = "AceGUI-3.0", 33 |
local AceGUI, oldminor = LibStub:NewLibrary(ACEGUI_MAJOR, ACEGUI_MINOR) |
if not AceGUI then return end -- No upgrade needed |
-- Lua APIs |
local tconcat, tremove, tinsert = table.concat, table.remove, table.insert |
local select, pairs, next, type = select, pairs, next, type |
local error, assert, loadstring = error, assert, loadstring |
local setmetatable, rawget, rawset = setmetatable, rawget, rawset |
local math_max = math.max |
-- WoW APIs |
local UIParent = UIParent |
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded |
-- List them here for Mikk's FindGlobals script |
-- GLOBALS: geterrorhandler, LibStub |
--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 |
--[[ |
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, ...) |
return Dispatchers[select("#", ...)](func, ...) |
end |
-- Recycling functions |
local newWidget, delWidget |
do |
-- Version Upgrade in Minor 29 |
-- Internal Storage of the objects changed, from an array table |
-- to a hash table, and additionally we introduced versioning on |
-- the widgets which would discard all widgets from a pre-29 version |
-- anyway, so we just clear the storage now, and don't try to |
-- convert the storage tables to the new format. |
-- This should generally not cause *many* widgets to end up in trash, |
-- since once dialogs are opened, all addons should be loaded already |
-- and AceGUI should be on the latest version available on the users |
-- setup. |
-- -- nevcairiel - Nov 2nd, 2009 |
if oldminor and oldminor < 29 and AceGUI.objPools then |
AceGUI.objPools = nil |
end |
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 newWidget(type) |
if not WidgetRegistry[type] then |
error("Attempt to instantiate unknown widget type", 2) |
end |
if not objPools[type] then |
objPools[type] = {} |
end |
local newObj = next(objPools[type]) |
if not newObj then |
newObj = WidgetRegistry[type]() |
newObj.AceGUIWidgetVersion = WidgetVersions[type] |
else |
objPools[type][newObj] = nil |
-- if the widget is older then the latest, don't even try to reuse it |
-- just forget about it, and grab a new one. |
if not newObj.AceGUIWidgetVersion or newObj.AceGUIWidgetVersion < WidgetVersions[type] then |
return newWidget(type) |
end |
end |
return newObj |
end |
-- Releases an instance to the Pool |
function delWidget(obj,type) |
if not objPools[type] then |
objPools[type] = {} |
end |
if objPools[type][obj] then |
error("Attempt to Release Widget that is already released", 2) |
end |
objPools[type][obj] = true |
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) |
if WidgetRegistry[type] then |
local widget = newWidget(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(widget.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(UIParent) |
widget.frame.width = nil |
widget.frame.height = nil |
if widget.content then |
widget.content.width = nil |
widget.content.height = nil |
end |
delWidget(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 |
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 |
:OnRelease() - Called when the object is Released, should remove any additional anchors and clear any data |
: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 |
:LayoutFinished(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 WidgetBase = AceGUI.WidgetBase |
WidgetBase.SetParent = function(self, parent) |
local frame = self.frame |
frame:SetParent(nil) |
frame:SetParent(parent.content) |
self.parent = parent |
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 = 1,#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") |
return widget |
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}) |
return widget |
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 |
--- Return the number of created widgets for this type. |
-- In contrast to GetNextWidgetNum, the number is not incremented. |
-- @param type The widget type |
function AceGUI:GetWidgetCount(type) |
return self.counts[type] or 0 |
end |
--- Return the version of the currently registered widget type. |
-- @param type The widget type |
function AceGUI:GetWidgetVersion(type) |
return WidgetVersions[type] |
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 = 1, #children do |
local child = children[i] |
local frame = child.frame |
frame:ClearAllPoints() |
frame:Show() |
if i == 1 then |
frame:SetPoint("TOPLEFT", content) |
else |
frame:SetPoint("TOPLEFT", children[i-1].frame, "BOTTOMLEFT") |
end |
if child.width == "fill" then |
child:SetWidth(width) |
frame:SetPoint("RIGHT", content) |
if child.DoLayout then |
child:DoLayout() |
end |
elseif child.width == "relative" then |
child:SetWidth(width * child.relWidth) |
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 = 1, #children do |
local child = children[i] |
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 |
-- HACK: Why did we set a frameoffset of (frameheight / 2) ? |
-- That was moving all widgets half the widgets size down, is that intended? |
-- Actually, it seems to be neccessary for many cases, we'll leave it in for now. |
-- If widgets seem to anchor weirdly with this, provide a valid alignoffset for them. |
-- TODO: Investigate moar! |
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) |
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 |
if isfullheight then |
-- a previous row has already filled the entire height, there's nothing we can usefully do anymore |
-- (maybe error/warn about this?) |
break |
end |
--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) |
usedwidth = 0 |
rowstart = frame |
rowstartoffset = frameoffset |
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.DoLayout then |
child:DoLayout() |
end |
elseif oversize then |
if width > 1 then |
frame:SetPoint("RIGHT", content) |
end |
end |
if child.height == "fill" then |
frame:SetPoint("BOTTOM", content) |
isfullheight = true |
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) |
<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> |
--- 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 877 2009-11-02 15:56:50Z 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") |
-- Lua APIs |
local pcall, error, type, pairs = pcall, error, type, pairs |
-- ------------------------------------------------------------------- |
-- :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 |
<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> |
--- 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 958 2010-07-03 10:22:29Z nevcairiel $ |
local LibStub = LibStub |
local MAJOR, MINOR = "AceConfigDialog-3.0", 49 |
local AceConfigDialog, oldminor = 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 {} |
AceConfigDialog.frame.closeAllOverride = AceConfigDialog.frame.closeAllOverride or {} |
local gui = LibStub("AceGUI-3.0") |
local reg = LibStub("AceConfigRegistry-3.0") |
-- Lua APIs |
local tconcat, tinsert, tsort, tremove = table.concat, table.insert, table.sort, table.remove |
local strmatch, format = string.match, string.format |
local assert, loadstring, error = assert, loadstring, error |
local pairs, next, select, type, unpack, wipe = pairs, next, select, type, unpack, wipe |
local rawset, tostring, tonumber = rawset, tostring, tonumber |
local math_min, math_max, math_floor = math.min, math.max, math.floor |
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded |
-- List them here for Mikk's FindGlobals script |
-- GLOBALS: NORMAL_FONT_COLOR, GameTooltip, StaticPopupDialogs, ACCEPT, CANCEL, StaticPopup_Show |
-- GLOBALS: PlaySound, GameFontHighlight, GameFontHighlightSmall, GameFontHighlightLarge |
-- GLOBALS: CloseSpecialWindows, InterfaceOptions_AddCategory, geterrorhandler |
local emptyTbl = {} |
--[[ |
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, ...) |
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, |
descStyle = 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(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 |
tsort(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) |
local descStyle = opt.descStyle |
if descStyle and descStyle ~= "tooltip" then return end |
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, unpack(basepath or emptyTbl)) |
del(info) |
end |
t.OnCancel = function() |
if dialog and oldstrata then |
dialog:SetFrameStrata(oldstrata) |
end |
AceConfigDialog:Open(appName, rootframe, unpack(basepath or emptyTbl)) |
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(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) |
else |
-- TODO: do something else. |
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 |
else |
-- TODO: do something else |
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(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(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(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") or emptyTbl |
--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, unpack(basepath)) |
else |
AceConfigDialog:Open(user.appName, unpack(basepath)) |
end |
end |
elseif option.type == "range" then |
if event == "OnMouseUp" then |
if iscustom then |
AceConfigDialog:Open(user.appName, user.rootframe, unpack(basepath)) |
else |
AceConfigDialog:Open(user.appName, 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, unpack(basepath)) |
else |
AceConfigDialog:Open(user.appName, 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 (not option.softMin and 0 or nil), option.max or (not option.softMax and 100 or nil), option.step |
if min then |
if step then |
value = math_floor((value - min) / step + 0.5) * step + min |
end |
value = math_max(value, min) |
end |
if max then |
value = math_min(value, max) |
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") or emptyTbl |
if iscustom then |
AceConfigDialog:Open(user.appName, user.rootframe, unpack(basepath)) |
else |
AceConfigDialog:Open(user.appName, 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") or emptyTbl |
if iscustom then |
AceConfigDialog:Open(user.appName, user.rootframe, unpack(basepath)) |
else |
AceConfigDialog:Open(user.appName, 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.iconCoords = GetOptionsMemberValue("iconCoords", 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 |
geterrorhandler()(("Invalid Custom Control Type - %s"):format(tostring(controlType))) |
control = gui:Create(v.multiline and "MultiLineEditBox" or "EditBox") |
end |
if v.multiline and control.SetNumLines then |
control:SetNumLines(tonumber(v.multiline) or 4) |
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) |
if v.descStyle == "inline" then |
local desc = GetOptionsMemberValue("desc", v, options, path, appName) |
control:SetDescription(desc) |
end |
local image = GetOptionsMemberValue("image", v, options, path, appName) |
local imageCoords = GetOptionsMemberValue("imageCoords", v, options, path, appName) |
if type(image) == "string" then |
if type(imageCoords) == "table" then |
control:SetImage(image, unpack(imageCoords)) |
else |
control:SetImage(image) |
end |
end |
elseif v.type == "range" then |
control = gui:Create("Slider") |
control:SetLabel(name) |
control:SetSliderValues(v.softMin or v.min or 0, v.softMax or 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 |
geterrorhandler()(("Invalid Custom Control Type - %s"):format(tostring(controlType))) |
control = gui:Create("Dropdown") |
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 |
tsort(valuesort) |
if controlType then |
control = gui:Create(controlType) |
if not control then |
geterrorhandler()(("Invalid Custom Control Type - %s"):format(tostring(controlType))) |
end |
end |
if control then |
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, ("\001"):split(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, ("\001"):split(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, ("\001"):split(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" |
for i = 1, #path do |
local v = path[i] |
group = GetSubOption(group, v) |
inline = inline or pickfirstset(v.dialogInline,v.guiInline,v.inline, false) |
parenttype = grouptype |
grouptype = group.childGroups |
end |
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" and container.type ~= "SimpleGroup" 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 |
local name = GetOptionsMemberValue("name", group, options, path, appName) |
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") |
select:SetTitle(name) |
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 |
for key, widget in pairs(AceConfigDialog.BlizOptions[appName]) do |
if not widget:IsVisible() then |
widget:ReleaseChildren() |
end |
end |
end |
this.closing[appName] = nil |
end |
if this.closeAll then |
for k, v in pairs(AceConfigDialog.OpenFrames) do |
if not this.closeAllOverride[k] then |
v:Hide() |
end |
end |
this.closeAll = nil |
wipe(this.closeAllOverride) |
end |
for appName in pairs(this.apps) do |
if AceConfigDialog.OpenFrames[appName] then |
local user = AceConfigDialog.OpenFrames[appName]:GetUserDataTable() |
AceConfigDialog:Open(appName, unpack(user.basepath or emptyTbl)) |
end |
if AceConfigDialog.BlizOptions and AceConfigDialog.BlizOptions[appName] then |
for key, widget in pairs(AceConfigDialog.BlizOptions[appName]) do |
local user = widget:GetUserDataTable() |
if widget:IsVisible() then |
AceConfigDialog:Open(widget:GetUserData("appName"), widget, unpack(user.basepath or emptyTbl)) |
end |
end |
end |
this.apps[appName] = nil |
end |
this:SetScript("OnUpdate", nil) |
end |
-- Upgrade the OnUpdate script as well, if needed. |
if AceConfigDialog.frame:GetScript("OnUpdate") then |
AceConfigDialog.frame:SetScript("OnUpdate", RefreshOnUpdate) |
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 |
if f.SetTitle then |
f:SetTitle(name or "") |
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) |
if AceConfigDialog.frame.closeAll then |
-- close all is set, but thats not good, since we're just opening here, so force it |
AceConfigDialog.frame.closeAllOverride[appName] = true |
end |
end |
-- convert pre-39 BlizOptions structure to the new format |
if oldminor and oldminor < 39 and AceConfigDialog.BlizOptions then |
local old = AceConfigDialog.BlizOptions |
local new = {} |
for key, widget in pairs(old) do |
local appName = widget:GetUserData("appName") |
if not new[appName] then new[appName] = {} end |
new[appName][key] = widget |
end |
AceConfigDialog.BlizOptions = new |
else |
AceConfigDialog.BlizOptions = AceConfigDialog.BlizOptions or {} |
end |
local function FeedToBlizPanel(widget, event) |
local path = widget:GetUserData("path") |
AceConfigDialog:Open(widget:GetUserData("appName"), widget, unpack(path or emptyTbl)) |
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[appName] then |
BlizOptions[appName] = {} |
end |
if not BlizOptions[appName][key] then |
local group = gui:Create("BlizOptionsGroup") |
BlizOptions[appName][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 |
<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> |
--- 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 904 2009-12-13 11:56:37Z nevcairiel $ |
--[[ |
AceConfigCmd-3.0 |
Handles commandline optionstable access |
REQUIRES: AceConsole-3.0 for command registration (loaded on demand) |
]] |
-- TODO: plugin args |
local MAJOR, MINOR = "AceConfigCmd-3.0", 12 |
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" |
-- Lua APIs |
local strsub, strsplit, strlower, strmatch, strtrim = string.sub, string.split, string.lower, string.match, string.trim |
local format, tonumber, tostring = string.format, tonumber, tostring |
local tsort, tinsert = table.sort, table.insert |
local select, pairs, next, type = select, pairs, next, type |
local error, assert = error, assert |
-- WoW APIs |
local _G = _G |
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded |
-- List them here for Mikk's FindGlobals script |
-- GLOBALS: LibStub, SELECTED_CHAT_FRAME, DEFAULT_CHAT_FRAME |
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 |
-- 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" |
-- 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 checkhidden(info, inputpos, tab) |
if tab.cmdHidden~=nil then |
return tab.cmdHidden |
end |
local hidden = tab.hidden |
if type(hidden) == "function" or type(hidden) == "string" then |
info.hidden = hidden |
hidden = callmethod(info, inputpos, tab, 'hidden') |
info.hidden = nil |
end |
return hidden |
end |
local function showhelp(info, inputpos, tab, depth, 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 |
tinsert(sortTbl, k) |
refTbl[k] = v |
end |
end |
tsort(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 i = 1, #sortTbl do |
local k = sortTbl[i] |
local v = refTbl[k] |
if not checkhidden(info, inputpos, v) then |
if v.type ~= "description" and v.type ~= "header" 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)..":") |
local oldhandler,oldhandler_at = getparam(info, inputpos, v, depth, "handler", handlertypes, handlermsg) |
showhelp(info, inputpos, v, depth, true) |
info.handler,info.handler_at = oldhandler,oldhandler_at |
else |
local key = k:gsub(" ", "_") |
print(" |cffffff78"..key.."|r - "..(desc or name or "")) |
end |
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 |
-- 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 = (info.input):find(" *([^ ]+) *", inputpos) |
if not arg then |
showhelp(info, inputpos, tab, depth) |
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 str:gmatch("[^ ]+") do |
--parse option=on etc |
local opt, val = v:match('(.+)=(.+)') |
--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 |
<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> |
--- 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.\\ |
-- Such functions receive three arguments: "uiType", "uiName", "appName". \\ |
-- * 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.\\ |
-- * The **appName** field is the options table name as given at registration time \\ |
-- |
-- :IterateOptionsTables() (and :GetOptionsTable() if only given one argument) return a function reference that the requesting config handling addon must call with valid "uiType", "uiName". |
-- @class file |
-- @name AceConfigRegistry-3.0 |
-- @release $Id: AceConfigRegistry-3.0.lua 921 2010-05-09 15:49:14Z nevcairiel $ |
local MAJOR, MINOR = "AceConfigRegistry-3.0", 12 |
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 |
-- Lua APIs |
local tinsert, tconcat = table.insert, table.concat |
local strfind, strmatch = string.find, string.match |
local type, tostring, select, pairs = type, tostring, select, pairs |
local error, assert = error, assert |
----------------------------------------------------------------------- |
-- 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(): "..tconcat(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, |
descStyle=optstring, |
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, |
image=optstringfunc, |
imageCoords=optmethodtable, |
}, |
tristate={ |
}, |
range={ |
min=optnumber, |
softMin=optnumber, |
max=optnumber, |
softMax=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 |
--- 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 |
-- @param options The table to be validated |
-- @param name The name of the table to be validated (shown in any error message) |
-- @param errlvl (optional number) error level offset, default 0 (=errors point to the function calling :ValidateOptionsTable) |
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. \\ |
-- See the top of the page for info on arguments passed to such functions. |
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, appName)) |
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 |
--- 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, one of "cmd", "dropdown", "dialog" |
-- @param uiName The name of the library/addon querying for the table, e.g. "MyLib-1.0" |
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 |
<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> |
--- **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]]. |
-- |
-- You may also be interested in [[libdualspec-1-0|LibDualSpec-1.0]] to do profile switching automatically when switching specs. |
-- |
-- @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 940 2010-06-19 08:01:47Z nevcairiel $ |
local ACEDB_MAJOR, ACEDB_MINOR = "AceDB-3.0", 21 |
local AceDB, oldminor = LibStub:NewLibrary(ACEDB_MAJOR, ACEDB_MINOR) |
if not AceDB then return end -- No upgrade needed |
-- Lua APIs |
local type, pairs, next, error = type, pairs, next, error |
local setmetatable, getmetatable, rawset, rawget = setmetatable, getmetatable, rawset, rawget |
-- WoW APIs |
local _G = _G |
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded |
-- List them here for Mikk's FindGlobals script |
-- GLOBALS: LibStub |
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) |
-- remove all metatables from the db, so we don't accidentally create new sub-tables through them |
setmetatable(db, nil) |
-- loop through the defaults and remove their content |
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 |
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 |
-- map "true" to our "Default" profile |
if defaultProfile == true then defaultProfile = "Default" end |
local profileKey |
if not parent then |
-- Make a container for profile keys |
if not sv.profileKeys then sv.profileKeys = {} end |
-- Try to get the profile selected from the char db |
profileKey = sv.profileKeys[charKey] or defaultProfile or charKey |
-- save the selected profile for later |
sv.profileKeys[charKey] = profileKey |
else |
-- Use the profile of the parents DB |
profileKey = parent.keys.profile or defaultProfile or charKey |
-- clear the profileKeys in the DB, namespaces don't need to store them |
sv.profileKeys = nil |
end |
-- 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 |
-- and cleans up empty sections |
local function logoutHandler(frame, event) |
if event == "PLAYER_LOGOUT" then |
for db in pairs(AceDB.db_registry) do |
db.callbacks:Fire("OnDatabaseShutdown", db) |
db:RegisterDefaults(nil) |
-- cleanup sections that are empty without defaults |
local sv = rawget(db, "sv") |
for section in pairs(db.keys) do |
if rawget(sv, section) then |
-- global is special, all other sections have sub-entrys |
-- also don't delete empty profiles on main dbs, only on namespaces |
if section ~= "global" and (section ~= "profiles" or rawget(db, "parent")) then |
for key in pairs(sv[section]) do |
if not next(sv[section][key]) then |
sv[section][key] = nil |
end |
end |
end |
if not next(sv[section]) then |
sv[section] = nil |
end |
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 |
-- if the storage exists, save the new profile |
-- this won't exist on namespaces. |
if self.sv.profileKeys then |
self.sv.profileKeys[charKey] = name |
end |
-- 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.profiles, name) and not silent then |
error("Cannot delete profile '" .. name .. "'. It does not exist.", 2) |
end |
self.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.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, nil, true) |
local profile = self.profile |
local source = self.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 |
-- @param noCallbacks if set to true, won't fire the OnProfileReset callback |
function DBObjectLib:ResetProfile(noChildren, noCallbacks) |
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, nil, noCallbacks) |
end |
end |
-- Callback: OnProfileReset, database |
if not noCallbacks then |
self.callbacks:Fire("OnProfileReset", self) |
end |
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 = _G[name] |
if not tbl then |
tbl = {} |
_G[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 |
--[[---------------------------------------------------------------------------- |
Name: LibSimpleTimer-1.0.lua |
Description: A simple timer |
Revision: $Revision: 32 $ |
Author: Whitetooth |
Email: hotdogee [at] gmail [dot] com |
Credits: Dongle Development Team |
Encoding: UTF-8 |
Features: |
* Schedule/Cancel one-time or repeating timer by id. |
* Able to schedule a timer without any callback. Why? Used with :IsTimerScheduled(id) for checks |
* Able to overwrite existing timer. |
* Fast OnUpdate utilizing a heap. |
* Embedable. |
------------------------------------------------------------------------------]] |
local MAJOR_VERSION = "LibSimpleTimer-1.0" |
local MINOR_VERSION = 90000 + tonumber(("$Revision: 32 $"):match("%d+")) |
local SimpleTimer, oldMinor = LibStub:NewLibrary(MAJOR_VERSION, MINOR_VERSION) |
if not SimpleTimer then return end -- No upgrade needed |
-------------------------------------------------------------------------------- |
-- Base code taken from Dongle, sightly modified |
-------------------------------------------------------------------------------- |
SimpleTimer.timers = SimpleTimer.timers or {} |
SimpleTimer.heap = SimpleTimer.heap or {} |
SimpleTimer.frame = SimpleTimer.frame or CreateFrame("Frame", "SimpleTimer10Frame") |
local timers = SimpleTimer.timers |
local heap = SimpleTimer.heap |
local frame = SimpleTimer.frame |
local GetTime = GetTime |
local pairs = pairs |
local unpack = unpack |
local floor = floor |
local select = select |
local type = type |
local error = error |
local strjoin = strjoin |
local debugstack = debugstack |
local strmatch = strmatch |
local format = format |
local pcall = pcall |
local geterrorhandler = geterrorhandler |
local function argcheck(value, num, ...) |
if type(num) ~= "number" then |
error(("bad argument #%d to '%s' (%s expected, got %s)"):format(2, "argcheck", "number", type(num)), 1) |
end |
for i=1,select("#", ...) do |
if type(value) == select(i, ...) then return end |
end |
local types = strjoin(", ", ...) |
local name = strmatch(debugstack(2,2,0), ": in function [`<](.-)['>]") |
error(("bad argument #%d to '%s' (%s expected, got %s)"):format(num, name, types, type(value)), 3) |
end |
local function safecall(func,...) |
local success,err = pcall(func,...) |
if not success then |
geterrorhandler()(err) |
end |
end |
local function HeapBubbleUp(index) |
while index > 1 do |
local parentIndex = floor(index / 2) |
if heap[index].timeToFire < heap[parentIndex].timeToFire then |
heap[index], heap[parentIndex] = heap[parentIndex], heap[index] |
index = parentIndex |
else |
break |
end |
end |
end |
local function HeapBubbleDown(index) |
while 2 * index <= heap.lastIndex do |
local leftIndex = 2 * index |
local rightIndex = leftIndex + 1 |
local current = heap[index] |
local leftChild = heap[leftIndex] |
local rightChild = heap[rightIndex] |
if not rightChild then |
if leftChild.timeToFire < current.timeToFire then |
heap[index], heap[leftIndex] = heap[leftIndex], heap[index] |
index = leftIndex |
else |
break |
end |
else |
if leftChild.timeToFire < current.timeToFire or |
rightChild.timeToFire < current.timeToFire then |
if leftChild.timeToFire < rightChild.timeToFire then |
heap[index], heap[leftIndex] = heap[leftIndex], heap[index] |
index = leftIndex |
else |
heap[index], heap[rightIndex] = heap[rightIndex], heap[index] |
index = rightIndex |
end |
else |
break |
end |
end |
end |
end |
local function OnUpdate() |
local schedule = heap[1] |
while schedule and schedule.timeToFire < GetTime() do |
if schedule.cancelled then |
local last = heap.lastIndex |
heap[1], heap[last] = heap[last], heap[1] |
heap[heap.lastIndex] = nil |
heap.lastIndex = heap.lastIndex - 1 |
HeapBubbleDown(1) |
else |
if schedule.func then |
if schedule.args then |
safecall(schedule.func, unpack(schedule.args)) |
else |
safecall(schedule.func) |
end |
end |
if schedule.repeating then |
schedule.timeToFire = schedule.timeToFire + schedule.repeating |
HeapBubbleDown(1) |
else |
local last = heap.lastIndex |
heap[1], heap[last] = heap[last], heap[1] |
heap[heap.lastIndex] = nil |
heap.lastIndex = heap.lastIndex - 1 |
HeapBubbleDown(1) |
timers[schedule.name] = nil |
end |
end |
schedule = heap[1] |
end |
if not schedule then frame:Hide() end |
end |
frame:SetScript("OnUpdate", OnUpdate) |
-------------------------------------------------------------------------------- |
-- :ScheduleTimer(name, func, delay, ...) |
-- Notes: |
-- * Schedule a timer to expire in delay seconds at which point it will call the callback func. name is an identifier for this timer. |
-- * If you try to schedule a timer with the same name a second time, the old schedule will be overwritten. |
-- Arguments: |
-- name (variant) - The name of the timer to be scheduled. You can use this name to check if this timer's status and/or cancel it. |
-- func (function or nil) - A function to be called when the timer expires, can be nil. |
-- delay (number) - The number of seconds it takes for this timer to expire. |
-- ... - Any additional arguments to pass to the callback. |
-- Callback Signature: |
-- func(...) |
-- Example: |
-- :ScheduleTimer("EncounterEnd", self.EncounterEnd, 10, self, 10) |
-- :ScheduleTimer("EncounterEnd", nil, 10) -- why? used with :IsTimerScheduled("EncounterEnd") |
-------------------------------------------------------------------------------- |
function SimpleTimer:ScheduleTimer(name, func, delay, ...) |
argcheck(self, 1, "table") |
argcheck(func, 3, "function", "nil") |
argcheck(delay, 4, "number") |
if SimpleTimer:IsTimerScheduled(name) then |
SimpleTimer:CancelTimer(name) |
end |
local schedule = {} |
timers[name] = schedule |
schedule.timeToFire = GetTime() + delay |
schedule.func = func |
schedule.name = name |
if select('#', ...) ~= 0 then |
schedule.args = { ... } |
end |
if heap.lastIndex then |
heap.lastIndex = heap.lastIndex + 1 |
else |
heap.lastIndex = 1 |
end |
heap[heap.lastIndex] = schedule |
HeapBubbleUp(heap.lastIndex) |
if not frame:IsShown() then |
frame:Show() |
end |
end |
-------------------------------------------------------------------------------- |
-- :ScheduleRepeatingTimer(name, func, delay, ...) |
-- Notes: |
-- * Schedule a repeating timer that expires every delay seconds. |
-- * If you try to schedule a timer with the same name a second time, the old schedule will be overwritten. |
-- Arguments: |
-- name (variant) - The name of the timer to be scheduled. You can use this name to check if this timer's status and/or cancel it. |
-- func (function) - A function to be called when the timer expires. |
-- delay (number) - The number of seconds it takes for this timer to expire. |
-- ... - Any additional arguments to pass to the callback. |
-- Callback Signature: |
-- func(...) |
-------------------------------------------------------------------------------- |
function SimpleTimer:ScheduleRepeatingTimer(name, func, delay, ...) |
argcheck(func, 3, "function") |
SimpleTimer:ScheduleTimer(name, func, delay, ...) |
timers[name].repeating = delay |
end |
-------------------------------------------------------------------------------- |
-- :IsTimerScheduled(name) |
-- Notes: |
-- * Returns if the timer with the name specified is scheduled or not and also returns the time remaining for it to expire. |
-- Arguments: |
-- name (variant) - The name of the timer to query. |
-- Returns: |
-- nil - if the timer is not scheduled. |
-- true, seconds (number) - if the timer is scheduled. seconds is the number of seconds required for the timer to expire. |
-------------------------------------------------------------------------------- |
function SimpleTimer:IsTimerScheduled(name) |
argcheck(self, 1, "table") |
local schedule = timers[name] |
if schedule then |
return true, schedule.timeToFire - GetTime() |
end |
end |
-------------------------------------------------------------------------------- |
-- :CancelTimer(name) |
-- Notes: |
-- * Cancels the timer scheduled with name. |
-- Arguments: |
-- name (variant) - The name of the timer to cancel. |
-------------------------------------------------------------------------------- |
function SimpleTimer:CancelTimer(name) |
argcheck(self, 1, "table") |
local schedule = timers[name] |
if not schedule then return end |
schedule.cancelled = true |
timers[name] = nil |
end |
-------------------------------------------------------------------------------- |
-- Embed handling |
-------------------------------------------------------------------------------- |
SimpleTimer.embeds = SimpleTimer.embeds or {} |
local mixins = { |
"ScheduleTimer", "ScheduleRepeatingTimer", "IsTimerScheduled", "CancelTimer", |
} |
-------------------------------------------------------------------------------- |
-- :Embed(target) |
-- Notes: |
-- * Embeds "ScheduleTimer", "ScheduleRepeatingTimer", "IsTimerScheduled", "CancelTimer" |
-- Arguments: |
-- target (table) - The table with which to export methods onto. |
-- Returns: |
-- The table provided, after embedding. |
-------------------------------------------------------------------------------- |
function SimpleTimer:Embed(target) |
SimpleTimer.embeds[target] = true |
for _, v in pairs(mixins) do |
target[v] = SimpleTimer[v] |
end |
return target |
end |
for addon in pairs(SimpleTimer.embeds) do |
SimpleTimer:Embed(addon) |
end |
## Interface: 30000 |
## LoadOnDemand: 1 |
## Title: Lib: SimpleTimer-1.0 |
## Notes: A Simple Timer |
## Notes-zhTW: æä¾ç°¡å®è¨æåè½çå½å¼åº« |
## Author: Whitetooth |
## X-eMail: hotdogee [at] gmail [dot] com |
## X-Credits: Dongle Development Team |
## X-Category: Library |
## X-License: LGPL v2.1 |
## X-Encoding: UTF-8 |
## X-Curse-Packaged-Version: r33 |
## X-Curse-Project-Name: LibSimpleTimer-1.0 |
## X-Curse-Project-ID: libsimpletimer-1-0 |
## X-Curse-Repository-ID: wow/libsimpletimer-1-0/mainline |
LibStub\LibStub.lua |
lib.xml |
-- 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 |
<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="LibSimpleTimer-1.0.lua"/> |
</Ui> |
## Interface: 30300 |
## Title: Lib: Fail-1.0 |
## Notes: Fires events whenever a raid member "fails." |
## Version: 1.0.248 |
## Author: Sylvanaar, Sztanpet, Rinu, Maat, MysticalOS |
## X-Curse-Packaged-Version: r248 |
## X-Curse-Project-Name: LibFail-1.0 |
## X-Curse-Project-ID: libfail-1-0 |
## X-Curse-Repository-ID: wow/libfail-1-0/mainline |
## OptionalDeps: Ace3, LibStub, CallBackHandler-1.0 |
## X-Embeds: LibStub, CallBackHandler-1.0 |
## LoadOnDemand: 1 |
## X-Credits: Veev-Medivh(US) author of FailBot, Maat author of EnsidiaFails |
embeds.xml |
lib.xml |
<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="LibFail-1.0.lua" /> |
</Ui> |
<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="LibStub\LibStub.lua"/> |
<Include file="CallbackHandler-1.0\CallbackHandler-1.0.xml" /> |
</Ui> |
--[[ $Id: CallbackHandler-1.0.lua 3 2008-09-29 16:54:20Z 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. |
<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> |
-- 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 |
## 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 |
local MAJOR, MINOR = "LibFail-1.0", tonumber("248") or 999 |
assert(LibStub, MAJOR.." requires LibStub") |
local lib = LibStub:NewLibrary(MAJOR, MINOR) |
if not lib then return end |
lib.callbacks = lib.callbacks or LibStub("CallbackHandler-1.0"):New(lib) |
local callbacks = lib.callbacks |
lib.frame = lib.frame or CreateFrame("Frame") |
local frame = lib.frame |
frame:RegisterEvent("PLAYER_ENTERING_WORLD") |
--- Fail Events. |
--@description The list of supported events |
--@class table |
--@name fail_events |
--@field 1 Fail_Deconstructor_Light |
--@field 2 Fail_Deconstructor_Gravity |
--@field 3 Fail_Frogger |
--@field 4 Fail_Heigan_Dance |
--@field 5 Fail_KelThuzad_VoidZone |
--@field 6 Fail_Mimiron_BombBots |
--@field 7 Fail_Mimiron_Rocket |
--@field 8 Fail_Mimiron_Shock |
--@field 9 Fail_Sapphiron_Breath |
--@field 10 Fail_Sartharion_LavaWaves |
--@field 11 Fail_Sartharion_VoidZone |
--@field 12 Fail_Thaddius_Jump |
--@field 13 Fail_Thaddius_PolaritySwitch |
--@field 14 Fail_Thorim_LightningChain |
--@field 15 Fail_Thorim_LightningCharge |
--@field 16 Fail_Thorim_Smash |
--@field 17 Fail_Vezax_ShadowCrash |
--@field 18 Fail_Vezax_Saronite |
--@field 19 Fail_Hodir_FlashFreeze |
--@field 20 Fail_Vezax_Leech |
--@field 21 Fail_Mimiron_LaserBarrage |
--@field 22 Fail_Mimiron_Flames |
--@field 23 Fail_Council_Overload |
--@field 24 Fail_Hodir_Icicle |
--@field 25 Fail_Grobbulus_PoisonCloud |
--@field 26 Fail_Freya_NatureBomb |
--@field 27 Fail_Thorim_Blizzard |
--@field 28 Fail_Yogg_Sanity |
--@field 29 Fail_Yogg_DeathRay |
--@field 30 Fail_Razorscale_Flame |
--@field 31 Fail_Kologarn_Eyebeam |
--@field 32 Fail_Auriaya_Voidzone |
--@field 33 Fail_Hodir_BitingCold |
--@field 34 Fail_Malygos_Dot |
--@field 35 Fail_Gormok_FireBomb |
--@field 36 Fail_Acidmaw_SlimePool |
--@field 37 Fail_Acidmaw_AcidicSpew |
--@field 38 Fail_Acidmaw_ParalyticToxin |
--@field 39 Fail_Dreadscale_MoltenSpew |
--@field 40 Fail_Icehowl_Trample |
--@field 41 Fail_Jaraxxus_FelInferno |
--@field 42 Fail_Jaraxxus_LegionFlame |
--@field 43 Fail_FactionChampions_Hellfire |
--@field 44 Fail_Valkyr_Orb |
--@field 45 Fail_Valkyr_Vortex |
--@field 46 Fail_Anubarak_Impale |
--@field 47 Fail_Mimiron_WaterSpray |
--@field 48 Fail_Mimiron_ProximityMine |
--@field 49 Fail_Mimiron_FrostBomb |
--@field 50 Fail_Yogg_LunaticGaze |
--@field 51 Fail_Algalon_BigBang |
--@field 52 Fail_Mimiron_Siren |
--@field 53 Fail_Koralon_MeteorFist |
--@field 54 Fail_Horsemen_VoideZone |
--@field 55 Fail_Horsemen_Mark |
--@field 56 Fail_Onyxia_FlameBreath |
--@field 57 Fail_Onyxia_TailSweep |
--@field 58 Fail_Archavon_ChokingCloud |
--@field 59 Fail_Emalon_LightningNova |
--@field 60 Fail_Emalon_ChainLightning |
--@field 61 Fail_Koralon_FlameCinder |
--@field 62 Fail_Auriaya_SonicScreech |
--@field 63 Fail_Onyxia_DeepBreath |
--@field 64 Fail_Algalon_CosmicSmash |
--@field 65 Fail_Mimiron_NapalmShell |
--@field 66 Fail_Freya_UnstableEnergy |
--@field 67 Fail_Council_RuneOfDeath |
--@field 68 Fail_Grobbulus_MutatingInjection |
--@field 69 Fail_Yogg_OminousCloud |
--@field 70 Fail_Marrowgar_Coldflame |
--@field 71 Fail_Rotface_StickyOoze |
--@field 72 Fail_Rotface_OozeExplosion |
--@field 73 Fail_Onyxia_WarderNova |
--@field 74 Fail_Onyxia_WarderCleave |
--@field 75 Fail_Onyxia_Cleave |
--@field 76 Fail_Malygos_ArcaneBreath |
--@field 77 Fail_Algalon_Blackhole |
--@field 78 Fail_Yogg_Malady |
--@field 79 Fail_Freya_GroundTremor |
--@field 80 Fail_Ignis_FlameJets |
--@field 81 Fail_Freya_BindLife |
--@field 82 Fail_Deconstructor_Voidzone |
--@field 83 Fail_Marrowgar_Whirlwind |
--@field 84 Fail_Marrowgar_SaberLash |
--@field 85 Fail_Festergut_VileGas |
--@field 86 Fail_Festergut_PungentBlight |
--@field 87 Fail_Sartharion_Breath |
--@field 88 Fail_Sartharion_TailLash |
--@field 89 Fail_Deathwhisper_DeathNDecay |
--@field 90 Fail_Sapphiron_TailSweep |
--@field 91 Fail_Sapphiron_Cleave |
--@field 92 Fail_Sindragosa_TailSmash |
--@field 93 Fail_Sindragosa_FrostBreath |
--@field 94 Fail_Sindragosa_BlisteringCold |
--@field 96 Fail_Sindragosa_Cleave |
--@field 97 Fail_Sindragosa_Instability |
--@field 98 Fail_Sindragosa_FrostBomb |
--@field 99 Fail_Sindragosa_IceTomb |
--@field 100 Fail_Professor_MutatedSlime |
--@field 101 Fail_LanaThel_UncontrollableFrenzy |
--@field 102 Fail_LanaThel_BloodboltSplash |
--@field 103 Fail_BloodPrinces_SystemicShockVortex |
--@field 104 Fail_LanaThel_DeliriousSlash |
--@field 105 Fail_Gunship_Explosion |
--@field 106 Fail_Gunship_Explosion_Knockback |
--@field 107 Fail_FactionChampions_Bladestorm |
--@field 108 Fail_Saurfang_Rune |
--@field 109 Fail_Saurfang_Beasts |
--@field 110 Fail_Deathwhisper_Shade |
--@field 111 Fail_Professor_MalleableGoo |
--@field 112 Fail_Rotface_SlimeSpray |
--@field 113 Fail_BloodPrinces_Flames |
--@field 114 Fail_LanaThel_Pact |
--@field 115 Fail_LanaThel_SwarmingShadows |
--@field 116 Fail_ColdflameTrap |
--@field 117 Fail_Professor_ChokingGas |
--@field 118 Fail_Valithria_ColumnofFrost |
--@field 119 Fail_TheLichKing_IceBurst |
--@field 120 Fail_Sindragosa_ChilledtotheBone |
--@field 121 Fail_TheLichKing_RemorselessWinter |
--@field 122 Fail_TheLichKing_NecroticPlague |
--@field 123 Fail_TheLichKing_ShadowTrap |
--@field 124 Fail_Festergut_MalleableGoo |
--@field 125 Fail_TheLichKing_Defile |
--@field 126 Fail_TheLichKing_Shockwave |
--@field 127 Fail_TheLichKing_SpiritBomb |
--@field 128 Fail_Deathwhisper_ShadeExplosion |
--@field 129 Fail_Halion_TwilightCutter |
--@field 129 Fail_Halion_MeteorStrike |
local fail_events = { |
"Fail_Deconstructor_Light", |
"Fail_Deconstructor_Gravity", |
"Fail_Frogger", |
"Fail_Heigan_Dance", |
"Fail_KelThuzad_VoidZone", |
"Fail_Mimiron_BombBots", |
"Fail_Mimiron_Rocket", |
"Fail_Mimiron_Shock", |
"Fail_Sapphiron_Breath", |
"Fail_Sartharion_LavaWaves", |
"Fail_Sartharion_VoidZone", |
"Fail_Thaddius_Jump", |
"Fail_Thaddius_PolaritySwitch", |
"Fail_Thorim_LightningChain", |
"Fail_Thorim_LightningCharge", |
"Fail_Thorim_Smash", |
"Fail_Vezax_ShadowCrash", |
"Fail_Vezax_Saronite", |
"Fail_Vezax_Leech", |
"Fail_Hodir_FlashFreeze", |
"Fail_Mimiron_LaserBarrage", |
"Fail_Mimiron_Flames", |
"Fail_Council_Overload", |
"Fail_Hodir_Icicle", |
"Fail_Grobbulus_PoisonCloud", |
"Fail_Freya_NatureBomb", |
"Fail_Thorim_Blizzard", |
"Fail_Yogg_Sanity", |
"Fail_Yogg_DeathRay", |
"Fail_Razorscale_Flame", |
"Fail_Kologarn_Eyebeam", |
"Fail_Auriaya_Voidzone", |
"Fail_Hodir_BitingCold", |
"Fail_Malygos_Dot", |
"Fail_Gormok_FireBomb", |
"Fail_Acidmaw_SlimePool", |
"Fail_Acidmaw_AcidicSpew", |
"Fail_Acidmaw_ParalyticToxin", |
"Fail_Dreadscale_MoltenSpew", |
"Fail_Icehowl_Trample", |
"Fail_Jaraxxus_FelInferno", |
"Fail_Jaraxxus_LegionFlame", |
"Fail_FactionChampions_Hellfire", |
"Fail_Valkyr_Orb", |
"Fail_Valkyr_Vortex", |
"Fail_Anubarak_Impale", |
"Fail_Mimiron_WaterSpray", |
"Fail_Mimiron_ProximityMine", |
"Fail_Mimiron_FrostBomb", |
"Fail_Yogg_LunaticGaze", |
"Fail_Algalon_BigBang", |
"Fail_Mimiron_Siren", |
"Fail_Koralon_MeteorFist", |
"Fail_Horsemen_VoideZone", |
"Fail_Horsemen_Mark", |
"Fail_Onyxia_FlameBreath", |
"Fail_Onyxia_TailSweep", |
"Fail_Archavon_ChokingCloud", |
"Fail_Emalon_LightningNova", |
"Fail_Emalon_ChainLightning", |
"Fail_Koralon_FlameCinder", |
"Fail_Auriaya_SonicScreech", |
"Fail_Onyxia_DeepBreath", |
"Fail_Algalon_CosmicSmash", |
"Fail_Mimiron_NapalmShell", |
"Fail_Freya_UnstableEnergy", |
"Fail_Council_RuneOfDeath", |
"Fail_Grobbulus_MutatingInjection", |
"Fail_Yogg_OminousCloud", |
"Fail_Marrowgar_Coldflame", |
"Fail_Rotface_StickyOoze", |
"Fail_Rotface_OozeExplosion", |
"Fail_Onyxia_WarderNova", |
"Fail_Onyxia_WarderCleave", |
"Fail_Onyxia_Cleave", |
"Fail_Malygos_ArcaneBreath", |
"Fail_Algalon_Blackhole", |
"Fail_Yogg_Malady", |
"Fail_Freya_GroundTremor", |
"Fail_Ignis_FlameJets", |
"Fail_Freya_BindLife", |
"Fail_Deconstructor_Voidzone", |
"Fail_Marrowgar_Whirlwind", |
"Fail_Marrowgar_SaberLash", |
"Fail_Festergut_VileGas", |
"Fail_Festergut_PungentBlight", |
"Fail_Sartharion_Breath", |
"Fail_Sartharion_TailLash", |
"Fail_Deathwhisper_DeathNDecay", |
"Fail_Sapphiron_TailSweep", |
"Fail_Sapphiron_Cleave", |
"Fail_Sindragosa_TailSmash", |
"Fail_Sindragosa_FrostBreath", |
"Fail_Sindragosa_BlisteringCold", |
"Fail_Sindragosa_Cleave", |
"Fail_Sindragosa_Instability", |
"Fail_Sindragosa_FrostBomb", |
"Fail_Sindragosa_IceTomb", |
"Fail_Professor_MutatedSlime", |
"Fail_LanaThel_UncontrollableFrenzy", |
"Fail_LanaThel_BloodboltSplash", |
"Fail_BloodPrinces_SystemicShockVortex", |
"Fail_LanaThel_DeliriousSlash", |
"Fail_Gunship_Explosion", |
"Fail_Gunship_Explosion_Knockback", |
"Fail_FactionChampions_Bladestorm", |
"Fail_Saurfang_Rune", |
"Fail_Saurfang_Beasts", |
"Fail_Deathwhisper_Shade", |
"Fail_Professor_MalleableGoo", |
"Fail_Rotface_SlimeSpray", |
"Fail_BloodPrinces_Flames", |
"Fail_LanaThel_Pact", |
"Fail_LanaThel_SwarmingShadows", |
"Fail_ColdflameTrap", |
"Fail_Professor_ChokingGas", |
"Fail_Valithria_ColumnofFrost", |
"Fail_TheLichKing_IceBurst", |
"Fail_Sindragosa_ChilledtotheBone", |
"Fail_TheLichKing_RemorselessWinter", |
"Fail_TheLichKing_NecroticPlague", |
"Fail_TheLichKing_ShadowTrap", |
"Fail_Festergut_MalleableGoo", |
"Fail_TheLichKing_Defile", |
"Fail_TheLichKing_Shockwave", |
"Fail_TheLichKing_SpiritBomb", |
"Fail_Deathwhisper_ShadeExplosion", |
"Fail_Halion_TwilightCutter", |
"Fail_Halion_MeteorStrike", |
} |
--[===[@debug@ |
function lib:Test(overrideName) |
local e = math.floor(math.random() * #fail_events) + 1 |
local p = math.floor(math.random() * 5) + 1 |
self:FailEvent(fail_events[e], overrideName or "Test"..p, lib.FAIL_TYPE_MOVING) |
end |
--@end-debug@]===] |
local zones_with_fails = { |
["The Ruby Sanctum"] = { |
"Fail_Halion_TwilightCutter", |
"Fail_Halion_MeteorStrike", |
}, |
["Icecrown Citadel"] = { |
"Fail_Rotface_StickyOoze", |
"Fail_Rotface_OozeExplosion", |
"Fail_Marrowgar_Whirlwind", |
"Fail_Marrowgar_Coldflame", |
"Fail_Marrowgar_SaberLash", |
"Fail_Festergut_VileGas", |
"Fail_Festergut_PungentBlight", |
"Fail_Deathwhisper_DeathNDecay", |
"Fail_Sindragosa_TailSmash", |
"Fail_Sindragosa_FrostBreath", |
"Fail_Sindragosa_BlisteringCold", |
"Fail_Sindragosa_Cleave", |
"Fail_Sindragosa_Instability", |
"Fail_Sindragosa_FrostBomb", |
"Fail_Sindragosa_IceTomb", |
"Fail_Professor_MutatedSlime", |
"Fail_LanaThel_UncontrollableFrenzy", |
"Fail_LanaThel_BloodboltSplash", |
"Fail_BloodPrinces_SystemicShockVortex", |
"Fail_LanaThel_DeliriousSlash", |
"Fail_Gunship_Explosion", |
"Fail_Gunship_Explosion_Knockback", |
"Fail_Saurfang_Rune", |
"Fail_Saurfang_Beasts", |
"Fail_Deathwhisper_Shade", |
"Fail_Professor_MalleableGoo", |
"Fail_Rotface_SlimeSpray", |
"Fail_BloodPrinces_Flames", |
"Fail_LanaThel_Pact", |
"Fail_LanaThel_SwarmingShadows", |
"Fail_ColdflameTrap", |
"Fail_Professor_ChokingGas", |
"Fail_Valithria_ColumnofFrost", |
"Fail_TheLichKing_IceBurst", |
"Fail_Sindragosa_ChilledtotheBone", |
"Fail_TheLichKing_RemorselessWinter", |
"Fail_TheLichKing_NecroticPlague", |
"Fail_TheLichKing_ShadowTrap", |
"Fail_Festergut_MalleableGoo", |
"Fail_TheLichKing_Defile", |
"Fail_TheLichKing_Shockwave", |
"Fail_TheLichKing_SpiritBomb", |
"Fail_Deathwhisper_ShadeExplosion", |
}, |
["Onyxia's Lair"] = { |
"Fail_Onyxia_FlameBreath", |
"Fail_Onyxia_TailSweep", |
"Fail_Onyxia_DeepBreath", |
"Fail_Onyxia_WarderNova", |
"Fail_Onyxia_WarderCleave", |
"Fail_Onyxia_Cleave", |
}, |
["Trial of the Crusader"] = { |
"Fail_Gormok_FireBomb", |
"Fail_Acidmaw_SlimePool", |
"Fail_Acidmaw_AcidicSpew", |
"Fail_Acidmaw_ParalyticToxin", |
"Fail_Dreadscale_MoltenSpew", |
"Fail_Icehowl_Trample", |
"Fail_Jaraxxus_FelInferno", |
"Fail_Jaraxxus_LegionFlame", |
"Fail_FactionChampions_Hellfire", |
"Fail_Valkyr_Orb", |
"Fail_Valkyr_Vortex", |
"Fail_Anubarak_Impale", |
"Fail_FactionChampions_Bladestorm", |
}, |
Ulduar = { |
"Fail_Deconstructor_Light", |
"Fail_Deconstructor_Gravity", |
"Fail_Hodir_FlashFreeze", |
"Fail_Hodir_BitingCold", |
"Fail_Hodir_Icicle", |
"Fail_Mimiron_BombBots", |
"Fail_Mimiron_Rocket", |
"Fail_Mimiron_Shock", |
"Fail_Mimiron_LaserBarrage", |
"Fail_Mimiron_Flames", |
"Fail_Thorim_LightningChain", |
"Fail_Thorim_LightningCharge", |
"Fail_Thorim_Smash", |
"Fail_Thorim_Blizzard", |
"Fail_Vezax_Leech", |
"Fail_Vezax_ShadowCrash", |
"Fail_Vezax_Saronite", |
"Fail_Council_Overload", |
"Fail_Freya_NatureBomb", |
"Fail_Yogg_Sanity", |
"Fail_Yogg_DeathRay", |
"Fail_Razorscale_Flame", |
"Fail_Kologarn_Eyebeam", |
"Fail_Auriaya_Voidzone", |
"Fail_Mimiron_WaterSpray", |
"Fail_Mimiron_ProximityMine", |
"Fail_Mimiron_FrostBomb", |
"Fail_Yogg_LunaticGaze", |
"Fail_Algalon_BigBang", |
"Fail_Mimiron_Siren", |
"Fail_Auriaya_SonicScreech", |
"Fail_Algalon_CosmicSmash", |
"Fail_Mimiron_NapalmShell", |
"Fail_Freya_UnstableEnergy", |
"Fail_Council_RuneOfDeath", |
"Fail_Yogg_OminousCloud", |
"Fail_Algalon_Blackhole", |
"Fail_Yogg_Malady", |
"Fail_Freya_GroundTremor", |
"Fail_Ignis_FlameJets", |
"Fail_Freya_BindLife", |
"Fail_Deconstructor_Voidzone", |
}, |
Naxxramas = { |
"Fail_Frogger", |
"Fail_Heigan_Dance", |
"Fail_KelThuzad_VoidZone", |
"Fail_Sapphiron_Breath", |
"Fail_Thaddius_Jump", |
"Fail_Thaddius_PolaritySwitch", |
"Fail_Horsemen_VoideZone", |
"Fail_Horsemen_Mark", |
"Fail_Grobbulus_MutatingInjection", |
"Fail_Grobbulus_PoisonCloud", |
"Fail_Sapphiron_TailSweep", |
"Fail_Sapphiron_Cleave", |
}, |
["The Obsidian Sanctum"] = { |
"Fail_Sartharion_LavaWaves", |
"Fail_Sartharion_VoidZone", |
"Fail_Sartharion_Breath", |
"Fail_Sartharion_TailLash", |
}, |
["Eye of Eternity"] = { |
"Fail_Malygos_Dot", |
"Fail_Malygos_ArcaneBreath", |
}, |
["Vault of Archavon"] = { |
"Fail_Koralon_MeteorFist", |
"Fail_Archavon_ChokingCloud", |
"Fail_Emalon_LightningNova", |
"Fail_Emalon_ChainLightning", |
"Fail_Koralon_FlameCinder", |
} |
} |
local fails_where_tanks_dont_fail = { |
"Fail_Onyxia_FlameBreath", |
"Fail_Onyxia_WarderNova", |
"Fail_Onyxia_WarderCleave", |
"Fail_Onyxia_Cleave", |
"Fail_Acidmaw_AcidicSpew", |
"Fail_Dreadscale_MoltenSpew", |
"Fail_Mimiron_BombBots", |
"Fail_Yogg_OminousCloud", |
"Fail_Razorscale_Flame", |
"Fail_Mimiron_ProximityMine", |
"Fail_Koralon_MeteorFist", |
"Fail_Emalon_LightningNova", |
"Fail_Malygos_ArcaneBreath", |
"Fail_Marrowgar_SaberLash", |
"Fail_Sartharion_Breath", |
"Fail_Sapphiron_Cleave", |
"Fail_Sindragosa_FrostBreath", |
"Fail_Sindragosa_BlisteringCold", |
"Fail_Sindragosa_Cleave", |
"Fail_Auriaya_SonicScreech", |
"Fail_LanaThel_DeliriousSlash", |
"Fail_Deathwhisper_Shade", |
"Fail_Rotface_SlimeSpray", |
"Fail_TheLichKing_NecroticPlague", |
"Fail_TheLichKing_Shockwave", |
"Fail_Deathwhisper_ShadeExplosion", |
"Fail_Marrowgar_Coldflame", |
"Fail_Festergut_MalleableGoo", |
} |
-- Spell id's to use for default localizations |
local event_spellids = { |
Fail_Acidmaw_AcidicSpew = 66819, |
Fail_Acidmaw_ParalyticToxin = 67618, |
Fail_Acidmaw_SlimePool = 66881, |
Fail_Algalon_BigBang = 64584, |
Fail_Algalon_CosmicSmash = 62311, |
Fail_Anubarak_Impale = 67860, |
Fail_Archavon_ChokingCloud = 58965, |
Fail_Auriaya_SonicScreech = 64688, |
Fail_Auriaya_Voidzone = 64459, |
Fail_Council_Overload = 61878, |
Fail_Council_RuneOfDeath = 63490, |
Fail_Deconstructor_Light = 65120, |
Fail_Deconstructor_Gravity = 64233, |
Fail_Dreadscale_MoltenSpew = 66820, |
Fail_Emalon_ChainLightning = 64213, |
Fail_Emalon_LightningNova = 65279, |
Fail_FactionChampions_Hellfire = 65817, |
Fail_Freya_NatureBomb = 64650, |
Fail_Freya_UnstableEnergy = 62865, |
Fail_Frogger = 28433, |
Fail_Gormok_FireBomb = 67472, |
Fail_Grobbulus_MutatingInjection = 28169, |
Fail_Grobbulus_PoisonCloud = 28158, |
Fail_Heigan_Dance = 29371, |
Fail_Hodir_BitingCold = 62038, |
Fail_Hodir_FlashFreeze = 61969, |
Fail_Hodir_Icicle = 62457, |
Fail_Horsemen_Mark = 28836, |
Fail_Horsemen_VoideZone = 28865, |
Fail_Icehowl_Trample = 66734, |
Fail_Jaraxxus_FelInferno = 68718, |
Fail_Jaraxxus_LegionFlame = 67072, |
Fail_KelThuzad_VoidZone = 27812, |
Fail_Kologarn_Eyebeam = 63976, |
Fail_Koralon_FlameCinder = 67332, |
Fail_Koralon_MeteorFist = 68161, |
Fail_Malygos_Dot = 56092, |
Fail_Mimiron_BombBots = 63811, |
Fail_Mimiron_Flames = 64566, |
Fail_Mimiron_FrostBomb = 65333, |
Fail_Mimiron_LaserBarrage = 63293, |
Fail_Mimiron_NapalmShell = 65026, |
Fail_Mimiron_ProximityMine = 63009, |
Fail_Mimiron_Rocket = 63041, |
Fail_Mimiron_Shock = 63631, |
Fail_Mimiron_Siren = 64616, |
Fail_Mimiron_WaterSpray = 64619, |
Fail_Onyxia_DeepBreath = 17086, |
Fail_Onyxia_FlameBreath = 68970, |
Fail_Onyxia_TailSweep = 69286, |
Fail_Onyxia_WarderCleave = 15284, |
Fail_Onyxia_WarderNova = 68958, |
Fail_Onyxia_Cleave = 68868, |
Fail_Razorscale_Flame = 64733, |
Fail_Rotface_OozeExplosion = 69839, |
Fail_Rotface_StickyOoze = 69778, |
Fail_Sapphiron_Breath = 28524, |
Fail_Sartharion_LavaWaves = 57491, |
Fail_Sartharion_VoidZone = 57581, |
Fail_Sartharion_Breath = 56908, |
Fail_Sartharion_TailLash = 56910, |
Fail_Thaddius_Jump = 28801, |
Fail_Thaddius_PolaritySwitch = 28089, -- 'polarity switch' spell id |
Fail_Thorim_Blizzard = 62602, |
Fail_Thorim_LightningChain = 64390, |
Fail_Thorim_LightningCharge = 62466, |
Fail_Thorim_Smash = 62465, |
Fail_Valkyr_Orb = 67174, |
Fail_Valkyr_Vortex = 67155, |
Fail_Vezax_Leech = 63278, |
Fail_Vezax_Saronite = 63338, |
Fail_Vezax_ShadowCrash = 62659, |
Fail_Yogg_DeathRay = 63884, |
Fail_Yogg_LunaticGaze = 64168, |
Fail_Yogg_OminousCloud = 60977, |
Fail_Yogg_Sanity = 63120, |
Fail_Malygos_ArcaneBreath = 56272, |
Fail_Algalon_Blackhole = 62169, |
Fail_Yogg_Malady = 63881, |
Fail_Freya_GroundTremor = 62859, |
Fail_Ignis_FlameJets = 62681, |
Fail_Freya_BindLife = 63559, |
Fail_Deconstructor_Voidzone = 64206, |
Fail_Marrowgar_Whirlwind = 69075, |
Fail_Marrowgar_Coldflame = 69138, -- the spellid of the summond "npc" that cralls, not the damage dealing spell |
Fail_Marrowgar_SaberLash = 69055, |
Fail_Festergut_VileGas = 71218, |
Fail_Festergut_PungentBlight = 71219, |
Fail_Deathwhisper_DeathNDecay = 71001, |
Fail_Sapphiron_TailSweep = 55696, |
Fail_Sapphiron_Cleave = 19983, |
Fail_Sindragosa_TailSmash = 71077, |
Fail_Sindragosa_FrostBreath = 69649, |
Fail_Sindragosa_BlisteringCold = 70123, |
Fail_Sindragosa_Cleave = 19983, |
Fail_Sindragosa_Instability = 69766, |
Fail_Sindragosa_FrostBomb = 69846, |
Fail_Sindragosa_IceTomb = 70157, |
Fail_Professor_MutatedSlime = 72456, |
Fail_LanaThel_UncontrollableFrenzy = 70923, |
Fail_LanaThel_BloodboltSplash = 71481, |
Fail_BloodPrinces_SystemicShockVortex = 72815, |
Fail_LanaThel_DeliriousSlash = 71624, |
Fail_Gunship_Explosion = 69680, |
Fail_Gunship_Explosion_Knockback = 69689, |
Fail_FactionChampions_Bladestorm = 65946, |
Fail_Saurfang_Rune = 72410, |
Fail_Saurfang_Beasts = 72173, --the spellid of Call Blood Beast, not the actual fail. |
Fail_Deathwhisper_Shade = 71426, --the spellid of Summon Spirit, not the actual fail. |
Fail_Professor_MalleableGoo = 72458, |
Fail_Rotface_SlimeSpray = 73190, |
Fail_BloodPrinces_Flames = 72789, |
Fail_LanaThel_Pact = 71341, |
Fail_LanaThel_SwarmingShadows = 72635, |
Fail_ColdflameTrap = 70461, |
Fail_Professor_ChokingGas = 72620, |
Fail_Valithria_ColumnofFrost = 72020, |
Fail_TheLichKing_IceBurst = 73773, |
Fail_Sindragosa_ChilledtotheBone = 70106, |
Fail_TheLichKing_RemorselessWinter = 74270, |
Fail_TheLichKing_NecroticPlague = 73913, |
Fail_TheLichKing_ShadowTrap = 73529, |
Fail_Festergut_MalleableGoo = 72550, |
Fail_TheLichKing_Defile = 73708, |
Fail_TheLichKing_Shockwave = 73794, |
Fail_TheLichKing_SpiritBomb = 73572, |
Fail_Deathwhisper_ShadeExplosion = 71544, |
Fail_Halion_TwilightCutter = 77845, |
Fail_Halion_MeteorStrike = 75952 |
} |
--[===[@debug@ |
--FAIL = lib |
function lib:TestEventIds() |
for k,v in pairs(event_spellids) do |
local spell = GetSpellInfo(v) or "" |
print(k.." = "..spell) |
end |
end |
--@end-debug@]===] |
--- Get a list of supported events. |
-- @see fail_events |
-- @return a table of event names which can be fired |
function lib:GetSupportedEvents() return fail_events end |
--- Get a list of supported events in the current zone |
-- @see fail_events |
-- @return a table of event names which can be fired |
function lib:GetSupportedZoneEvents(name) return zones_with_fails[name] end |
--- Get a spell id which can be used for a default event string by calling GetSpellInfo() |
-- @see fail_events |
-- @param event_name the event name |
-- @return a spell id represting this failure |
function lib:GetEventSpellId(event_name) return event_spellids[event_name] end |
--- Get a list of events where tanks do not fail, it is the responsibility of the hosting addon to determine who constitutes as a tank and ignore the event fired |
-- @see fail_events |
-- @return a table of event names which can be fired |
function lib:GetFailsWhereTanksDoNotFail() return fails_where_tanks_dont_fail end |
-- mainly for the Faction Champions - Hellfire event but could be usefull |
local snare_effects = { |
[1] = GetSpellInfo(65857), -- Entangling Roots |
[2] = GetSpellInfo(66071), -- Natures Grasp |
[3] = GetSpellInfo(65545), -- Psychic Horror |
[4] = GetSpellInfo(65543), -- Psychic Scream |
[5] = GetSpellInfo(65792), -- Frost Nova |
[6] = GetSpellInfo(65809), -- Fear |
[7] = GetSpellInfo(66613), -- Hammer of Justice |
[8] = GetSpellInfo(65930), -- Intimidating Shout |
[9] = GetSpellInfo(65880), -- Frost Trap |
[10] = GetSpellInfo(66207), -- Wing Clip |
[11] = GetSpellInfo(66020), -- Chains of Ice |
--- ICC |
[12] = GetSpellInfo(71615), -- Tear Gas -- Professor Putricide |
[13] = GetSpellInfo(70447), -- Volatile Ooze Adhesive -- Professor Putricide |
} |
function lib:IsSnared(target) |
for _, debuff in ipairs(snare_effects) do |
if debuff == UnitDebuff(target, debuff) then return true end |
end |
return false |
end |
function lib:SaurfangCheck() |
local bossId = lib:findTargetByGUID(37813) |
if not bossId then return end |
local target = UnitName(bossId .. "target") |
if target then |
if UnitIsUnit(target, lib.SaurfangTarget) then -- after 1 sec or many sec target is still same (2nd tank is failing) |
lib.SaurfangTimer = lib.SaurfangTimer + 1 -- increase the variable so we know how much he is failing |
lib:ScheduleTimer("SaurfangCheck", lib.SaurfangCheck, 1) -- check again in 1 sec if he is still failing |
else -- after 1 sec or many sec we got a new target someone either didnt fail at 1st check or this is not the 1st check so someone already failed time to report it |
if lib.SaurfangTimer > 1 then -- not the 1st check aka someone failed |
lib:FailEvent("Fail_Saurfang_Rune", lib.SaurfangTarget, lib.FAIL_TYPE_SWITCHING) |
lib.SaurfangTimer = 0 -- reset the timer after reporting |
end -- do nothing if we got a new target at the 1st check |
end |
end |
end |
function lib:GetMobId(GUID) |
if not GUID then return end |
return tonumber(GUID:sub(-12, -7), 16) |
end |
function lib:findTargetByGUID(id) |
local idType = type(id) |
for i, unit in next, lib.targetlist do |
if UnitExists(unit) and not UnitIsPlayer(unit) then |
local unitId = UnitGUID(unit) |
if idType == "number" then unitId = tonumber(unitId:sub(-12, -7), 16) end |
if unitId == id then return unit end |
end |
end |
end |
function lib:InitVariables() |
if not self.active then return end |
self.ChargeCounter = {} |
self.MalygosAlive = true |
self.BigbangCasting = false |
self.ThreePeopleHugging = false -- emalon chain lightning thing, needs a better name |
self.VezaxLeechTarget = nil |
self.DeathTime = 0 |
self.RaidTable = {} -- Mostly for the Auriaya fail, but could be usefull |
self.SindragosaSingleBeacon = 0 |
self.SindragosaBeaconTarget = nil |
self.TheLichKingNecroticPlagueTarget = {} |
self.TheLichKingNecroticPlagueDispelCounter = 0 |
self.TheLichKingShadowTrapTarget = nil |
self.DefileCastStart = 0 |
self.SaurfangTimer = 0 |
self.SaurfangTarget = nil |
self.LastEvent = {} |
self.targetlist = {"target", "targettarget", "focus", "focustarget", "mouseover", "mouseovertarget"} |
for i = 1, 4 do self.targetlist[#self.targetlist+1] = string.format("boss%d", i) end |
for i = 1, 4 do self.targetlist[#self.targetlist+1] = string.format("party%dtarget", i) end |
for i = 1, 40 do self.targetlist[#self.targetlist+1] = string.format("raid%dtarget", i) end |
-- Last whatever |
for i=1, #fail_events do |
self.LastEvent[fail_events[i]] = {} |
end |
end |
function lib:InitRaidTable() |
if next(self.RaidTable) then return end |
local difficulty = GetRaidDifficulty() |
for raidindex = 1, GetNumRaidMembers() do |
local name, _, group, _, _, _, _, online = GetRaidRosterInfo(raidindex) |
if difficulty <= 2 and group <= 2 and online then -- 10 man |
self.RaidTable[name] = true |
elseif group <= 5 and online then -- 25 man |
self.RaidTable[name] = true |
end |
end |
end |
do |
frame:Hide() |
frame:SetScript("OnUpdate", function(self, elapsed) |
for name, timer in pairs(lib.timers) do |
timer.elapsed = timer.elapsed + elapsed |
if timer.elapsed > timer.delay then |
timer.func() |
lib:CancelTimer(name) |
end |
end |
end) |
end |
function lib:ScheduleTimer(name, func, delay) |
if not self.timers then self.timers = {} end |
self.timers[name] = { |
elapsed = 0, |
func = func, |
delay = delay, |
} |
if not frame:IsShown() then frame:Show() end |
end |
function lib:CancelTimer(name) |
if not name then |
self.timers = {} |
return frame:Hide() |
end |
self.timers[name] = nil |
if not next(self.timers) then self:CancelTimer() end |
end |
function lib:IsTimerRunning(name) |
return (self.timers and self.timers[name]) and true or false |
end |
lib.FAIL_TYPE_NOTMOVING = "notmoving" -- fails at not moving with probably something on him that triggers on movement |
lib.FAIL_TYPE_MOVING = "moving" -- fails at moving out of shit |
lib.FAIL_TYPE_NOTSPREADING = "notspreading" -- fails at standing together (think auriaya) |
lib.FAIL_TYPE_SPREADING = "spreading" -- fails at not having enough distance between people |
lib.FAIL_TYPE_DISPELLING = "dispelling" -- fails at not dispelling something you should be dispelling (not very usable yes, but for completeness) |
lib.FAIL_TYPE_NOTDISPELLING = "notdispelling" -- fails at dispelling something you should NOT be dispelling |
lib.FAIL_TYPE_WRONGPLACE = "wrongplace" -- being in the wrong place in the wrong time (cleave, etc) |
lib.FAIL_TYPE_NOTCASTING = "notcasting" -- casting spells when you shouldnt have |
lib.FAIL_TYPE_NOTATTACKING = "notattacking" -- attacking when you shouldnt have |
lib.FAIL_TYPE_CASTING = "casting" -- not casting spells when you should have (think malygos phase3) |
lib.FAIL_TYPE_SWITCHING = "switching" -- not taunting/switching tanks when you're supposed to |
lib.BLOODPRINCES_FLAMES = 25000 -- make 25k default for achievment |
lib.THADDIUS_JUMP_WINDOW = 120 |
lib.THADDIUS_JUMP_RETRY_WINDOW = 5 |
lib.FROGGER_DEATH_WINDOW = 4 |
lib.YOGGSARON_GAZE_THRESHOLD = 15 -- after how many ticks do we fail? |
lib.VEZAX_LEECH_THRESHOLD = 400000 -- how much heal is "acceptable" |
lib.EMALON_NOVA_THRESHOLD = 15000 -- on being hit by lightning nova, above what dmg does it take for it to be a fail (think DK-s with AMS) |
lib.ONYXIA_DEEPBREATH_THRESHOLD = 5000 -- same as above |
lib.COUNCIL_OVERLOAD_THRESHOLD = 4000 -- ^ |
lib.ALGALON_SMASH_THRESHOLD = 7000 |
lib.COUNCIL_RUNE_THRESHOLD = 3 -- the player got 3 seconds to move out of Rune of Death |
lib.SINDRAGOSA_FROSTBOMB_THRESHOLD = 5000 |
lib.SINDRAGOSA_BLISTERINGCOLD_THRESHOLD = 10000 |
lib.HODIR_COLD_THRESHOLD = 2 -- stacks needed for a fail |
do |
local _, etype, f |
frame:SetScript("OnEvent", function (self, event, ...) |
if event == "COMBAT_LOG_EVENT_UNFILTERED" then |
_, etype = ... |
if etype == "SPELL_MISSED" then -- lets hack the misses onto the damage event |
local timestamp, _, sourceGUID, sourceName, sourceFlags, destGUID, destName, destFlags, spellId, spellName, spellSchool, missType, amountMissed = ... |
local damage, overkill = 0, 0 |
lib.SPELL_DAMAGE(lib, timestamp, etype, sourceGUID, sourceName, sourceFlags, destGUID, destName, destFlags, spellId, spellName, spellSchool, damage, overkill, missType, amountMissed) |
return |
end |
f = lib[etype] |
if f then |
f(lib, ...) |
end |
return |
end |
f = lib[event] |
if f then |
f(lib, ...) |
end |
end) |
end |
function lib:FailEvent(failname, playername, failtype, ...) |
callbacks:Fire(failname, playername, failtype, ...) |
callbacks:Fire("AnyFail", failname, playername, failtype, ...) |
end |
function lib:GoActive() |
if self.active then return end |
frame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED") |
frame:RegisterEvent("PLAYER_REGEN_ENABLED") |
frame:RegisterEvent("CHAT_MSG_MONSTER_EMOTE") |
self:InitVariables() |
self.active = true |
callbacks:Fire("Fail_Active") |
end |
function lib:GoInactive() |
if not self.active then return end |
self:InitVariables() |
self.active = nil |
frame:RegisterEvent("RAID_ROSTER_UPDATE") |
frame:UnregisterEvent("CHAT_MSG_MONSTER_EMOTE") |
frame:UnregisterEvent("COMBAT_LOG_EVENT_UNFILTERED") |
frame:UnregisterEvent("PLAYER_REGEN_ENABLED") |
callbacks:Fire("Fail_Inactive") |
end |
lib.active = true |
lib:GoInactive() |
function lib:PLAYER_ENTERING_WORLD(...) |
if GetNumRaidMembers() > 0 then |
self:GoActive() |
else |
self:GoInactive() |
end |
end |
function lib:RAID_ROSTER_UPDATE(...) |
if GetNumRaidMembers() > 0 then |
self:GoActive() |
else |
self:GoInactive() |
end |
end |
function lib:PLAYER_REGEN_ENABLED() |
self:InitVariables() |
end |
local ominous_cloud_name = GetSpellInfo(60977) |
function lib:CHAT_MSG_MONSTER_EMOTE(message, sourceName, language, channelName, destName, ...) |
-- Yogg-Saron - Ominous Cloud (spawning new mobs in phase 1) |
if sourceName:find(ominous_cloud_name) then |
self:FailEvent("Fail_Yogg_OminousCloud", destName, self.FAIL_TYPE_NOTMOVING) |
end |
end |
local onyxia_breath_name = GetSpellInfo(18351) |
function lib:SPELL_DAMAGE(timestamp, type, sourceGUID, sourceName, sourceFlags, destGUID, destName, destFlags, spellId, spellName, spellSchool, damage, overkill) |
-- Guardian activities ignored after this point |
--5/7 21:13:33.865 SPELL_DAMAGE,0xF1300079F0003A98,"Mirror Image",0x2114,0xF130008092003842,"Elder Stonebark",0xa48,59637,"Fire Blast",0x4,139,0,4,0,0,0,nil,nil,nil |
--5/7 21:13:36.092 SPELL_HEAL,0x01800000007C56B2,"Blackknite",0x512,0xF1300079F0003A97,"Mirror Image",0x2114,54968,"Glyph of Holy Light",0x2,1240,1240,nil |
if bit.band(sourceFlags or 0, COMBATLOG_OBJECT_TYPE_GUARDIAN) > 0 or bit.band(destFlags or 0, COMBATLOG_OBJECT_TYPE_GUARDIAN) > 0 or not spellId then return end |
local is_playerevent = bit.band(destFlags or 0, COMBATLOG_OBJECT_TYPE_PLAYER) > 0 |
damage = damage ~= "ABSORB" and damage or 0 |
overkill = overkill or 0 |
-- Malygos - Arcane Breath(the cone attack, credits to mysticalos and Aviana) |
if (spellId == 56272 or spellId == 60072) and is_playerevent and overkill > 0 then |
self:FailEvent("Fail_Malygos_ArcaneBreath", destName, self.FAIL_TYPE_WRONGPLACE) |
return |
end |
-- Halion - Twilight Cutter |
if (spellId == 74769 or spellId == 77844 or spellId == 77845 or spellId == 77846) and is_playerevent and overkill > 0 then |
self:FailEvent("Fail_Halion_TwilightCutter", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- Halion - Meteor Strike (first 4 are impact, you died cause you let meteor land on you, rest are from standing in fire after impact. Seems to have various spellids for range from center) |
if (spellId == 74648 or spellId == 75877 or spellId == 75878 or spellId == 75879 |
or spellId == 75952 or spellId == 75951 or spellId == 75950 or spellId == 75949 or spellId == 75948 or spellId == 75947) and is_playerevent and overkill > 0 then |
self:FailEvent("Fail_Halion_MeteorStrike", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- Icecrown Citadel |
-- The Lich King - Shockwave |
if (spellId == 73794 or spellId == 73795 or spellId == 72149 or spellId == 73796) and is_playerevent then |
self:FailEvent("Fail_TheLichKing_Shockwave", destName, self.FAIL_TYPE_WRONGPLACE) |
return |
end |
-- The Lich King - Defile |
if (spellId == 73708 or spellId == 73709 or spellId == 72754 or spellId == 73710) and is_playerevent then |
if (((timestamp - self.DefileCastStart) > 3.3) and ((timestamp - self.DefileCastStart) < 5)) then -- cast time is 2 sec, and we are only interested in fails at the first 3 sec, after that its just all spam, but lets give you 1.3 sec to move out |
self:FailEvent("Fail_TheLichKing_Defile", destName, self.FAIL_TYPE_NOTMOVING) |
end |
return |
end |
-- The Lich King - Spirit Bomb |
if (spellId == 73804 or spellId == 73805) and is_playerevent then |
self:FailEvent("Fail_TheLichKing_SpiritBomb", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- The Lich King - Shadow Trap |
if spellId == 73529 and is_playerevent then |
if self.LastEvent.Fail_TheLichKing_ShadowTrap[destName] == nil then |
self:FailEvent("Fail_TheLichKing_ShadowTrap", destName, self.FAIL_TYPE_NOTMOVING) |
self.LastEvent.Fail_TheLichKing_ShadowTrap[destName] = timestamp |
else |
if (timestamp - self.LastEvent.Fail_TheLichKing_ShadowTrap[destName]) > 5 then |
self:FailEvent("Fail_TheLichKing_ShadowTrap", destName, self.FAIL_TYPE_NOTMOVING) |
end |
end |
self.LastEvent.Fail_TheLichKing_ShadowTrap[destName] = timestamp |
return |
end |
-- Frogger like fail for the Coldflame Trap after Deathbringers Rise |
if spellId == 70461 and is_playerevent and overkill > 0 then |
self:FailEvent("Fail_ColdflameTrap", destName, self.FAIL_TYPE_WRONGPLACE) |
return |
end |
-- Gunship -- Explosion Knockback (heroic only) |
if (spellId == 69688 or spellId == 69689) and is_playerevent then |
self:FailEvent("Fail_Gunship_Explosion_Knockback", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- Gunship -- Explosion (it's still avoidable so optional fail for normal mode) |
if (spellId == 69680 or spellId == 69687) and is_playerevent then |
self:FailEvent("Fail_Gunship_Explosion", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
--11/13 19:42:32.500 SPELL_DAMAGE,0x0100000000004105,"Fenitalol",0x514,0x010000000004AB38,"Belth",0x514,72815,"Systemic Shock Vortex",0x1,4477,227,1,0,0,0,nil,nil,nil |
-- Blood Princes -- Systemic Shock Vortex |
if (spellId == 72815 or spellId == 72816 or spellId == 72817 or spellId == 72038) and is_playerevent and overkill > 0 then |
if bit.band(sourceFlags or 0, COMBATLOG_OBJECT_TYPE_PLAYER) > 0 then |
self:FailEvent("Fail_BloodPrinces_SystemicShockVortex", destName, self.FAIL_TYPE_NOTSPREADING) |
end |
return |
end |
-- Blood Princes -- Flames |
if spellId == 72789 and is_playerevent and damage > self.BLOODPRINCES_FLAMES then |
self:FailEvent("Fail_BloodPrinces_Flames", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- Blood Queen Lana'thel -- Swarming Shadows |
if (spellId == 71268 or spellId == 72635 or spellId == 72636 or spellId == 72637) and is_playerevent and overkill > 0 then |
self:FailEvent("Fail_LanaThel_SwarmingShadows", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- Blood Queen Lana'thel - Pact of the Darkfallen |
if spellId == 71341 and is_playerevent and overkill > 0 then |
self:FailEvent("Fail_LanaThel_Pact", destName, self.FAIL_TYPE_WRONGPLACE) |
return |
end |
-- Blood Queen Lana'thel - Bloodbolt Splash |
if (spellId == 71447 or spellId == 71481 or spellId == 71482 or spellId == 71483) and is_playerevent and overkill > 0 then |
self:FailEvent("Fail_LanaThel_BloodboltSplash", destName, self.FAIL_TYPE_NOTSPREADING) |
return |
end |
-- Valithria Dreamwalker - Column of Frost |
if (spellId == 70702 or spellId == 71746 or spellId == 72019 or spellId == 72020) and is_playerevent then |
self:FailEvent("Fail_Valithria_ColumnofFrost", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- Festergut - Pungent Blight |
if (spellId == 71219 or spellId == 69195) and is_playerevent and overkill > 0 then |
self:FailEvent("Fail_Festergut_PungentBlight", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- Lady Deathwhisper Vengeful Shades Explosion(Melee are responsible for not standing in this if they target a tank.) |
-- Tanks exempt though because a tank isn't going to kite the boss or adds around room just to dodge these |
if (spellId == 71544 or spellId == 72010 or spellId == 72011 or spellId == 72012) and is_playerevent and overkill > 0 then |
self:FailEvent("Fail_Deathwhisper_ShadeExplosion", destName, self.FAIL_TYPE_MOVING) |
self.LastEvent.Fail_Deathwhisper_ShadeExplosion[destName] = timestamp |
return |
end |
-- Lord Marrowgar - Whirlwind |
if (spellId == 69075 or (spellId >= 70834 and spellId <= 70836)) and is_playerevent and overkill > 0 then |
self:FailEvent("Fail_Marrowgar_Whirlwind", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- Lord Marrowgar - Saber Lash (69055 trash mobs leading to marrowgar, other 2 marrowgar. Leaving all 3 since announcing fails on the trash still amusing) |
if (spellId == 69055 or spellId == 70814 or spellId == 71021) and is_playerevent and overkill > 0 then |
self:FailEvent("Fail_Marrowgar_SaberLash", destName, self.FAIL_TYPE_WRONGPLACE) |
return |
end |
-- Rotface - Sticky Ooze (the slime pools) |
if (spellId == 69778 or spellId == 71208 or spellId == 69776 or spellId == 69774) and is_playerevent then |
if self.LastEvent.Fail_Rotface_StickyOoze[destName] ~= nil then |
if (timestamp - self.LastEvent.Fail_Rotface_StickyOoze[destName]) > 3 then |
self:FailEvent("Fail_Rotface_StickyOoze", destName, self.FAIL_TYPE_NOTMOVING) |
end |
end |
self.LastEvent.Fail_Rotface_StickyOoze[destName] = timestamp |
return |
end |
-- Rotface - Slime Spray |
if (spellId == 69507 or spellId == 71213 or spellId == 73189 or spellId == 73190) and is_playerevent then |
if self.LastEvent.Fail_Rotface_SlimeSpray[destName] ~= nil then |
if (timestamp - self.LastEvent.Fail_Rotface_SlimeSpray[destName]) > 3 then |
self:FailEvent("Fail_Rotface_SlimeSpray", destName, self.FAIL_TYPE_NOTMOVING) |
end |
end |
self.LastEvent.Fail_Rotface_SlimeSpray[destName] = timestamp |
return |
end |
-- Rotface - Unstable Ooze Explosion |
if (spellId == 69839 or spellId == 71209 or spellId == 69833 or spellId == 69832) and is_playerevent then |
self:FailEvent("Fail_Rotface_OozeExplosion", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- Sindragosa - Tail Smash |
if (spellId == 71077) and is_playerevent then |
self:FailEvent("Fail_Sindragosa_TailSmash", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- Sindragosa - Frost Breath |
if (spellId == 69649 or spellId == 71056 or spellId == 71057 or spellId == 71058 |
or spellId == 73061 or spellId == 73062 or spellId == 73063 or spellId == 73064) and is_playerevent and overkill > 0 then |
self:FailEvent("Fail_Sindragosa_FrostBreath", destName, self.FAIL_TYPE_WRONGPLACE) |
return |
end |
-- Sindragosa - Blistering Cold |
if (spellId == 70123 or spellId == 71047 or spellId == 71048 or spellId == 71049) and is_playerevent and damage > self.SINDRAGOSA_BLISTERINGCOLD_THRESHOLD then |
self:FailEvent("Fail_Sindragosa_BlisteringCold", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- Sindragosa - Cleave |
if spellId == 19983 and is_playerevent and overkill > 0 then |
if self:GetMobId(sourceGUID) ~= 36853 then return end |
self:FailEvent("Fail_Sindragosa_Cleave", destName, self.FAIL_TYPE_WRONGPLACE) |
return |
end |
-- Sindragosa - Frost Bomb |
if (spellId == 69845 or spellId == 71053 or spellId == 71054 or spellId == 71055) and is_playerevent and damage > self.SINDRAGOSA_FROSTBOMB_THRESHOLD then |
self:FailEvent("Fail_Sindragosa_FrostBomb", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- Sindragosa - Backlash (the damage part of Unchained Magic/Instability stacks) |
if (spellId == 69770 or spellId == 71044) and is_playerevent and overkill > 0 then |
self:FailEvent("Fail_Sindragosa_Instability", destName, self.FAIL_TYPE_NOTCASTING) |
return |
end |
-- Sindragosa - Backlash-Heroic (This damages you AND anyone near you. this fail means you killed everyone near you) UNTESTED |
if (spellId == 71045 or spellId == 71046) and is_playerevent and overkill > 0 then |
self:FailEvent("Fail_Sindragosa_Instability", sourceName, self.FAIL_TYPE_NOTCASTING) |
return |
end |
-- Saurfang Rune of Blood (More than 1 heal per taunt, 1 is super hard to avoid no matter how fast you taunt) |
if (spellId == 72409 or spellId == 72447 or spellId == 72448 or spellId == 72449) and is_playerevent then |
self.SaurfangTarget = destName |
lib:ScheduleTimer("SaurfangCheck", lib.SaurfangCheck, 1) -- start the check in 1 sec |
return |
end |
-- The Lich King - Ice Burst |
if spellId == 73773 and is_playerevent then |
self:FailEvent("Fail_TheLichKing_IceBurst", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- The Lich King - Remorseless Winter |
if (spellId == 68981 or spellId == 68983 or spellId == 73791 or spellId == 73792 or spellId == 73793) and is_playerevent and overkill > 0 then |
self:FailEvent("Fail_TheLichKing_RemorselessWinter", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- Professor - Mutated Slime |
if spellId == 72456 and is_playerevent and damage > 0 then--Only one spellid seems needed, it seems the other IDs are server side and only thing sent to combat log is a dummyID for any difficulty |
if self:IsSnared(destName) then return end |
if self.LastEvent.Fail_Professor_MutatedSlime[destName] ~= nil then |
local deltaT = (timestamp - self.LastEvent.Fail_Professor_MutatedSlime[destName]) |
if (((deltaT) > 3) and ((deltaT) < 9)) then--If >3 times threshold reset timestamp since it's probably from earlier fight and not genuine fail. |
self:FailEvent("Fail_Professor_MutatedSlime", destName, self.FAIL_TYPE_NOTMOVING) |
else |
self.LastEvent.Fail_Professor_MutatedSlime[destName] = timestamp |
end |
end |
self.LastEvent.Fail_Professor_MutatedSlime[destName] = timestamp |
return |
end |
-- Festergut Heroic -- Malleable goo (Debuff) |
if (spellId == 72549 or spellId == 72550) and is_playerevent and (damage > 10000 or overkill > 0) then |
if self.LastEvent.Fail_Festergut_MalleableGoo[destName] ~= nil then |
if (timestamp - self.LastEvent.Fail_Festergut_MalleableGoo[destName]) > 3 then |
self:FailEvent("Fail_Festergut_MalleableGoo", destName, self.FAIL_TYPE_NOTMOVING) |
end |
else |
self:FailEvent("Fail_Festergut_MalleableGoo", destName, self.FAIL_TYPE_NOTMOVING) |
end |
self.LastEvent.Fail_Festergut_MalleableGoo[destName] = timestamp |
return |
end |
-- Professor - Malleable Goo (Debuff) |
if (spellId == 70853 or spellId == 72458 or spellId == 72873 or spellId == 72874) and is_playerevent and (damage > 10000 or overkill > 0) then |
if self:IsSnared(destName) then return end |
if self.LastEvent.Fail_Professor_MalleableGoo[destName] ~= nil then |
if (timestamp - self.LastEvent.Fail_Professor_MalleableGoo[destName]) > 3 then |
self:FailEvent("Fail_Professor_MalleableGoo", destName, self.FAIL_TYPE_NOTMOVING) |
end |
else |
self:FailEvent("Fail_Professor_MalleableGoo", destName, self.FAIL_TYPE_NOTMOVING) |
end |
self.LastEvent.Fail_Professor_MalleableGoo[destName] = timestamp |
return |
end |
-- Professor - Choking Gas (Damage) |
if (spellId == 72460 or spellId == 72619 or spellId == 72620 or spellId == 71278 |
or spellId == 71279 or spellId == 72459 or spellId == 72621 or spellId == 72622) and is_playerevent and overkill > 0 then |
if self:IsSnared(destName) then return end |
self:FailEvent("Fail_Professor_ChokingGas", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- VAULT OF ARCHAVON |
-- Emalon - Lightning Nova |
if (spellId == 65279 or spellId == 64216) and is_playerevent and damage >= self.EMALON_NOVA_THRESHOLD then |
self:FailEvent("Fail_Emalon_LightningNova", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- Emalon - Chain Lightning |
if (spellId == 64213 or spellId == 64215) and is_playerevent then |
if damage >= 10000 then -- at least 3 ppl hugging, and I think highest damage appears in combat log first always (Maat @Ensidiafails) |
self.ThreePeopleHugging = true |
self:ScheduleTimer("EmalonChainLightning", function() lib.ThreePeopleHugging = false end, 3) |
end |
if self.ThreePeopleHugging then |
if self.LastEvent.Fail_Emalon_ChainLightning.time ~= nil then |
if (timestamp - self.LastEvent.Fail_Emalon_ChainLightning.time) < 1 then |
self:FailEvent("Fail_Emalon_ChainLightning", destName, self.FAIL_TYPE_NOTSPREADING) |
end |
end |
self.LastEvent.Fail_Emalon_ChainLightning.time = timestamp |
end |
return |
end |
-- Koralon - Flame Cinder |
if (spellId == 67332 or spellId == 66684) and is_playerevent then |
if self.LastEvent.Fail_Koralon_FlameCinder[destName] ~= nil then |
local deltaT = (timestamp - self.LastEvent.Fail_Koralon_FlameCinder[destName]) |
if (((deltaT) > 2) and ((deltaT) < 6)) then--If >3 times threshold reset timestamp since it's probably from earlier fight and not genuine fail. |
self:FailEvent("Fail_Koralon_FlameCinder", destName, self.FAIL_TYPE_NOTMOVING) |
else |
self.LastEvent.Fail_Koralon_FlameCinder[destName] = timestamp |
end |
end |
self.LastEvent.Fail_Koralon_FlameCinder[destName] = timestamp |
return |
end |
-- ONYXIA'S LAIR |
-- Onyxian Lair Guard - Blast Nova |
if spellId == 68958 and overkill > 0 and is_playerevent then |
self:FailEvent("Fail_Onyxia_WarderNova", destName, self.FAIL_TYPE_WRONGPLACE) |
return |
end |
-- Onyxian Warder - Cleave |
--10/21 21:44:57.024 SPELL_DAMAGE,0xF130002F610053DF,"Onyxian Warder",0xa48,0x05000000025092DE,"Nopher",0x514,15284,"Cleave",0x1,8816,0,1,0,0,2120,nil,nil,nil |
if spellId == 15284 and overkill > 0 and is_playerevent then |
if self:GetMobId(sourceGUID) ~= 12129 then return end |
self:FailEvent("Fail_Onyxia_WarderCleave", destName, self.FAIL_TYPE_WRONGPLACE) |
return |
end |
-- Onyxia - Cleave |
if spellId == 68868 and overkill > 0 and is_playerevent then |
if UnitDebuff(destName, GetSpellInfo(18431)) then return end -- target afflicted by fear, dont fail it |
self:FailEvent("Fail_Onyxia_Cleave", destName, self.FAIL_TYPE_WRONGPLACE) |
return |
end |
-- Onyxia - Deep Breath (when flying) |
-- The deal with the spellIds is that it depends on WHERE onyxia is, from that point |
-- every breath has 8 corresponding spellIds (the farther you are the less dmg, well |
-- those are seperate spells, there are ~90 spellids, so we check for the name instead (idea by mysticalos)) |
if spellName == onyxia_breath_name and is_playerevent then |
if overkill > 0 or damage >= self.ONYXIA_DEEPBREATH_THRESHOLD then |
if self.LastEvent.Fail_Onyxia_DeepBreath[destName] ~= nil then |
if (timestamp - self.LastEvent.Fail_Onyxia_DeepBreath[destName]) > 5 then |
self:FailEvent("Fail_Onyxia_DeepBreath", destName, self.FAIL_TYPE_NOTMOVING) |
end |
else |
self:FailEvent("Fail_Onyxia_DeepBreath", destName, self.FAIL_TYPE_NOTMOVING) |
end |
self.LastEvent.Fail_Onyxia_DeepBreath[destName] = timestamp |
end |
return |
end |
-- Onyxia - Flame Breath (the cone attack) |
if (spellId == 68970 or spellId == 18435) and is_playerevent then -- not a fail for tanks, but we dont care about that here |
if UnitDebuff(destName, GetSpellInfo(18431)) then return end -- target afflicted by fear, dont fail it |
self:FailEvent("Fail_Onyxia_FlameBreath", destName, self.FAIL_TYPE_WRONGPLACE) |
return |
end |
-- Onyxia - Tail Sweep |
if (spellId == 69286 or spellId == 68867) and is_playerevent then |
if UnitDebuff(destName, GetSpellInfo(18431)) then return end -- target afflicted by fear, dont fail it |
self:FailEvent("Fail_Onyxia_TailSweep", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- TRIAL OF THE CRUSADER |
-- Northrend Beasts - Gormok - Fire Bomb |
if spellId == 66317 and is_playerevent then -- the initial damage from whence you have 2 seconds to move |
self.LastEvent.Fail_Gormok_FireBomb[destName] = timestamp |
return |
elseif (spellId == 67472 or spellId == 66320 or spellId == 67475 or spellId == 67473) and is_playerevent then |
if not self.LastEvent.Fail_Gormok_FireBomb[destName] then |
-- no initial damage, so the failer managed to go into the flame on the ground, good job |
self.LastEvent.Fail_Gormok_FireBomb[destName] = timestamp |
end |
if (timestamp - self.LastEvent.Fail_Gormok_FireBomb[destName]) > 2 then |
self:FailEvent("Fail_Gormok_FireBomb", destName, self.FAIL_TYPE_NOTMOVING) |
self.LastEvent.Fail_Gormok_FireBomb[destName] = timestamp -- so as not to spam |
end |
return |
end |
-- Northrend Beasts - Acidmaw - Slime Pool (only trigger on damage, touching the slime pool should'nt be a fail) |
if (spellId == 66881 or spellId == 67638 or spellId == 67639 or spellId == 67640) and is_playerevent then |
if UnitDebuff(destName, GetSpellInfo(67618)) then return end -- Paralytic Toxin (if the dude can't move, let's not fail him/her) |
if self.LastEvent.Fail_Acidmaw_SlimePool[destName] ~= nil then |
if (timestamp - self.LastEvent.Fail_Acidmaw_SlimePool[destName]) > 3 then |
self:FailEvent("Fail_Acidmaw_SlimePool", destName, self.FAIL_TYPE_NOTMOVING) |
end |
else |
self:FailEvent("Fail_Acidmaw_SlimePool", destName, self.FAIL_TYPE_NOTMOVING) |
end |
self.LastEvent.Fail_Acidmaw_SlimePool[destName] = timestamp |
return |
end |
-- Northrend Beasts - Dreadscale - Molten Spew (the cone attack (breath)) |
if (spellId == 66820 or spellId == 67635 or spellId == 67636 or spellId == 67637) and overkill > 0 and is_playerevent then |
self:FailEvent("Fail_Dreadscale_MoltenSpew", destName, self.FAIL_TYPE_WRONGPLACE) |
return |
end |
-- Northrend Beasts - Acidmaw - Acidic Spew (the cone attack (breath)) |
if (spellId == 66819 or spellId == 67609 or spellId == 67610 or spellId == 67611) and overkill > 0 and is_playerevent then |
self:FailEvent("Fail_Acidmaw_AcidicSpew", destName, self.FAIL_TYPE_WRONGPLACE) |
return |
end |
-- Northrend Beasts - Icehowl - Trample |
if spellId == 66734 and is_playerevent then |
self:FailEvent("Fail_Icehowl_Trample", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- Lord Jaraxxus - Legion Flame |
if (spellId == 67072 or spellId == 67070 or spellId == 66877 or spellId == 67071) and overkill > 0 and is_playerevent then |
self:FailEvent("Fail_Jaraxxus_LegionFlame", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- Lord Jaraxxus - Fel Inferno |
if (spellId == 68718 or spellId == 66496 or spellId == 68716 or spellId == 68717) and is_playerevent and overkill > 0 then |
self:FailEvent("Fail_Jaraxxus_FelInferno", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- Faction Champions - Hellfire |
if (spellId == 65817 or spellId == 68142 or spellId == 68143 or spellId == 68144) and is_playerevent and overkill > 0 then |
self:FailEvent("Fail_FactionChampions_Hellfire", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- Faction Champions - Bladestorm |
if spellId == 65946 and is_playerevent and overkill > 0 then |
self:FailEvent("Fail_FactionChampions_Bladestorm", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- Twin Val'kyr - Unleashed Light / Dark (the orbs, only from heroic) |
if (spellId == 67174 or spellId == 67240 or spellId == 67173 or spellId == 67239) and is_playerevent and damage > 0 and overkill > 0 then |
self:FailEvent("Fail_Valkyr_Orb", destName, self.FAIL_TYPE_NOTMOVING) |
return |
-- Twin Val'kyr - Unleashed Light / Dark (the rest of the orbs) |
elseif (spellId == 65808 or spellId == 67172 or spellId == 65795 or spellId == 67238) and is_playerevent and damage > 0 and overkill > 0 then |
self:FailEvent("Fail_Valkyr_Orb", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- Twin Val'kyr - Light / Dark Vortex - Non-Heroic (it's a fail only on death) |
-- When you have the correct color you resist the vortex with 100% chance |
-- but because we hax the SPELL_MISS event onto the SPELL_DAMAGE event, we must |
-- check for the damage done |
if (spellId == 67155 or spellId == 67203 or spellId == 66048 or spellId == 66059) and damage > 0 and overkill > 0 and is_playerevent then |
self:FailEvent("Fail_Valkyr_Vortex", destName, self.FAIL_TYPE_NOTMOVING) |
return |
-- Twin Val'kyr - Light / Dark Vortex - Heroic |
elseif (spellId == 67205 or spellId == 67157 or spellId == 67156 or spellId == 67204) and damage > 0 and overkill > 0 and is_playerevent then |
self:FailEvent("Fail_Valkyr_Vortex", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- Anub'arak - Impale |
if (spellId == 65919 or spellId == 67860 or spellId == 67858 or spellId == 67859) and overkill > 0 and is_playerevent then |
self:FailEvent("Fail_Anubarak_Impale", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- ULDUAR |
-- Kologarn Eyebeam |
if (spellId == 63976 or spellId == 63346) and is_playerevent then |
if self.LastEvent.Fail_Kologarn_Eyebeam[destName] ~= nil then |
if (timestamp - self.LastEvent.Fail_Kologarn_Eyebeam[destName]) > 5 then |
self:FailEvent("Fail_Kologarn_Eyebeam", destName, self.FAIL_TYPE_NOTMOVING) |
end |
else |
self:FailEvent("Fail_Kologarn_Eyebeam", destName, self.FAIL_TYPE_NOTMOVING) |
end |
self.LastEvent.Fail_Kologarn_Eyebeam[destName] = timestamp |
return |
end |
-- Auriaya - Sonic Screech (not standing in it is a fail) |
-- Look in CAST_START for the details |
if (spellId == 64688 or spellId == 64422) and is_playerevent then |
self.RaidTable[destName] = false |
return |
end |
-- Auriaya Void Zone (not a fail if stunned by the kitty) |
if (spellId == 64459 or spellId == 64675) and is_playerevent then |
if UnitDebuff(destName, GetSpellInfo(64386)) then return end |
if self.LastEvent.Fail_Auriaya_Voidzone[destName] ~= nil then |
local deltaT = (timestamp - self.LastEvent.Fail_Auriaya_Voidzone[destName]) |
if (((deltaT) > 3) and ((deltaT) < 9)) then--If >3 times threshold reset timestamp since it's probably from earlier fight and not genuine fail. |
self:FailEvent("Fail_Auriaya_Voidzone", destName, self.FAIL_TYPE_NOTMOVING) |
else |
self.LastEvent.Fail_Auriaya_Voidzone[destName] = timestamp |
end |
end |
self.LastEvent.Fail_Auriaya_Voidzone[destName] = timestamp |
return |
end |
-- Razorscale Flame |
if (spellId == 64733 or spellId == 64704) and is_playerevent then |
if self.LastEvent.Fail_Razorscale_Flame[destName] ~= nil then |
local deltaT = (timestamp - self.LastEvent.Fail_Razorscale_Flame[destName]) |
if (((deltaT) > 2) and ((deltaT) < 6)) then--If >3 times threshold reset timestamp since it's probably from earlier fight and not genuine fail. |
self:FailEvent("Fail_Razorscale_Flame", destName, self.FAIL_TYPE_NOTMOVING) |
else |
self.LastEvent.Fail_Razorscale_Flame[destName] = timestamp |
end |
end |
self.LastEvent.Fail_Razorscale_Flame[destName] = timestamp |
return |
end |
-- Yogg Saron Death Ray |
if (spellId == 63884 or spellId == 63891) and is_playerevent then |
if self.LastEvent.Fail_Yogg_DeathRay[destName] ~= nil then |
if (timestamp - self.LastEvent.Fail_Yogg_DeathRay[destName]) > 5 then |
self:FailEvent("Fail_Yogg_DeathRay", destName, self.FAIL_TYPE_NOTMOVING) |
end |
else |
self:FailEvent("Fail_Yogg_DeathRay", destName, self.FAIL_TYPE_NOTMOVING) |
end |
self.LastEvent.Fail_Yogg_DeathRay[destName] = timestamp |
return |
end |
-- Yogg-Saron - Lunatic Gaze |
if (spellId == 64168 or spellId == 64164) and is_playerevent then |
if not self.LastEvent.Fail_Yogg_LunaticGaze[destName] then self.LastEvent.Fail_Yogg_LunaticGaze[destName] = 1 end |
if spellId == 64168 then -- Yogg-Saron's lunatic gaze, not so serious |
self.LastEvent.Fail_Yogg_LunaticGaze[destName] = self.LastEvent.Fail_Yogg_LunaticGaze[destName] + 1 |
else -- Laughing Skull's lunatic gaze, more serious |
self.LastEvent.Fail_Yogg_LunaticGaze[destName] = self.LastEvent.Fail_Yogg_LunaticGaze[destName] + 2 |
end |
if self.LastEvent.Fail_Yogg_LunaticGaze[destName] >= self.YOGGSARON_GAZE_THRESHOLD then |
self.LastEvent.Fail_Yogg_LunaticGaze[destName] = 0 |
self:FailEvent("Fail_Yogg_LunaticGaze", destName, self.FAIL_TYPE_NOTMOVING) |
end |
return |
end |
-- Algalon - Cosmic Smash |
if (spellId == 62311 or spellId == 64596) and is_playerevent and damage >= self.ALGALON_SMASH_THRESHOLD then |
if self.LastEvent.Fail_Algalon_CosmicSmash[destName] ~= nil then |
if (timestamp - self.LastEvent.Fail_Algalon_CosmicSmash[destName]) > 2 then |
self:FailEvent("Fail_Algalon_CosmicSmash", destName, self.FAIL_TYPE_NOTMOVING) |
end |
else |
self:FailEvent("Fail_Algalon_CosmicSmash", destName, self.FAIL_TYPE_NOTMOVING) |
end |
self.LastEvent.Fail_Algalon_CosmicSmash[destName] = timestamp |
return |
end |
-- Algalon - Big Bang |
if (spellId == 64584 or spellId == 64443) and is_playerevent and overkill > 0 then |
self:FailEvent("Fail_Algalon_BigBang", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- Freya Nature Bomb |
if (spellId == 64650 or spellId == 64587) and is_playerevent then |
if UnitDebuff(destName, GetSpellInfo(62861)) then return end |
self:FailEvent("Fail_Freya_NatureBomb", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- Hodir Icicle (aka Ice Shards) |
if (spellId == 62457 or spellId == 65370) and is_playerevent then |
self:FailEvent("Fail_Hodir_Icicle", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- EnsidiaFails - Maat |
-- Hodir Biting Cold |
if (spellId == 62038 or spellId == 62188) and is_playerevent then |
local stack = select(4, UnitDebuff(destName, GetSpellInfo(62039))) |
if stack ~= nil and stack > self.HODIR_COLD_THRESHOLD then |
if self.LastEvent.Fail_Hodir_BitingCold[destName] == nil or (timestamp - self.LastEvent.Fail_Hodir_BitingCold[destName]) > 5 then |
self:FailEvent("Fail_Hodir_BitingCold", destName, self.FAIL_TYPE_NOTMOVING) |
self.LastEvent.Fail_Hodir_BitingCold[destName] = timestamp |
end |
end |
return |
end |
-- Council Overload |
if (spellId == 61878 or spellId == 63480) and is_playerevent and damage >= self.COUNCIL_OVERLOAD_THRESHOLD then -- DKs with AMS shouln't fail |
if self:GetMobId(sourceGUID) ~= 32857 then return end |
self:FailEvent("Fail_Council_Overload", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- XT-002 Deconstructor: Light Bomb |
if (spellId == 65120 or spellId == 63023) and sourceGUID ~= destGUID and is_playerevent then |
if self.LastEvent.Fail_Deconstructor_Light[sourceName] ~= nil then |
if (timestamp - self.LastEvent.Fail_Deconstructor_Light[sourceName]) > 9 then--Reset timestamp if you were out of it for a while to prevent instant fails from outdated timestamps from earlier fight. |
self.LastEvent.Fail_Deconstructor_Light[sourceName] = timestamp |
elseif (timestamp - self.LastEvent.Fail_Deconstructor_Light[sourceName]) > 3 then |
self:FailEvent("Fail_Deconstructor_Light", sourceName, self.FAIL_TYPE_NOTMOVING) |
end |
end |
self.LastEvent.Fail_Deconstructor_Light[sourceName] = timestamp |
return |
end |
-- XT-002 Deconstructor: Gravity Bomb (bomb part) |
if (spellId == 64233 or spellId == 63025) and sourceGUID ~= destGUID and is_playerevent then |
if self.LastEvent.Fail_Deconstructor_Gravity[sourceName] ~= nil then |
self:FailEvent("Fail_Deconstructor_Gravity", sourceName, self.FAIL_TYPE_NOTMOVING) |
self.LastEvent.Fail_Deconstructor_Gravity[sourceName] = nil |
end |
return |
end |
-- XT-002 Deconstructor - Void Zone (on heroic, what the gravity bomb leaves behind) |
--5/7 18:19:04.078 SPELL_DAMAGE,0xF1300084D1002E23,"Void Zone",0xa48,0x0300000001D3239F,"Diomache",0x514,64208,"Consumption",0x20,6258,0,32,0,0,0,nil,nil,nil |
if (spellId == 64208 or spellId == 64206) and is_playerevent then |
self:FailEvent("Fail_Deconstructor_Voidzone", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- Failbot - Viiv |
-- 4/16 22:06:17.885 SPELL_DAMAGE,0xF1300081F702D928,"General Vezax",0x10a48,0x05000000027FCDFE,"Kosie",0x514,62659,"Shadow Crash",0x20,9413,0,32,2285,0,0,nil,nil,nil |
-- Vezax Shadow Crash |
if (spellId == 62659 or spellId == 63277) and is_playerevent and damage > 0 then |
self:FailEvent("Fail_Vezax_ShadowCrash", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- Vezax Saronite Vapor Suicide |
if spellId == 63338 and is_playerevent then |
self.LastEvent.Fail_Vezax_Saronite[destName] = timestamp |
return |
end |
-- Failbot - Viiv |
-- 4/16 18:20:24.295 SPELL_DAMAGE,0xF130008061018374,"Thorim",0x8010a48,0x0500000001E8AF39,"Thefeint",0x514,62466,"Lightning Charge",0x8,8977,0,8,3966,0,0,nil,nil,nil |
-- Thorim Lightning Charge |
if spellId == 62466 and is_playerevent then |
if self:GetMobId(sourceGUID) ~= 32865 then return end -- it's not from Thorim |
self:FailEvent("Fail_Thorim_LightningCharge", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- Thorim Chain Lightning |
if (spellId == 64390 or spellId == 62131) and is_playerevent then |
if damage > 10000 then |
self.ThreePeopleHugging = true |
self:ScheduleTimer("ThorimChainLightning", function() lib.ThreePeopleHugging = false end, 3) |
end |
if self.ThreePeopleHugging then |
if self.LastEvent.Fail_Thorim_LightningChain[destName] ~= nil then |
if (timestamp - self.LastEvent.Fail_Thorim_LightningChain[destName]) < 1 then |
self:FailEvent("Fail_Thorim_LightningChain", destName, self.FAIL_TYPE_NOTSPREADING) |
end |
end |
self.LastEvent.Fail_Thorim_LightningChain[destName] = timestamp |
end |
return |
end |
-- 4/16 01:06:26.414 SPELL_DAMAGE,0x0000000000000000,nil,0x80000000,0x05000000027ECA9C,"Cn",0x514,62465,"Runic Smash",0x4,6544,0,4,3116,0,0,nil,nil,nil |
-- Thorim Hallway Smash |
if spellId == 62465 and is_playerevent then |
self:FailEvent("Fail_Thorim_Smash", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- Failbot - Viiv |
-- 4/16 18:50:56.578 SPELL_DAMAGE,0x0000000000000000,nil,0x80000000,0x05000000027ECB89,"Logicalness",0x514,64875,"Sapper Explosion",0x40,67542,45099,64,28421,0,0,nil,nil,nil |
-- Mimiron Trash - Sapper Explosion |
if spellId == 64875 and is_playerevent then |
self:FailEvent("Fail_Boss_Sapper", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- Mimiron - Flames |
if spellId == 64566 and is_playerevent and damage > 0 then |
if self.LastEvent.Fail_Mimiron_Flames[destName] ~= nil then |
local deltaT = (timestamp - self.LastEvent.Fail_Mimiron_Flames[destName]) |
if (((deltaT) > 3) and ((deltaT) < 9)) then--If >3 times threshold reset timestamp since it's probably from earlier fight and not genuine fail. |
self:FailEvent("Fail_Mimiron_Flames", destName, self.FAIL_TYPE_NOTMOVING) |
else |
self.LastEvent.Fail_Mimiron_Flames[destName] = timestamp |
end |
end |
self.LastEvent.Fail_Mimiron_Flames[destName] = timestamp |
return |
end |
-- Mimiron - Napalm Shell |
-- Two or more people getting damage usually triggers this |
if (spellId == 65026 or spellId == 63666) and is_playerevent then |
if self.LastEvent.Fail_Mimiron_NapalmShell[destName] ~= nil then |
if (timestamp - self.LastEvent.Fail_Mimiron_NapalmShell[destName]) < 1 then |
self:FailEvent("Fail_Mimiron_NapalmShell", destName, self.FAIL_TYPE_MOVING) |
end |
end |
self.LastEvent.Fail_Mimiron_NapalmShell[destName] = timestamp |
return |
end |
-- Mimiron - Water Spray |
if spellId == 64619 and is_playerevent then |
self:FailEvent("Fail_Mimiron_WaterSpray", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- Mimiron - Proximity Mine (should check for sourcename == proximity mine?) |
if (spellId == 63009 or spellId == 66351) and is_playerevent then |
if self:GetMobId(sourceGUID) ~= 34362 then return end -- Explosion not from mines |
if self.LastEvent.Fail_Mimiron_ProximityMine[destName] ~= nil then |
if (timestamp - self.LastEvent.Fail_Mimiron_ProximityMine[destName]) > 3 then |
self:FailEvent("Fail_Mimiron_ProximityMine", destName, self.FAIL_TYPE_NOTMOVING) |
end |
else |
self:FailEvent("Fail_Mimiron_ProximityMine", destName, self.FAIL_TYPE_NOTMOVING) |
end |
self.LastEvent.Fail_Mimiron_ProximityMine[destName] = timestamp |
return |
end |
-- Mimiron - Frost Bomb |
if (spellId == 65333 or spellId == 64626) and is_playerevent then |
if self:GetMobId(sourceGUID) ~= 34149 then return end --Explosion not from Frost Bomb |
self:FailEvent("Fail_Mimiron_FrostBomb", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- Mimiron Laser Barrage |
if spellId == 63293 and is_playerevent then |
if self.LastEvent.Fail_Mimiron_LaserBarrage[destName] ~= nil then |
if (timestamp - self.LastEvent.Fail_Mimiron_LaserBarrage[destName]) > 10 then |
self:FailEvent("Fail_Mimiron_LaserBarrage", destName, self.FAIL_TYPE_NOTMOVING) |
end |
else |
self:FailEvent("Fail_Mimiron_LaserBarrage", destName, self.FAIL_TYPE_NOTMOVING) |
end |
self.LastEvent.Fail_Mimiron_LaserBarrage[destName] = timestamp |
return |
end |
-- Mimiron Rocket Strike |
if spellId == 63041 and is_playerevent then |
self:FailEvent("Fail_Mimiron_Rocket", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- Failbot - Viiv |
-- 4/16 13:35:12.750 SPELL_DAMAGE,0xF13000842C0094E3,"Bomb Bot",0xa48,0x05000000027ECCA5,"Naddia",0x512,63801,"Bomb Bot",0x4,20216,4025,4,5054,0,0,nil,nil,nil |
-- Mimiron Bomb Bots |
if spellId == 63801 and is_playerevent and damage > 0 then |
self:FailEvent("Fail_Mimiron_BombBots", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- 3/13 21:17:23.756 SPELL_DAMAGE,0xF150008298002210,"Leviathan Mk II",0x10a48,0xF1300007AC0025A9,"Treant",0x1114,63631,"Shock Blast",0x8,97000,92908,8,0,0,0,nil,nil,nil |
-- Mimiron Shock Blast |
if spellId == 63631 and is_playerevent and damage > 0 then |
self:FailEvent("Fail_Mimiron_Shock", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- OBSIDIAN SANCTUM |
-- Sartharion Lava Waves: Flame Tsunami |
if spellId == 57491 and is_playerevent and damage > 0 then |
if self.LastEvent.Fail_Sartharion_LavaWaves[destName] ~= nil then |
if (timestamp - self.LastEvent.Fail_Sartharion_LavaWaves[destName]) > 10 then |
self:FailEvent("Fail_Sartharion_LavaWaves", destName, self.FAIL_TYPE_NOTMOVING) |
end |
else |
self:FailEvent("Fail_Sartharion_LavaWaves", destName, self.FAIL_TYPE_NOTMOVING) |
end |
self.LastEvent.Fail_Sartharion_LavaWaves[destName] = timestamp |
return |
end |
-- Sartharion - Void Zone |
if (spellId == 57581 or spellId == 59128) and damage > 0 and is_playerevent then |
self:FailEvent("Fail_Sartharion_VoidZone", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- Sartharion - Flame Breath |
if (spellId == 56908 or spellId == 58956) and is_playerevent then |
self:FailEvent("Fail_Sartharion_Breath", destName, self.FAIL_TYPE_WRONGPLACE) |
return |
end |
-- Sartharion - Tail Lash |
if (spellId == 56910 or spellId == 58957) and is_playerevent then |
self:FailEvent("Fail_Sartharion_TailLash", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- NAXXRAMAS |
-- Grobbulus - Poison (the cloud that the injection leaves behind) |
-- When the Mutating Injection ends or Grobbulus thinks its time to take a shit under itself, |
-- it SPELL_SUMMON's a Grobbulus Cloud (which is the cloud and it grows) and applies a buff to itself called Posion |
-- Poison is what damages people, and that is why you don't get out of combat until all the clouds disappear |
if (spellId == 28158 or spellId == 54362) and is_playerevent then |
if self.LastEvent.Fail_Grobbulus_PoisonCloud[destName] ~= nil then |
local deltaT = (timestamp - self.LastEvent.Fail_Grobbulus_PoisonCloud[destName]) |
if (((deltaT) > 3) and ((deltaT) < 9)) then--If >3 times threshold reset timestamp since it's probably from earlier fight and not genuine fail. |
self:FailEvent("Fail_Grobbulus_PoisonCloud", destName, self.FAIL_TYPE_NOTMOVING) |
else |
self.LastEvent.Fail_Grobbulus_PoisonCloud[destName] = timestamp |
end |
end |
self.LastEvent.Fail_Grobbulus_PoisonCloud[destName] = timestamp |
return |
end |
-- The Four Horsemen - Void Zone |
if spellId == 28865 and damage > 0 and is_playerevent then |
if self.LastEvent.Fail_Horsemen_VoideZone[destName] ~= nil then |
if (timestamp - self.LastEvent.Fail_Horsemen_VoideZone[destName]) > 3 then |
self:FailEvent("Fail_Horsemen_VoideZone", destName, self.FAIL_TYPE_NOTMOVING) |
end |
else |
self:FailEvent("Fail_Horsemen_VoideZone", destName, self.FAIL_TYPE_NOTMOVING) |
end |
self.LastEvent.Fail_Horsemen_VoideZone[destName] = timestamp |
return |
end |
-- The Four Horsemen - Mark death |
if spellId == 28836 and is_playerevent and overkill > 0 then |
self:FailEvent("Fail_Horsemen_Mark", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- Heigan - Eruption (aka dance fail) |
if spellId == 29371 and is_playerevent then |
self:FailEvent("Fail_Heigan_Dance", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- Kel'Thuzad - Void Blast (aka Void Zone) |
if spellId == 27812 and is_playerevent then |
self:FailEvent("Fail_KelThuzad_VoidZone", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- Sapphiron - Frost Breath |
if (spellId == 28524 or spellId == 29318) and is_playerevent then |
self:FailEvent("Fail_Sapphiron_Breath", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- Sartharion - Tail Sweep |
if (spellId == 55696 or spellId == 55697) and is_playerevent then |
self:FailEvent("Fail_Sapphiron_TailSweep", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- Sartharion - Cleave |
if spellId == 19983 and overkill > 0 and is_playerevent then |
if self:GetMobId(sourceGUID) ~= 15989 then return end |
self:FailEvent("Fail_Sapphiron_Cleave", destName, self.FAIL_TYPE_WRONGPLACE) |
return |
end |
if spellId == 28433 and is_playerevent then |
if overkill > 0 then |
self:FailEvent("Fail_Frogger", destName, self.FAIL_TYPE_WRONGPLACE) |
else |
self.LastEvent.Fail_Frogger[destName] = timestamp |
end |
return |
end |
-- Thaddius Polarity Switch |
-- 28062 Positive Charge |
-- 28085 Negative Charge |
if spellId == 28062 or spellId == 28085 then |
if self.ChargeCounter[sourceName] == nil then |
self.ChargeCounter[sourceName] = 1 |
self.LastEvent.Fail_Thaddius_PolaritySwitch[sourceName] = timestamp |
elseif (timestamp - self.LastEvent.Fail_Thaddius_PolaritySwitch[sourceName]) < 2 then |
self.ChargeCounter[sourceName] = self.ChargeCounter[sourceName] + 1 |
self.LastEvent.Fail_Thaddius_PolaritySwitch[sourceName] = timestamp |
else |
self.ChargeCounter[sourceName] = 1 |
self.LastEvent.Fail_Thaddius_PolaritySwitch[sourceName] = timestamp |
end |
if self.ChargeCounter[sourceName] == 3 then |
self:FailEvent("Fail_Thaddius_PolaritySwitch", sourceName, self.FAIL_TYPE_NOTMOVING) |
end |
return |
end |
end |
function lib:SWING_DAMAGE(timestamp, type, sourceGUID, sourceName, sourceFlags, destGUID, destName, destFlags, damage, overkill) |
local is_playerevent = bit.band(destFlags or 0, COMBATLOG_OBJECT_TYPE_PLAYER) > 0 |
damage = damage ~= "ABSORB" and damage or 0 |
overkill = overkill or 0 |
--12/26 20:27:36.560 SWING_DAMAGE,0xF13000966C005B92,"Blood Beast",0x10a48,0x040000000396C708,"Outofcontrol",0x2000514,5033,0,1,0,0,1258,nil,nil,nil |
-- Saurfang Blood Beasts |
if self:GetMobId(sourceGUID) == 38508 and is_playerevent and damage > 0 then |
self:FailEvent("Fail_Saurfang_Beasts", destName, self.FAIL_TYPE_MOVING) |
self.LastEvent.Fail_Saurfang_Beasts[destName] = timestamp |
return |
end |
-- Lady Deathwhisper Vengeful Shades |
-- The shade will swing (and hit or miss) its target after it catches up with it, then explode. Fail should be given to the player that failed to avoid the shade, not necessarily others within the explosion range (which is 20 yards in 25 heroic) |
if self:GetMobId(sourceGUID) == 38222 and is_playerevent then |
self:FailEvent("Fail_Deathwhisper_Shade", destName, self.FAIL_TYPE_MOVING) |
self.LastEvent.Fail_Deathwhisper_Shade[destName] = timestamp |
return |
end |
end |
function lib:SWING_MISSED(timestamp, type, sourceGUID, sourceName, sourceFlags, destGUID, destName, destFlags) |
local is_playerevent = bit.band(destFlags or 0, COMBATLOG_OBJECT_TYPE_PLAYER) > 0 |
-- Lady Deathwhisper Vengeful Shades |
-- The shade will swing (and hit or miss) its target after it catches up with it, then explode. Fail should be given to the player that failed to avoid the shade, not necessarily others within the explosion range (which is 20 yards in 25 heroic) |
if self:GetMobId(sourceGUID) == 38222 and is_playerevent then |
self:FailEvent("Fail_Deathwhisper_Shade", destName, self.FAIL_TYPE_MOVING) |
self.LastEvent.Fail_Deathwhisper_Shade[destName] = timestamp |
return |
end |
end |
function lib:ENVIRONMENTAL_DAMAGE(timestamp, type, sourceGUID, sourceName, sourceFlags, destGUID, destName, destFlags, dmgType) |
local is_playerevent = bit.band(destFlags or 0, COMBATLOG_OBJECT_TYPE_PLAYER) > 0 |
-- Thaddius Falling |
if (timestamp - self.DeathTime) < self.THADDIUS_JUMP_WINDOW and dmgType == "FALLING" and is_playerevent then |
self:FailEvent("Fail_Thaddius_Jump", destName, self.FAIL_TYPE_MOVING) |
self.LastEvent.Fail_Thaddius_Jump[destName] = timestamp |
return |
end |
end |
-- Thaddius Polarity Shift |
function lib:SPELL_CAST_START(timestamp, type, sourceGUID, sourceName, sourceFlags, destGUID, destName, destFlags, spellId, spellName, spellSchool) |
-- local is_playerevent = bit.band(destFlags or 0, COMBATLOG_OBJECT_TYPE_PLAYER) > 0 |
-- Auriaya - Sonic Screech |
-- The raid table is initialized in this form: "playername" => true |
-- in SPELL_DAMAGE above, we set those to false who get the damage |
-- and check here for who is still true, we also reset the whole thing |
-- so it can be reused in in the fight (InitRaidtable will return |
-- if the table is already filled) |
if spellId == 64688 or spellId == 64422 then |
self:InitRaidTable() |
self:ScheduleTimer("AuriayaScreech", function() |
for name, failed in pairs(lib.RaidTable) do |
if failed then |
lib:FailEvent("Fail_Auriaya_SonicScreech", name, self.FAIL_TYPE_MOVING) |
else |
lib.RaidTable[name] = true |
end |
end |
end, 4) |
return |
end |
-- Algalon - Big Bang timer |
if spellId == 64584 or spellId == 64443 then |
self.BigbangCasting = true |
self:ScheduleTimer("Algalon_BigBang", function() lib.BigbangCasting = false end, 8) |
return |
end |
-- The Lich King - Defile timer |
if spellId == 72762 then |
self.DefileCastStart = timestamp |
return |
end |
end |
function lib:UNIT_DIED(timestamp, type, sourceGUID, sourceName, sourceFlags, destGUID, destName, destFlags) |
local is_playerevent = bit.band(destFlags or 0, COMBATLOG_OBJECT_TYPE_PLAYER) > 0 |
local mobid = self:GetMobId(destGUID) |
-- 15929 stalagg 15930 feugen for thaddius fails |
if mobid == 15929 or mobid == 15930 then |
self.DeathTime = timestamp |
return |
end |
if self.LastEvent.Fail_Frogger[destName] then |
if (timestamp - self.LastEvent.Fail_Frogger[destName]) < self.FROGGER_DEATH_WINDOW and is_playerevent then |
self:FailEvent("Fail_Frogger", destName, self.FAIL_TYPE_WRONGPLACE) |
end |
self.LastEvent.Fail_Frogger[destName] = nil |
return |
end |
-- Saronite Vapor Suicide (Fail_Vezax_Saronite) death within 2sec of saronite damage |
if self.LastEvent.Fail_Vezax_Saronite[destName] then |
if (timestamp - self.LastEvent.Fail_Vezax_Saronite[destName]) < 2 then |
self:FailEvent("Fail_Vezax_Saronite", destName, self.FAIL_TYPE_NOTMOVING) |
end |
self.LastEvent.Fail_Vezax_Saronite[destName] = nil |
return |
end |
end |
function lib:SPELL_PERIODIC_DAMAGE(timestamp, type, sourceGUID, sourceName, sourceFlags, destGUID, destName, destFlags, spellId, spellName, spellSchool, damage, overkill) |
local is_playerevent = bit.band(destFlags or 0, COMBATLOG_OBJECT_TYPE_PLAYER) > 0 |
damage = damage ~= "ABSORB" and damage or 0 |
overkill = overkill or 0 |
-- Sindragosa - Chilled to the Bone (Melee debuff from attacking too much without clearing it) |
if spellId == 70106 and is_playerevent and overkill > 0 then |
self:FailEvent("Fail_Sindragosa_ChilledtotheBone", destName, self.FAIL_TYPE_NOTATTACKING) |
return |
end |
-- Lady Deathwhisper - Death and Decay |
if (spellId == 71001 or spellId == 72108 or spellId == 72109 or spellId == 72110) and is_playerevent then |
if self.LastEvent.Fail_Deathwhisper_DeathNDecay[destName] ~= nil then |
local deltaT = (timestamp - self.LastEvent.Fail_Deathwhisper_DeathNDecay[destName]) |
if (((deltaT) > 3) and ((deltaT) < 9)) then--If >3 times threshold reset timestamp since it's probably from earlier fight and not genuine fail. |
self:FailEvent("Fail_Deathwhisper_DeathNDecay", destName, self.FAIL_TYPE_NOTMOVING) |
else |
self.LastEvent.Fail_Deathwhisper_DeathNDecay[destName] = timestamp |
end |
end |
self.LastEvent.Fail_Deathwhisper_DeathNDecay[destName] = timestamp |
return |
end |
--[==[ -- Festergut - Vile Gas (disabled until a more reliable method is found) |
if (spellId == 71218 or spellId == 69240 or spellId == 69244 or spellId == 69248) and is_playerevent then |
if self.LastEvent.Fail_Festergut_VileGas[destName] ~= nil then |
if (timestamp - self.LastEvent.Fail_Festergut_VileGas[destName]) > 3 then |
self:FailEvent("Fail_Festergut_VileGas", destName, self.FAIL_TYPE_NOTMOVING) |
end |
end |
self.LastEvent.Fail_Festergut_VileGas[destName] = timestamp |
return |
end]==] |
-- Archavon - Choking Cloud |
if (spellId == 58965 or spellId == 61672) and overkill > 0 and is_playerevent then |
self:FailEvent("Fail_Archavon_ChokingCloud", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- Northrend Beasts - Acidmaw - Paralytic Toxin |
if (spellId == 67618 or spellId == 67619 or spellId == 67620 or spellId == 66823) and overkill > 0 and is_playerevent then |
self:FailEvent("Fail_Acidmaw_ParalyticToxin", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- Freya - Unstable Energy |
if (spellId == 62865 or spellId == 62451) and is_playerevent then |
local hasroots = UnitDebuff(destName, GetSpellInfo(62861)) |
if self.LastEvent.Fail_Freya_UnstableEnergy[destName] ~= nil then |
if (timestamp - self.LastEvent.Fail_Freya_UnstableEnergy[destName]) > 4 and not hasroots then |
self:FailEvent("Fail_Freya_UnstableEnergy", destName, self.FAIL_TYPE_NOTMOVING) |
end |
elseif not hasroots then |
self:FailEvent("Fail_Freya_UnstableEnergy", destName, self.FAIL_TYPE_NOTMOVING) |
end |
self.LastEvent.Fail_Freya_UnstableEnergy[destName] = timestamp |
return |
end |
-- Thorim Blizzard |
if (spellId == 62602 or spellId == 62576) and is_playerevent then |
if self.LastEvent.Fail_Thorim_Blizzard[destName] == nil then |
self.LastEvent.Fail_Thorim_Blizzard[destName] = 0 |
end |
self.LastEvent.Fail_Thorim_Blizzard[destName] = self.LastEvent.Fail_Thorim_Blizzard[destName] + 1 |
if self.LastEvent.Fail_Thorim_Blizzard[destName] == 2 then |
self:FailEvent("Fail_Thorim_Blizzard", destName, self.FAIL_TYPE_NOTMOVING) |
self.LastEvent.Fail_Thorim_Blizzard[destName] = 0 |
end |
return |
end |
-- The Iron Council - Rune of Death |
if (spellId == 63490 or spellId == 62269) and is_playerevent then |
if self.LastEvent.Fail_Council_RuneOfDeath[destName] ~= nil then |
if (timestamp - self.LastEvent.Fail_Council_RuneOfDeath[destName]) > self.COUNCIL_RUNE_THRESHOLD then |
self:FailEvent("Fail_Council_RuneOfDeath", destName, self.FAIL_TYPE_NOTMOVING) |
end |
end |
self.LastEvent.Fail_Council_RuneOfDeath[destName] = timestamp |
return |
end |
-- Lord Marrowgar - Coldflame |
if (spellId == 69146 or (spellId >= 70823 and spellId <= 70825)) and is_playerevent then |
if self.LastEvent.Fail_Marrowgar_Coldflame[destName] ~= nil then |
if (timestamp - self.LastEvent.Fail_Marrowgar_Coldflame[destName]) > 4 then--Reset timestamp if you were out of it for 2 times fail threshold to prevent instant fails from out of date timestamps. |
self.LastEvent.Fail_Marrowgar_Coldflame[destName] = timestamp |
elseif (timestamp - self.LastEvent.Fail_Marrowgar_Coldflame[destName]) > 2 then |
self:FailEvent("Fail_Marrowgar_Coldflame", destName, self.FAIL_TYPE_NOTMOVING) |
end |
end |
self.LastEvent.Fail_Marrowgar_Coldflame[destName] = timestamp |
return |
end |
end |
function lib:SPELL_HEAL(timestamp, type, sourceGUID, sourceName, sourceFlags, destGUID, destName, destFlags, spellId, spellName, spellSchool, damage) |
-- local is_playerevent = bit.band(destFlags or 0, COMBATLOG_OBJECT_TYPE_PLAYER) > 0 |
-- Vezax Mark of the Faceless |
if spellId == 63278 then |
if self.LastEvent.Fail_Vezax_Leech > self.VEZAX_LEECH_THRESHOLD then |
self:FailEvent("Fail_Vezax_Leech", self.VezaxLeechTarget, self.FAIL_TYPE_NOTMOVING) |
self.LastEvent.Fail_Vezax_Leech = 0 |
end |
self.LastEvent.Fail_Vezax_Leech = self.LastEvent.Fail_Vezax_Leech + damage |
return |
end |
end |
function lib:SPELL_AURA_APPLIED(timestamp, type, sourceGUID, sourceName, sourceFlags, destGUID, destName, destFlags, spellId, spellName, spellSchool, auraType) |
local is_playerevent = bit.band(destFlags or 0, COMBATLOG_OBJECT_TYPE_PLAYER) > 0 |
-- Festergut Heroic -- Malleable goo (Debuff) |
if (spellId == 72549 or spellId == 72550) and is_playerevent then |
if self.LastEvent.Fail_Festergut_MalleableGoo[destName] ~= nil then |
if (timestamp - self.LastEvent.Fail_Festergut_MalleableGoo[destName]) > 3 then |
self:FailEvent("Fail_Festergut_MalleableGoo", destName, self.FAIL_TYPE_NOTMOVING) |
end |
else |
self:FailEvent("Fail_Festergut_MalleableGoo", destName, self.FAIL_TYPE_NOTMOVING) |
end |
self.LastEvent.Fail_Festergut_MalleableGoo[destName] = timestamp |
return |
end |
-- Professor - Malleable Goo (Debuff) |
if (spellId == 70853 or spellId == 72458 or spellId == 72873 or spellId == 72874) and is_playerevent then |
if self:IsSnared(destName) then return end |
if self.LastEvent.Fail_Professor_MalleableGoo[destName] ~= nil then |
if (timestamp - self.LastEvent.Fail_Professor_MalleableGoo[destName]) > 3 then |
self:FailEvent("Fail_Professor_MalleableGoo", destName, self.FAIL_TYPE_NOTMOVING) |
end |
else |
self:FailEvent("Fail_Professor_MalleableGoo", destName, self.FAIL_TYPE_NOTMOVING) |
end |
self.LastEvent.Fail_Professor_MalleableGoo[destName] = timestamp |
return |
end |
-- Professor - Choking Gas (Debuff) |
if (spellId == 72460 or spellId == 72619 or spellId == 72620 or spellId == 71278) and is_playerevent then |
if self:IsSnared(destName) then return end |
self:FailEvent("Fail_Professor_ChokingGas", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- Blood Queen Lana'thel - Delirious Slash |
if spellId == 71624 and is_playerevent then |
self:FailEvent("Fail_LanaThel_DeliriousSlash", destName, self.FAIL_TYPE_WRONGPLACE) |
return |
end |
-- Blood Queen Lana'thel - Uncontrollable Frenzy |
if (spellId == 70923 or spellId == 70924) then |
self:FailEvent("Fail_LanaThel_UncontrollableFrenzy", destName, self.FAIL_TYPE_CASTING) |
return |
end |
-- Sindragosa - Frost Beacon (detecting if only one people got it) |
if spellId == 70126 and is_playerevent then |
if self.SindragosaSingleBeacon ~= 0 then |
self.SindragosaSingleBeacon = false |
return |
end |
if self.SindragosaSingleBeacon == 0 then |
self.SindragosaSingleBeacon = true |
self.SindragosaBeaconTarget = destName |
self:ScheduleTimer("Sindragosa_SingleBeacon", function() lib.SindragosaSingleBeacon = 0 end, 10) |
end |
-- Sindragosa - Ice Tomb (print the message only once) |
elseif spellId == 70157 and is_playerevent then |
if not self.SindragosaSingleBeacon or self:IsTimerRunning("Sindragosa_TombFail") or lib.SindragosaBeaconTarget == destName then return end |
self:ScheduleTimer("Sindragosa_TombFail", function() |
lib:FailEvent("Fail_Sindragosa_IceTomb", lib.SindragosaBeaconTarget, lib.FAIL_TYPE_NOTMOVING) |
end, 0.2) |
end |
-- Vezax Mark of the Faceless |
if spellId == 63276 and is_playerevent then |
-- save the name of the player who gains mark of the faceless |
self.VezaxLeechTarget = destName |
self.LastEvent.Fail_Vezax_Leech = 0 |
return |
end |
-- Hodir Flash Freeze |
if (spellId == 61969 or spellId == 61990) and is_playerevent and auraType ~= "BUFF" then |
self:FailEvent("Fail_Hodir_FlashFreeze", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- Yogg Saron Sanity Lost |
if spellId == 63120 and is_playerevent then |
self:FailEvent("Fail_Yogg_Sanity", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- Yogg Saron Malady aka Death Coil |
if spellId == 63881 and is_playerevent then |
self:FailEvent("Fail_Yogg_Malady", destName, self.FAIL_TYPE_MOVING) |
return |
end |
-- Thaddius Jump |
if spellId == 28801 and (timestamp - self.DeathTime) < self.THADDIUS_JUMP_WINDOW and is_playerevent then |
if self.LastEvent.Fail_Thaddius_Jump[destName] == nil then |
self:FailEvent("Fail_Thaddius_Jump", destName, self.FAIL_TYPE_NOTMOVING) |
elseif (timestamp - self.LastEvent.Fail_Thaddius_Jump[destName]) > self.THADDIUS_JUMP_RETRY_WINDOW then |
self:FailEvent("Fail_Thaddius_Jump", destName, self.FAIL_TYPE_NOTMOVING) |
end |
return |
end |
-- Algalon - Black Hole (if big bang is not casting, it's a fail) |
if spellId == 62169 and is_playerevent and not self.BigbangCasting then |
self:FailEvent("Fail_Algalon_Blackhole", destName, self.FAIL_TYPE_MOVING) |
return |
end |
-- Light Bomb |
if (spellId == 65120 or spellId == 63023) and is_playerevent then |
self.LastLight[destName] = timestamp |
return |
end |
-- Mimiron - Deafening Siren |
if spellId == 64616 and is_playerevent then |
self:FailEvent("Fail_Mimiron_Siren", destName, self.FAIL_TYPE_NOTMOVING) |
return |
end |
-- Koralon the Flame Watcher - Meteor Fist (a fail if a non-tank gets it, let "userspace" handle it) |
if (spellId == 67333 or spellId == 66765) and is_playerevent and overkill > 0 then |
self:FailEvent("Fail_Koralon_MeteorFist", destName, self.FAIL_TYPE_WRONGPLACE) |
return |
end |
end |
function lib:SPELL_INTERRUPT(timestamp, type, sourceGUID, sourceName, sourceFlags, destGUID, destName, destFlags, spellId, spellName, spellSchool, extraSpellId) |
local is_playerevent = bit.band(destFlags or 0, COMBATLOG_OBJECT_TYPE_PLAYER) > 0 |
-- Flame Jets -- Ignis |
if spellId == 62681 and is_playerevent then |
self:FailEvent("Fail_Ignis_FlameJets", destName, self.FAIL_TYPE_NOTCASTING) |
return |
end |
-- Ground Tremor -- Freya and Elder |
if (spellId == 62859 or spellId == 62437 or spellId == 62325 or spellId == 62932) and is_playerevent then |
self:FailEvent("Fail_Freya_GroundTremor", destName, self.FAIL_TYPE_NOTCASTING) |
return |
end |
end |
function lib:SPELL_SUMMON(timestamp, type, sourceGUID, sourceName, sourceFlags, destGUID, destName, destFlags, spellId, spellName) |
-- local is_playerevent = bit.band(destFlags or 0, COMBATLOG_OBJECT_TYPE_PLAYER) > 0 |
--SPELL_SUMMON,0xF15000838601084D,"Aerial Command Unit",0xa48,0xF13000842C010A24,"Bomb Bot",0xa28,63811,"Bomb Bot",0x1 |
if spellId == 63811 then |
-- could add the GUID for each bot if this doesnt work. |
self.LastEvent.Fail_Mimiron_BombBots = timestamp + 30 |
return |
end |
end |
--70337, 73912, 73913, 73914 are cast success IDs (from lich king) |
--70338, 73785, 73786, 73787 are jump spellids (from another player, these don't show in combat log when they jump, only do damage) |
function lib:SPELL_CAST_SUCCESS(timestamp, type, sourceGUID, sourceName, sourceFlags, destGUID, destName, destFlags, spellId, spellName, spellSchool) |
-- The Lich King - Necrotic Plague |
if spellId == 70337 or spellId == 73912 or spellId == 73913 or spellId == 73914 then |
if self.LastEvent.TheLichKing_NecroticPlague and timestamp - self.LastEvent.TheLichKing_NecroticPlague > 35 then |
self.TheLichKingNecroticPlagueDispelCounter = 0 |
self.TheLichKingNecroticPlagueTarget = {} |
else |
if self.TheLichKingNecroticPlagueDispelCounter > 1 then |
for i=0, self.TheLichKingNecroticPlagueDispelCounter do |
self:FailEvent("Fail_TheLichKing_NecroticPlague", self.TheLichKingNecroticPlagueTarget[i], self.FAIL_TYPE_NOTMOVING) |
end |
end |
self.TheLichKingNecroticPlagueDispelCounter = 0 |
self.TheLichKingNecroticPlagueTarget = {} |
end |
self.LastEvent.TheLichKing_NecroticPlague = timestamp |
end |
end |
local necrotic_plague = GetSpellInfo(73912) |
function lib:SPELL_DISPEL(timestamp, type, sourceGUID, sourceName, sourceFlags, destGUID, destName, destFlags, spellId, spellName, spellSchool, extraSpellId, extraSpellName) |
-- Grobbulus - Mutating Injection |
if extraSpellId == 28169 then |
self:FailEvent("Fail_Grobbulus_MutatingInjection", sourceName, self.FAIL_TYPE_NOTDISPELLING) |
return |
end |
-- Bind Life - Freya Trash |
if extraSpellId == 63559 then |
self:FailEvent("Fail_Freya_BindLife", sourceName, self.FAIL_TYPE_NOTDISPELLING) |
return |
end |
-- The Lich King - Necrotic Plague |
if extraSpellName == necrotic_plague and is_playerevent then |
if UnitHealthMax(destName) < 50000 then -- poor mans tank check (you really should't do LK Heroic if your tank has less than 50k HP) |
self.TheLichKingNecroticPlagueTarget[self.TheLichKingNecroticPlagueDispelCounter] = destName |
self.TheLichKingNecroticPlagueDispelCounter = self.TheLichKingNecroticPlagueDispelCounter + 1 |
end |
end |
end |
function lib:SPELL_AURA_REMOVED(timestamp, type, sourceGUID, sourceName, sourceFlags, destGUID, destName, destFlags, spellId, spellName, spellSchool) |
local is_playerevent = bit.band(destFlags or 0, COMBATLOG_OBJECT_TYPE_PLAYER) > 0 |
-- Malygos Phase3 Dot |
-- fail when you let the dot expire |
if (spellId == 56092 or spellId == 61621) and self.MalygosAlive then |
local failer = nil |
for raidid = 1, GetNumRaidMembers() do |
local pet = format("%s%d", "raidpet", raidid); |
if (UnitGUID(pet) == sourceGUID) then |
if UnitHealth(pet) > 0 then |
local member = format("%s%d", "raid", raidid); |
failer = UnitName(member); |
else |
failer = nil; |
end |
end |
end |
if failer ~= nil then |
self:FailEvent("Fail_Malygos_Dot", failer, self.FAIL_TYPE_CASTING) |
end |
return |
end |
-- Thaddius Jump |
if spellId == 28801 and (timestamp - self.DeathTime) < self.THADDIUS_JUMP_WINDOW and is_playerevent then |
self.LastEvent.Fail_Thaddius_Jump[destName] = timestamp |
return |
end |
-- Light Bomb |
if spellId == 65120 or spellId == 63026 then |
self.LastEvent.Fail_Deconstructor_Light[destName] = nil |
return |
end |
-- Gravity Bomb |
if spellId == 64233 or spellId == 63025 then |
self.LastEvent.Fail_Deconstructor_Gravity[destName] = timestamp |
return |
end |
end |
<?xml version="1.0" encoding="utf-8"?> |
<Ui xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.blizzard.com/wow/ui/" xsi:schemaLocation="http://www.blizzard.com/wow/ui/ |
..\FrameXML\UI.xsd"> |
<Include file="lib\includes.xml"/> |
</Ui> |
-- 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 |
--[[ |
Name: LibBabble-Boss-3.0 |
Revision: $Rev: 287 $ |
Maintainers: ckknight, nevcairiel, Ackis |
Website: http://www.wowace.com/projects/libbabble-boss-3-0/ |
Dependencies: None |
License: MIT |
]] |
local MAJOR_VERSION = "LibBabble-Boss-3.0" |
local MINOR_VERSION = 90000 + tonumber(("$Rev: 287 $"):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 { |
Acidmaw = "Acidmaw", |
Aeonus = "Aeonus", |
["Aerial Command Unit"] = "Aerial Command Unit", |
["Agathelos the Raging"] = "Agathelos the Raging", |
Ahune = "Ahune", |
["Akil'zon"] = "Akil'zon", |
["Aku'mai"] = "Aku'mai", |
["Al'ar"] = "Al'ar", |
["Algalon the Observer"] = "Algalon the Observer", |
["Alzzin the Wildshaper"] = "Alzzin the Wildshaper", |
Amanitar = "Amanitar", |
["Ambassador Flamelash"] = "Ambassador Flamelash", |
["Ambassador Hellmaw"] = "Ambassador Hellmaw", |
["Amnennar the Coldbringer"] = "Amnennar the Coldbringer", |
["Ancient Stone Keeper"] = "Ancient Stone Keeper", |
Anetheron = "Anetheron", |
["Anger'rel"] = "Anger'rel", |
Anomalus = "Anomalus", |
["Antu'sul"] = "Antu'sul", |
["Anub'arak"] = "Anub'arak", |
["Anubisath Defender"] = "Anubisath Defender", |
["Anubisath Guardian"] = "Anubisath Guardian", |
["Anub'Rekhan"] = "Anub'Rekhan", |
["Anub'shiah"] = "Anub'shiah", |
Anzu = "Anzu", |
["Arcane Watchman"] = "Arcane Watchman", |
["Arcanist Doan"] = "Arcanist Doan", |
Archaedas = "Archaedas", |
["Archavon the Stone Watcher"] = "Archavon the Stone Watcher", |
Archimonde = "Archimonde", |
["Archivist Galford"] = "Archivist Galford", |
["Archmage Arugal"] = "Archmage Arugal", |
["Argent Confessor Paletress"] = "Argent Confessor Paletress", |
["Arugal's Voidwalker"] = "Arugal's Voidwalker", |
["Assault Bot"] = "Assault Bot", |
["Atal'alarion"] = "Atal'alarion", |
["Attumen the Huntsman"] = "Attumen the Huntsman", |
Auriaya = "Auriaya", |
Avalanchion = "Avalanchion", |
["Avatar of Hakkar"] = "Avatar of Hakkar", |
["Ayamiss the Hunter"] = "Ayamiss the Hunter", |
Azgalor = "Azgalor", |
["Azshir the Sleepless"] = "Azshir the Sleepless", |
Azuregos = "Azuregos", |
["Bael'Gar"] = "Bael'Gar", |
Baelog = "Baelog", |
Balnazzar = "Balnazzar", |
["Baltharus the Warborn"] = "Baltharus the Warborn", |
["Bannok Grimaxe"] = "Bannok Grimaxe", |
["Baron Aquanis"] = "Baron Aquanis", |
["Baron Charr"] = "Baron Charr", |
["Baroness Anastari"] = "Baroness Anastari", |
["Baron Geddon"] = "Baron Geddon", |
["Baron Kazum"] = "Baron Kazum", |
["Baron Rivendare"] = "Baron Rivendare", |
["Baron Silverlaine"] = "Baron Silverlaine", |
["Battleguard Sartura"] = "Battleguard Sartura", |
["Bazil Thredd"] = "Bazil Thredd", |
Bazzalan = "Bazzalan", |
["Black Guard Swordsmith"] = "Black Guard Swordsmith", |
["Blackheart the Inciter"] = "Blackheart the Inciter", |
["Blindeye the Seer"] = "Blindeye the Seer", |
["Blind Hunter"] = "Blind Hunter", |
["Blood Guard Porung"] = "Blood Guard Porung", |
["Bloodlord Mandokir"] = "Bloodlord Mandokir", |
["Bloodmage Thalnos"] = "Bloodmage Thalnos", |
["Blood Prince Council"] = "Blood Prince Council", |
["Blood Princes"] = "Blood Princes", |
["Blood-Queen Lana'thel"] = "Blood-Queen Lana'thel", |
["Blood Steward of Kirtonos"] = "Blood Steward of Kirtonos", |
Boahn = "Boahn", |
["Bomb Bot"] = "Bomb Bot", |
["Brain of Yogg-Saron"] = "Brain of Yogg-Saron", |
["Brainwashed Noble"] = "Brainwashed Noble", |
Broggok = "Broggok", |
Brokentoe = "Brokentoe", |
Bronjahm = "Bronjahm", |
["Broodlord Lashlayer"] = "Broodlord Lashlayer", |
["Bruegal Ironknuckle"] = "Bruegal Ironknuckle", |
Brutallus = "Brutallus", |
["Burning Felguard"] = "Burning Felguard", |
["Buru the Gorger"] = "Buru the Gorger", |
["Cache of the Firelord"] = "Cache of the Firelord", |
["Cannon Master Willey"] = "Cannon Master Willey", |
["Captain Greenskin"] = "Captain Greenskin", |
["Captain Kromcrush"] = "Captain Kromcrush", |
["Captain Skarloc"] = "Captain Skarloc", |
["Celebras the Cursed"] = "Celebras the Cursed", |
["Charlga Razorflank"] = "Charlga Razorflank", |
["Chess Event"] = "Chess Event", |
["Chest of The Seven"] = "Chest of The Seven", |
["Chief Ukorz Sandscalp"] = "Chief Ukorz Sandscalp", |
["Cho'Rush the Observer"] = "Cho'Rush the Observer", |
Chromaggus = "Chromaggus", |
["Chrono Lord Deja"] = "Chrono Lord Deja", |
["Chrono-Lord Epoch"] = "Chrono-Lord Epoch", |
Claw = "Claw", |
["Coilfang Elite"] = "Coilfang Elite", |
["Coilfang Strider"] = "Coilfang Strider", |
["Commander Kolurg"] = "Commander Kolurg", |
["Commander Sarannis"] = "Commander Sarannis", |
["Commander Springvale"] = "Commander Springvale", |
["Commander Stoutbeard"] = "Commander Stoutbeard", |
["Constructor & Controller"] = "Constructor & Controller", |
Cookie = "Cookie", |
["Coren Direbrew"] = "Coren Direbrew", |
["Cosmic Infuser"] = "Cosmic Infuser", |
["Crimson Hammersmith"] = "Crimson Hammersmith", |
["Crowd Pummeler 9-60"] = "Crowd Pummeler 9-60", |
["Crystal Fang"] = "Crystal Fang", |
["C'Thun"] = "C'Thun", |
Cyanigosa = "Cyanigosa", |
["Dalliah the Doomsayer"] = "Dalliah the Doomsayer", |
["Dalronn the Controller"] = "Dalronn the Controller", |
["Dark Iron Ambassador"] = "Dark Iron Ambassador", |
["Darkmaster Gandling"] = "Darkmaster Gandling", |
["Darkweaver Syth"] = "Darkweaver Syth", |
["Deathbound Ward"] = "Deathbound Ward", |
["Deathbringer Saurfang"] = "Deathbringer Saurfang", |
["Death Knight Darkreaver"] = "Death Knight Darkreaver", |
["Death Knight Understudy"] = "Death Knight Understudy", |
["Deathspeaker High Priest"] = "Deathspeaker High Priest", |
["Death Speaker Jargba"] = "Death Speaker Jargba", |
["Deathstalker Visceri"] = "Deathstalker Visceri", |
["Deathsworn Captain"] = "Deathsworn Captain", |
Devastation = "Devastation", |
["Deviate Faerie Dragon"] = "Deviate Faerie Dragon", |
["Devourer of Souls"] = "Devourer of Souls", |
["Dextren Ward"] = "Dextren Ward", |
["Digmaster Shovelphlange"] = "Digmaster Shovelphlange", |
["Doctor Theolen Krastinov"] = "Doctor Theolen Krastinov", |
["Doom Lord Kazzak"] = "Doom Lord Kazzak", |
["Doom'rel"] = "Doom'rel", |
Doomwalker = "Doomwalker", |
["Dope'rel"] = "Dope'rel", |
Dorothee = "Dorothee", |
["Drakkari Colossus"] = "Drakkari Colossus", |
["Drakos the Interrogator"] = "Drakos the Interrogator", |
Dreadscale = "Dreadscale", |
Dreamscythe = "Dreamscythe", |
["Dust Covered Chest"] = "Dust Covered Chest", |
Dustwraith = "Dustwraith", |
["Eadric the Pure"] = "Eadric the Pure", |
["Earthcaller Halmgar"] = "Earthcaller Halmgar", |
Ebonroc = "Ebonroc", |
["Eck the Ferocious"] = "Eck the Ferocious", |
["Edwin VanCleef"] = "Edwin VanCleef", |
["Elder Brightleaf"] = "Elder Brightleaf", |
["Elder Ironbranch"] = "Elder Ironbranch", |
["Elder Nadox"] = "Elder Nadox", |
["Elder Stonebark"] = "Elder Stonebark", |
["Electrocutioner 6000"] = "Electrocutioner 6000", |
["Emalon the Storm Watcher"] = "Emalon the Storm Watcher", |
Emeriss = "Emeriss", |
["Emperor Dagran Thaurissan"] = "Emperor Dagran Thaurissan", |
["Emperor Vek'lor"] = "Emperor Vek'lor", |
["Emperor Vek'nilash"] = "Emperor Vek'nilash", |
Entropius = "Entropius", |
["Eonar's Gift"] = "Eonar's Gift", |
["Epoch Hunter"] = "Epoch Hunter", |
Erekem = "Erekem", |
["Eressea Dawnsinger"] = "Eressea Dawnsinger", |
["Essence of Anger"] = "Essence of Anger", |
["Essence of Desire"] = "Essence of Desire", |
["Essence of Suffering"] = "Essence of Suffering", |
Eviscerator = "Eviscerator", |
["Exarch Maladaar"] = "Exarch Maladaar", |
["Expedition Commander"] = "Expedition Commander", |
["Eydis Darkbane"] = "Eydis Darkbane", |
["Eye of C'Thun"] = "Eye of C'Thun", |
["Faction Champions"] = "Faction Champions", |
["Fallen Champion"] = "Fallen Champion", |
Falric = "Falric", |
["Falric and Marwyn"] = "Falric and Marwyn", |
["Fankriss the Unyielding"] = "Fankriss the Unyielding", |
["Fathom-Lord Karathress"] = "Fathom-Lord Karathress", |
Felmyst = "Felmyst", |
["Fenrus the Devourer"] = "Fenrus the Devourer", |
["Feral Defender"] = "Feral Defender", |
Festergut = "Festergut", |
Feugen = "Feugen", |
["Fineous Darkvire"] = "Fineous Darkvire", |
Firemaw = "Firemaw", |
["Fjola Lightbane"] = "Fjola Lightbane", |
Flamegor = "Flamegor", |
["Flame Leviathan"] = "Flame Leviathan", |
["Foreman Thistlenettle"] = "Foreman Thistlenettle", |
["Forgemaster Garfrost"] = "Forgemaster Garfrost", |
["Four Horsemen Chest"] = "Four Horsemen Chest", |
["Fras Siabi"] = "Fras Siabi", |
Freya = "Freya", |
["Gahz'ranka"] = "Gahz'ranka", |
["Gahz'rilla"] = "Gahz'rilla", |
["Gal'darah"] = "Gal'darah", |
["Galgann Firehammer"] = "Galgann Firehammer", |
Garr = "Garr", |
["Garrosh Hellscream"] = "Garrosh Hellscream", |
Gasher = "Gasher", |
["Gatewatcher Gyro-Kill"] = "Gatewatcher Gyro-Kill", |
["Gatewatcher Iron-Hand"] = "Gatewatcher Iron-Hand", |
["Gathios the Shatterer"] = "Gathios the Shatterer", |
Gehennas = "Gehennas", |
Gelihast = "Gelihast", |
Gelk = "Gelk", |
["General Angerforge"] = "General Angerforge", |
["General Bjarngrim"] = "General Bjarngrim", |
["General Drakkisath"] = "General Drakkisath", |
["General Rajaxx"] = "General Rajaxx", |
["General Vezax"] = "General Vezax", |
["General Zarithrian"] = "General Zarithrian", |
["Ghamoo-ra"] = "Ghamoo-ra", |
["Ghaz'an"] = "Ghaz'an", |
["Ghok Bashguud"] = "Ghok Bashguud", |
Gilnid = "Gilnid", |
["Gizrul the Slavener"] = "Gizrul the Slavener", |
["Gloom'rel"] = "Gloom'rel", |
Gluth = "Gluth", |
Glutton = "Glutton", |
["Golemagg the Incinerator"] = "Golemagg the Incinerator", |
["Golem Lord Argelmach"] = "Golem Lord Argelmach", |
["Goraluk Anvilcrack"] = "Goraluk Anvilcrack", |
["Gormok the Impaler"] = "Gormok the Impaler", |
["Gorosh the Dervish"] = "Gorosh the Dervish", |
["Gortok Palehoof"] = "Gortok Palehoof", |
["Gothik the Harvester"] = "Gothik the Harvester", |
["Grand Astromancer Capernian"] = "Grand Astromancer Capernian", |
["Grand Champions"] = "Grand Champions", |
["Grand Magus Telestra"] = "Grand Magus Telestra", |
["Grandmaster Vorpil"] = "Grandmaster Vorpil", |
Grandmother = "Grandmother", |
["Grand Warlock Alythess"] = "Grand Warlock Alythess", |
["Grand Warlock Nethekurse"] = "Grand Warlock Nethekurse", |
["Grand Widow Faerlina"] = "Grand Widow Faerlina", |
["Grethok the Controller"] = "Grethok the Controller", |
["Gri'lek"] = "Gri'lek", |
Grimlok = "Grimlok", |
Grizzle = "Grizzle", |
Grobbulus = "Grobbulus", |
Grubbis = "Grubbis", |
["Gruul the Dragonkiller"] = "Gruul the Dragonkiller", |
["Guard Fengus"] = "Guard Fengus", |
["Guardian of Yogg-Saron"] = "Guardian of Yogg-Saron", |
["Guard Mol'dar"] = "Guard Mol'dar", |
["Guard Slip'kik"] = "Guard Slip'kik", |
["Gurtogg Bloodboil"] = "Gurtogg Bloodboil", |
Gyth = "Gyth", |
Hadronox = "Hadronox", |
Hakkar = "Hakkar", |
Halazzi = "Halazzi", |
Halion = "Halion", |
Halycon = "Halycon", |
Hamhock = "Hamhock", |
["Harbinger Skyriss"] = "Harbinger Skyriss", |
["Hate'rel"] = "Hate'rel", |
["Hazza'rah"] = "Hazza'rah", |
Hazzas = "Hazzas", |
["Headless Horseman"] = "Headless Horseman", |
["Hearthsinger Forresten"] = "Hearthsinger Forresten", |
["Hedrum the Creeper"] = "Hedrum the Creeper", |
["Heigan the Unclean"] = "Heigan the Unclean", |
["Hellfire Channeler"] = "Hellfire Channeler", |
["Henry Stern"] = "Henry Stern", |
["Herald Volazj"] = "Herald Volazj", |
Herod = "Herod", |
["Hex Lord Malacrass"] = "Hex Lord Malacrass", |
["High Astromancer Solarian"] = "High Astromancer Solarian", |
["High Botanist Freywinn"] = "High Botanist Freywinn", |
["High Inquisitor Fairbanks"] = "High Inquisitor Fairbanks", |
["High Inquisitor Whitemane"] = "High Inquisitor Whitemane", |
["High Interrogator Gerstahn"] = "High Interrogator Gerstahn", |
["High King Maulgar"] = "High King Maulgar", |
["Highlord Mograine"] = "Highlord Mograine", |
["Highlord Omokk"] = "Highlord Omokk", |
["High Marshal Whirlaxis"] = "High Marshal Whirlaxis", |
["High Nethermancer Zerevor"] = "High Nethermancer Zerevor", |
["High Overlord Saurfang"] = "High Overlord Saurfang", |
["High Priestess Arlokk"] = "High Priestess Arlokk", |
["High Priestess Jeklik"] = "High Priestess Jeklik", |
["High Priestess Mar'li"] = "High Priestess Mar'li", |
["High Priestess of Thaurissan"] = "High Priestess of Thaurissan", |
["High Priest Thekal"] = "High Priest Thekal", |
["High Priest Venoxis"] = "High Priest Venoxis", |
["High Warlord Naj'entus"] = "High Warlord Naj'entus", |
Hodir = "Hodir", |
["Houndmaster Grebmar"] = "Houndmaster Grebmar", |
["Houndmaster Loksey"] = "Houndmaster Loksey", |
Hukku = "Hukku", |
Hungarfen = "Hungarfen", |
["Hurley Blackbreath"] = "Hurley Blackbreath", |
["Hyakiss the Lurker"] = "Hyakiss the Lurker", |
["Hydromancer Thespia"] = "Hydromancer Thespia", |
["Hydromancer Velratha"] = "Hydromancer Velratha", |
Hydrospawn = "Hydrospawn", |
["Hydross the Unstable"] = "Hydross the Unstable", |
["Icecrown Gunship Battle"] = "Icecrown Gunship Battle", |
Icehowl = "Icehowl", |
["Ice Sphere"] = "Ice Sphere", |
Ichoron = "Ichoron", |
Ick = "Ick", |
["Ignis the Furnace Master"] = "Ignis the Furnace Master", |
["Illidan Stormrage"] = "Illidan Stormrage", |
["Illidari Council"] = "Illidari Council", |
["Illyanna Ravenoak"] = "Illyanna Ravenoak", |
["Immol'thar"] = "Immol'thar", |
["Infinite Corruptor"] = "Infinite Corruptor", |
["Infinity Blades"] = "Infinity Blades", |
["Ingvar the Plunderer"] = "Ingvar the Plunderer", |
["Instructor Malicia"] = "Instructor Malicia", |
["Instructor Razuvious"] = "Instructor Razuvious", |
["Interrogator Vishas"] = "Interrogator Vishas", |
Ionar = "Ionar", |
Ironaya = "Ironaya", |
Ironspine = "Ironspine", |
Isalien = "Isalien", |
Jade = "Jade", |
["Jammal'an the Prophet"] = "Jammal'an the Prophet", |
["Jan'alai"] = "Jan'alai", |
["Jandice Barov"] = "Jandice Barov", |
["Jedoga Shadowseeker"] = "Jedoga Shadowseeker", |
["Jed Runewatcher"] = "Jed Runewatcher", |
["Jergosh the Invoker"] = "Jergosh the Invoker", |
["Jin'do the Hexxer"] = "Jin'do the Hexxer", |
["Jormungar Behemoth"] = "Jormungar Behemoth", |
Jormungars = "Jormungars", |
Julianne = "Julianne", |
["Junk Bot"] = "Junk Bot", |
["Kael'thas Sunstrider"] = "Kael'thas Sunstrider", |
Kalecgos = "Kalecgos", |
["Kam Deepfury"] = "Kam Deepfury", |
["Kazkaz the Unholy"] = "Kazkaz the Unholy", |
["Kaz'rogal"] = "Kaz'rogal", |
["Keli'dan the Breaker"] = "Keli'dan the Breaker", |
["Kel'Thuzad"] = "Kel'Thuzad", |
Keristrasza = "Keristrasza", |
["Kiggler the Crazed"] = "Kiggler the Crazed", |
["Kil'jaeden"] = "Kil'jaeden", |
["Kil'rek"] = "Kil'rek", |
["King Dred"] = "King Dred", |
["King Gordok"] = "King Gordok", |
["King Llane Piece"] = "King Llane Piece", |
["King Ymiron"] = "King Ymiron", |
["Kirtonos the Herald"] = "Kirtonos the Herald", |
["Knot Thimblejack's Cache"] = "Knot Thimblejack's Cache", |
Kolk = "Kolk", |
Kologarn = "Kologarn", |
["Koralon the Flame Watcher"] = "Koralon the Flame Watcher", |
Kormok = "Kormok", |
Kresh = "Kresh", |
Krick = "Krick", |
["Krick and Ick"] = "Krick and Ick", |
["Krik'thir the Gatewatcher"] = "Krik'thir the Gatewatcher", |
["Krosh Firehand"] = "Krosh Firehand", |
Krystallus = "Krystallus", |
Kurinnaxx = "Kurinnaxx", |
["Lady Anacondra"] = "Lady Anacondra", |
["Lady Blaumeux"] = "Lady Blaumeux", |
["Lady Deathwhisper"] = "Lady Deathwhisper", |
["Lady Illucia Barov"] = "Lady Illucia Barov", |
["Lady Malande"] = "Lady Malande", |
["Lady Sacrolash"] = "Lady Sacrolash", |
["Lady Sarevess"] = "Lady Sarevess", |
["Lady Vashj"] = "Lady Vashj", |
Laj = "Laj", |
Landslide = "Landslide", |
Lavanthor = "Lavanthor", |
["Left Arm"] = "Left Arm", |
["Leotheras the Blind"] = "Leotheras the Blind", |
Lethon = "Lethon", |
Lethtendris = "Lethtendris", |
["Leviathan Mk II"] = "Leviathan Mk II", |
["Ley-Guardian Eregos"] = "Ley-Guardian Eregos", |
["Lieutenant Drake"] = "Lieutenant Drake", |
["Lieutenant General Andorov"] = "Lieutenant General Andorov", |
Loatheb = "Loatheb", |
Loken = "Loken", |
["Lord Alexei Barov"] = "Lord Alexei Barov", |
["Lord Cobrahn"] = "Lord Cobrahn", |
["Lord Hel'nurath"] = "Lord Hel'nurath", |
["Lord Incendius"] = "Lord Incendius", |
["Lord Jaraxxus"] = "Lord Jaraxxus", |
["Lord Kazzak"] = "Lord Kazzak", |
["Lord Kri"] = "Lord Kri", |
["Lord Marrowgar"] = "Lord Marrowgar", |
["Lord Pythas"] = "Lord Pythas", |
["Lord Roccor"] = "Lord Roccor", |
["Lord Sanguinar"] = "Lord Sanguinar", |
["Lord Serpentis"] = "Lord Serpentis", |
["Lord Skwol"] = "Lord Skwol", |
["Lord Valthalak"] = "Lord Valthalak", |
["Lord Victor Nefarius"] = "Lord Victor Nefarius", |
["Lord Vyletongue"] = "Lord Vyletongue", |
["Lorekeeper Polkelt"] = "Lorekeeper Polkelt", |
Loro = "Loro", |
Lucifron = "Lucifron", |
["Mad Magglish"] = "Mad Magglish", |
Maexxna = "Maexxna", |
["Mage-Lord Urom"] = "Mage-Lord Urom", |
["Magister Kalendris"] = "Magister Kalendris", |
["Magistrate Barthilas"] = "Magistrate Barthilas", |
Magmadar = "Magmadar", |
Magmus = "Magmus", |
Magra = "Magra", |
Magtheridon = "Magtheridon", |
["Maiden of Grief"] = "Maiden of Grief", |
["Maiden of Virtue"] = "Maiden of Virtue", |
["Majordomo Executus"] = "Majordomo Executus", |
Malacrass = "Malacrass", |
["Maleki the Pallid"] = "Maleki the Pallid", |
["Mal'Ganis"] = "Mal'Ganis", |
Malygos = "Malygos", |
Maraudos = "Maraudos", |
["Marduk Blackpool"] = "Marduk Blackpool", |
["Marisa du'Paige"] = "Marisa du'Paige", |
Marwyn = "Marwyn", |
["Master Engineer Telonicus"] = "Master Engineer Telonicus", |
["Maur Grimtotem"] = "Maur Grimtotem", |
Meathook = "Meathook", |
["Mechano-Lord Capacitus"] = "Mechano-Lord Capacitus", |
Medivh = "Medivh", |
["Mekgineer Steamrigger"] = "Mekgineer Steamrigger", |
["Mekgineer Thermaplugg"] = "Mekgineer Thermaplugg", |
["Mennu the Betrayer"] = "Mennu the Betrayer", |
["Meshlok the Harvester"] = "Meshlok the Harvester", |
Midnight = "Midnight", |
Mijan = "Mijan", |
Mimiron = "Mimiron", |
["Miner Johnson"] = "Miner Johnson", |
["Mistress of Pain"] = "Mistress of Pain", |
Moam = "Moam", |
Mogor = "Mogor", |
["Mokra the Skullcrusher"] = "Mokra the Skullcrusher", |
Moorabi = "Moorabi", |
Moragg = "Moragg", |
["Mordresh Fire Eye"] = "Mordresh Fire Eye", |
["Mor Grayhoof"] = "Mor Grayhoof", |
Moroes = "Moroes", |
["Morogrim Tidewalker"] = "Morogrim Tidewalker", |
Morphaz = "Morphaz", |
["Mother Shahraz"] = "Mother Shahraz", |
["Mother Smolderweb"] = "Mother Smolderweb", |
["Mr. Smite"] = "Mr. Smite", |
["Muradin Bronzebeard"] = "Muradin Bronzebeard", |
["Murkblood Twin"] = "Murkblood Twin", |
["Murkblood Twins"] = "Murkblood Twins", |
Murmur = "Murmur", |
["Murta Grimgut"] = "Murta Grimgut", |
["M'uru"] = "M'uru", |
Mushgog = "Mushgog", |
["Mutanus the Devourer"] = "Mutanus the Devourer", |
Nalorakk = "Nalorakk", |
Nazan = "Nazan", |
Nefarian = "Nefarian", |
["Nekrum Gutchewer"] = "Nekrum Gutchewer", |
["Nerub'enkan"] = "Nerub'enkan", |
["Nethermancer Sepethrea"] = "Nethermancer Sepethrea", |
Netherspite = "Netherspite", |
["Netherstrand Longbow"] = "Netherstrand Longbow", |
["Nexus-Prince Shaffar"] = "Nexus-Prince Shaffar", |
Nightbane = "Nightbane", |
["Noth the Plaguebringer"] = "Noth the Plaguebringer", |
["Novos the Summoner"] = "Novos the Summoner", |
Noxxion = "Noxxion", |
["Obsidian Sentinel"] = "Obsidian Sentinel", |
["Odo the Blindwatcher"] = "Odo the Blindwatcher", |
["Ogom the Wretched"] = "Ogom the Wretched", |
["Ok'thor the Breaker"] = "Ok'thor the Breaker", |
["Old Serra'kis"] = "Old Serra'kis", |
["Olm the Summoner"] = "Olm the Summoner", |
["Omor the Unscarred"] = "Omor the Unscarred", |
Onyxia = "Onyxia", |
["Orgrim's Hammer"] = "Orgrim's Hammer", |
["Ormorok the Tree-Shaper"] = "Ormorok the Tree-Shaper", |
["Oro Eyegouge"] = "Oro Eyegouge", |
["Ossirian the Unscarred"] = "Ossirian the Unscarred", |
Ouro = "Ouro", |
["Overlord Ramtusk"] = "Overlord Ramtusk", |
["Overlord Wyrmthalak"] = "Overlord Wyrmthalak", |
["Overmaster Pyron"] = "Overmaster Pyron", |
["Overseer Tidewrath"] = "Overseer Tidewrath", |
Pandemonius = "Pandemonius", |
["Panzor the Invincible"] = "Panzor the Invincible", |
Patchwerk = "Patchwerk", |
["Pathaleon the Calculator"] = "Pathaleon the Calculator", |
Phalanx = "Phalanx", |
["Phaseshift Bulwark"] = "Phaseshift Bulwark", |
Pimgib = "Pimgib", |
["Plaguemaw the Rotting"] = "Plaguemaw the Rotting", |
["Plugger Spazzring"] = "Plugger Spazzring", |
["Postmaster Malown"] = "Postmaster Malown", |
["Priestess Delrissa"] = "Priestess Delrissa", |
["Prince Keleseth"] = "Prince Keleseth", |
["Prince Malchezaar"] = "Prince Malchezaar", |
["Prince Skaldrenox"] = "Prince Skaldrenox", |
["Princess Huhuran"] = "Princess Huhuran", |
["Princess Moira Bronzebeard"] = "Princess Moira Bronzebeard", |
["Princess Tempestria"] = "Princess Tempestria", |
["Princess Theradras"] = "Princess Theradras", |
["Princess Yauj"] = "Princess Yauj", |
["Prince Taldaram"] = "Prince Taldaram", |
["Prince Tenris Mirkblood"] = "Prince Tenris Mirkblood", |
["Prince Tortheldrin"] = "Prince Tortheldrin", |
["Prince Valanar"] = "Prince Valanar", |
["Professor Putricide"] = "Professor Putricide", |
["Pure Spawn of Hydross"] = "Pure Spawn of Hydross", |
Pusillin = "Pusillin", |
["Pyroguard Emberseer"] = "Pyroguard Emberseer", |
["Pyromancer Loregrain"] = "Pyromancer Loregrain", |
Quagmirran = "Quagmirran", |
["Quartermaster Zigris"] = "Quartermaster Zigris", |
["Rage Winterchill"] = "Rage Winterchill", |
Ragglesnout = "Ragglesnout", |
["Raging Spirit"] = "Raging Spirit", |
Ragnaros = "Ragnaros", |
["Ramstein the Gorger"] = "Ramstein the Gorger", |
["Ras Frostwhisper"] = "Ras Frostwhisper", |
Rattlegore = "Rattlegore", |
["Razorclaw the Butcher"] = "Razorclaw the Butcher", |
["Razorgore the Untamed"] = "Razorgore the Untamed", |
Razorlash = "Razorlash", |
Razorscale = "Razorscale", |
["Reliquary of Souls"] = "Reliquary of Souls", |
Renataki = "Renataki", |
["Restless Skeleton"] = "Restless Skeleton", |
Rethilgore = "Rethilgore", |
Revelosh = "Revelosh", |
["Rhahk'Zor"] = "Rhahk'Zor", |
["Ribbly Screwspigot"] = "Ribbly Screwspigot", |
["Right Arm"] = "Right Arm", |
Roar = "Roar", |
["Rokad the Ravager"] = "Rokad the Ravager", |
["Rokdar the Sundered Lord"] = "Rokdar the Sundered Lord", |
["Rokmar the Crackler"] = "Rokmar the Crackler", |
Romulo = "Romulo", |
["Romulo & Julianne"] = "Romulo & Julianne", |
Rotface = "Rotface", |
Rotgrip = "Rotgrip", |
["Runemaster Molgeim"] = "Runemaster Molgeim", |
["Runok Wildmane"] = "Runok Wildmane", |
Ruuzlu = "Ruuzlu", |
["Salramm the Fleshcrafter"] = "Salramm the Fleshcrafter", |
["Sanctum Sentry"] = "Sanctum Sentry", |
["Sandarr Dunereaver"] = "Sandarr Dunereaver", |
["Sandfury Executioner"] = "Sandfury Executioner", |
Sapphiron = "Sapphiron", |
Sara = "Sara", |
["Saronite Animus"] = "Saronite Animus", |
Sartharion = "Sartharion", |
["Sathrovarr the Corruptor"] = "Sathrovarr the Corruptor", |
["Saviana Ragefire"] = "Saviana Ragefire", |
["Scarlet Commander Mograine"] = "Scarlet Commander Mograine", |
["Scourgelord Tyrannus"] = "Scourgelord Tyrannus", |
["Seeth'rel"] = "Seeth'rel", |
["Selin Fireheart"] = "Selin Fireheart", |
["Sergeant Bly"] = "Sergeant Bly", |
["Shade of Akama"] = "Shade of Akama", |
["Shade of Aran"] = "Shade of Aran", |
["Shade of Eranikus"] = "Shade of Eranikus", |
["Shadikith the Glider"] = "Shadikith the Glider", |
["Shadow Hunter Vosh'gajin"] = "Shadow Hunter Vosh'gajin", |
["Shadow of Leotheras"] = "Shadow of Leotheras", |
["Shadowpriest Sezz'ziz"] = "Shadowpriest Sezz'ziz", |
Shadron = "Shadron", |
Shazzrah = "Shazzrah", |
["Shirrak the Dead Watcher"] = "Shirrak the Dead Watcher", |
Sindragosa = "Sindragosa", |
["Sir Zeliek"] = "Sir Zeliek", |
["Sjonnir The Ironshaper"] = "Sjonnir The Ironshaper", |
["Skadi the Ruthless"] = "Skadi the Ruthless", |
["Skarr the Unbreakable"] = "Skarr the Unbreakable", |
["Skarvald the Constructor"] = "Skarvald the Constructor", |
["Skra'gath"] = "Skra'gath", |
Skul = "Skul", |
Skum = "Skum", |
["Slad'ran"] = "Slad'ran", |
Sneed = "Sneed", |
["Sneed's Shredder"] = "Sneed's Shredder", |
["Solakar Flamewreath"] = "Solakar Flamewreath", |
["Solarium Agent"] = "Solarium Agent", |
["Solarium Priest"] = "Solarium Priest", |
["Spirestone Battle Lord"] = "Spirestone Battle Lord", |
["Spirestone Butcher"] = "Spirestone Butcher", |
["Spirestone Lord Magus"] = "Spirestone Lord Magus", |
["Staff of Disintegration"] = "Staff of Disintegration", |
Stalagg = "Stalagg", |
Steelbreaker = "Steelbreaker", |
["Stomper Kreeg"] = "Stomper Kreeg", |
Stonespine = "Stonespine", |
["Stormcaller Brundir"] = "Stormcaller Brundir", |
Strawman = "Strawman", |
["Sulfuron Harbinger"] = "Sulfuron Harbinger", |
Supremus = "Supremus", |
["Svala Sorrowgrave"] = "Svala Sorrowgrave", |
["Swamplord Musel'ek"] = "Swamplord Musel'ek", |
Taerar = "Taerar", |
["Tainted Spawn of Hydross"] = "Tainted Spawn of Hydross", |
["Talon King Ikiss"] = "Talon King Ikiss", |
["Taragaman the Hungerer"] = "Taragaman the Hungerer", |
["Targorr the Dread"] = "Targorr the Dread", |
Tavarok = "Tavarok", |
Techbot = "Techbot", |
Temporus = "Temporus", |
["Tendris Warpwood"] = "Tendris Warpwood", |
Tenebron = "Tenebron", |
["Terestian Illhoof"] = "Terestian Illhoof", |
["Teron Gorefiend"] = "Teron Gorefiend", |
Thaddius = "Thaddius", |
["Thaladred the Darkener"] = "Thaladred the Darkener", |
["Thane Korth'azz"] = "Thane Korth'azz", |
["The Beast"] = "The Beast", |
["The Beasts of Northrend"] = "The Beasts of Northrend", |
["The Big Bad Wolf"] = "The Big Bad Wolf", |
["The Black Knight"] = "The Black Knight", |
["The Black Stalker"] = "The Black Stalker", |
["The Blue Brothers"] = "The Blue Brothers", |
["The Bug Family"] = "The Bug Family", |
["The Crone"] = "The Crone", |
["The Curator"] = "The Curator", |
["The Eredar Twins"] = "The Eredar Twins", |
["The Four Horsemen"] = "The Four Horsemen", |
["The Illidari Council"] = "The Illidari Council", |
["The Iron Council"] = "The Iron Council", |
["Theka the Martyr"] = "Theka the Martyr", |
["The Lich King"] = "The Lich King", |
["The Lurker Below"] = "The Lurker Below", |
["The Maker"] = "The Maker", |
["The Prophet Skeram"] = "The Prophet Skeram", |
["The Prophet Tharon'ja"] = "The Prophet Tharon'ja", |
["The Ravenian"] = "The Ravenian", |
["The Razza"] = "The Razza", |
["The Seven Dwarves"] = "The Seven Dwarves", |
["The Skybreaker"] = "The Skybreaker", |
["The Tribunal of Ages"] = "The Tribunal of Ages", |
["The Twin Emperors"] = "The Twin Emperors", |
["The Twin Val'kyr"] = "The Twin Val'kyr", |
["The Unforgiven"] = "The Unforgiven", |
["The Windreaver"] = "The Windreaver", |
Thorim = "Thorim", |
["Thorngrin the Tender"] = "Thorngrin the Tender", |
["Tidewalker Lurker"] = "Tidewalker Lurker", |
["Timmy the Cruel"] = "Timmy the Cruel", |
Tinhead = "Tinhead", |
["Tinkerer Gizlock"] = "Tinkerer Gizlock", |
["Tirion Fordring"] = "Tirion Fordring", |
Tito = "Tito", |
["Toravon the Ice Watcher"] = "Toravon the Ice Watcher", |
["Trigore the Lasher"] = "Trigore the Lasher", |
Trollgore = "Trollgore", |
["Tsu'zee"] = "Tsu'zee", |
["Tuten'kash"] = "Tuten'kash", |
["Twilight Lord Kelris"] = "Twilight Lord Kelris", |
["Urok Doomhowl"] = "Urok Doomhowl", |
["Vaelastrasz the Corrupt"] = "Vaelastrasz the Corrupt", |
["Valithria Dreamwalker"] = "Valithria Dreamwalker", |
["Val'kyr Shadowguard"] = "Val'kyr Shadowguard", |
["Varian Wrynn"] = "Varian Wrynn", |
["Varos Cloudstrider"] = "Varos Cloudstrider", |
Vazruden = "Vazruden", |
["Vazruden the Herald"] = "Vazruden the Herald", |
Vectus = "Vectus", |
Vem = "Vem", |
Veng = "Veng", |
["Veras Darkshadow"] = "Veras Darkshadow", |
["Verdan the Everliving"] = "Verdan the Everliving", |
Verek = "Verek", |
Vesperon = "Vesperon", |
Vexallus = "Vexallus", |
["Veyzhak the Cannibal"] = "Veyzhak the Cannibal", |
["Vile'rel"] = "Vile'rel", |
Viscidus = "Viscidus", |
["Viscous Fallout"] = "Viscous Fallout", |
["Void Reaver"] = "Void Reaver", |
Volkhan = "Volkhan", |
["VX-001"] = "VX-001", |
["Warbringer O'mrogg"] = "Warbringer O'mrogg", |
["Warchief Blackhand Piece"] = "Warchief Blackhand Piece", |
["Warchief Kargath Bladefist"] = "Warchief Kargath Bladefist", |
["Warchief Rend Blackhand"] = "Warchief Rend Blackhand", |
["Warden Mellichar"] = "Warden Mellichar", |
["Warder Stilgiss"] = "Warder Stilgiss", |
["Warlord Kalithresh"] = "Warlord Kalithresh", |
["War Master Voone"] = "War Master Voone", |
["Warmaul Champion"] = "Warmaul Champion", |
["Warp Slicer"] = "Warp Slicer", |
["Warp Splinter"] = "Warp Splinter", |
["Watchkeeper Gargolmar"] = "Watchkeeper Gargolmar", |
Weaver = "Weaver", |
["Witch Doctor Zum'rah"] = "Witch Doctor Zum'rah", |
["Wolf Master Nandos"] = "Wolf Master Nandos", |
["Wrath-Scryer Soccothrates"] = "Wrath-Scryer Soccothrates", |
Wushoolay = "Wushoolay", |
Xevozz = "Xevozz", |
["XT-002 Deconstructor"] = "XT-002 Deconstructor", |
["Yogg-Saron"] = "Yogg-Saron", |
Ysondre = "Ysondre", |
Zekkis = "Zekkis", |
["Zelemar the Wrathful"] = "Zelemar the Wrathful", |
["Zereketh the Unbound"] = "Zereketh the Unbound", |
Zerillis = "Zerillis", |
["Zevrim Thornhoof"] = "Zevrim Thornhoof", |
Zolo = "Zolo", |
["Zul'Farrak Dead Hero"] = "Zul'Farrak Dead Hero", |
["Zul'jin"] = "Zul'jin", |
["Zul'Lor"] = "Zul'Lor", |
["Zul'tore"] = "Zul'tore", |
["Zuramat the Obliterator"] = "Zuramat the Obliterator", |
} |
if GAME_LOCALE == "enUS" then |
lib:SetCurrentTranslations(true) |
elseif GAME_LOCALE == "deDE" then |
lib:SetCurrentTranslations { |
Acidmaw = "Ãtzschlund", |
Aeonus = "Aeonus", |
["Aerial Command Unit"] = "Luftkommandoeinheit", |
["Agathelos the Raging"] = "Agathelos der Tobende", |
Ahune = "Ahune", |
["Akil'zon"] = "Akil'zon", |
["Aku'mai"] = "Aku'mai", |
["Al'ar"] = "Al'ar", |
["Algalon the Observer"] = "Algalon der Beobachter", |
["Alzzin the Wildshaper"] = "Alzzin der Wildformer", |
Amanitar = "Amanitar", |
["Ambassador Flamelash"] = "Botschafter Flammenschlag", |
["Ambassador Hellmaw"] = "Botschafter Höllenschlund", |
["Amnennar the Coldbringer"] = "Amnennar der Kältebringer", |
["Ancient Stone Keeper"] = "Uralter Steinbewahrer", |
Anetheron = "Anetheron", |
["Anger'rel"] = "Anger'rel", |
Anomalus = "Anomalus", |
["Antu'sul"] = "Antu'sul", |
["Anub'arak"] = "Anub'arak", |
["Anubisath Defender"] = "Verteidiger des Anubisath", |
["Anubisath Guardian"] = "Beschützer des Anubisath", |
["Anub'Rekhan"] = "Anub'Rekhan", |
["Anub'shiah"] = "Anub'shiah", |
Anzu = "Anzu", |
["Arcane Watchman"] = "Arkanwachmann", |
["Arcanist Doan"] = "Arkanist Doan", |
Archaedas = "Archaedas", |
["Archavon the Stone Watcher"] = "Archavon der Steinwächter", |
Archimonde = "Archimonde", |
["Archivist Galford"] = "Archivar Galford", |
["Archmage Arugal"] = "Erzmagier Arugal", |
["Argent Confessor Paletress"] = "Argentumbeichtpatin Blondlocke", |
["Arugal's Voidwalker"] = "Arugals Leerwandler", |
["Assault Bot"] = "Angriffsbot", |
["Atal'alarion"] = "Atal'alarion", |
["Attumen the Huntsman"] = "Attumen der Jäger", |
Auriaya = "Auriaya", |
Avalanchion = "Avalanchion", |
["Avatar of Hakkar"] = "Avatar von Hakkar", |
["Ayamiss the Hunter"] = "Ayamiss der Jäger", |
Azgalor = "Azgalor", |
["Azshir the Sleepless"] = "Azshir der Schlaflose", |
Azuregos = "Azuregos", |
["Bael'Gar"] = "Bael'Gar", |
Baelog = "Baelog", |
Balnazzar = "Balnazzar", |
["Baltharus the Warborn"] = "Baltharus der Kriegsjünger", |
["Bannok Grimaxe"] = "Bannok Grimmaxt", |
["Baron Aquanis"] = "Baron Aquanis", |
["Baron Charr"] = "Baron Glutarr", |
["Baroness Anastari"] = "Baroness Anastari", |
["Baron Geddon"] = "Baron Geddon", |
["Baron Kazum"] = "Baron Kazum", |
["Baron Rivendare"] = "Baron Totenschwur", |
["Baron Silverlaine"] = "Baron Silberlein", |
["Battleguard Sartura"] = "Schlachtwache Sartura", |
["Bazil Thredd"] = "Bazil Thredd", |
Bazzalan = "Bazzalan", |
["Black Guard Swordsmith"] = "Schwertschmied der schwarzen Wache", |
["Blackheart the Inciter"] = "Schwarzherz der Hetzer", |
["Blindeye the Seer"] = "Blindauge der Seher", |
["Blind Hunter"] = "Blinder Jäger", |
["Blood Guard Porung"] = "Blutwache Porung", |
["Bloodlord Mandokir"] = "Blutfürst Mandokir", |
["Bloodmage Thalnos"] = "Blutmagier Thalnos", |
["Blood Prince Council"] = "Rat der Blutprinzen", |
["Blood Princes"] = "Rat der Blutprinzen", |
["Blood-Queen Lana'thel"] = "Blutkönigin Lana'thel", |
["Blood Steward of Kirtonos"] = "Blutdiener von Kirtonos", |
Boahn = "Boahn", |
["Bomb Bot"] = "Bombenbot", |
["Brain of Yogg-Saron"] = "Yogg-Sarons Gehirn", |
["Brainwashed Noble"] = "Manipulierter Adliger", |
Broggok = "Broggok", |
Brokentoe = "Schmetterzehe", |
Bronjahm = "Bronjahm", |
["Broodlord Lashlayer"] = "Brutwächter Dreschbringer", |
["Bruegal Ironknuckle"] = "Bruegal Eisenfaust", |
Brutallus = "Brutallus", |
["Burning Felguard"] = "Brennende Teufelswache", |
["Buru the Gorger"] = "Buru der Verschlinger", |
["Cache of the Firelord"] = "Truhe des Feuerlords", |
["Cannon Master Willey"] = "Kanonenmeister Willey", |
["Captain Greenskin"] = "Kapitän Grünhaut", |
["Captain Kromcrush"] = "Hauptmann Krombruch", |
["Captain Skarloc"] = "Kapitän Skarloc", |
["Celebras the Cursed"] = "Celebras der Verfluchte", |
["Charlga Razorflank"] = "Charlga Klingenflanke", |
["Chess Event"] = "Chess Event", |
["Chest of The Seven"] = "Truhe der Sieben", |
["Chief Ukorz Sandscalp"] = "Häuptling Ukorz Sandwüter", |
["Cho'Rush the Observer"] = "Cho'Rush der Beobachter", |
Chromaggus = "Chromaggus", |
["Chrono Lord Deja"] = "Chronolord Deja", |
["Chrono-Lord Epoch"] = "Chronolord Epoch", |
Claw = "Klaue", |
["Coilfang Elite"] = "Elitesoldat des Echsenkessels", |
["Coilfang Strider"] = "Schreiter des Echsenkessels", |
["Commander Kolurg"] = "Kommandant Kolurg", |
["Commander Sarannis"] = "Kommandant Sarannis", |
["Commander Springvale"] = "Kommandant Springvale", |
["Commander Stoutbeard"] = "Kommandant Starkbart", |
["Constructor & Controller"] = "Konstrukteur & Kontrolleur", |
Cookie = "Krümel", |
["Coren Direbrew"] = "Coren Düsterbräu", |
["Cosmic Infuser"] = "Kosmische Macht", |
["Crimson Hammersmith"] = "Purpurroter Hammerschmied", |
["Crowd Pummeler 9-60"] = "Meuteverprügler 9-60", |
["Crystal Fang"] = "Kristallfangzahn", |
["C'Thun"] = "C'Thun", |
Cyanigosa = "Cyanigosa", |
["Dalliah the Doomsayer"] = "Dalliah die Verdammnisverkünderin", |
["Dalronn the Controller"] = "Dalronn der Kontrolleur", |
["Dark Iron Ambassador"] = "Botschafter der Dunkeleisenzwerge", |
["Darkmaster Gandling"] = "Dunkelmeister Gandling", |
["Darkweaver Syth"] = "Dunkelwirker Syth", |
["Deathbound Ward"] = "Todesgeweihter Wächter", |
["Deathbringer Saurfang"] = "Todesbringer Saurfang", |
["Death Knight Darkreaver"] = "Todesritter Schattensichel", |
["Death Knight Understudy"] = "Reservist der Todesritter", |
["Deathspeaker High Priest"] = "Hohepriester der Todessprecher", |
["Death Speaker Jargba"] = "Todessprecher Jargba", |
["Deathstalker Visceri"] = "Todespirscher Visceri", |
["Deathsworn Captain"] = "Todeshöriger Captain", |
Devastation = "Verwüstung", |
["Deviate Faerie Dragon"] = "Deviatfeendrache", |
["Devourer of Souls"] = "Verschlinger der Seelen", |
["Dextren Ward"] = "Dextren Ward", |
["Digmaster Shovelphlange"] = "Grubenmeister Schaufelphlansch", |
["Doctor Theolen Krastinov"] = "Doktor Theolen Krastinov", |
["Doom Lord Kazzak"] = "Verdammnislord Kazzak", |
["Doom'rel"] = "Un'rel", |
Doomwalker = "Verdammniswandler", |
["Dope'rel"] = "Trott'rel", |
Dorothee = "Dorothee", |
["Drakkari Colossus"] = "Koloss der Drakkari", |
["Drakos the Interrogator"] = "Drakos der Befrager", |
Dreadscale = "Schreckensmaul", |
Dreamscythe = "Traumsense", |
["Dust Covered Chest"] = "Staub Bedeckter Kasten", |
Dustwraith = "Karaburan", |
["Eadric the Pure"] = "Eadric der Reine", |
["Earthcaller Halmgar"] = "Erdenrufer Halmgar", |
Ebonroc = "Schattenschwinge", |
["Eck the Ferocious"] = "Der wilde Eck", |
["Edwin VanCleef"] = "Edwin van Cleef", |
["Elder Brightleaf"] = "Ãltester Hellblatt", |
["Elder Ironbranch"] = "Ãltester Eisenast", |
["Elder Nadox"] = "Urahne Nadox", |
["Elder Stonebark"] = "Ãltester Steinrinde", |
["Electrocutioner 6000"] = "Elektrokutor 6000", |
["Emalon the Storm Watcher"] = "Emalon der Sturmwächter", |
Emeriss = "Smariss", |
["Emperor Dagran Thaurissan"] = "Imperator Dagran Thaurissan", |
["Emperor Vek'lor"] = "Imperator Vek'lor", |
["Emperor Vek'nilash"] = "Imperator Vek'nilash", |
Entropius = "Entropius", |
["Eonar's Gift"] = "Eonars Geschenk", |
["Epoch Hunter"] = "Epochenjäger", |
Erekem = "Erekem", |
["Eressea Dawnsinger"] = "Eressea Morgensänger", |
["Essence of Anger"] = "Essenz des Zorns", |
["Essence of Desire"] = "Essenz der Begierde", |
["Essence of Suffering"] = "Essenz des Leidens", |
Eviscerator = "Ausweider", |
["Exarch Maladaar"] = "Exarch Maladaar", |
["Expedition Commander"] = "Kommandant der Expedition", |
["Eydis Darkbane"] = "Eydis Nachtbann", |
["Eye of C'Thun"] = "Auge von C'Thun", |
["Faction Champions"] = "Fraktionschampions", |
["Fallen Champion"] = "Gestürzter Held", |
Falric = "Falric", |
["Falric and Marwyn"] = "Falric und Marwyn", |
["Fankriss the Unyielding"] = "Fankriss der Unnachgiebige", |
["Fathom-Lord Karathress"] = "Tiefenlord Karathress", |
Felmyst = "Teufelsruch", |
["Fenrus the Devourer"] = "Fenrus der Verschlinger", |
["Feral Defender"] = "Wilder Verteidiger", |
Festergut = "Fauldarm", |
Feugen = "Feugen", |
["Fineous Darkvire"] = "Fineous Dunkelader", |
Firemaw = "Feuerschwinge", |
["Fjola Lightbane"] = "Fjola Lichtbann", |
Flamegor = "Flammenmaul", |
["Flame Leviathan"] = "Flammenleviathan", |
["Foreman Thistlenettle"] = "GroÃknecht Distelklette", |
["Forgemaster Garfrost"] = "Schmiedenmeister Garfrost", |
["Four Horsemen Chest"] = "Die Vier Reiter Kiste", |
["Fras Siabi"] = "Fras Siabi", |
Freya = "Freya", |
["Gahz'ranka"] = "Gahz'ranka", |
["Gahz'rilla"] = "Gahz'rilla", |
["Gal'darah"] = "Gal'darah", |
["Galgann Firehammer"] = "Galgann Feuerhammer", |
Garr = "Garr", |
["Garrosh Hellscream"] = "Garrosh Höllschrei", |
Gasher = "Schlitzer", |
["Gatewatcher Gyro-Kill"] = "Torwächter Gyrotot", |
["Gatewatcher Iron-Hand"] = "Torwächter Eisenhand", |
["Gathios the Shatterer"] = "Gathios der Zerschmetterer", |
Gehennas = "Gehennas", |
Gelihast = "Gelihast", |
Gelk = "Gelk", |
["General Angerforge"] = "General Zornesschmied", |
["General Bjarngrim"] = "General Bjarngrim", |
["General Drakkisath"] = "General Drakkisath", |
["General Rajaxx"] = "General Rajaxx", |
["General Vezax"] = "General Vezax", |
["General Zarithrian"] = "General Zarithrian", |
["Ghamoo-ra"] = "Ghamoo-ra", |
["Ghaz'an"] = "Ghaz'an", |
["Ghok Bashguud"] = "Ghok Haudrauf", |
Gilnid = "Gilnid", |
["Gizrul the Slavener"] = "Gizrul der Geifernde", |
["Gloom'rel"] = "Dunk'rel", |
Gluth = "Gluth", |
Glutton = "Nimmersatt", |
["Golemagg the Incinerator"] = "Golemagg der Verbrenner", |
["Golem Lord Argelmach"] = "Golemlord Argelmach", |
["Goraluk Anvilcrack"] = "Goraluk Hammerbruch", |
["Gormok the Impaler"] = "Gormok der Pfähler", |
["Gorosh the Dervish"] = "Gorosh der Derwisch", |
["Gortok Palehoof"] = "Gortok Bleichhuf", |
["Gothik the Harvester"] = "Gothik der Ernter", |
["Grand Astromancer Capernian"] = "GroÃastronom Capernian", |
["Grand Champions"] = "GroÃchampions", |
["Grand Magus Telestra"] = "GroÃmagistrix Telestra", |
["Grandmaster Vorpil"] = "GroÃmeister Vorpil", |
Grandmother = "GroÃmutter", |
["Grand Warlock Alythess"] = "GroÃhexenmeisterin Alythess", |
["Grand Warlock Nethekurse"] = "GroÃhexenmeister Nethekurse", |
["Grand Widow Faerlina"] = "GroÃwitwe Faerlina", |
["Grethok the Controller"] = "Grethok der Aufseher", |
["Gri'lek"] = "Gri'lek", |
Grimlok = "Grimlok", |
Grizzle = "Grizzle", |
Grobbulus = "Grobbulus", |
Grubbis = "Grubbis", |
["Gruul the Dragonkiller"] = "Gruul der Drachenschlächter", |
["Guard Fengus"] = "Wache Fengus", |
["Guardian of Yogg-Saron"] = "Wächter des Yogg-Saron", |
["Guard Mol'dar"] = "Wache Mol'dar", |
["Guard Slip'kik"] = "Wache Slip'kik", |
["Gurtogg Bloodboil"] = "Gurtogg Siedeblut", |
Gyth = "Gyth", |
Hadronox = "Hadronox", |
Hakkar = "Hakkar", |
Halazzi = "Halazzi", |
Halion = "Halion", |
Halycon = "Halycon", |
Hamhock = "Hamhock", |
["Harbinger Skyriss"] = "Herold Horizontiss", |
["Hate'rel"] = "Hass'rel", |
["Hazza'rah"] = "Hazza'rah", |
Hazzas = "Hazzas", |
["Headless Horseman"] = "Der kopflose Reiter", |
["Hearthsinger Forresten"] = "Herdsinger Forresten", |
["Hedrum the Creeper"] = "Hedrum der Krabbler", |
["Heigan the Unclean"] = "Heigan der Unreine", |
["Hellfire Channeler"] = "Kanalisierer des Höllenfeuers", |
["Henry Stern"] = "Henry Stern", |
["Herald Volazj"] = "Verkünder Volazj", |
Herod = "Herod", |
["Hex Lord Malacrass"] = "Hexlord Malacrass", |
["High Astromancer Solarian"] = "Hochastromantin Solarian", |
["High Botanist Freywinn"] = "Hochbotaniker Freywinn", |
["High Inquisitor Fairbanks"] = "Hochinquisitor Fairbanks", |
["High Inquisitor Whitemane"] = "Hochinquisitor WeiÃsträhne", |
["High Interrogator Gerstahn"] = "Verhörmeisterin Gerstahn", |
["High King Maulgar"] = "Hochkönig Maulgar", |
["Highlord Mograine"] = "Hochlord Mograine", |
["Highlord Omokk"] = "Hochlord Omokk", |
["High Marshal Whirlaxis"] = "Hochmarschall Whirlaxis", |
["High Nethermancer Zerevor"] = "Hochnethermant Zerevor", |
["High Overlord Saurfang"] = "Hochfürst Saurfang", |
["High Priestess Arlokk"] = "Hohepriesterin Arlokk", |
["High Priestess Jeklik"] = "Hohepriesterin Jeklik", |
["High Priestess Mar'li"] = "Hohepriesterin Mar'li", |
["High Priestess of Thaurissan"] = "\009Hohepriesterin von Thaurissan", |
["High Priest Thekal"] = "Hohepriester Thekal", |
["High Priest Venoxis"] = "Hohepriester Venoxis", |
["High Warlord Naj'entus"] = "Oberster Kriegsfürst Naj'entus", |
Hodir = "Hodir", |
["Houndmaster Grebmar"] = "Hundemeister Grebmar", |
["Houndmaster Loksey"] = "Hundemeister Loksey", |
Hukku = "Hukku", |
Hungarfen = "Hungarfenn", |
["Hurley Blackbreath"] = "Hurley Pestatem", |
["Hyakiss the Lurker"] = "Hyakiss der Lauerer", |
["Hydromancer Thespia"] = "Wasserbeschwörerin Thespia", |
["Hydromancer Velratha"] = "Wasserbeschwörerin Velratha", |
Hydrospawn = "Hydrobrut", |
["Hydross the Unstable"] = "Hydross der Unstete", |
["Icecrown Gunship Battle"] = "Luftschlacht um die Eiskronenzitadelle", |
Icehowl = "Eisheuler", |
["Ice Sphere"] = "Eissphäre", |
Ichoron = "Ichoron", |
Ick = "Ick", |
["Ignis the Furnace Master"] = "Ignis, Meister des Eisenwerks", |
["Illidan Stormrage"] = "Illidan Sturmgrimm", |
["Illidari Council"] = "Rat der Illidari", |
["Illyanna Ravenoak"] = "Illyanna Rabeneiche", |
["Immol'thar"] = "Immol'thar", |
["Infinite Corruptor"] = "Ewiger Verderber", |
["Infinity Blades"] = "Klinge der Unendlichkeit", |
["Ingvar the Plunderer"] = "Ingvar der Brandschatzer", |
["Instructor Malicia"] = "Instrukteurin Malicia", |
["Instructor Razuvious"] = "Instrukteur Razuvious", |
["Interrogator Vishas"] = "Befrager Vishas", |
Ionar = "Ionar", |
Ironaya = "Ironaya", |
Ironspine = "Eisenrücken", |
Isalien = "Isalien", |
Jade = "Jade", |
["Jammal'an the Prophet"] = "Jammal'an der Prophet", |
["Jan'alai"] = "Jan'alai", |
["Jandice Barov"] = "Jandice Barov", |
["Jedoga Shadowseeker"] = "Jedoga Schattensucher", |
["Jed Runewatcher"] = "Jed Runenblick", |
["Jergosh the Invoker"] = "Jergosh der Herbeirufer", |
["Jin'do the Hexxer"] = "Jin'do der Verhexer", |
["Jormungar Behemoth"] = "Jormungarungetüm", |
Jormungars = "Jormungars", |
Julianne = "Julianne", |
["Junk Bot"] = "Schrottbot", |
["Kael'thas Sunstrider"] = "Kael'thas Sonnenwanderer", |
Kalecgos = "Kalecgos", |
["Kam Deepfury"] = "Kam Tiefenzorn", |
["Kazkaz the Unholy"] = "Kazkaz der Unheilige", |
["Kaz'rogal"] = "Kaz'rogal", |
["Keli'dan the Breaker"] = "Keli'dan der Zerstörer", |
["Kel'Thuzad"] = "Kel'Thuzad", |
Keristrasza = "Keristrasza", |
["Kiggler the Crazed"] = "Kiggler the Crazed", |
["Kil'jaeden"] = "Kil'jaeden", |
["Kil'rek"] = "Kil'rek", |
["King Dred"] = "König Dred", |
["King Gordok"] = "König Gordok", |
["King Llane Piece"] = "König Llane", |
["King Ymiron"] = "König Ymiron", |
["Kirtonos the Herald"] = "Kirtonos der Herold", |
["Knot Thimblejack's Cache"] = "Knot Thimblejacks Truhe", |
Kolk = "Kolk", |
Kologarn = "Kologarn", |
["Koralon the Flame Watcher"] = "Koralon der Flammenwächter", |
Kormok = "Kormok", |
Kresh = "Kresh", |
Krick = "Krick", |
["Krick and Ick"] = "Krick und Ick", |
["Krik'thir the Gatewatcher"] = "Krik'thir der Torwächter", |
["Krosh Firehand"] = "Krosh Feuerhand", |
Krystallus = "Krystallus", |
Kurinnaxx = "Kurinnaxx", |
["Lady Anacondra"] = "Lady Anacondra", |
["Lady Blaumeux"] = "Lady Blaumeux", |
["Lady Deathwhisper"] = "Lady Todeswisper", |
["Lady Illucia Barov"] = "Lady Illucia Barov", |
["Lady Malande"] = "Lady Malande", |
["Lady Sacrolash"] = "Lady Sacrolash", |
["Lady Sarevess"] = "Lady Sarevess", |
["Lady Vashj"] = "Lady Vashj", |
Laj = "Laj", |
Landslide = "Erdrutsch", |
Lavanthor = "Lavanthor", |
["Left Arm"] = "Linker Arm", |
["Leotheras the Blind"] = "Leotheras der Blinde", |
Lethon = "Lethon", |
Lethtendris = "Lethtendris", |
["Leviathan Mk II"] = "Leviathan Mk II", |
["Ley-Guardian Eregos"] = "Leywächter Eregos", |
["Lieutenant Drake"] = "Leutnant Drach", |
["Lieutenant General Andorov"] = "Generallieutenant Andorov", |
Loatheb = "Loatheb", |
Loken = "Loken", |
["Lord Alexei Barov"] = "Lord Alexei Barov", |
["Lord Cobrahn"] = "Lord Kobrahn", |
["Lord Hel'nurath"] = "Lord Hel'nurath", |
["Lord Incendius"] = "Lord Incendius", |
["Lord Jaraxxus"] = "Lord Jaraxxus", |
["Lord Kazzak"] = "Lord Kazzak", |
["Lord Kri"] = "Lord Kri", |
["Lord Marrowgar"] = "Lord Mark'gar", |
["Lord Pythas"] = "Lord Pythas", |
["Lord Roccor"] = "Lord Roccor", |
["Lord Sanguinar"] = "Fürst Blutdurst", |
["Lord Serpentis"] = "Lord Serpentis", |
["Lord Skwol"] = "Lord Skwol", |
["Lord Valthalak"] = "Lord Valthalak", |
["Lord Victor Nefarius"] = "Lord Victor Nefarius", |
["Lord Vyletongue"] = "Lord Schlangenzunge", |
["Lorekeeper Polkelt"] = "Hüter des Wissens Polkelt", |
Loro = "Loro", |
Lucifron = "Lucifron", |
["Mad Magglish"] = "Zausel der Verrückte", |
Maexxna = "Maexxna", |
["Mage-Lord Urom"] = "Magierlord Urom", |
["Magister Kalendris"] = "Magister Kalendris", |
["Magistrate Barthilas"] = "Magistrat Barthilas", |
Magmadar = "Magmadar", |
Magmus = "Magmus", |
Magra = "Magra", |
Magtheridon = "Magtheridon", |
["Maiden of Grief"] = "Maid der Trauer", |
["Maiden of Virtue"] = "Tugendhafte Maid", |
["Majordomo Executus"] = "Majordomus Exekutus", |
Malacrass = "Malacrass", |
["Maleki the Pallid"] = "Maleki der Leichenblasse", |
["Mal'Ganis"] = "Mal'Ganis", |
Malygos = "Malygos", |
Maraudos = "Maraudos", |
["Marduk Blackpool"] = "Marduk Blackpool", |
["Marisa du'Paige"] = "Marisa du'Paige", |
Marwyn = "Marwyn", |
["Master Engineer Telonicus"] = "Meisteringenieur Telonicus", |
["Maur Grimtotem"] = "Maur Grimmtotem", |
Meathook = "Fleischhaken", |
["Mechano-Lord Capacitus"] = "Mechanolord Kapazitus", |
Medivh = "Medivh", |
["Mekgineer Steamrigger"] = "Robogenieur Dampfhammer", |
["Mekgineer Thermaplugg"] = "Robogenieur Thermadraht", |
["Mennu the Betrayer"] = "Mennu der Verräter", |
["Meshlok the Harvester"] = "Meshlok der Ernter", |
Midnight = "Mittnacht", |
Mijan = "Mijan", |
Mimiron = "Mimiron", |
["Miner Johnson"] = "Minenarbeiter Johnson", |
["Mistress of Pain"] = "Herrin der Schmerzen", |
Moam = "Moam", |
Mogor = "Mogor", |
["Mokra the Skullcrusher"] = "Mokra der Schädelberster", |
Moorabi = "Moorabi", |
Moragg = "Moragg", |
["Mordresh Fire Eye"] = "Mordresh Feuerauge", |
["Mor Grayhoof"] = "Mor Grauhuf", |
Moroes = "Moroes", |
["Morogrim Tidewalker"] = "Morogrim Gezeitenwandler", |
Morphaz = "Morphaz", |
["Mother Shahraz"] = "Mutter Shahraz", |
["Mother Smolderweb"] = "Mutter Glimmernetz", |
["Mr. Smite"] = "Handlanger Pein", |
["Muradin Bronzebeard"] = "Muradin Bronzebart", |
["Murkblood Twin"] = "Zwilling der Finsterblut", |
["Murkblood Twins"] = "Zwillinge der Finsterblut", |
Murmur = "Murmur", |
["Murta Grimgut"] = "Murta Bauchgrimm", |
["M'uru"] = "M'uru", |
Mushgog = "Mushgog", |
["Mutanus the Devourer"] = "Mutanus der Verschlinger", |
Nalorakk = "Nalorakk", |
Nazan = "Nazan", |
Nefarian = "Nefarian", |
["Nekrum Gutchewer"] = "Nekrum der Ausweider", |
["Nerub'enkan"] = "Nerub'enkan", |
["Nethermancer Sepethrea"] = "Nethermant Sepethrea", |
Netherspite = "Nethergroll", |
["Netherstrand Longbow"] = "Netherbespannter Langbogen", |
["Nexus-Prince Shaffar"] = "Nexusprinz Shaffar", |
Nightbane = "Schrecken der Nacht", |
["Noth the Plaguebringer"] = "Noth der Seuchenfürst", |
["Novos the Summoner"] = "Novos der Beschwörer", |
Noxxion = "Noxxion", |
["Obsidian Sentinel"] = "Obsidianschildwache", |
["Odo the Blindwatcher"] = "Odo der Blindseher", |
["Ogom the Wretched"] = "Ogom der Elende", |
["Ok'thor the Breaker"] = "Ok'thor der Zerstörer", |
["Old Serra'kis"] = "Old Serra'kis", |
["Olm the Summoner"] = "Olm der Beschwörer", |
["Omor the Unscarred"] = "Omor der Narbenlose", |
Onyxia = "Onyxia", |
["Orgrim's Hammer"] = "Orgrims Hammer", |
["Ormorok the Tree-Shaper"] = "Ormorok der Baumformer", |
["Oro Eyegouge"] = "Oro Hohlauge", |
["Ossirian the Unscarred"] = "Ossirian der Narbenlose", |
Ouro = "Ouro", |
["Overlord Ramtusk"] = "Oberanführer Rammhauer", |
["Overlord Wyrmthalak"] = "Oberanführer Wyrmthalak", |
["Overmaster Pyron"] = "Ãbermeister Pyron", |
["Overseer Tidewrath"] = "Overseer Tidewrath", |
Pandemonius = "Pandemonius", |
["Panzor the Invincible"] = "Panzor der Unbesiegbare", |
Patchwerk = "Flickwerk", |
["Pathaleon the Calculator"] = "Pathaleon der Kalkulator", |
Phalanx = "Phalanx", |
["Phaseshift Bulwark"] = "Phasenverschobenes Bollwerk", |
Pimgib = "Pimgib", |
["Plaguemaw the Rotting"] = "Seuchenschlund der Faulende", |
["Plugger Spazzring"] = "Stöpsel Zapfring", |
["Postmaster Malown"] = "Postmeister Malown", |
["Priestess Delrissa"] = "Priesterin Delrissa", |
["Prince Keleseth"] = "Prinz Keleseth", |
["Prince Malchezaar"] = "Prinz Malchezaar", |
["Prince Skaldrenox"] = "Prince Skaldrenox", |
["Princess Huhuran"] = "Prinzessin Huhuran", |
["Princess Moira Bronzebeard"] = "Prinzessin Moira Bronzebeard", |
["Princess Tempestria"] = "Prinzessin Tempestria", |
["Princess Theradras"] = "Prinzessin Theradras", |
["Princess Yauj"] = "Prinzessin Yauj", |
["Prince Taldaram"] = "Prinz Taldaram", |
["Prince Tenris Mirkblood"] = "Prinz Tenris Mirkblut", |
["Prince Tortheldrin"] = "Prinz Tortheldrin", |
["Prince Valanar"] = "Prinz Valanar", |
["Professor Putricide"] = "Professor Seuchenmord", |
["Pure Spawn of Hydross"] = "Gereinigter Nachkomme Hydross'", |
Pusillin = "Pusillin", |
["Pyroguard Emberseer"] = "Feuerwache Glutseher", |
["Pyromancer Loregrain"] = "Pyromant Weisenkorn", |
Quagmirran = "Quagmirran", |
["Quartermaster Zigris"] = "Rüstmeister Zigris", |
["Rage Winterchill"] = "Furor Winterfrost", |
Ragglesnout = "Struppmähne", |
["Raging Spirit"] = "Tobender Geist", |
Ragnaros = "Ragnaros", |
["Ramstein the Gorger"] = "Ramstein der Verschlinger", |
["Ras Frostwhisper"] = "Ras Frostraunen", |
Rattlegore = "Blutrippe", |
["Razorclaw the Butcher"] = "Klingenklaue der Metzger", |
["Razorgore the Untamed"] = "Razorgore der Ungezähmte", |
Razorlash = "Schlingwurzler", |
Razorscale = "Klingenschuppe", |
["Reliquary of Souls"] = "Reliquium der Seelen", |
Renataki = "Renataki", |
["Restless Skeleton"] = "Ruheloses Skelett", |
Rethilgore = "Rotkralle", |
Revelosh = "Revelosh", |
["Rhahk'Zor"] = "Rhahk'Zor", |
["Ribbly Screwspigot"] = "Ribbly Schraubstutz", |
["Right Arm"] = "Rechter Arm", |
Roar = "Brüller", |
["Rokad the Ravager"] = "Rokad der Verheerer", |
["Rokdar the Sundered Lord"] = "Rokdar der Zerklüftete", |
["Rokmar the Crackler"] = "Rokmar der Zerquetscher", |
Romulo = "Romulo", |
["Romulo & Julianne"] = "Romulo & Julianne", |
Rotface = "Modermiene", |
Rotgrip = "Faulschnapper", |
["Runemaster Molgeim"] = "Runenmeister Molgeim", |
["Runok Wildmane"] = "Runok Wildmähne", |
Ruuzlu = "Ruuzlu", |
["Salramm the Fleshcrafter"] = "Salramm der Fleischformer", |
["Sanctum Sentry"] = "Späher des Sanktums", |
["Sandarr Dunereaver"] = "Sandarr der Wüstenräuber", |
["Sandfury Executioner"] = "Henker der Sandwüter", |
Sapphiron = "Saphiron", |
Sara = "Sara", |
["Saronite Animus"] = "Saronitanimus", |
Sartharion = "Sartharion", |
["Sathrovarr the Corruptor"] = "Sathrovarr der Verderber", |
["Saviana Ragefire"] = "Saviana Flammenschlund", |
["Scarlet Commander Mograine"] = "Scharlachroter Kommandant Mograine", |
["Scourgelord Tyrannus"] = "GeiÃelfürst Tyrannus", |
["Seeth'rel"] = "Wut'rel", |
["Selin Fireheart"] = "Selin Feuerherz", |
["Sergeant Bly"] = "Unteroffizier Bly", |
["Shade of Akama"] = "Akamas Schemen", |
["Shade of Aran"] = "Arans Schemen", |
["Shade of Eranikus"] = "Eranikus' Schemen", |
["Shadikith the Glider"] = "Shadikith der Segler", |
["Shadow Hunter Vosh'gajin"] = "Schattenjägerin Vosh'gajin", |
["Shadow of Leotheras"] = "Schatten von Leotheras", |
["Shadowpriest Sezz'ziz"] = "Schattenpriester Sezz'ziz", |
Shadron = "Shadron", |
Shazzrah = "Shazzrah", |
["Shirrak the Dead Watcher"] = "Shirrak der Totenwächter", |
Sindragosa = "Sindragosa", |
["Sir Zeliek"] = "Sir Zeliek", |
["Sjonnir The Ironshaper"] = "Sjonnir der Eisenformer", |
["Skadi the Ruthless"] = "Skadi der Skrupellose", |
["Skarr the Unbreakable"] = "Skarr der Unbezwingbare", |
["Skarvald the Constructor"] = "Skarvald der Konstrukteur", |
["Skra'gath"] = "Skra'gath", |
Skul = "Skul", |
Skum = "Skum", |
["Slad'ran"] = "Slad'ran", |
Sneed = "Sneed", |
["Sneed's Shredder"] = "Sneeds Schredder", |
["Solakar Flamewreath"] = "Solakar Feuerkrone", |
["Solarium Agent"] = "Solarian Agent", |
["Solarium Priest"] = "Solarian Priester", |
["Spirestone Battle Lord"] = "Kampflord der Felsspitzoger", |
["Spirestone Butcher"] = "Metzger der Felsspitzoger", |
["Spirestone Lord Magus"] = "Maguslord der Felsspitzoger", |
["Staff of Disintegration"] = "Stab der Auflösung", |
Stalagg = "Stalagg", |
Steelbreaker = "Stahlbrecher", |
["Stomper Kreeg"] = "Stampfer Kreeg", |
Stonespine = "Steinbuckel", |
["Stormcaller Brundir"] = "Sturmrufer Brundir", |
Strawman = "Strohmann", |
["Sulfuron Harbinger"] = "Sulfuronherold", |
Supremus = "Supremus", |
["Svala Sorrowgrave"] = "Svala Grabesleid", |
["Swamplord Musel'ek"] = "Sumpffürst Musel'ek", |
Taerar = "Taerar", |
["Tainted Spawn of Hydross"] = "Besudelter Nachkomme Hydross'", |
["Talon King Ikiss"] = "Klauenkönig Ikiss", |
["Taragaman the Hungerer"] = "Taragaman der Hungerleider", |
["Targorr the Dread"] = "Targorr der Schreckliche", |
Tavarok = "Tavarok", |
Techbot = "Techbot", |
Temporus = "Temporus", |
["Tendris Warpwood"] = "Tendris Wucherborke", |
Tenebron = "Tenebron", |
["Terestian Illhoof"] = "Terestian Siechhuf", |
["Teron Gorefiend"] = "Teron Blutschatten", |
Thaddius = "Thaddius", |
["Thaladred the Darkener"] = "Thaladred der Verfinsterer", |
["Thane Korth'azz"] = "Than Korth'azz", |
["The Beast"] = "Die Bestie", |
["The Beasts of Northrend"] = "Bestien von Nordend", |
["The Big Bad Wolf"] = "Der groÃe böse Wolf", |
["The Black Knight"] = "Der Schwarze Ritter", |
["The Black Stalker"] = "Die Schattenmutter", |
["The Blue Brothers"] = "Die Blaumänner", |
["The Bug Family"] = "Die Käferfamilie", |
["The Crone"] = "Die böse Hexe", |
["The Curator"] = "Der Kurator", |
["The Eredar Twins"] = "Die Eredar Zwillinge", |
["The Four Horsemen"] = "Die Vier Reiter", |
["The Illidari Council"] = "Rat der Illidari", |
["The Iron Council"] = "Rat der Eisernen", |
["Theka the Martyr"] = "Theka der Märtyrer", |
["The Lich King"] = "Der Lichkönig", |
["The Lurker Below"] = "Das Grauen aus der Tiefe", |
["The Maker"] = "Der Schöpfer", |
["The Prophet Skeram"] = "Der Prophet Skeram", |
["The Prophet Tharon'ja"] = "Der Prophet Tharon'ja", |
["The Ravenian"] = "Der Ravenier", |
["The Razza"] = "Der Razza", |
["The Seven Dwarves"] = "Die Sieben Zwerge", |
["The Skybreaker"] = "Die Himmelsbrecher", |
["The Tribunal of Ages"] = "Das Tribunal der Zeitalter", |
["The Twin Emperors"] = "Die Zwillings-Imperatoren", |
["The Twin Val'kyr"] = "Zwillingsval'kyr", |
["The Unforgiven"] = "Der Unverziehene", |
["The Windreaver"] = "Der Windhäscher", |
Thorim = "Thorim", |
["Thorngrin the Tender"] = "Dorngrin der Hüter", |
["Tidewalker Lurker"] = "Lauerer der Gezeitenwandler", |
["Timmy the Cruel"] = "Timmy der Grausame", |
Tinhead = "Blechkopf", |
["Tinkerer Gizlock"] = "Tüftler Gizlock", |
["Tirion Fordring"] = "Tirion Fordring", |
Tito = "Tito", |
["Toravon the Ice Watcher"] = "Toravon der Eiswächter", |
["Trigore the Lasher"] = "Trigore der Peitscher", |
Trollgore = "Trollgrind", |
["Tsu'zee"] = "Tsu'zee", |
["Tuten'kash"] = "Tuten'kash", |
["Twilight Lord Kelris"] = "Lord des Schattenhammers Kelris", |
["Urok Doomhowl"] = "Urok Schreckensbote", |
["Vaelastrasz the Corrupt"] = "Vaelastrasz der Verdorbene", |
["Valithria Dreamwalker"] = "Valithria Traumwandler", |
["Val'kyr Shadowguard"] = "Schattenwächterin der Val'kyr", |
["Varian Wrynn"] = "Varian Wrynn", |
["Varos Cloudstrider"] = "Varos Wolkenschreiter", |
Vazruden = "Vazruden", |
["Vazruden the Herald"] = "Vazruden der Herold", |
Vectus = "Vectus", |
Vem = "Vem", |
Veng = "Veng", |
["Veras Darkshadow"] = "Veras Schwarzschatten", |
["Verdan the Everliving"] = "Verdan der Ewiglebende", |
Verek = "Verek", |
Vesperon = "Vesperon", |
Vexallus = "Vexallus", |
["Veyzhak the Cannibal"] = "Veyzhack der Kannibale", |
["Vile'rel"] = "Bös'rel", |
Viscidus = "Viscidus", |
["Viscous Fallout"] = "Verflüssigte Ablagerung", |
["Void Reaver"] = "Leerhäscher", |
Volkhan = "Volkhan", |
["VX-001"] = "VX-001", |
["Warbringer O'mrogg"] = "Kriegshetzer O'mrogg", |
["Warchief Blackhand Piece"] = "Kriegshäuptling Schwarzfaust", |
["Warchief Kargath Bladefist"] = "Kriegshäuptling Kargath Messerfaust", |
["Warchief Rend Blackhand"] = "Kriegshäuptling Rend Schwarzfaust", |
["Warden Mellichar"] = "Aufseher Mellichar", |
["Warder Stilgiss"] = "Wärter Stilgiss", |
["Warlord Kalithresh"] = "Kriegsherr Kalithresh", |
["War Master Voone"] = "Kriegsmeister Voone", |
["Warmaul Champion"] = "Champion der Totschläger", |
["Warp Slicer"] = "Warpschnitter", |
["Warp Splinter"] = "Warpzweig", |
["Watchkeeper Gargolmar"] = "Wachhabender Gargolmar", |
Weaver = "Wirker", |
["Witch Doctor Zum'rah"] = "Hexendoktor Zum'rah", |
["Wolf Master Nandos"] = "Wolfmeister Nados", |
["Wrath-Scryer Soccothrates"] = "Zornseher Soccothrates", |
Wushoolay = "Wushoolay", |
Xevozz = "Xevozz", |
["XT-002 Deconstructor"] = "XT-002 Dekonstruktor", |
["Yogg-Saron"] = "Yogg-Saron", |
Ysondre = "Ysondre", |
Zekkis = "Zekkis", |
["Zelemar the Wrathful"] = "Zelemar der Hasserfüllte", |
["Zereketh the Unbound"] = "Zereketh der Unabhängige", |
Zerillis = "Zerillis", |
["Zevrim Thornhoof"] = "Zevrim Dornhuf", |
Zolo = "Zolo", |
["Zul'Farrak Dead Hero"] = "Untoter Held aus Zul'Farrak", |
["Zul'jin"] = "Zul'jin", |
["Zul'Lor"] = "Zul'Lor", |
["Zul'tore"] = "Zul'tore", |
["Zuramat the Obliterator"] = "Zuramat der Auslöscher", |
} |
elseif GAME_LOCALE == "frFR" then |
lib:SetCurrentTranslations { |
Acidmaw = "Gueule-d'acide", |
Aeonus = "Aeonus", |
["Aerial Command Unit"] = "Unité de commandement aérien", |
["Agathelos the Raging"] = "Agathelos le Déchaîné", |
Ahune = "Ahune", |
["Akil'zon"] = "Akil'zon", |
["Aku'mai"] = "Aku'mai", |
["Al'ar"] = "Al'ar", |
["Algalon the Observer"] = "Algalon l'Observateur", |
["Alzzin the Wildshaper"] = "Alzzin le Modeleur", |
Amanitar = "Amanitar", |
["Ambassador Flamelash"] = "Ambassadeur Cinglefouet", |
["Ambassador Hellmaw"] = "Ambassadeur Gueule-d'enfer", |
["Amnennar the Coldbringer"] = "Amnennar le Porte-froid", |
["Ancient Stone Keeper"] = "Ancien Gardien des pierres", |
Anetheron = "Anetheron", |
["Anger'rel"] = "Colé'rel", |
Anomalus = "Anomalus", |
["Antu'sul"] = "Antu'sul", |
["Anub'arak"] = "Anub'arak", |
["Anubisath Defender"] = "Défenseur Anubisath", |
["Anubisath Guardian"] = "Gardien Anubisath", |
["Anub'Rekhan"] = "Anub'Rekhan", |
["Anub'shiah"] = "Anub'shiah", |
Anzu = "Anzu", |
["Arcane Watchman"] = "Veilleur arcanique", |
["Arcanist Doan"] = "Arcaniste Doan", |
Archaedas = "Archaedas", |
["Archavon the Stone Watcher"] = "Archavon le Gardien des pierres", |
Archimonde = "Archimonde", |
["Archivist Galford"] = "Archiviste Galford", |
["Archmage Arugal"] = "Archimage Arugal", |
["Argent Confessor Paletress"] = "Confesseur d'argent Paletress", |
["Arugal's Voidwalker"] = "Marcheur du Vide d'Arugal", |
["Assault Bot"] = "Robot d'assaut", |
["Atal'alarion"] = "Atal'alarion", |
["Attumen the Huntsman"] = "Attumen le Veneur", |
Auriaya = "Auriaya", |
Avalanchion = "Avalanchion", |
["Avatar of Hakkar"] = "Avatar d'Hakkar", |
["Ayamiss the Hunter"] = "Ayamiss le Chasseur", |
Azgalor = "Azgalor", |
["Azshir the Sleepless"] = "Azshir le Sans-sommeil", |
Azuregos = "Azuregos", |
["Bael'Gar"] = "Bael'Gar", |
Baelog = "Baelog", |
Balnazzar = "Balnazzar", |
["Baltharus the Warborn"] = "Baltharus l'Enfant de la guerre", |
["Bannok Grimaxe"] = "Bannok Hache-sinistre", |
["Baron Aquanis"] = "Baron Aquanis", |
["Baron Charr"] = "Baron Charr", |
["Baroness Anastari"] = "Baronne Anastari", |
["Baron Geddon"] = "Baron Geddon", |
["Baron Kazum"] = "Baron Kazum", |
["Baron Rivendare"] = "Baron Vaillefendre", |
["Baron Silverlaine"] = "Baron d'Argelaine", |
["Battleguard Sartura"] = "Garde de guerre Sartura", |
["Bazil Thredd"] = "Bazil Thredd", |
Bazzalan = "Bazzalan", |
["Black Guard Swordsmith"] = "Fabricant d'épées de la Garde noire", |
["Blackheart the Inciter"] = "Coeur-noir le Séditieux", |
["Blindeye the Seer"] = "Oeillaveugle le Voyant", |
["Blind Hunter"] = "Chasseur aveugle", |
["Blood Guard Porung"] = "Garde de sang Porung", |
["Bloodlord Mandokir"] = "Seigneur sanglant Mandokir", |
["Bloodmage Thalnos"] = "Mage de sang Thalnos", |
["Blood Prince Council"] = "Conseil des princes de sang", |
["Blood Princes"] = "Princes de sang", |
["Blood-Queen Lana'thel"] = "Reine de sang Lana'thel", |
["Blood Steward of Kirtonos"] = "Régisseuse sanglante de Kirtonos", |
Boahn = "Boahn", |
["Bomb Bot"] = "Robo-bombe", |
["Brain of Yogg-Saron"] = "Cerveau de Yogg-Saron", |
["Brainwashed Noble"] = "Noble manipulé", |
Broggok = "Broggok", |
Brokentoe = "Brisorteil", |
Bronjahm = "Bronjahm", |
["Broodlord Lashlayer"] = "Seigneur des couvées Lanistaire", |
["Bruegal Ironknuckle"] = "Bruegal Poing-de-fer", |
Brutallus = "Brutallus", |
["Burning Felguard"] = "Gangregarde ardent", |
["Buru the Gorger"] = "Buru Grandgosier", |
["Cache of the Firelord"] = "Cachette du Seigneur du feu", |
["Cannon Master Willey"] = "Maître canonnier Willey", |
["Captain Greenskin"] = "Capitaine Vertepeau", |
["Captain Kromcrush"] = "Capitaine Kromcrush", |
["Captain Skarloc"] = "Capitaine Skarloc", |
["Celebras the Cursed"] = "Celebras le Maudit", |
["Charlga Razorflank"] = "Charlga Trancheflanc", |
["Chess Event"] = "Partie d'échec", |
["Chest of The Seven"] = "Coffre des sept", |
["Chief Ukorz Sandscalp"] = "Chef Ukorz Scalpessable", |
["Cho'Rush the Observer"] = "Cho'Rush l'Observateur", |
Chromaggus = "Chromaggus", |
["Chrono Lord Deja"] = "Chronoseigneur Déjà ", |
["Chrono-Lord Epoch"] = "Chronoseigneur Epoch", |
Claw = "Griffe", |
["Coilfang Elite"] = "Elite de Glissecroc", |
["Coilfang Strider"] = "Trotteur de Glissecroc", |
["Commander Kolurg"] = "Commandant Kolurg", |
["Commander Sarannis"] = "Commandant Sarannis", |
["Commander Springvale"] = "Commandant Springvale", |
["Commander Stoutbeard"] = "Commandant Rudebarbe", |
["Constructor & Controller"] = "Constructeur & Contrôleur", |
Cookie = "Macaron", |
["Coren Direbrew"] = "Coren Navrebière", |
["Cosmic Infuser"] = "Masse d'infusion cosmique", |
["Crimson Hammersmith"] = "Forgeur de marteaux cramoisi", |
["Crowd Pummeler 9-60"] = "Faucheur de foule 9-60", |
["Crystal Fang"] = "Croc cristallin", |
["C'Thun"] = "C'Thun", |
Cyanigosa = "Cyanigosa", |
["Dalliah the Doomsayer"] = "Dalliah l'Auspice-funeste", |
["Dalronn the Controller"] = "Dalronn le Contrôleur", |
["Dark Iron Ambassador"] = "Ambassadeur Sombrefer", |
["Darkmaster Gandling"] = "Sombre Maître Gandling", |
["Darkweaver Syth"] = "Tisseur d'ombre Syth", |
["Deathbound Ward"] = "Gardien lié par la mort", |
["Deathbringer Saurfang"] = "Porte-mort Saurcroc", |
["Death Knight Darkreaver"] = "Chevalier de la mort Ravassombre", |
["Death Knight Understudy"] = "Doublure de chevalier de la mort", |
["Deathspeaker High Priest"] = "Grand prêtre nécrorateur", |
["Death Speaker Jargba"] = "Nécrorateur Jargba", |
["Deathstalker Visceri"] = "Nécrotraqueur Viscéri", |
["Deathsworn Captain"] = "Capitaine Ligemort", |
Devastation = "Dévastation", |
["Deviate Faerie Dragon"] = "Dragon féérique déviant", |
["Devourer of Souls"] = "Dévoreur dââmes", |
["Dextren Ward"] = "Dextren Ward", |
["Digmaster Shovelphlange"] = "Maître des fouilles Pellaphlange", |
["Doctor Theolen Krastinov"] = "Docteur Theolen Krastinov", |
["Doom Lord Kazzak"] = "Seigneur funeste Kazzak", |
["Doom'rel"] = "Tragi'rel", |
Doomwalker = "Marche-funeste", |
["Dope'rel"] = "Demeu'rel", |
Dorothee = "Dorothée", |
["Drakkari Colossus"] = "Colosse drakkari", |
["Drakos the Interrogator"] = "Drakos l'Interrogateur", |
Dreadscale = "Ãcaille-d'effroi", |
Dreamscythe = "Fauche-rêve", |
["Dust Covered Chest"] = "Coffre couvert de poussière", |
Dustwraith = "Ame en peine poudreuse", |
["Eadric the Pure"] = "Eadric le Pur", |
["Earthcaller Halmgar"] = "Implorateur de la terre Halmgar", |
Ebonroc = "Rochébène", |
["Eck the Ferocious"] = "Eck le Féroce", |
["Edwin VanCleef"] = "Edwin VanCleef", |
["Elder Brightleaf"] = "Ancien Brillefeuille", |
["Elder Ironbranch"] = "Ancien Branchefer", |
["Elder Nadox"] = "Ancien Nadox", |
["Elder Stonebark"] = "Ancien Ecorcepierre", |
["Electrocutioner 6000"] = "Electrocuteur 6000", |
["Emalon the Storm Watcher"] = "Emalon le Guetteur d'orage", |
Emeriss = "Emeriss", |
["Emperor Dagran Thaurissan"] = "Empereur Dagran Thaurissan", |
["Emperor Vek'lor"] = "Empereur Vek'lor", |
["Emperor Vek'nilash"] = "Empereur Vek'nilash", |
Entropius = "Entropius", |
["Eonar's Gift"] = "Cadeau d'Eonar", |
["Epoch Hunter"] = "Chasseur d'époques", |
Erekem = "Erekem", |
["Eressea Dawnsinger"] = "Eressa Chantelaube", |
["Essence of Anger"] = "Essence de la colère", |
["Essence of Desire"] = "Essence du désir", |
["Essence of Suffering"] = "Essence de la souffrance", |
Eviscerator = "Eviscérateur", |
["Exarch Maladaar"] = "Exarque Maladaar", |
["Expedition Commander"] = "Commandant de l'expédition", |
["Eydis Darkbane"] = "Eydis Plaie-sombre", |
["Eye of C'Thun"] = "Åil de C'Thun", |
["Faction Champions"] = "Champions de faction", |
["Fallen Champion"] = "Champion mort", |
Falric = "Falric", |
["Falric and Marwyn"] = "Falric et Marwyn", |
["Fankriss the Unyielding"] = "Fankriss l'Inflexible", |
["Fathom-Lord Karathress"] = "Seigneur des fonds Karathress", |
Felmyst = "Gangrebrume", |
["Fenrus the Devourer"] = "Fenrus le Dévoreur", |
["Feral Defender"] = "Défenseur farouche", |
Festergut = "Pulentraille", |
Feugen = "Feugen", |
["Fineous Darkvire"] = "Fineous Sombrevire", |
Firemaw = "Gueule-de-feu", |
["Fjola Lightbane"] = "Fjola Plaie-lumineuse", |
Flamegor = "Flamegor", |
["Flame Leviathan"] = "Léviathan des flammes", |
["Foreman Thistlenettle"] = "Contremaître Crispechardon", |
["Forgemaster Garfrost"] = "Maître-forge Gargivre", |
["Four Horsemen Chest"] = "Coffre des quatre cavaliers", |
["Fras Siabi"] = "Fras Siabi", |
Freya = "Freya", |
["Gahz'ranka"] = "Gahz'ranka", |
["Gahz'rilla"] = "Gahz'rilla", |
["Gal'darah"] = "Gal'darah", |
["Galgann Firehammer"] = "Galgann Martel-de-feu", |
Garr = "Garr", |
["Garrosh Hellscream"] = "Garrosh Hurlenfer", |
Gasher = "Gasher", |
["Gatewatcher Gyro-Kill"] = "Gardien de porte Gyro-Meurtre", |
["Gatewatcher Iron-Hand"] = "Gardien de porte Main-en-fer", |
["Gathios the Shatterer"] = "Gathios le Briseur", |
Gehennas = "Gehennas", |
Gelihast = "Gelihast", |
Gelk = "Gelk", |
["General Angerforge"] = "Général Forgehargne", |
["General Bjarngrim"] = "Général Bjarngrim", |
["General Drakkisath"] = "Général Drakkisath", |
["General Rajaxx"] = "Général Rajaxx", |
["General Vezax"] = "Général Vezax", |
["General Zarithrian"] = "Général Zarithrian", |
["Ghamoo-ra"] = "Ghamoo-ra", |
["Ghaz'an"] = "Ghaz'an", |
["Ghok Bashguud"] = "Ghok Bounnebaffe", |
Gilnid = "Gilnid", |
["Gizrul the Slavener"] = "Gizrul l'esclavagiste", |
["Gloom'rel"] = "Funéb'rel", |
Gluth = "Gluth", |
Glutton = "Glouton", |
["Golemagg the Incinerator"] = "Golemagg l'Incinérateur", |
["Golem Lord Argelmach"] = "Seigneur golem Argelmach", |
["Goraluk Anvilcrack"] = "Goraluk Brisenclume", |
["Gormok the Impaler"] = "Gormok l'Empaleur", |
["Gorosh the Dervish"] = "Gorosh le Derviche", |
["Gortok Palehoof"] = "Gortok Pâle-sabot", |
["Gothik the Harvester"] = "Gothik le Moissonneur", |
["Grand Astromancer Capernian"] = "Grande astromancienne Capernian", |
["Grand Champions"] = "Grand champions", |
["Grand Magus Telestra"] = "Grand magus Telestra", |
["Grandmaster Vorpil"] = "Grand Maître Vorpil", |
Grandmother = "Mère-grand", |
["Grand Warlock Alythess"] = "Grande démoniste Alythess", |
["Grand Warlock Nethekurse"] = "Grand démoniste Néanathème", |
["Grand Widow Faerlina"] = "Grande veuve Faerlina", |
["Grethok the Controller"] = "Grethok le Contrôleur", |
["Gri'lek"] = "Gri'lek", |
Grimlok = "Grimlok", |
Grizzle = "Grison", |
Grobbulus = "Grobbulus", |
Grubbis = "Grubbis", |
["Gruul the Dragonkiller"] = "Gruul le Tue-dragon", |
["Guard Fengus"] = "Garde Fengus", |
["Guardian of Yogg-Saron"] = "Gardien de Yogg-Saron", |
["Guard Mol'dar"] = "Garde Mol'dar", |
["Guard Slip'kik"] = "Garde Slip'kik", |
["Gurtogg Bloodboil"] = "Gurtogg Fièvresang", |
Gyth = "Gyth", |
Hadronox = "Hadronox", |
Hakkar = "Hakkar", |
Halazzi = "Halazzi", |
Halion = "Halion", |
Halycon = "Halycon", |
Hamhock = "Hamhock", |
["Harbinger Skyriss"] = "Messager Cieuriss", |
["Hate'rel"] = "Haine'rel", |
["Hazza'rah"] = "Hazza'rah", |
Hazzas = "Hazzas", |
["Headless Horseman"] = "Cavalier sans tête", |
["Hearthsinger Forresten"] = "Chanteloge Forrestin", |
["Hedrum the Creeper"] = "Hedrum le Rampant", |
["Heigan the Unclean"] = "Heigan l'Impur", |
["Hellfire Channeler"] = "Canaliste des Flammes infernales", |
["Henry Stern"] = "Henry Stern", |
["Herald Volazj"] = "Héraut Volazj", |
Herod = "Hérode", |
["Hex Lord Malacrass"] = "Seigneur des maléfices Malacrass", |
["High Astromancer Solarian"] = "Grande astromancienne Solarian", |
["High Botanist Freywinn"] = "Grand botaniste Freywinn", |
["High Inquisitor Fairbanks"] = "Grand Inquisiteur Fairbanks", |
["High Inquisitor Whitemane"] = "Grand Inquisiteur Blanchetête", |
["High Interrogator Gerstahn"] = "Grand Interrogateur Gerstahn", |
["High King Maulgar"] = "Haut Roi Maulgar", |
["Highlord Mograine"] = "Généralissime Mograine", |
["Highlord Omokk"] = "Généralissime Omokk", |
["High Marshal Whirlaxis"] = "Haut maréchal Trombe", |
["High Nethermancer Zerevor"] = "Grand néantomancien Zerevor", |
["High Overlord Saurfang"] = "Haut seigneur Saurcroc", |
["High Priestess Arlokk"] = "Grande prêtresse Arlokk", |
["High Priestess Jeklik"] = "Grande prêtresse Jeklik", |
["High Priestess Mar'li"] = "Grande prêtresse Mar'li", |
["High Priestess of Thaurissan"] = "Grande prêtresse de Thaurissan", |
["High Priest Thekal"] = "Grand prêtre Thekal", |
["High Priest Venoxis"] = "Grand prêtre Venoxis", |
["High Warlord Naj'entus"] = "Grand seigneur de guerre Naj'entus", |
Hodir = "Hodir", |
["Houndmaster Grebmar"] = "Maître-chien Grebmar", |
["Houndmaster Loksey"] = "Maître-chien Loksey", |
Hukku = "Hukku", |
Hungarfen = "Hungarfen", |
["Hurley Blackbreath"] = "Hurley Soufflenoir", |
["Hyakiss the Lurker"] = "Hyakiss le rôdeur", |
["Hydromancer Thespia"] = "Hydromancienne Thespia", |
["Hydromancer Velratha"] = "Hydromancienne Velratha", |
Hydrospawn = "Hydrogénos", |
["Hydross the Unstable"] = "Hydross l'Instable", |
["Icecrown Gunship Battle"] = "Bataille des canonnières", |
Icehowl = "Glace-hurlante", |
["Ice Sphere"] = "Sphère de glace", |
Ichoron = "Ichoron", |
Ick = "Ick", |
["Ignis the Furnace Master"] = "Ignis le maître de la Fournaise", |
["Illidan Stormrage"] = "Illidan Hurlorage", |
["Illidari Council"] = "Conseil illidari", |
["Illyanna Ravenoak"] = "Illyanna Corvichêne", |
["Immol'thar"] = "Immol'thar", |
["Infinite Corruptor"] = "Corrupteur infini", |
["Infinity Blades"] = "Lames d'infinité", |
["Ingvar the Plunderer"] = "Ingvar le Pilleur", |
["Instructor Malicia"] = "Instructeur Malicia", |
["Instructor Razuvious"] = "Instructeur Razuvious", |
["Interrogator Vishas"] = "Interrogateur Vishas", |
Ionar = "Ionar", |
Ironaya = "Ironaya", |
Ironspine = "Echine-de-fer", |
Isalien = "Isalien", |
Jade = "Jade", |
["Jammal'an the Prophet"] = "Jammal'an le prophète", |
["Jan'alai"] = "Jan'alai", |
["Jandice Barov"] = "Jandice Barov", |
["Jedoga Shadowseeker"] = "Jedoga Cherchelombre", |
["Jed Runewatcher"] = "Jed Guette-runes", |
["Jergosh the Invoker"] = "Jergosh l'Invocateur", |
["Jin'do the Hexxer"] = "Jin'do le Maléficieur", |
["Jormungar Behemoth"] = "Béhémoth jormungar", |
Jormungars = "Jormungars", |
Julianne = "Julianne", |
["Junk Bot"] = "Robot camelote", |
["Kael'thas Sunstrider"] = "Kael'thas Haut-soleil", |
Kalecgos = "Kalecgos", |
["Kam Deepfury"] = "Kam Furie-du-fond", |
["Kazkaz the Unholy"] = "Kazkaz l'Impie", |
["Kaz'rogal"] = "Kaz'rogal", |
["Keli'dan the Breaker"] = "Keli'dan le Briseur", |
["Kel'Thuzad"] = "Kel'Thuzad", |
Keristrasza = "Keristrasza", |
["Kiggler the Crazed"] = "Kiggler le Cinglé", |
["Kil'jaeden"] = "Kil'jaeden", |
["Kil'rek"] = "Kil'rek", |
["King Dred"] = "Roi Dred", |
["King Gordok"] = "Roi Gordok", |
["King Llane Piece"] = "Pion du Roi Llane", |
["King Ymiron"] = "Roi Ymiron", |
["Kirtonos the Herald"] = "Kirtonos le Héraut", |
["Knot Thimblejack's Cache"] = "Réserve de Noué Dédodevie", |
Kolk = "Kolk", |
Kologarn = "Kologarn", |
["Koralon the Flame Watcher"] = "Koralon le Veilleur des flammes", |
Kormok = "Kormok", |
Kresh = "Kresh", |
Krick = "Krick", |
["Krick and Ick"] = "Krick et Ick", |
["Krik'thir the Gatewatcher"] = "Krik'thir le Gardien de porte", |
["Krosh Firehand"] = "Krosh Brasemain", |
Krystallus = "Krystallus", |
Kurinnaxx = "Kurinnaxx", |
["Lady Anacondra"] = "Dame Anacondra", |
["Lady Blaumeux"] = "Dame Blaumeux", |
["Lady Deathwhisper"] = "Dame Murmemort", |
["Lady Illucia Barov"] = "Dame Illucia Barov", |
["Lady Malande"] = "Dame Malande", |
["Lady Sacrolash"] = "Dame Sacrocingle", |
["Lady Sarevess"] = "Dame Sarevess", |
["Lady Vashj"] = "Dame Vashj", |
Laj = "Laj", |
Landslide = "Glissement de terrain", |
Lavanthor = "Lavanthor", |
["Left Arm"] = "Bras gauche", |
["Leotheras the Blind"] = "Leotheras l'Aveugle", |
Lethon = "Léthon", |
Lethtendris = "Lethtendris", |
["Leviathan Mk II"] = "Léviathan Mod. II", |
["Ley-Guardian Eregos"] = "Gardien-tellurique Eregos", |
["Lieutenant Drake"] = "Lieutenant Drake", |
["Lieutenant General Andorov"] = "Général de division Andorov", |
Loatheb = "Horreb", |
Loken = "Loken", |
["Lord Alexei Barov"] = "Seigneur Alexei Barov", |
["Lord Cobrahn"] = "Seigneur Cobrahn", |
["Lord Hel'nurath"] = "Seigneur Hel'nurath", |
["Lord Incendius"] = "Seigneur Incendius", |
["Lord Jaraxxus"] = "Seigneur Jaraxxus", |
["Lord Kazzak"] = "Seigneur Kazzak", |
["Lord Kri"] = "Seigneur Kri", |
["Lord Marrowgar"] = "Seigneur Gargamoelle", |
["Lord Pythas"] = "Seigneur Pythas", |
["Lord Roccor"] = "Seigneur Roccor", |
["Lord Sanguinar"] = "Seigneur Sanguinar", |
["Lord Serpentis"] = "Seigneur Serpentis", |
["Lord Skwol"] = "Seigneur Skwol", |
["Lord Valthalak"] = "Seigneur Valthalak", |
["Lord Victor Nefarius"] = "Seigneur Victor Nefarius", |
["Lord Vyletongue"] = "Seigneur Vylelangue", |
["Lorekeeper Polkelt"] = "Gardien du savoir Polkelt", |
Loro = "Loro", |
Lucifron = "Lucifron", |
["Mad Magglish"] = "Magglish le Dingue", |
Maexxna = "Maexxna", |
["Mage-Lord Urom"] = "Seigneur-mage Urom", |
["Magister Kalendris"] = "Magistère Kalendris", |
["Magistrate Barthilas"] = "Magistrat Barthilas", |
Magmadar = "Magmadar", |
Magmus = "Magmus", |
Magra = "Magra", |
Magtheridon = "Magtheridon", |
["Maiden of Grief"] = "Damoiselle de peine", |
["Maiden of Virtue"] = "Damoiselle de vertu", |
["Majordomo Executus"] = "Chambellan Executus", |
Malacrass = "Malacrass", |
["Maleki the Pallid"] = "Maleki le Blafard", |
["Mal'Ganis"] = "Mal'Ganis", |
Malygos = "Malygos", |
Maraudos = "Maraudos", |
["Marduk Blackpool"] = "Marduk Noirétang", |
["Marisa du'Paige"] = "Marisa du'Paige", |
Marwyn = "Marwyn", |
["Master Engineer Telonicus"] = "Maître ingénieur Telonicus", |
["Maur Grimtotem"] = "Maur Totem-sinistre", |
Meathook = "Grancrochet", |
["Mechano-Lord Capacitus"] = "Mécano-seigneur Capacitus", |
Medivh = "Medivh", |
["Mekgineer Steamrigger"] = "Mékgénieur Montevapeur", |
["Mekgineer Thermaplugg"] = "Mekgénieur Thermojoncteur", |
["Mennu the Betrayer"] = "Mennu le Traître", |
["Meshlok the Harvester"] = "Meshlok le Moissonneur", |
Midnight = "Minuit", |
Mijan = "Mijan", |
Mimiron = "Mimiron", |
["Miner Johnson"] = "Mineur Johnson", |
["Mistress of Pain"] = "Maîtresse de Douleur", |
Moam = "Moam", |
Mogor = "Mogor", |
["Mokra the Skullcrusher"] = "Mokra le Brise-tête", |
Moorabi = "Moorabi", |
Moragg = "Moragg", |
["Mordresh Fire Eye"] = "Mordresh Oeil-de-feu", |
["Mor Grayhoof"] = "Mor Sabot-gris", |
Moroes = "Moroes", |
["Morogrim Tidewalker"] = "Morogrim Marcheur-des-flots", |
Morphaz = "Morphaz", |
["Mother Shahraz"] = "Mère Shahraz", |
["Mother Smolderweb"] = "Matriarche Couveuse", |
["Mr. Smite"] = "M. Châtiment", |
["Muradin Bronzebeard"] = "Muradin Barbe-de-bronze", |
["Murkblood Twin"] = "Jumeau bourbesang", |
["Murkblood Twins"] = "Jumeaux bourbesang", |
Murmur = "Marmon", |
["Murta Grimgut"] = "Murta Mornentraille", |
["M'uru"] = "M'uru", |
Mushgog = "Mushgog", |
["Mutanus the Devourer"] = "Mutanus le Dévoreur", |
Nalorakk = "Nalorakk", |
Nazan = "Nazan", |
Nefarian = "Nefarian", |
["Nekrum Gutchewer"] = "Nekrum Mâchetripes", |
["Nerub'enkan"] = "Nerub'enkan", |
["Nethermancer Sepethrea"] = "Néantomancien Sepethrea", |
Netherspite = "Dédain-du-Néant", |
["Netherstrand Longbow"] = "Arc long brins-de-Néant", |
["Nexus-Prince Shaffar"] = "Prince-nexus Shaffar", |
Nightbane = "Plaie-de-nuit", |
["Noth the Plaguebringer"] = "Noth le Porte-peste", |
["Novos the Summoner"] = "Novos l'Invocateur", |
Noxxion = "Noxcion", |
["Obsidian Sentinel"] = "Sentinelle d'obsidienne", |
["Odo the Blindwatcher"] = "Odo l'Aveugle", |
["Ogom the Wretched"] = "Ogom le Misérable", |
["Ok'thor the Breaker"] = "Ok'thor le Briseur", |
["Old Serra'kis"] = "Vieux Serra'kis", |
["Olm the Summoner"] = "Olm l'Invocateur", |
["Omor the Unscarred"] = "Omor l'Intouché", |
Onyxia = "Onyxia", |
["Orgrim's Hammer"] = "Marteau d'Orgrim", |
["Ormorok the Tree-Shaper"] = "Ormorok le Sculpte-arbre", |
["Oro Eyegouge"] = "Oro Crève-oeil ", |
["Ossirian the Unscarred"] = "Ossirian l'Intouché", |
Ouro = "Ouro", |
["Overlord Ramtusk"] = "Seigneur Brusquebroche", |
["Overlord Wyrmthalak"] = "Seigneur Wyrmthalak", |
["Overmaster Pyron"] = "Grand seigneur Pyron", |
["Overseer Tidewrath"] = "Surveillant Tidewrath", |
Pandemonius = "Pandemonius", |
["Panzor the Invincible"] = "Panzor l'Invincible", |
Patchwerk = "Le Recousu", |
["Pathaleon the Calculator"] = "Pathaleon le Calculateur", |
Phalanx = "Phalange", |
["Phaseshift Bulwark"] = "Rempart de déphasage", |
Pimgib = "Pimgib", |
["Plaguemaw the Rotting"] = "Pestegueule le Pourrissant", |
["Plugger Spazzring"] = "Lanfiche Brouillecircuit", |
["Postmaster Malown"] = "Postier Malown", |
["Priestess Delrissa"] = "Prêtresse Delrissa", |
["Prince Keleseth"] = "Prince Keleseth", |
["Prince Malchezaar"] = "Prince Malchezaar", |
["Prince Skaldrenox"] = "Prince Skaldrenox ", |
["Princess Huhuran"] = "Princesse Huhuran", |
["Princess Moira Bronzebeard"] = "Princesse Moira Barbe-de-bronze", |
["Princess Tempestria"] = "Princesse Tempestria", |
["Princess Theradras"] = "Princesse Theradras", |
["Princess Yauj"] = "Princesse Yauj", |
["Prince Taldaram"] = "Prince Taldaram", |
["Prince Tenris Mirkblood"] = "Prince Tenris Bourbassang", |
["Prince Tortheldrin"] = "Prince Tortheldrin", |
["Prince Valanar"] = "Prince Valanar", |
["Professor Putricide"] = "Professeur Putricide", |
["Pure Spawn of Hydross"] = "Pur rejeton d'Hydross", |
Pusillin = "Pusillin", |
["Pyroguard Emberseer"] = "Pyrogarde Prophète ardent", |
["Pyromancer Loregrain"] = "Pyromancien Blé-du-savoir", |
Quagmirran = "Bourbierreux", |
["Quartermaster Zigris"] = "Intendant Zigris", |
["Rage Winterchill"] = "Rage Froidhiver", |
Ragglesnout = "Groinfendu", |
["Raging Spirit"] = "Esprit déchaîné", |
Ragnaros = "Ragnaros", |
["Ramstein the Gorger"] = "Ramstein Grandgosier", |
["Ras Frostwhisper"] = "Ras Murmegivre", |
Rattlegore = "Cliquettripes", |
["Razorclaw the Butcher"] = "Tranchegriffe le Boucher", |
["Razorgore the Untamed"] = "Tranchetripe l'Indompté", |
Razorlash = "Tranchefouet", |
Razorscale = "Tranchécaille", |
["Reliquary of Souls"] = "Le reliquaire des âmes", |
Renataki = "Renataki", |
["Restless Skeleton"] = "Squelette sans repos", |
Rethilgore = "Rethiltripe", |
Revelosh = "Revelosh", |
["Rhahk'Zor"] = "Rhahk'Zor", |
["Ribbly Screwspigot"] = "Ribbly Fermevanne", |
["Right Arm"] = "Bras droit", |
Roar = "Graou", |
["Rokad the Ravager"] = "Rodak le ravageur", |
["Rokdar the Sundered Lord"] = "Rokdar le Seigneur scindé", |
["Rokmar the Crackler"] = "Rokmar le Crépitant", |
Romulo = "Romulo", |
["Romulo & Julianne"] = "Romulo & Julianne", |
Rotface = "Trognepus", |
Rotgrip = "Grippe-charogne", |
["Runemaster Molgeim"] = "Maître des runes Molgeim", |
["Runok Wildmane"] = "Runok Crin-sauvage", |
Ruuzlu = "Ruuzlu", |
["Salramm the Fleshcrafter"] = "Salramm le Façonneur de chair", |
["Sanctum Sentry"] = "Factionnaire du sanctum", |
["Sandarr Dunereaver"] = "Sandarr Ravadune", |
["Sandfury Executioner"] = "Bourreau Furie-des-sables", |
Sapphiron = "Saphiron", |
Sara = "Sara", |
["Saronite Animus"] = "Animus de saronite", |
Sartharion = "Sartharion", |
["Sathrovarr the Corruptor"] = "Sathrovarr le Corrupteur", |
["Saviana Ragefire"] = "Saviana Ragefeu", |
["Scarlet Commander Mograine"] = "Commandant écarlate Mograine", |
["Scourgelord Tyrannus"] = "Seigneur du Fléau Tyrannus", |
["Seeth'rel"] = "Fulmi'rel", |
["Selin Fireheart"] = "Selin Coeur-de-feu", |
["Sergeant Bly"] = "Sergent Bly", |
["Shade of Akama"] = "Ombre d'Akama", |
["Shade of Aran"] = "Ombre d'Aran", |
["Shade of Eranikus"] = "Ombre d'Eranikus", |
["Shadikith the Glider"] = "Shadikith le glisseur", |
["Shadow Hunter Vosh'gajin"] = "Chasseresse des ombres Vosh'gajin", |
["Shadow of Leotheras"] = "Ombre de Leotheras", |
["Shadowpriest Sezz'ziz"] = "Prêtre des ombres Sezz'ziz", |
Shadron = "Obscuron", |
Shazzrah = "Shazzrah", |
["Shirrak the Dead Watcher"] = "Shirrak le Veillemort", |
Sindragosa = "Sindragosa", |
["Sir Zeliek"] = "Sire Zeliek", |
["Sjonnir The Ironshaper"] = "Sjonnir le Sculptefer", |
["Skadi the Ruthless"] = "Skadi le Brutal", |
["Skarr the Unbreakable"] = "Bâlhafr l'Invaincu", |
["Skarvald the Constructor"] = "Skarvald le Constructeur", |
["Skra'gath"] = "Skra'gath", |
Skul = "Krân", |
Skum = "Skum", |
["Slad'ran"] = "Slad'ran", |
Sneed = "Sneed", |
["Sneed's Shredder"] = "Déchiqueteur de Sneed", |
["Solakar Flamewreath"] = "Solakar Voluteflamme", |
["Solarium Agent"] = "Agent du Solarium", |
["Solarium Priest"] = "Prêtre du Solarium", |
["Spirestone Battle Lord"] = "Seigneur de bataille Pierre-du-pic", |
["Spirestone Butcher"] = "Boucher Pierre-du-pic", |
["Spirestone Lord Magus"] = "Seigneur magus Pierre-du-pic", |
["Staff of Disintegration"] = "Bâton de désintégration", |
Stalagg = "Stalagg", |
Steelbreaker = "Brise-acier", |
["Stomper Kreeg"] = "Kreeg le Marteleur", |
Stonespine = "Echine-de-pierre", |
["Stormcaller Brundir"] = "Mande-foudre Brundir", |
Strawman = "Homme de paille", |
["Sulfuron Harbinger"] = "Messager de Sulfuron", |
Supremus = "Supremus", |
["Svala Sorrowgrave"] = "Svala Tristetombe", |
["Swamplord Musel'ek"] = "Seigneur des marais Musel'ek", |
Taerar = "Taerar", |
["Tainted Spawn of Hydross"] = "Rejeton d'Hydross souillé", |
["Talon King Ikiss"] = "Roi-serre Ikiss", |
["Taragaman the Hungerer"] = "Taragaman l'Affameur", |
["Targorr the Dread"] = "Targorr le Terrifiant", |
Tavarok = "Tavarok", |
Techbot = "Techbot", |
Temporus = "Temporus", |
["Tendris Warpwood"] = "Tendris Crochebois", |
Tenebron = "Ténébron", |
["Terestian Illhoof"] = "Terestian Malsabot", |
["Teron Gorefiend"] = "Teron Fielsang", |
Thaddius = "Thaddius", |
["Thaladred the Darkener"] = "Thaladred l'Assombrisseur", |
["Thane Korth'azz"] = "Thane Korth'azz", |
["The Beast"] = "La Bête", |
["The Beasts of Northrend"] = "Les bêtes du Norfendre", |
["The Big Bad Wolf"] = "Le Grand Méchant Loup", |
["The Black Knight"] = "Le Chevalier noir", |
["The Black Stalker"] = "La Traqueuse noire", |
["The Blue Brothers"] = "Les Grands Bleus", |
["The Bug Family"] = "La famille insecte", |
["The Crone"] = "La Mégère", |
["The Curator"] = "Le conservateur", |
["The Eredar Twins"] = "Les jumelles érédars", |
["The Four Horsemen"] = "Les quatre cavaliers", |
["The Illidari Council"] = "Le conseil illidari", |
["The Iron Council"] = "Assemblée du fer", |
["Theka the Martyr"] = "Theka le Martyr", |
["The Lich King"] = "Le roi-liche", |
["The Lurker Below"] = "Le Rôdeur d'En bas", |
["The Maker"] = "Le Faiseur", |
["The Prophet Skeram"] = "Le Prophète Skeram", |
["The Prophet Tharon'ja"] = "Le prophète Tharon'ja", |
["The Ravenian"] = "Le Voracien", |
["The Razza"] = "La Razza", |
["The Seven Dwarves"] = "Les sept nains", |
["The Skybreaker"] = "Le Brise-ciel", |
["The Tribunal of Ages"] = "Le tribunal des Ãges", |
["The Twin Emperors"] = "Les Empereurs jumeaux", |
["The Twin Val'kyr"] = "Les jumelles val'kyr", |
["The Unforgiven"] = "Le Condamné", |
["The Windreaver"] = "Ouraganien", |
Thorim = "Thorim", |
["Thorngrin the Tender"] = "Rirépine le Tendre", |
["Tidewalker Lurker"] = "Rôdeur marcheur-des-flots", |
["Timmy the Cruel"] = "Timmy le Cruel", |
Tinhead = "Tête de fer-blanc", |
["Tinkerer Gizlock"] = "Bricoleur Kadenaz", |
["Tirion Fordring"] = "Tirion Fordring", |
Tito = "Tito", |
["Toravon the Ice Watcher"] = "Toravon la Sentinelle de glace", |
["Trigore the Lasher"] = "Trigore le Flagelleur", |
Trollgore = "Trollétripe", |
["Tsu'zee"] = "Tsu'zee", |
["Tuten'kash"] = "Tuten'kash", |
["Twilight Lord Kelris"] = "Seigneur du crépuscule Kelris", |
["Urok Doomhowl"] = "Urok Hurleruine", |
["Vaelastrasz the Corrupt"] = "Vaelastrasz le Corrompu", |
["Valithria Dreamwalker"] = "Valithria Marcherêve", |
["Val'kyr Shadowguard"] = "Garde de l'ombre val'kyr", |
["Varian Wrynn"] = "Varian Wrynn", |
["Varos Cloudstrider"] = "Varos Arpentenuée", |
Vazruden = "Vazruden", |
["Vazruden the Herald"] = "Vazruden le Héraut", |
Vectus = "Vectus", |
Vem = "Vem", |
Veng = "Veng", |
["Veras Darkshadow"] = "Veras Ombrenoir", |
["Verdan the Everliving"] = "Verdan l'Immortel", |
Verek = "Verek", |
Vesperon = "Vespéron", |
Vexallus = "Vexallus", |
["Veyzhak the Cannibal"] = "Veyzhak le Cannibale", |
["Vile'rel"] = "Ignobl'rel", |
Viscidus = "Viscidus", |
["Viscous Fallout"] = "Retombée visqueuse", |
["Void Reaver"] = "Saccageur du Vide", |
Volkhan = "Volkhan", |
["VX-001"] = "VX-001", |
["Warbringer O'mrogg"] = "Porteguerre O'mrogg", |
["Warchief Blackhand Piece"] = "Pion du Chef de guerre Main-noire", |
["Warchief Kargath Bladefist"] = "Chef de guerre Kargath Lamepoing", |
["Warchief Rend Blackhand"] = "Chef de guerre Rend Main-noire", |
["Warden Mellichar"] = "Gardien Mellichar", |
["Warder Stilgiss"] = "Gardien Stilgiss", |
["Warlord Kalithresh"] = "Seigneur de guerre Kalithresh", |
["War Master Voone"] = "Maître de guerre Voone", |
["Warmaul Champion"] = "Champion Cogneguerre", |
["Warp Slicer"] = "Tranchoir dimensionnel", |
["Warp Splinter"] = "Brise-dimension", |
["Watchkeeper Gargolmar"] = "Gardien des guetteurs Gargolmar", |
Weaver = "Tisserand", |
["Witch Doctor Zum'rah"] = "Sorcier-docteur Zum'rah", |
["Wolf Master Nandos"] = "Maître-loup Nandos", |
["Wrath-Scryer Soccothrates"] = "Scrute-courroux Soccothrates", |
Wushoolay = "Wushoolay", |
Xevozz = "Xevozz", |
["XT-002 Deconstructor"] = "Déconstructeur XT-002", |
["Yogg-Saron"] = "Yogg-Saron", |
Ysondre = "Ysondre", |
Zekkis = "Zekkis", |
["Zelemar the Wrathful"] = "Zelemar le Courroucé", |
["Zereketh the Unbound"] = "Zereketh le Délié", |
Zerillis = "Zerillis", |
["Zevrim Thornhoof"] = "Zevrim Sabot-de-ronce", |
Zolo = "Zolo", |
["Zul'Farrak Dead Hero"] = "Héros mort de Zul'Farrak", |
["Zul'jin"] = "Zul'jin", |
["Zul'Lor"] = "Zul'Lor", |
["Zul'tore"] = "Zul'tore", |
["Zuramat the Obliterator"] = "Zuramat l'Oblitérateur", |
} |
elseif GAME_LOCALE == "koKR" then |
lib:SetCurrentTranslations { |
Acidmaw = "ê³µí¬ë¹ë", |
Aeonus = "ììëì¤", |
["Aerial Command Unit"] = "ê³µì¤ ì§í기", |
["Agathelos the Raging"] = "íí¬í ìê°í ë¡ì¤", |
Ahune = "ìí", |
["Akil'zon"] = "ìí¬ì¡´", |
["Aku'mai"] = "ìì¿ ë§ì´", |
["Al'ar"] = "ìë¼ë¥´", |
["Algalon the Observer"] = "ê´ì°°ì ìê°ë¡ ", |
["Alzzin the Wildshaper"] = "ì¹¼ë ë°ë ìì§", |
Amanitar = "ìë§ëí르", |
["Ambassador Flamelash"] = "ì¬ì íì¼ì±ì°", |
["Ambassador Hellmaw"] = "ì¬ì ì§ì¥ìê·", |
["Amnennar the Coldbringer"] = "í¹íì ìë¤ë르", |
["Ancient Stone Keeper"] = "ê³ ë ë°ì 문ì§ê¸°", |
Anetheron = "ìë¤í ë¡ ", |
["Anger'rel"] = "ê²©ë ¸ì 문ì§ê¸°", |
Anomalus = "ìë ¸ë§ë£¨ì¤", |
["Antu'sul"] = "ìí¬ì ", |
["Anub'arak"] = "ìëìë½", |
["Anubisath Defender"] = "ìëë¹ì¬ì¤ 문ì§ê¸°", |
["Anubisath Guardian"] = "ìëë¹ì¬ì¤ ê°ìì", |
["Anub'Rekhan"] = "ìëë 칸", |
["Anub'shiah"] = "ìëì¬ì", |
Anzu = "ì주", |
["Arcane Watchman"] = "ë¹ì ë³´ì´", |
["Arcanist Doan"] = "ì ë¹ì ì¬ ëì", |
Archaedas = "ìì¹´ìë¤ì¤", |
["Archavon the Stone Watcher"] = "ë°ì ê°ìì ì카본", |
Archimonde = "ìí¤ëª¬ë", |
["Archivist Galford"] = "기ë¡ê´ ê°í¬ë", |
["Archmage Arugal"] = "ëë§ë²ì¬ ì루ê°", |
["Argent Confessor Paletress"] = "ìë¹ ê³ í´ì¬ì íì¼í¸ë¦¬ì¤", |
["Arugal's Voidwalker"] = "ì루ê°ì ë³´ì´ëì커", |
["Assault Bot"] = "ë격ë¡ë´", |
["Atal'alarion"] = "ìíìë¼ë¦¬ì¨", |
["Attumen the Huntsman"] = "ì¬ë¥ê¾¼ ì´íë©", |
Auriaya = "ìì°ë¦¬ìì¼", |
Avalanchion = "ìë°ëì¹ì¨", |
["Avatar of Hakkar"] = "í카르ì íì ", |
["Ayamiss the Hunter"] = "ì¬ë¥ê¾¼ ìì¼ë¯¸ì¤", |
Azgalor = "ìì¦ê°ë¡", |
["Azshir the Sleepless"] = "ì ë¤ì§ ìë ìì¦ì르", |
Azuregos = "ì주ì´ê³ ì¤", |
["Bael'Gar"] = "벨ê°ë¥´", |
Baelog = "ë°¸ë¡ê·¸", |
Balnazzar = "ë°ëì르", |
-- ["Baltharus the Warborn"] = "", |
["Bannok Grimaxe"] = "ë°ë ¸í¬ 그림ì¡ì¤", |
["Baron Aquanis"] = "ë¨ì ìì¿ ìëì¤", |
["Baron Charr"] = "ë¨ì 차르", |
["Baroness Anastari"] = "ë¨ìë¶ì¸ ìëì¤í리", |
["Baron Geddon"] = "ë¨ì ê²ë", |
["Baron Kazum"] = "ë¨ì ì¹´ì¤", |
["Baron Rivendare"] = "ë¨ì 리ë¸ë°ì´", |
["Baron Silverlaine"] = "ë¨ì ì¤ë²ë ì¸", |
["Battleguard Sartura"] = "ì í¬ê°ìë³ ì´í¬ë¼", |
["Bazil Thredd"] = "ë°ì§ ì¤ë ë", |
Bazzalan = "ë°ìë", |
["Black Guard Swordsmith"] = "ê²ìí¸ìë ê²ì ìì", |
["Blackheart the Inciter"] = "ì ëì ê²ìì¬ì¥", |
["Blindeye the Seer"] = "íì ë¸ë¼ì¸ëìì´", |
["Blind Hunter"] = "ì¥ë ì¬ë¥ê¾¼", |
["Blood Guard Porung"] = "íí¬ì¬ í¬ë£½", |
["Bloodlord Mandokir"] = "í군주 ë§ëí¤ë¥´", |
["Bloodmage Thalnos"] = "íë²ì¬ íë ¸ì¤", |
["Blood Prince Council"] = "í¼ì ê³µì ìí", |
["Blood Princes"] = "í¼ì ê³µì", |
["Blood-Queen Lana'thel"] = "í¼ì ì¬ì ë¼ëí ", |
["Blood Steward of Kirtonos"] = "í¤ë¥´í ë ¸ì¤ì íì§ê¸°", |
Boahn = "ë³´ì", |
["Bomb Bot"] = "ííë¡ë´", |
["Brain of Yogg-Saron"] = "ìê·¸ì¬ë¡ ì ë", |
["Brainwashed Noble"] = "ì¸ëë¹í ê·ì¡±", |
Broggok = "ë¸ë¡ê³ í¬", |
Brokentoe = "ë§ì¹ë°êµ½", |
Bronjahm = "ë¸ë¡ ì ", |
["Broodlord Lashlayer"] = "ì©ê¸°ëì¥ ëì¬ë ì´ì´", |
["Bruegal Ironknuckle"] = "무ì 주먹 ë¸ë£¨ê°", |
Brutallus = "ë¸ë£¨í루ì¤", |
["Burning Felguard"] = "ë¶íë ì§ì¥ìí¸ë³", |
["Buru the Gorger"] = "먹보 ë¶ë£¨", |
["Cache of the Firelord"] = "Cache of the Firelord", |
["Cannon Master Willey"] = "í¬ë³ëì¥ ì리", |
["Captain Greenskin"] = "ì ì¥ ê·¸ë¦°ì¤í¨", |
["Captain Kromcrush"] = "ëì¥ í¬ë¡¬í¬ë¬ì¬", |
["Captain Skarloc"] = "ê²½ë¹ëì¥ ì¤ì¹¼ë¡", |
["Celebras the Cursed"] = "ì 주ë°ì ì ë ë¸ë¼ì¤", |
["Charlga Razorflank"] = "ìì¬ê¹ 차를ê°", |
["Chess Event"] = "Chess Event", |
["Chest of The Seven"] = "Chest of The Seven", |
["Chief Ukorz Sandscalp"] = "ì¡±ì¥ ì°ì½ë¥´ì¦ ìëì¤ì¹¼í", |
["Cho'Rush the Observer"] = "ì ì°°ë³ ì´ë£¨ì¬", |
Chromaggus = "í¬ë¡ë§êµ¬ì¤", |
["Chrono Lord Deja"] = "ìê°ì 군주 ë°ì", |
["Chrono-Lord Epoch"] = "ìê°ì 군주 ìí¬í¬", |
Claw = "í´ë¡", |
["Coilfang Elite"] = "ê°í´ì¡ê³³ë ì ìë³", |
["Coilfang Strider"] = "ê°í´ì¡ê³³ë í¬ìì", |
["Commander Kolurg"] = "ì¬ë ¹ê´ ì½ë£¨ë¥´ê·¸", |
["Commander Sarannis"] = "ì§íê´ ìëëì¤", |
["Commander Springvale"] = "ì¬ë ¹ê´ ì¤íë§ë² ì¼", |
["Commander Stoutbeard"] = "ì¬ë ¹ê´ ì¤íì°í¸ë¹ì´ë", |
["Constructor & Controller"] = "ê±´ì¶ê°ì ê°ìì", |
Cookie = "ì¿ í¤", |
["Coren Direbrew"] = "ì½ë ë¤ì´ì´ë¸ë£¨", |
["Cosmic Infuser"] = "ë¶ê´´ì ì§í¡ì´", |
["Crimson Hammersmith"] = "ì§íììêµ° ëì¥ì¥ì´", |
["Crowd Pummeler 9-60"] = "ê³ ì² ìì¶ê¸° 9-60", |
["Crystal Fang"] = "ìì 맹ë 거미", |
["C'Thun"] = "ì¨", |
Cyanigosa = "ììëê³ ì¬", |
["Dalliah the Doomsayer"] = "í멸ì ìì¸ì ë¬ë¦¬ì", |
["Dalronn the Controller"] = "ê°ìì ë¬ë¡ ", |
["Dark Iron Ambassador"] = "ê²ì무ì ë¨ ì¬ì ", |
["Darkmaster Gandling"] = "ìíì¤ì¹ ê°íë§", |
["Darkweaver Syth"] = "íë§ì ì¬ ìì¤", |
["Deathbound Ward"] = "죽ìì ìë°ë ê°ìì", |
["Deathbringer Saurfang"] = "죽ìì ì¸ëì ì¬ì¸í½", |
["Death Knight Darkreaver"] = "죽ìì ê¸°ì¬ ë¤í¬ë¦¬ë²", |
["Death Knight Understudy"] = "죽ìì ê¸°ì¬ ììµì", |
["Deathspeaker High Priest"] = "죽ììì¸ì ëì¬ì ", |
["Death Speaker Jargba"] = "죽ìì ìì¸ì ìê·¸ë°", |
["Deathstalker Visceri"] = "죽ììì¶ì ì ë¹ì¸ë¦¬", |
["Deathsworn Captain"] = "죽ìì ê²½ë¹ëì¥", |
Devastation = "í©íì ëë¼", |
["Deviate Faerie Dragon"] = "ëì°ë³ì´ ìì ì©", |
["Devourer of Souls"] = "ìí¼ì í¬ìì", |
["Dextren Ward"] = "ë±ì¤í¸ë ìë", |
["Digmaster Shovelphlange"] = "ë°êµ´ë¨ì¥ ì¼ë²¨íëì§", |
["Doctor Theolen Krastinov"] = "íì í ì¬ë¦° í¬ë¼ì¤í°ë ¸ë¸", |
["Doom Lord Kazzak"] = "í멸ì 군주 ì¹´ìí¬", |
["Doom'rel"] = "ì´ëª ì 문ì§ê¸°", |
Doomwalker = "í멸ì ì ë¨ê¸°", |
["Dope'rel"] = "ìµë©´ì 문ì§ê¸°", |
Dorothee = "ëë¡ì", |
["Drakkari Colossus"] = "ëë¼ì¹´ë¦¬ ê±°ë골ë ", |
["Drakos the Interrogator"] = "ì¬ë¬¸ê´ ëë¼ì½ì¤", |
Dreadscale = "ê³µí¬ë¹ë", |
Dreamscythe = "ë림ì¬ì´ë", |
["Dust Covered Chest"] = "Dust Covered Chest", |
Dustwraith = "ëì¤í¸ë ì´ì¤", |
["Eadric the Pure"] = "ì±ê¸°ì¬ ìëë¦", |
["Earthcaller Halmgar"] = "ëì§ì ì¬ í¨ê°ë¥´", |
Ebonroc = "ì본ë¡í¬", |
["Eck the Ferocious"] = "ì¬ëì´ ìí¬", |
["Edwin VanCleef"] = "ìëì ë°´í´ë¦¬í", |
["Elder Brightleaf"] = "ì¥ë¡ ë°ìì", |
["Elder Ironbranch"] = "ì¥ë¡ 무ì ë기", |
["Elder Nadox"] = "ì¥ë¡ ëë ì¤", |
["Elder Stonebark"] = "ì¥ë¡ ëë무ê»ì§", |
["Electrocutioner 6000"] = "기ê³í 문ì§ê¸° 6000", |
["Emalon the Storm Watcher"] = "íí ê°ìì ìë§ë¡ ", |
Emeriss = "ìë©ë¦¬ì¤", |
["Emperor Dagran Thaurissan"] = "ì ì ë¤ê·¸ë íì°ë¦¿ì°", |
["Emperor Vek'lor"] = "ì ì ë² í´ë¡ì´", |
["Emperor Vek'nilash"] = "ì ì ë² í¬ëë¼ì¬", |
Entropius = "ìí¸ë¡í¼ì°ì¤", |
["Eonar's Gift"] = "ì´ì¤ëì ì 물", |
["Epoch Hunter"] = "ìëì ì¬ë¥ê¾¼", |
Erekem = "ìë ì¼", |
["Eressea Dawnsinger"] = "ìë ìì ëì±ì´", |
["Essence of Anger"] = "ê²©ë ¸ì ì ì", |
["Essence of Desire"] = "ìë§ì ì ì", |
["Essence of Suffering"] = "ê³ ëì ì ì", |
Eviscerator = "ì ì¶ì", |
["Exarch Maladaar"] = "ì´ë ë§ë¼ë¤ë¥´", |
["Expedition Commander"] = "ìì ë ëì¥", |
["Eydis Darkbane"] = "ìì´ëì¤ ë¤í¬ë² ì¸", |
["Eye of C'Thun"] = "ì¨ì ë", |
["Faction Champions"] = "ì§ì ëí ì©ì¬", |
["Fallen Champion"] = "íë½í ì©ì¬", |
Falric = "íë¦", |
["Falric and Marwyn"] = "íë¦ê³¼ ë§ì", |
["Fankriss the Unyielding"] = "ë¶êµ´ì íí¬ë¦¬ì¤", |
["Fathom-Lord Karathress"] = "ì¬ì°ì 군주 ì¹´ë¼ëë ì¤", |
Felmyst = "ì§ì¥ìê°", |
["Fenrus the Devourer"] = "í멸ì í루ì¤", |
["Feral Defender"] = "ìí¸ ì¼ì", |
Festergut = "구린ì", |
Feugen = "í¨ì§", |
["Fineous Darkvire"] = "íì´ëì¤ ë¤í¬ë°ì´ì´", |
Firemaw = "íì¼ìê·", |
["Fjola Lightbane"] = "í¼ìë¼ ë¼ì´í¸ë² ì¸", |
Flamegor = "íë ìê³ ë¥´", |
["Flame Leviathan"] = "ê±°ë íì¼ì ì°¨", |
["Foreman Thistlenettle"] = "íì¥ê°ë ìì¬ë¤í", |
["Forgemaster Garfrost"] = "ê´´ì² ë¡ê°ë ê´ ê°íë¡ì¤í¸", |
["Four Horsemen Chest"] = "Four Horsemen Chest", |
["Fras Siabi"] = "íë¼ì¤ ì¤ë¹", |
Freya = "íë ì´ì¼", |
["Gahz'ranka"] = "ê°ì¦ëì¹´", |
["Gahz'rilla"] = "ê°ì¦ë¦´ë¼", |
["Gal'darah"] = "ê°ë¤ë¼", |
["Galgann Firehammer"] = "ê°ê° íì´ì´í´ë¨¸", |
Garr = "ê°ë¥´", |
["Garrosh Hellscream"] = "ê°ë¡ì¬ í¬ì¤í¬ë¦¼", |
Gasher = "ê²ì´ì ", |
["Gatewatcher Gyro-Kill"] = "문ì§ê¸° íì í±ë ", |
["Gatewatcher Iron-Hand"] = "문ì§ê¸° 무ì 주먹", |
["Gathios the Shatterer"] = "íê´´ì ê°ëì¤ì¤", |
Gehennas = "ê²í¨ëì¤", |
Gelihast = "ê²ë¦¬íì¤í¸", |
Gelk = "ê²í¬", |
["General Angerforge"] = "ì¬ë ¹ê´ ìµê±°í¬ì§", |
["General Bjarngrim"] = "ì¥êµ° ë¹ì¼ë¥¸ê·¸ë¦¼", |
["General Drakkisath"] = "ì¬ë ¹ê´ ëë¼í¤ì¬ì¤", |
["General Rajaxx"] = "ì¥êµ° ë¼ìì¤", |
["General Vezax"] = "ì¥êµ° ë² ìì¤", |
["General Zarithrian"] = "ì¥êµ° ì리ì¤ë¦¬ì", |
["Ghamoo-ra"] = "ê°ë¬´ë¼ ", |
["Ghaz'an"] = "ê°ì¦ì", |
["Ghok Bashguud"] = "ê³ í¬ ë°°ì구ë", |
Gilnid = "길ëë", |
["Gizrul the Slavener"] = "íí¬í 기ì¦ë£°", |
["Gloom'rel"] = "ê·¸ëì 문ì§ê¸°", |
Gluth = "ê¸ë£¨ì¤", |
Glutton = "ê²ê±¸ë¨¹ë³´", |
["Golemagg the Incinerator"] = "ì´ì´ì 골ë ë§ê·¸", |
["Golem Lord Argelmach"] = "골ë 군주 ìì ¤ë§í¬", |
["Goraluk Anvilcrack"] = "ê³ ëë£¨í¬ ì¤ë¹í¬ë", |
["Gormok the Impaler"] = "ê¿°ë«ë ì ê³ ë¥´ëª©", |
["Gorosh the Dervish"] = "ê´ì ì ê³ ë¡ì¬", |
["Gortok Palehoof"] = "ê³ ë¥´í¡ íì¼íí", |
["Gothik the Harvester"] = "ìí¼ ì°©ì·¨ì ê³ ë", |
["Grand Astromancer Capernian"] = "ëì ì±ì ì¬ ì¹´í¼ëì", |
["Grand Champions"] = "ëì ìµê³ ì©ì¬", |
["Grand Magus Telestra"] = "ëíì í ë ì¤í¸ë¼", |
["Grandmaster Vorpil"] = "ë¨ì¥ 보르í", |
Grandmother = "í 머ë", |
["Grand Warlock Alythess"] = "ëíë§ë²ì¬ ì리í ì¤", |
["Grand Warlock Nethekurse"] = "ëíë§ë²ì¬ ë¤ëì¿ ë¥´ì¤", |
["Grand Widow Faerlina"] = "ê·ë¶ì¸ í°ë¦¬ë", |
["Grethok the Controller"] = "ê°ìì ê·¸ë í í¬", |
["Gri'lek"] = "그리ë ", |
Grimlok = "그림ë¡í¬", |
Grizzle = "그리ì¦", |
Grobbulus = "ê·¸ë¼ë¶ë£¨ì¤", |
Grubbis = "그루ë¹ì¤ ", |
["Gruul the Dragonkiller"] = "ì© íì´ì 그룰", |
["Guard Fengus"] = "ê²½ë¹ë³ í구ì¤", |
["Guardian of Yogg-Saron"] = "ìê·¸ì¬ë¡ ì ìí¸ì", |
["Guard Mol'dar"] = "ê²½ë¹ë³ 몰ë¤ë¥´", |
["Guard Slip'kik"] = "ê²½ê¸°ë³ ì¬ë¦½í¥", |
["Gurtogg Bloodboil"] = "구르í ê·¸ ë¸ë¬ëë³´ì¼", |
Gyth = "기ì¤", |
Hadronox = "íëë¡ë ¹ì¤", |
Hakkar = "í카르", |
Halazzi = "í ë¼ì§", |
Halion = "í 리ì¨", |
Halycon = "í 리ì½", |
Hamhock = "íí¹", |
["Harbinger Skyriss"] = "ì 구ì ì¤í¤ë¦¬ì¤", |
["Hate'rel"] = "ì¦ì¤ì 문ì§ê¸°", |
["Hazza'rah"] = "íìë¼", |
Hazzas = "íìì¤", |
["Headless Horseman"] = "ì 주ë°ì 기ì¬", |
["Hearthsinger Forresten"] = "íì¤ì±ì´ í¬ë ì¤í´", |
["Hedrum the Creeper"] = "ì거미 í¤ë룸", |
["Heigan the Unclean"] = "ë¶ì ì í¤ì´ê±´", |
["Hellfire Channeler"] = "ì§ì¥ë¶ ìì ì¬", |
["Henry Stern"] = "í¨ë¦¬ ì¤í´", |
["Herald Volazj"] = "ì¬ì ë³¼ë¼ì¦", |
Herod = "í¤ë¡ë", |
["Hex Lord Malacrass"] = "주ì 군주 ë§ë¼í¬ë¼ì¤", |
["High Astromancer Solarian"] = "ê³ ì ì ì±ì ì¬ ìë¼ë¦¬ì", |
["High Botanist Freywinn"] = "ê³ ì ì물íì íë ì´ì", |
["High Inquisitor Fairbanks"] = "ì¢ êµì¬íê´ íì´ë± í¬ì¤", |
["High Inquisitor Whitemane"] = "ì¢ êµì¬íê´ íì´í¸ë©ì¸", |
["High Interrogator Gerstahn"] = "ëì¬ë¬¸ê´ ê²ë¥´ì¤í", |
["High King Maulgar"] = "ìì¤ì ë§ì¸ê°ë¥´", |
["Highlord Mograine"] = "ëì주 모그ë ì¸", |
["Highlord Omokk"] = "ë군주 ì¤ëª¨í¬", |
["High Marshal Whirlaxis"] = "ëì¥êµ° í ë½ìì¤", |
["High Nethermancer Zerevor"] = "ê³ ì í©ì²ì ì¬ ì ë 보르", |
["High Overlord Saurfang"] = "ë군주 ì¬ì¸í½", |
["High Priestess Arlokk"] = "ëì¬ì¬ì ìë¡í¬", |
["High Priestess Jeklik"] = "ëì¬ì¬ì ì í´ë¦", |
["High Priestess Mar'li"] = "ëì¬ì¬ì ë§ë¦¬", |
["High Priestess of Thaurissan"] = "íì°ë¦¿ì°ì ëì¬ì¬ì ", |
["High Priest Thekal"] = "ëì¬ì ë°ì¹¼", |
["High Priest Venoxis"] = "ëì¬ì ë² ë ¹ìì¤", |
["High Warlord Naj'entus"] = "ëì¥êµ° ëì í¬ì¤", |
Hodir = "í¸ë르", |
["Houndmaster Grebmar"] = "ì¬ë¥ê°ì¡°ë ¨ì¬ ê·¸ë ë§ë¥´", |
["Houndmaster Loksey"] = "ì¬ë¥ê° ì¡°ë ¨ì¬ ë¡ì", |
Hukku = "íì¿ ", |
Hungarfen = "íê°ë¥´í", |
["Hurley Blackbreath"] = "íë ì´ ë¸ëë¸ë ì¤", |
["Hyakiss the Lurker"] = "ì 복꾼 íìí¤ì¤", |
["Hydromancer Thespia"] = "íìì¬ ì¸ì¤í¼ì", |
["Hydromancer Velratha"] = "ì ì²´ì ì¬ ë²¨ë¼í", |
Hydrospawn = "íëë¡ì¤í°", |
["Hydross the Unstable"] = "ë¶ìì í íëë¡ì¤", |
["Icecrown Gunship Battle"] = "ì¼ììê´ ë¹íí¬ê²©ì ì í¬", |
Icehowl = "ì¼ìì¸ì", |
["Ice Sphere"] = "ì¼ì 구ì¬", |
Ichoron = "ì´ì½ë¡ ", |
Ick = "ì´í¬", |
["Ignis the Furnace Master"] = "ì©ê´ë¡ 군주 ì´ê·¸ëì¤", |
["Illidan Stormrage"] = "ì¼ë¦¬ë¨ ì¤í°ë ì´ì§", |
["Illidari Council"] = "ì¼ë¦¬ë¤ë¦¬ ìí", |
["Illyanna Ravenoak"] = "ì¼ì¨ë ë ì´ë¸í¸í¬", |
["Immol'thar"] = "ì´ëª°í르", |
["Infinite Corruptor"] = "무íì íë½ì", |
["Infinity Blades"] = "무íì ë¹ì", |
["Ingvar the Plunderer"] = "ì½íì ìê·¸ë°ë¥´", |
["Instructor Malicia"] = "ì¡°êµ ë§ë¦¬ìì", |
["Instructor Razuvious"] = "íë ¨êµê´ ë¼ì£¼ë¹ì´ì¤", |
["Interrogator Vishas"] = "ì¬ë¬¸ê´ ë¹ì¤ì¤", |
Ionar = "ìì´ì¤ë", |
Ironaya = "ìì´ë¡ëì¼", |
Ironspine = "무ì í´ê³¨", |
Isalien = "ì´ì´ë¦¬ì", |
Jade = "ì ì´ë", |
["Jammal'an the Prophet"] = "ìì¸ì ì ë§ë", |
["Jan'alai"] = "ììë¼ì´", |
["Jandice Barov"] = "ìë¤ì´ì¤ ë°ë¡ë¸", |
["Jedoga Shadowseeker"] = "ì´ë ì¶ì ì ì ëê°", |
["Jed Runewatcher"] = "ì ë 룬ìì²", |
["Jergosh the Invoker"] = "기ìì¬ ì ë¡ì¬", |
["Jin'do the Hexxer"] = "주ì ì¬ ì§ë", |
["Jormungar Behemoth"] = "ì르문ê°ë¥´ ê±°ì", |
Jormungars = "ì르문ê°ë¥´", |
Julianne = "ì¤ë¦¬ì", |
["Junk Bot"] = "ê³ ì² ë¡ë´", |
["Kael'thas Sunstrider"] = "ìºíì¤ ì ì¤í¸ë¼ì´ë", |
Kalecgos = "ì¹¼ë ê³ ì¤", |
["Kam Deepfury"] = "ìº ë¥í¨ë¦¬", |
["Kazkaz the Unholy"] = "íë½í ì¹´ì¦ì¹´ì¦", |
["Kaz'rogal"] = "ì¹´ì¦ë¡ê°", |
["Keli'dan the Breaker"] = "íê´´ì ì¼ë¦¬ë¨", |
["Kel'Thuzad"] = "ì¼í¬ìë", |
Keristrasza = "ì¼ë¦¬ì¤í¸ë¼ì", |
["Kiggler the Crazed"] = "ê´ê¸°ì í¤ê¸ë¬", |
["Kil'jaeden"] = "í¬ì ë´", |
["Kil'rek"] = "í¬ë ", |
["King Dred"] = "ë©í°ì ìì¬ë°í±", |
["King Gordok"] = "ì ê³ ë¥´ë ", |
["King Llane Piece"] = "êµì ë ì¸", |
["King Ymiron"] = "ì ì´ë¯¸ë¡ ", |
["Kirtonos the Herald"] = "ì¬ì í¤ë¥´í ë ¸ì¤", |
["Knot Thimblejack's Cache"] = "ë ¸í¸ íë¸ì ì ìëí", |
Kolk = "ì½í¬", |
Kologarn = "ì½ë¡ê°", |
["Koralon the Flame Watcher"] = "íì¼ ê°ìì ì½ëë¡ ", |
Kormok = "ì½ë¥´ëª¨í¬", |
Kresh = "í¬ë ì¬", |
Krick = "í¬ë¦¬í¬", |
["Krick and Ick"] = "í¬ë¦¬í¬ì ì´í¬", |
["Krik'thir the Gatewatcher"] = "문ì§ê¸° í¬ë¦ì르", |
["Krosh Firehand"] = "í¬ë¡ì¬ íì´ì´í¸ë", |
Krystallus = "í¬ë¦¬ì¤í루ì¤", |
Kurinnaxx = "ì¿ ë¦°ëì¤", |
["Lady Anacondra"] = "ì¬êµ°ì£¼ ìëì½ëë¼", |
["Lady Blaumeux"] = "ì¬êµ°ì£¼ ë¸ë¼ë¯¸ì°ì¤", |
["Lady Deathwhisper"] = "ì¬êµì£¼ ë°ì¤ìì¤í¼", |
["Lady Illucia Barov"] = "ì¬êµ°ì£¼ ì¼ë£¨ìì ë°ë¡ë¸", |
["Lady Malande"] = "ì¬êµ°ì£¼ ë§ëë°", |
["Lady Sacrolash"] = "ì¬êµ°ì£¼ ì¬í¬ë¡ëì¬", |
["Lady Sarevess"] = "ì¬ì ì¬ë ë² ì¤", |
["Lady Vashj"] = "ì¬êµ°ì£¼ ë°ì¬", |
Laj = "ë¼ì¦", |
Landslide = "ì°ì¬í", |
Lavanthor = "ë¼ë°í 르", |
["Left Arm"] = "ì¼í", |
["Leotheras the Blind"] = "ë먼 ë ì¤í ë¼ì¤", |
Lethon = "ë ì", |
Lethtendris = "ë ì¤í ë리ì¤", |
["Leviathan Mk II"] = "ê±°ë ì ì°¨ Mk II", |
["Ley-Guardian Eregos"] = "ì§ë§¥ ìí¸ì ìë ê³ ì¤", |
["Lieutenant Drake"] = "ë¶ê´ ëë ì´í¬", |
["Lieutenant General Andorov"] = "ì¬ë ¹ê´ ìëë¡ë¸", |
Loatheb = "ë¡ë°ë¸", |
Loken = "ë¡ì¼", |
["Lord Alexei Barov"] = "군주 ìë ì¸ì´ ë°ë¡ë¸", |
["Lord Cobrahn"] = "군주 ì½ë¸ë", |
["Lord Hel'nurath"] = "군주 í¬ëë¼ì¤", |
["Lord Incendius"] = "군주 ì¸ì¼ëì°ì¤", |
["Lord Jaraxxus"] = "군주 ìë½ìì¤", |
["Lord Kazzak"] = "군주 ì¹´ìí¬", |
["Lord Kri"] = "군주 í¬ë¦¬", |
["Lord Marrowgar"] = "군주 매ë¡ì°ê°ë¥´", |
["Lord Pythas"] = "군주 í¼íì¤", |
["Lord Roccor"] = "ë¶ì군주 ë¡ì½ë¥´", |
["Lord Sanguinar"] = "군주 ìê·ë르", |
["Lord Serpentis"] = "군주 ìíëì¤", |
["Lord Skwol"] = "군주 ì¤í", |
["Lord Valthalak"] = "군주 ë°íë¼í¬", |
["Lord Victor Nefarius"] = "군주 ë¹ í° ë¤í리ì°ì¤", |
["Lord Vyletongue"] = "군주 ë°ì¼í ", |
["Lorekeeper Polkelt"] = "íì í´ì¼í¸", |
Loro = "ë¡ë¡", |
Lucifron = "루ìíë¡ ", |
["Mad Magglish"] = "ê´ê¸°ì 매ê¸ë¦¬ì", |
Maexxna = "맥ì¤ë", |
["Mage-Lord Urom"] = "ë§ë²ì¬ 군주 ì°ë¡¬", |
["Magister Kalendris"] = "ë§ë²ì¬ ì¹¼ë ë리ì¤", |
["Magistrate Barthilas"] = "ì§ì ê´ ë°ì¤ë¼ì¤", |
Magmadar = "ë§ê·¸ë§ë¤ë¥´", |
Magmus = "ë§ê·¸ë¬´ì¤", |
Magra = "ë§ê·¸ë¼", |
Magtheridon = "ë§ê·¸í 리ë", |
["Maiden of Grief"] = "ê³ ëì ë§ë ", |
["Maiden of Virtue"] = "ê³ ê²°ì ì¬ì ", |
["Majordomo Executus"] = "ì²ì§ê¸° ì´ê·¸ì íí¬ì¤", |
Malacrass = "ë§ë¼í¬ë¼ì¤", |
["Maleki the Pallid"] = "ëíí ë§ë í¤", |
["Mal'Ganis"] = "ë§ê°ëì¤", |
Malygos = "ë§ë¦¬ê³ ì¤", |
Maraudos = "ë§ë¼ì°ëì¤", |
["Marduk Blackpool"] = "ë§ë¥´ëí¬ ë¸ëí", |
["Marisa du'Paige"] = "ë§ë¦¬ì¬ ëíì´ì§", |
Marwyn = "ë§ì", |
["Master Engineer Telonicus"] = "ìì기ì ì í ë¡ëì¿ ì¤", |
["Maur Grimtotem"] = "ë§ì°ë¥´ 그림í í ", |
Meathook = "ì´ë©ì´ê°ê³ 리", |
["Mechano-Lord Capacitus"] = "기ê³êµ°ì£¼ ìºí¼ìí¬ì¤", |
Medivh = "ë©ëë¸", |
["Mekgineer Steamrigger"] = "기ê³ê³µíì ì¤í리거", |
["Mekgineer Thermaplugg"] = "ë©ê¸°ëì´ í ë§íë¬ê·¸", |
["Mennu the Betrayer"] = "ë°°ë°ì ë©ë", |
["Meshlok the Harvester"] = "ì ìì¬ ë©ì¬ë¡í¬", |
Midnight = "ì²ë¥ì´", |
Mijan = "ë§ì´ì", |
Mimiron = "ë¯¸ë¯¸ë¡ ", |
["Miner Johnson"] = "ê´ë¶ ì¡´ì¨", |
["Mistress of Pain"] = "ê³ íµì ì¬êµ°ì£¼", |
Moam = "모ì", |
Mogor = "ëª¨ê³ ë¥´", |
["Mokra the Skullcrusher"] = "í´ê³¨ë¶ìì 모í¬ë¼", |
Moorabi = "무ë¼ë¹", |
Moragg = "모ë¼ê·¸", |
["Mordresh Fire Eye"] = "ë¶ê½ë 모ëë ì¬", |
["Mor Grayhoof"] = "모르 ê·¸ë ì´íí", |
Moroes = "모ë¡ì¤", |
["Morogrim Tidewalker"] = "ê² ë¥íë 모ë¡ê·¸ë¦¼", |
Morphaz = "몰íì¦", |
["Mother Shahraz"] = "ë모 ì¤ë¼ì¦", |
["Mother Smolderweb"] = "ì¬ì ë¶ê·¸ë¬¼ê±°ë¯¸", |
["Mr. Smite"] = "미ì¤í° ì¤ë§ì´í¸", |
["Muradin Bronzebeard"] = "무ë¼ë ë¸ë¡ ì¦ë¹ì´ë", |
["Murkblood Twin"] = "ìë í¼ì¼ì¡± ìë¥ì´", |
["Murkblood Twins"] = "ìë í¼ì¼ì¡± ìë¥ì´", |
Murmur = "ì¸ë¦¼", |
["Murta Grimgut"] = "무르í 그림구í¸", |
["M'uru"] = "ë¯ì°ë£¨", |
Mushgog = "머ì¬ê³ ê·¸", |
["Mutanus the Devourer"] = "걸ì ë¤ë¦° 무íëì¤", |
Nalorakk = "ë ë¡ë¼í¬", |
Nazan = "ëì", |
Nefarian = "ë¤í리ì", |
["Nekrum Gutchewer"] = "ë¤í¬ë£¸ ê±°í¸ì¸ì´", |
["Nerub'enkan"] = "ë¤ë£¹ì칸", |
["Nethermancer Sepethrea"] = "í©ì²ì ì¬ ì¸íì¤ë ì", |
Netherspite = "í©ì²ì ìë ¹", |
["Netherstrand Longbow"] = "í©ì²ë§¤ë ì¥ê¶", |
["Nexus-Prince Shaffar"] = "ì°í©ìì ì¤í르", |
Nightbane = "í멸ì ì´ë ", |
["Noth the Plaguebringer"] = "ìë³ì ì¬ ë ¸ì¤", |
["Novos the Summoner"] = "ìíì¬ ë ¸ë³´ì¤", |
Noxxion = "ë ¹ìì¨", |
["Obsidian Sentinel"] = "íìì íìê¾¼", |
["Odo the Blindwatcher"] = "ë먼ê°ìì ì¤ë", |
["Ogom the Wretched"] = "ë¹ì´ì ì¤ê·¸ì´", |
["Ok'thor the Breaker"] = "íê´´ì ì¤í¬í 르", |
["Old Serra'kis"] = "ëì ì¸ë¼í¤ì¤", |
["Olm the Summoner"] = "ìíì¬ ì¬ë¦", |
["Omor the Unscarred"] = "무ì ì ì¤ëª¨ë¥´", |
Onyxia = "ì¤ëìì", |
["Orgrim's Hammer"] = "ì¤ê·¸ë¦¼ì ë§ì¹í¸", |
["Ormorok the Tree-Shaper"] = "ì ìì¬ ì¤ë¥´ëª¨ë¡í¬", |
["Oro Eyegouge"] = "ì¤ë¡ ìì´ê°ì°ì§", |
["Ossirian the Unscarred"] = "무ì ì ì¤ì리ì", |
Ouro = "ìì°ë¡", |
["Overlord Ramtusk"] = "ë군주 ë¨í°ì¤í¬", |
["Overlord Wyrmthalak"] = "ë군주 ìíë¼í¬", |
["Overmaster Pyron"] = "멸ë§ì íì´ë¡ ", |
["Overseer Tidewrath"] = "ì°ë머리 ì±ëíë", |
Pandemonius = "í¬ë모ëì°ì¤", |
["Panzor the Invincible"] = "무ì ì íì ", |
Patchwerk = "í¨ì¹ìí¬", |
["Pathaleon the Calculator"] = "ì² ëì² ë¯¸í íí리ì¨", |
Phalanx = "íëì¤", |
["Phaseshift Bulwark"] = "ìì ë³íì 보루방í¨", |
Pimgib = "í기ë¸", |
["Plaguemaw the Rotting"] = "ì©ì´ê°ë ìë³ìê·", |
["Plugger Spazzring"] = "íë¬ê±°ì¤íì¦ë§", |
["Postmaster Malown"] = "ì°ì²´êµì¥ ë§ë¡ì´", |
["Priestess Delrissa"] = "ì¬ì¬ì ë¸ë¦¬ì¬", |
["Prince Keleseth"] = "ê³µì ì¼ë ì¸ì¤", |
["Prince Malchezaar"] = "ê³µì ë§ì²´ì르", |
["Prince Skaldrenox"] = "ìì ì¤ì¹¼ë ë ¹ì¤", |
["Princess Huhuran"] = "공주 ííë", |
["Princess Moira Bronzebeard"] = "공주 모ì´ë¼ ë¸ë¡ ì¦ë¹ì´ë", |
["Princess Tempestria"] = "공주 í íì¤í¸ë¦¬ì", |
["Princess Theradras"] = "공주 í ë¼ëë¼ì¤", |
["Princess Yauj"] = "공주 ì¼ì°ì¦", |
["Prince Taldaram"] = "ê³µì íë¤ë", |
["Prince Tenris Mirkblood"] = "ê³µì í ë¦¬ì¤ ë¨¸í¬ë¸ë¬ë", |
["Prince Tortheldrin"] = "ìì í 르í ë린", |
["Prince Valanar"] = "ê³µì ë°ë¼ë르", |
["Professor Putricide"] = "êµì í¨í¸ë¦¬ì¬ì´ë", |
["Pure Spawn of Hydross"] = "ììí íëë¡ì¤ì í¼ì¡°ë¬¼", |
Pusillin = "í¸ì¤ë¦°", |
["Pyroguard Emberseer"] = "ë¶ì ìí¸ì ì ë²ìì´", |
["Pyromancer Loregrain"] = "íì¼ì ì¬ ë¡ì´ê·¸ë ì¸", |
Quagmirran = "ì¿ ì그미ë", |
["Quartermaster Zigris"] = "ë³ì°¸ì¥êµ ì§ê·¸ë¦¬ì¤", |
["Rage Winterchill"] = "ê²©ë ¸í ìí°ì¹ ", |
Ragglesnout = "ëë주ë¥ì´", |
["Raging Spirit"] = "ë¶ë ¸í ìí¼", |
Ragnaros = "ë¼ê·¸ëë¡ì¤", |
["Ramstein the Gorger"] = "먹보 ëì¤íì¸", |
["Ras Frostwhisper"] = "ë¼ì¤ íë¡ì¤í¸ìì¤í¼", |
Rattlegore = "ë¤ì°½ì´ê¸ë", |
["Razorclaw the Butcher"] = "ëì´ì ì¹¼ë ë°í±", |
["Razorgore the Untamed"] = "íêµ° ìì¬ì¡ê³³ë", |
Razorlash = "ì¹¼ë ì±ì°", |
Razorscale = "ì¹¼ë ë¹ë", |
["Reliquary of Souls"] = "ìí¼ì ì±ë¬¼í¨", |
Renataki = "ë ëíí¤", |
["Restless Skeleton"] = "ì 못 ëë í´ê³¨", |
Rethilgore = "ë ì¤ê³ ì´", |
Revelosh = "ë 벨ë¡ì¬", |
["Rhahk'Zor"] = "ë¼í¬ì¡°ë¥´", |
["Ribbly Screwspigot"] = "리ë¸ë¦¬ ì¤í¬ë¥ì¤í¼ê³³", |
["Right Arm"] = "ì¤ë¥¸í", |
Roar = "ì´í¥ì´", |
["Rokad the Ravager"] = "íê´´ì ë¡ì¹´ë", |
["Rokdar the Sundered Lord"] = "íê´´ì 군주 ë¡í¬ë¤ë¥´", |
["Rokmar the Crackler"] = "ë±ë±ì´ ë¡í¬ë§ë¥´", |
Romulo = "ë¡ë°ë¡", |
["Romulo & Julianne"] = "ë¡ë°ë¡ & ì¤ë¦¬ì", |
Rotface = "ì©ìì¼êµ´", |
Rotgrip = "ì©ì ìê·", |
["Runemaster Molgeim"] = "룬ì ì¬ ëª°ê°ì", |
["Runok Wildmane"] = "ë£¨ë ¸í¬ ìì¼ëë©ì¸", |
Ruuzlu = "루ì¦ë£¨", |
["Salramm the Fleshcrafter"] = "ì´ë©ì´ì°½ì¡°ì ì´ë", |
["Sanctum Sentry"] = "ì±ìì íìê¾¼", |
["Sandarr Dunereaver"] = "ì°ë¤ë¥´ ë리ë²", |
["Sandfury Executioner"] = "ì±ë모ëë¶ì¡± ì¬íì§íì¸", |
Sapphiron = "ì¬í¼ë¡ ", |
Sara = "ì¬ë¼", |
["Saronite Animus"] = "ì¬ë¡ëì´í¸ ìí¼", |
Sartharion = "ì´í리ì¨", |
["Sathrovarr the Corruptor"] = "íë½ì ì¬ì¤ë¡ë°ë¥´", |
["Saviana Ragefire"] = "ì¬ë¹ìë ë ì´ì§íì´ì´", |
["Scarlet Commander Mograine"] = "ë¶ìììêµ° ì¬ë ¹ê´ 모그ë ì¸", |
["Scourgelord Tyrannus"] = "ì¤ì»¬ì§êµ°ì£¼ í°ë¼ëì¤", |
["Seeth'rel"] = "ë¶ìì 문ì§ê¸°", |
["Selin Fireheart"] = "ì 린 íì´ì´íí¸", |
["Sergeant Bly"] = "íì¬ê´ ë¸ë¼ì´", |
["Shade of Akama"] = "ìì¹´ë§ì ë§ë ¹", |
["Shade of Aran"] = "ìëì ë§ë ¹", |
["Shade of Eranikus"] = "ìë¼ëì¿ ì¤ì ì¬ë ¹", |
["Shadikith the Glider"] = "íê°ì ì¤ëí¤ì¤", |
["Shadow Hunter Vosh'gajin"] = "ì´ë ì¬ë¥ê¾¼ ë³´ì¬ê°ì§", |
["Shadow of Leotheras"] = "ë ì¤í ë¼ì¤ì 그림ì", |
["Shadowpriest Sezz'ziz"] = "ì´ë ìì¬ì ì¸ì¦ì§ì¦", |
Shadron = "ì¤ëë¡ ", |
Shazzrah = "ì¤ì¦ë¼", |
["Shirrak the Dead Watcher"] = "죽ìì ê°ìì¸ ì´ë¼í¬", |
Sindragosa = "ì ëë¼ê³ ì¬", |
["Sir Zeliek"] = "ì ¤ë¦¬ìí¬ ê²½", |
["Sjonnir The Ironshaper"] = "무ì 구체ì ì¼ë르", |
["Skadi the Ruthless"] = "íì´ì ì¤ì¹´ë", |
["Skarr the Unbreakable"] = "무ì ì ì¤ì¹´ë¥´", |
["Skarvald the Constructor"] = "ê±´ì¶ê° ì¤ì¹´ë°ë", |
["Skra'gath"] = "ì¤í¬ë¼ê°ì¤", |
Skul = "ì¤ì»¬", |
Skum = "ì¤ì»´", |
["Slad'ran"] = "ì¬ë¼ëë", |
Sneed = "ì¤ëë", |
["Sneed's Shredder"] = "ì¤ëëì ë²ëª©ê¸°", |
["Solakar Flamewreath"] = "íì¼ê³ 리 ìë¼ì¹´ë¥´", |
["Solarium Agent"] = "íìì ì ë¹ ìì", |
["Solarium Priest"] = "íìì ì ë¹ ì¬ì ", |
["Spirestone Battle Lord"] = "뾰족ë°ìì¼ì¡± ì í¬ëì¥", |
["Spirestone Butcher"] = "뾰족ë°ìì¼ì¡± íì´ì", |
["Spirestone Lord Magus"] = "뾰족ë°ìì¼ì¡± ë§ë²ì¬ì¥", |
["Staff of Disintegration"] = "ì°ì£¼ ìëì§ ì£¼ì 기", |
Stalagg = "ì¤íë¼ê·¸", |
Steelbreaker = "ê°ì² íê´´ì", |
["Stomper Kreeg"] = "ì²ë¥ë° í¬ë¦¬ê·¸", |
Stonespine = "뾰족ë°ì", |
["Stormcaller Brundir"] = "ííìíì¬ ë¸ë£¬ë르", |
Strawman = "íììë¹", |
["Sulfuron Harbinger"] = "ì¤í¼ë¡ ì¬ì", |
Supremus = "ê¶ê·¹ì ì¬ì°", |
["Svala Sorrowgrave"] = "ì¤ë°ë¼ ìë¡ì°ê·¸ë ì´ë¸", |
["Swamplord Musel'ek"] = "ëªêµ°ì£¼ 뮤ì¦ë í¬", |
Taerar = "íìë¼", |
["Tainted Spawn of Hydross"] = "ì¤ì¼ë íëë¡ì¤ì í¼ì¡°ë¬¼", |
["Talon King Ikiss"] = "ê°í´ëì ì´í¤ì¤", |
["Taragaman the Hungerer"] = "ìë§ì íë¼ê°ë§", |
["Targorr the Dread"] = "íì ë² íê³ ë¥´", |
Tavarok = "íë°ë¡í¬", |
Techbot = "첨ë¨ë¡ë´", |
Temporus = "í í¼ë£¨ì¤", |
["Tendris Warpwood"] = "êµ½ì´ë무 í ë리ì¤", |
Tenebron = "í ë¤ë¸ë¡ ", |
["Terestian Illhoof"] = "í ë ì¤í°ì ì¼íí", |
["Teron Gorefiend"] = "í ë¡ ê³ ì´íë", |
Thaddius = "íëì°ì¤", |
["Thaladred the Darkener"] = "ìíì ì¸ëì íë¼ëë ë", |
["Thane Korth'azz"] = "ì주 ì½ì¤ìì¦", |
["The Beast"] = "ê´´ì", |
["The Beasts of Northrend"] = "ë ¸ì¤ë ëì ì¼ì", |
["The Big Bad Wolf"] = "커ë¤ë ëì ëë", |
["The Black Knight"] = "í기ì¬", |
["The Black Stalker"] = "ê²ì ì¶ì ì", |
["The Blue Brothers"] = "í¸ë¥¸ íì ë¤", |
["The Bug Family"] = "ë²ë 무리", |
["The Crone"] = "ë§ë ", |
["The Curator"] = "ì ì ê´ë¦¬ì¸", |
["The Eredar Twins"] = "ìë ë¤ë¥´ ìë¥ì´", |
["The Four Horsemen"] = "4ì¸ì 기ë³ë", |
["The Illidari Council"] = "ì¼ë¦¬ë¤ë¦¬ ìí", |
["The Iron Council"] = "무ì íìí", |
["Theka the Martyr"] = "ìêµì ë°ì¹´", |
["The Lich King"] = "ë¦¬ì¹ ì", |
["The Lurker Below"] = "ì¬ì°ì ì 복꾼", |
["The Maker"] = "ì¬ìì 창조ì", |
["The Prophet Skeram"] = "ìì¸ì ì¤ì¼ë", |
["The Prophet Tharon'ja"] = "ìì¸ì íë¡ ì", |
["The Ravenian"] = "ë¼ë² ëì", |
["The Razza"] = "ë¼ì", |
["The Seven Dwarves"] = "The Seven Dwarves", -- Needs review |
["The Skybreaker"] = "íëíê´´ìí¸", |
["The Tribunal of Ages"] = "ìëì ì¬íì¥", |
["The Twin Emperors"] = "ìë¥ì´ ì ì", |
["The Twin Val'kyr"] = "ë°í¤ë¥´ ìë¥ì´", |
["The Unforgiven"] = "ì©ìë°ì§ 못í ì", |
["The Windreaver"] = "ì¹¼ë ë°ë", |
Thorim = "í 림", |
["Thorngrin the Tender"] = "ê°ìì¸ ì그린", |
["Tidewalker Lurker"] = "ê² ë¥íë ì 복꾼", |
["Timmy the Cruel"] = "ìí¹í í°ë¯¸", |
Tinhead = "ìì² ë무꾼", |
["Tinkerer Gizlock"] = "ëì¥ì´ 기ì¦ë¡", |
["Tirion Fordring"] = "í°ë¦¬ì¨ í´ëë§", |
Tito = "í°í ", |
["Toravon the Ice Watcher"] = "ì¼ì ê°ìì í ë¼ë³¸", |
["Trigore the Lasher"] = "ì±ì°ê¼¬ë¦¬ í¸ë¦¬ê³ ì´", |
Trollgore = "ì¡ê³³ìê·", |
["Tsu'zee"] = "ì¸ì§", |
["Tuten'kash"] = "í¬í ì¹´ì¬", |
["Twilight Lord Kelris"] = "í©í¼ì 군주 ì¼ë¦¬ì¤", |
["Urok Doomhowl"] = "ì°ë¥´í¬ ë íì¸", |
["Vaelastrasz the Corrupt"] = "íë½í ë°¸ë¼ì¤í¸ë¼ì¦", |
["Valithria Dreamwalker"] = "ë°ë¦¬ì¤ë¦¬ì ë림ì커", |
["Val'kyr Shadowguard"] = "ë°í¤ë¥´ ì´ë ìí¸ë³", |
["Varian Wrynn"] = "ë°ë¦¬ì 린", |
["Varos Cloudstrider"] = "ë°ë¡ì¤ í´ë¼ì°ëì¤í¸ë¼ì´ë", |
Vazruden = "ë°ì¦ë£¨ë´", |
["Vazruden the Herald"] = "ì¬ì ë°ì¦ë£¨ë´", |
Vectus = "벡í¬ì¤", |
Vem = "ë²°", |
Veng = "ë²µ", |
["Veras Darkshadow"] = "ë² ë¼ì¤ ë¤í¬ìë", |
["Verdan the Everliving"] = "ììì ë² ë¥´ë¨", |
Verek = "ë² ë í¬", |
Vesperon = "ë² ì¤íë¡ ", |
Vexallus = "벡ì´ë£¨ì¤", |
["Veyzhak the Cannibal"] = "ìì¸í¸ë¡¤ ë² ì´ì", |
["Vile'rel"] = "íë½ì 문ì§ê¸°", |
Viscidus = "ë¹ìëì°ì¤", |
["Viscous Fallout"] = "ë°©ì¬ì± í기물", |
["Void Reaver"] = "ê³µíì ì ë¨ê¸°", |
Volkhan = "볼칸", |
["VX-001"] = "VX-001", |
["Warbringer O'mrogg"] = "ë격ëì¥ ì¤ë¯ë¡ê·¸", |
["Warchief Blackhand Piece"] = "ëì¡±ì¥ ë¸ëí¸ë", |
["Warchief Kargath Bladefist"] = "ëì¡±ì¥ ì¹´ë¥´ê°ì¤ ë¸ë ì´ëí¼ì¤í¸", |
["Warchief Rend Blackhand"] = "ëì¡±ì¥ ë ë ë¸ëí¸ë", |
["Warden Mellichar"] = "êµëê´ ë©ë¦¬ì± 르", |
["Warder Stilgiss"] = "문ì§ê¸° ì¤í¸ê¸°ì¤", |
["Warlord Kalithresh"] = "ì¥êµ° 칼리ì¤ë ì¬", |
["War Master Voone"] = "ëì¥êµ° ë¶ë¤", |
["Warmaul Champion"] = "ì ìë§ì¹ì¼ì¡± ì©ì¬", |
["Warp Slicer"] = "ì°¨ìì ì ë¨ê¸°", |
["Warp Splinter"] = "ì°¨ìì ë¶ë¦¬ì", |
["Watchkeeper Gargolmar"] = "ê°ìì ê°ë¥´ê³¨ë§ë¥´", |
Weaver = "ìë²", |
["Witch Doctor Zum'rah"] = "ìì ì¬ ì¤ë¼", |
["Wolf Master Nandos"] = "ëëì ëëì¤", |
["Wrath-Scryer Soccothrates"] = "ê²©ë ¸ì ì ì ì¬ ìì½ëë¼í ì¤", |
Wushoolay = "ì°ì¬ë ì´", |
Xevozz = "ì ë³´ì¦", |
["XT-002 Deconstructor"] = "XT-002 í´ì²´ì", |
["Yogg-Saron"] = "ìê·¸ì¬ë¡ ", |
Ysondre = "ì´ìëë ", |
Zekkis = "ì í¤ì¤", |
["Zelemar the Wrathful"] = "ì§ë ¸ì ì ¤ë ë§ë¥´", |
["Zereketh the Unbound"] = "ìë°ì´ í린 ì ë ì¼ì¤", |
Zerillis = "ì 릴리ì¤", |
["Zevrim Thornhoof"] = "ì ë¸ë¦¼ ìíí", |
Zolo = "졸ë¡", |
["Zul'Farrak Dead Hero"] = "ì¤íë½ ì£½ìì ìì ", |
["Zul'jin"] = "ì¤ì§", |
["Zul'Lor"] = "ì¤ë¡", |
["Zul'tore"] = "ì¤í ì´", |
["Zuramat the Obliterator"] = "í멸ì 주ë¼ë§í¸", |
} |
elseif GAME_LOCALE == "esES" then |
lib:SetCurrentTranslations { |
Acidmaw = "Fauceácida", |
Aeonus = "Aeonus", |
["Aerial Command Unit"] = "Unidad de mando aérea", |
["Agathelos the Raging"] = "Agathelos el Furioso", |
Ahune = "Ahune", |
["Akil'zon"] = "Akil'zon", |
["Aku'mai"] = "Aku'mai", |
["Al'ar"] = "Al'ar", |
["Algalon the Observer"] = "Algalon el Observador", |
["Alzzin the Wildshaper"] = "Alzzin el Formaferal", |
Amanitar = "Amanitar", |
["Ambassador Flamelash"] = "Embajador Latifuego", |
["Ambassador Hellmaw"] = "Embajador Faucinferno", |
["Amnennar the Coldbringer"] = "Amnennar el Gélido", |
["Ancient Stone Keeper"] = "Vigilante pétreo anciano", |
Anetheron = "Anetheron", |
["Anger'rel"] = "Anger'rel", |
Anomalus = "Anomalus", |
["Antu'sul"] = "Antu'sul", |
["Anub'arak"] = "Anub'arak", |
["Anubisath Defender"] = "Defensor Anubisath", |
["Anubisath Guardian"] = "Guardián Anubisath", |
["Anub'Rekhan"] = "Anub'Rekhan", |
["Anub'shiah"] = "Anub'shiah", |
Anzu = "Anzu", |
["Arcane Watchman"] = "Vigilante Arcano", |
["Arcanist Doan"] = "Arcanista Doan", |
Archaedas = "Archaedas", |
["Archavon the Stone Watcher"] = "Archavon el VigÃa de piedra", |
Archimonde = "Archimonde", |
["Archivist Galford"] = "Archivista Galford", |
["Archmage Arugal"] = "Archimago Arugal", |
["Argent Confessor Paletress"] = "Confesora Argenta Cabelloclaro", |
["Arugal's Voidwalker"] = "Abisario de Arugal", |
["Assault Bot"] = "Robot de asalto", |
["Atal'alarion"] = "Atal'alarion", |
["Attumen the Huntsman"] = "Attumen el Montero", |
Auriaya = "Auriaya", |
Avalanchion = "Avalanchion", |
["Avatar of Hakkar"] = "Avatar de Hakkar", |
["Ayamiss the Hunter"] = "Ayamiss el Cazador", |
Azgalor = "Azgalor", |
["Azshir the Sleepless"] = "Azshir el Insomne", |
Azuregos = "Azuregos", |
["Bael'Gar"] = "Bael'Gar", |
Baelog = "Baelog", |
Balnazzar = "Balnazzar", |
-- ["Baltharus the Warborn"] = "", |
["Bannok Grimaxe"] = "Bannok Hachamacabra", |
["Baron Aquanis"] = "Barón Aquanis", |
["Baron Charr"] = "Barón Charr", |
["Baroness Anastari"] = "Baronesa Anastari", |
["Baron Geddon"] = "Barón Geddon", |
["Baron Kazum"] = "Barón Kazum", |
["Baron Rivendare"] = "Barón Rivendare", |
["Baron Silverlaine"] = "Barón Filargenta", |
["Battleguard Sartura"] = "Guardia de batalla Sartura", |
["Bazil Thredd"] = "Bazil Thredd", |
Bazzalan = "Bazzalan", |
["Black Guard Swordsmith"] = "Armero Guardia Negra", |
["Blackheart the Inciter"] = "Negrozón el Incitador", |
["Blindeye the Seer"] = "Ciego el Vidente", |
["Blind Hunter"] = "Cazador ciego", |
["Blood Guard Porung"] = "Guardia de sangre Porung", |
["Bloodlord Mandokir"] = "Señor sangriento Mandokir", |
["Bloodmage Thalnos"] = "Mago sangriento Thalnos", |
["Blood Prince Council"] = "Blood Prince Council", -- Needs review |
["Blood Princes"] = "PrÃncipes de sangre", -- Needs review |
["Blood-Queen Lana'thel"] = "Reina de sangre Lanaâthel", |
["Blood Steward of Kirtonos"] = "Administrador de sangre de Kirtonos", |
Boahn = "Boahn", |
["Bomb Bot"] = "Robot bum", |
["Brain of Yogg-Saron"] = "Cerebro de Yogg-Saron", |
["Brainwashed Noble"] = "Noble aducido", |
Broggok = "Broggok", |
Brokentoe = "Dedorroto", |
Bronjahm = "Bronjahm", |
["Broodlord Lashlayer"] = "Señor de prole Capazote", |
["Bruegal Ironknuckle"] = "Bruegal Nudoferro", |
Brutallus = "Brutallus", |
["Burning Felguard"] = "Guarda vil ardiente", |
["Buru the Gorger"] = "Buru el Manducador", |
["Cache of the Firelord"] = "BotÃn del Señor del Fuego", |
["Cannon Master Willey"] = "Cañonero Jefe Willey", |
["Captain Greenskin"] = "Capitán Verdepel", |
["Captain Kromcrush"] = "Capitán Kromcrush", |
["Captain Skarloc"] = "Capitán Skarloc", |
["Celebras the Cursed"] = "Celebras el Maldito", |
["Charlga Razorflank"] = "Charlga Filonavaja", |
["Chess Event"] = "Evento de ajedrez", |
["Chest of The Seven"] = "Tesoro de los Siete", |
["Chief Ukorz Sandscalp"] = "Jefe Ukorz Cabellarena", |
["Cho'Rush the Observer"] = "Cho'Rush el Observador", |
Chromaggus = "Chromaggus", |
["Chrono Lord Deja"] = "Cronolord Deja", |
["Chrono-Lord Epoch"] = "Chrono-Lord Epoch", |
Claw = "Zarpa", |
["Coilfang Elite"] = "Elite Colimillo Torcido", |
["Coilfang Strider"] = "Zancudo Colmillo Torcido", |
["Commander Kolurg"] = "Comandante Kolurg", |
["Commander Sarannis"] = "Comandante Sarannis", |
["Commander Springvale"] = "Comandante Vallefont", |
["Commander Stoutbeard"] = "Comandante Barbarrecia", |
["Constructor & Controller"] = "Constructor y Controlador", |
Cookie = "El Chef", |
["Coren Direbrew"] = "Coren Cerveza Temible", |
["Cosmic Infuser"] = "Infusor cósmico", |
["Crimson Hammersmith"] = "Forjamartillos CarmesÃ", |
["Crowd Pummeler 9-60"] = "Gopleamasa 9-60", |
["Crystal Fang"] = "Colmillor de cristal", |
["C'Thun"] = "C'Thun", |
Cyanigosa = "Cyanigosa", |
["Dalliah the Doomsayer"] = "Dalliah la Decidora del Destino", |
["Dalronn the Controller"] = "Dalronn el Controlador", |
["Dark Iron Ambassador"] = "Embajador Hierro Negro", |
["Darkmaster Gandling"] = "Maestro oscuro Gandling", |
["Darkweaver Syth"] = "Tejeoscuro Syth", |
-- ["Deathbound Ward"] = "", |
["Deathbringer Saurfang"] = "Lamorte Saurfang", |
["Death Knight Darkreaver"] = "Caballero de la Muerte Atracoscuro", |
["Death Knight Understudy"] = "Suplente Caballero de la Muerte", |
-- ["Deathspeaker High Priest"] = "", |
["Death Speaker Jargba"] = "Médium Jargba", |
["Deathstalker Visceri"] = "Mortacechador Visceri", |
["Deathsworn Captain"] = "Capitán Juramorte", |
Devastation = "Devastación", |
["Deviate Faerie Dragon"] = "Dragón férico descarriado", |
["Devourer of Souls"] = "Devoradora de almas", |
["Dextren Ward"] = "Dextren Tutor", |
["Digmaster Shovelphlange"] = "Maestro de excavación Palatiro", |
["Doctor Theolen Krastinov"] = "Doctor Theolen Krastinov", |
["Doom Lord Kazzak"] = "Señor ApocalÃptico Kazzak", |
["Doom'rel"] = "Doom'rel", |
Doomwalker = "Caminante del Destino", |
["Dope'rel"] = "Dope'rel", |
Dorothee = "Dorothea", |
["Drakkari Colossus"] = "Coloso Drakkari", |
["Drakos the Interrogator"] = "Drakos el interrogador", |
Dreadscale = "Aterraescama", |
Dreamscythe = "Guadañasueños", |
["Dust Covered Chest"] = "Cofre cubierto de polvo", |
Dustwraith = "Ãnima de polvo", |
["Eadric the Pure"] = "Eadric el Puro", |
["Earthcaller Halmgar"] = "Clamor de Tierra Halmgar", |
Ebonroc = "Ebonroc", |
["Eck the Ferocious"] = "Eck the Ferocious", |
["Edwin VanCleef"] = "Edwin VanCleef", |
["Elder Brightleaf"] = "Ancestro Hojabrillante", |
["Elder Ironbranch"] = "Ancestro Hierrorrama", |
["Elder Nadox"] = "Ancestro Nadox", |
["Elder Stonebark"] = "Ancestro Cortezapiedra", |
["Electrocutioner 6000"] = "Electrocutor 6000", |
["Emalon the Storm Watcher"] = "Emalon el VigÃa de la Tormenta", |
Emeriss = "Emeriss", |
["Emperor Dagran Thaurissan"] = "Emperador Dagran Thaurissan", |
["Emperor Vek'lor"] = "Emperador Vek'lor", |
["Emperor Vek'nilash"] = "Emperador Vek'nilash", |
Entropius = "Entropius", |
["Eonar's Gift"] = "Don de Eonar", |
["Epoch Hunter"] = "Cazador de eras", |
Erekem = "Erekem", |
["Eressea Dawnsinger"] = "Eressea Cantoalba", |
["Essence of Anger"] = "Esencia de Cólera", |
["Essence of Desire"] = "Esencia de Deseo", |
["Essence of Suffering"] = "Esencia de Sufrimiento", |
Eviscerator = "Eviscerador", |
["Exarch Maladaar"] = "Exarca Maladaar", |
["Expedition Commander"] = "Comandante de expedición", |
["Eydis Darkbane"] = "Eydis Penaumbra", |
["Eye of C'Thun"] = "Ojo de C'Thun", |
["Faction Champions"] = "Campeones de la facción", |
["Fallen Champion"] = "Campeón caÃdo", |
Falric = "Falric", |
["Falric and Marwyn"] = "Falric and Marwyn", -- Needs review |
["Fankriss the Unyielding"] = "Fankriss el Implacable", |
["Fathom-Lord Karathress"] = "Señor de la profundidades Karathress", |
Felmyst = "Brumavil", |
["Fenrus the Devourer"] = "Fenrus el Devorador", |
["Feral Defender"] = "Defensor feral", |
Festergut = "Panzachancro", |
Feugen = "Feugen", |
["Fineous Darkvire"] = "Finoso Virunegro", |
Firemaw = "Faucefogo", |
["Fjola Lightbane"] = "Fjola PenÃvea", |
Flamegor = "Flamagor", |
["Flame Leviathan"] = "Leviatán de llamas", |
["Foreman Thistlenettle"] = "Supervisor Cardortiga", |
["Forgemaster Garfrost"] = "Maestro de forja Gargelus", |
["Four Horsemen Chest"] = "Cofre de los Cuatro Jinetes", |
["Fras Siabi"] = "Fras Siabi", |
Freya = "Freya", |
["Gahz'ranka"] = "Gahz'ranka", |
["Gahz'rilla"] = "Gahz'rilla", |
["Gal'darah"] = "Gal'darah", |
["Galgann Firehammer"] = "Galgann Flamartillo", |
Garr = "Garr", |
["Garrosh Hellscream"] = "Garrosh Grito Infernal", |
Gasher = "Gasher", |
["Gatewatcher Gyro-Kill"] = "VÃgia de las puertas Giromata", |
["Gatewatcher Iron-Hand"] = "VigÃa de las puertas Manoyerro", |
["Gathios the Shatterer"] = "Gathios the Shatterer", |
Gehennas = "Gehennas", |
Gelihast = "Gelihast", |
Gelk = "Gelk", |
["General Angerforge"] = "General Forjira", |
["General Bjarngrim"] = "General Bjarngrim", |
["General Drakkisath"] = "General Drakkisath", |
["General Rajaxx"] = "General Rajaxx", |
["General Vezax"] = "General Vezax", |
-- ["General Zarithrian"] = "", |
["Ghamoo-ra"] = "Ghamoo-ra", |
["Ghaz'an"] = "Ghaz'an", |
["Ghok Bashguud"] = "Ghok Bashguud", |
Gilnid = "Gilnid", |
["Gizrul the Slavener"] = "Gizrul el Esclavista", |
["Gloom'rel"] = "Gloom'rel", |
Gluth = "Gluth", |
Glutton = "Glotón", |
["Golemagg the Incinerator"] = "Golemagg el Incinerador", |
["Golem Lord Argelmach"] = "Señor Golem Argelmach", |
["Goraluk Anvilcrack"] = "Goraluk Yunquegrieta", |
["Gormok the Impaler"] = "Gormok el Empalador", |
["Gorosh the Dervish"] = "Gorosh el Endemoniado", |
["Gortok Palehoof"] = "Gortok Pezuña Pálida", |
["Gothik the Harvester"] = "Gothik el Cosechador", |
["Grand Astromancer Capernian"] = "Gran astromántica Capernian", |
["Grand Champions"] = "Grandes campeones", |
["Grand Magus Telestra"] = "Gran maga Telestra", |
["Grandmaster Vorpil"] = "Maestro mayor Vorpil", |
Grandmother = "Abuela", |
["Grand Warlock Alythess"] = "Bruja suprema Alythess", |
["Grand Warlock Nethekurse"] = "Brujo supremo Malbisal", |
["Grand Widow Faerlina"] = "Gran Viuda Faerlina", |
["Grethok the Controller"] = "Grethok el Controlador", |
["Gri'lek"] = "Gri'lek", |
Grimlok = "Grimlok", |
Grizzle = "\009Grisez", |
Grobbulus = "Grobbulus", |
Grubbis = "Grubbis", |
["Gruul the Dragonkiller"] = "Gruul el Asesino de Dragones", |
["Guard Fengus"] = "Guardia Fengus", |
["Guardian of Yogg-Saron"] = "Guardián de Yogg-Saron", |
["Guard Mol'dar"] = "Guardia Mol'dar", |
["Guard Slip'kik"] = "Guardia Slip'kik", |
["Gurtogg Bloodboil"] = "Gurtogg Sangre Hirviente", |
Gyth = "Gyth", |
Hadronox = "Hadronox", |
Hakkar = "Hakkar", |
Halazzi = "Halazzi", |
-- Halion = "", |
Halycon = "Halycon", |
Hamhock = "Hamhock", |
["Harbinger Skyriss"] = "Presagista Cieloriss", |
["Hate'rel"] = "Odio'rel", |
["Hazza'rah"] = "Hazza'rah", |
Hazzas = "Hazzas", |
["Headless Horseman"] = "Cofre de los Cuatro Jinetes", |
["Hearthsinger Forresten"] = "Escupezones Foreste", |
["Hedrum the Creeper"] = "Hedrum el Trepador", |
["Heigan the Unclean"] = "Heigan el Impuro", |
["Hellfire Channeler"] = "Canalizador Fuego Infernal", |
["Henry Stern"] = "Henry Stern", |
["Herald Volazj"] = "Heraldo Volazj", |
Herod = "Herod", |
["Hex Lord Malacrass"] = "Señor aojador Malacrass", |
["High Astromancer Solarian"] = "Gran astromántica Solarian", |
["High Botanist Freywinn"] = "Gran botánico Freywinn", |
["High Inquisitor Fairbanks"] = "Alto Inquisidor Ribalimpia", |
["High Inquisitor Whitemane"] = "Alta Inquisidora Melenablanca", |
["High Interrogator Gerstahn"] = "Alto Interrogador Gerstahn", |
["High King Maulgar"] = "Su majestad Maulgar", |
["Highlord Mograine"] = "Alto Señor Mograine", |
["Highlord Omokk"] = "Alto Señor Omokk", |
["High Marshal Whirlaxis"] = "High Marshal Whirlaxis", |
["High Nethermancer Zerevor"] = "High Nethermancer Zerevor", |
["High Overlord Saurfang"] = "Alto señor supremo Colmillosauro", |
["High Priestess Arlokk"] = "Suma Sacerdotisa Arlokk", |
["High Priestess Jeklik"] = "Suma Sacerdotisa Jeklik", |
["High Priestess Mar'li"] = "Suma Sacerdotisa Mar'li", |
["High Priestess of Thaurissan"] = "Alta Sacerdotisa de Thaurissan", |
["High Priest Thekal"] = "Sumo Sacerdote Thekal", |
["High Priest Venoxis"] = "Sumo Sacerdote Venoxis", |
["High Warlord Naj'entus"] = "Gran Señor de la Guerra Naj'entus", |
Hodir = "Hodir", |
["Houndmaster Grebmar"] = "Maestro de canes Grebmar", |
["Houndmaster Loksey"] = "Maestro de canes Loksey", |
Hukku = "Hukku", |
Hungarfen = "Panthambre", |
["Hurley Blackbreath"] = "Hurley Negrálito", |
["Hyakiss the Lurker"] = "Hyakiss el Rondador", |
["Hydromancer Thespia"] = "Hidromántico Thespia", |
["Hydromancer Velratha"] = "Hidromántica Velratha", |
Hydrospawn = "Hidromilecio", |
["Hydross the Unstable"] = "Hydross el Inestable", |
["Icecrown Gunship Battle"] = "Batalla aerea", -- Needs review |
Icehowl = "Aullahielo", |
["Ice Sphere"] = "Ice Sphere", -- Needs review |
Ichoron = "Icoron", |
Ick = "Ick", -- Needs review |
["Ignis the Furnace Master"] = "Ignis el Maestro de la Caldera", |
["Illidan Stormrage"] = "Illidan Tempestira", |
["Illidari Council"] = "Concilio Illidari", |
["Illyanna Ravenoak"] = "Illyanna Roblecuervo", |
["Immol'thar"] = "Immol'thar", |
["Infinite Corruptor"] = "Corruptor Infinito", |
["Infinity Blades"] = "Hojas de infinidad", |
["Ingvar the Plunderer"] = "Ingvar the Plunderer", |
["Instructor Malicia"] = "Instructor Malicia", |
["Instructor Razuvious"] = "Instructor Razuvious", |
["Interrogator Vishas"] = "Interrogador Vishas", |
Ionar = "Ionar", |
Ironaya = "Hierraya", |
Ironspine = "Dorsacerado", |
Isalien = "Isalien", |
Jade = "Jade", |
["Jammal'an the Prophet"] = "Jammal'an el Profeta", |
["Jan'alai"] = "Jan'alai", |
["Jandice Barov"] = "Jandice Barov", |
["Jedoga Shadowseeker"] = "Jedoga Buscasombras", |
["Jed Runewatcher"] = "Jed vigÃa de las runas", |
["Jergosh the Invoker"] = "Jergosh el Convocador", |
["Jin'do the Hexxer"] = "Jin'do el Aojador", |
["Jormungar Behemoth"] = "Behemoth Jormungar", |
Jormungars = "jormungar", |
Julianne = "Julianne", |
["Junk Bot"] = "Chatarrobot", |
["Kael'thas Sunstrider"] = "Kael'thas Caminante del Sol", |
Kalecgos = "Kalecgos", |
["Kam Deepfury"] = "Kam Furiahonda", |
["Kazkaz the Unholy"] = "Kazkaz el Blasfemo", |
["Kaz'rogal"] = "Kaz'rogal", |
["Keli'dan the Breaker"] = "Keli'dan el Ultrajador", |
["Kel'Thuzad"] = "Kel'Thuzad", |
Keristrasza = "Keristrasza", |
["Kiggler the Crazed"] = "Kiggler el Enloquecido", |
["Kil'jaeden"] = "Kil'jaeden", |
["Kil'rek"] = "Kil'rek", |
["King Dred"] = "Rey Dred", |
["King Gordok"] = "Rey Gordok", |
["King Llane Piece"] = "Rey Llane", |
["King Ymiron"] = "Rey Ymiron", |
["Kirtonos the Herald"] = "Kirtonos el Heraldo", |
["Knot Thimblejack's Cache"] = "Carretilla de Knot Llavededo", |
Kolk = "Kolk", |
Kologarn = "Kologarn", |
["Koralon the Flame Watcher"] = "Koralon el VigÃa de las llamas", |
Kormok = "Kormok", |
Kresh = "Kresh", |
Krick = "Krick", -- Needs review |
["Krick and Ick"] = "Krick and Ick", -- Needs review |
["Krik'thir the Gatewatcher"] = "Krikâthir el vÃgia de las puertas", |
["Krosh Firehand"] = "Krosh Manofuego", |
Krystallus = "Krystallus", |
Kurinnaxx = "Kurinnaxx", |
["Lady Anacondra"] = "Lady Anacondra", |
["Lady Blaumeux"] = "Lady Blaumeux", |
["Lady Deathwhisper"] = "Lady Susurramuerte", |
["Lady Illucia Barov"] = "Lady Illucia Barov", |
["Lady Malande"] = "Lady Malande", |
["Lady Sacrolash"] = "Lady Sacrolash", |
["Lady Sarevess"] = "Lady Sarevess", |
["Lady Vashj"] = "Lady Vashj", |
Laj = "Laj", |
Landslide = "Derrumblo", |
Lavanthor = "Lavanthor", |
["Left Arm"] = "Brazo izquierdo", |
["Leotheras the Blind"] = "Leotheras el Ciego", |
Lethon = "Lethon", |
Lethtendris = "Lethtendris", |
["Leviathan Mk II"] = "Mk II de leviatán", |
["Ley-Guardian Eregos"] = "Guardian-Ley Eregos", |
["Lieutenant Drake"] = "Teniente Draco", |
["Lieutenant General Andorov"] = "Teniente General Andorov", |
Loatheb = "Loatheb", |
Loken = "Loken", |
["Lord Alexei Barov"] = "Lord Alexei Barov", |
["Lord Cobrahn"] = "Lord Cobrahn", |
["Lord Hel'nurath"] = "Lord Hel'nurath", |
["Lord Incendius"] = "Lord Incendius", |
["Lord Jaraxxus"] = "Lord Jaraxxus", |
["Lord Kazzak"] = "Lord Kazzak", |
["Lord Kri"] = "Lord Kri", |
["Lord Marrowgar"] = "Lord Tuétano", |
["Lord Pythas"] = "Lord Pythas", |
["Lord Roccor"] = "Lord Roccor", |
["Lord Sanguinar"] = "Lord Sanguinar", |
["Lord Serpentis"] = "Lord Serpentis", |
["Lord Skwol"] = "Lord Skwol", |
["Lord Valthalak"] = "Lord Valthalak", |
["Lord Victor Nefarius"] = "Lord VÃctor Nefarius", |
["Lord Vyletongue"] = "Lord Lenguavil", |
["Lorekeeper Polkelt"] = "Tradicionalista Polkelt", |
Loro = "Loro", |
Lucifron = "Lucifron", |
["Mad Magglish"] = "Magglish el Loco", |
Maexxna = "Maexxna", |
["Mage-Lord Urom"] = "Señor de la Magia Urom", |
["Magister Kalendris"] = "Magister Kalendris", |
["Magistrate Barthilas"] = "Magistrado Barthilas", |
Magmadar = "Magmadar", |
Magmus = "Magmus", |
Magra = "Magra", |
Magtheridon = "Magtheridon", |
["Maiden of Grief"] = "Doncella de Pena", |
["Maiden of Virtue"] = "Doncella de Virtud", |
["Majordomo Executus"] = "Mayordomo Executus", |
Malacrass = "Malacrass", |
["Maleki the Pallid"] = "Maleki el Pálido", |
["Mal'Ganis"] = "Mal'Ganis", |
Malygos = "Malygos", |
Maraudos = "Maraudos", |
["Marduk Blackpool"] = "Marduz Pozonegro", |
["Marisa du'Paige"] = "Marisa du'Paige", |
Marwyn = "Marwyn", |
["Master Engineer Telonicus"] = "Maestro Ingeriero Telonicus", |
["Maur Grimtotem"] = "Maur Tótem Siniestro", |
Meathook = "Meathook", |
["Mechano-Lord Capacitus"] = "Lord-mecano Capacitus", |
Medivh = "Medivh", |
["Mekgineer Steamrigger"] = "Mekigeniero Vaporino", |
["Mekgineer Thermaplugg"] = "Mekigeniero Termochufe", |
["Mennu the Betrayer"] = "Mennu el Traidor", |
["Meshlok the Harvester"] = "Meshlok el Cosechador", |
Midnight = "Medianoche", |
Mijan = "Mijar", |
Mimiron = "Mimiron", |
["Miner Johnson"] = "Minero Johnson", |
["Mistress of Pain"] = "Maestra de dolor", |
Moam = "Moam", |
Mogor = "Mogor", |
["Mokra the Skullcrusher"] = "Mokra el Trituracráneos", |
Moorabi = "Moorabi", |
Moragg = "Moragg", |
["Mordresh Fire Eye"] = "Mordresh Ojo de Fuego", |
["Mor Grayhoof"] = "Mor Grayhoof", |
Moroes = "Moroes", |
["Morogrim Tidewalker"] = "Morogrim Levantamareas", |
Morphaz = "Morphaz", |
["Mother Shahraz"] = "Madre Shahraz", |
["Mother Smolderweb"] = "Madre Telabrasada", |
["Mr. Smite"] = "Sr. Golpin", |
["Muradin Bronzebeard"] = "Muradin Barbabronce", |
["Murkblood Twin"] = "Gemelo Sangreoscura", |
["Murkblood Twins"] = "Gemelos Sangreoscura", |
Murmur = "Murmur", |
["Murta Grimgut"] = "Murta Tripuriosa", |
["M'uru"] = "M'uru", |
Mushgog = "Mushgog", |
["Mutanus the Devourer"] = "Mutanus el Devorador", |
Nalorakk = "Nalorakk", |
Nazan = "Nazan", |
Nefarian = "Nefarian", |
["Nekrum Gutchewer"] = "Nekrum Cometripas", |
["Nerub'enkan"] = "Nerub'enkan", |
["Nethermancer Sepethrea"] = "Abisálico Sepethrea", |
Netherspite = "Rencor abisal", |
["Netherstrand Longbow"] = "Arco largo de fibra abisal", |
["Nexus-Prince Shaffar"] = "PrÃncipe-nexo Shaffar", |
Nightbane = "Nocturno", |
["Noth the Plaguebringer"] = "Noth el Pesteador", |
["Novos the Summoner"] = "Novos el Invocador", |
Noxxion = "Noxxion", |
["Obsidian Sentinel"] = "Centinela Obsidiano", |
["Odo the Blindwatcher"] = "Odo el vigÃa ciego", |
["Ogom the Wretched"] = "Ogom el Desdichado", |
["Ok'thor the Breaker"] = "Ok'thor el Rompedor", |
["Old Serra'kis"] = "Viejo Serra'kis", |
["Olm the Summoner"] = "Olm el Invocador", |
["Omor the Unscarred"] = "Omor el Sinmarcas", |
Onyxia = "Onyxia", |
["Orgrim's Hammer"] = "Martillo de Orgrim", |
["Ormorok the Tree-Shaper"] = "Ormorok el cortador de árboles", |
["Oro Eyegouge"] = "Oro Bocojo ", |
["Ossirian the Unscarred"] = "Osirio el Sinmarcas", |
Ouro = "Ouro", |
["Overlord Ramtusk"] = "Señor Supremo Colmicarnero", |
["Overlord Wyrmthalak"] = "Señor Supremo Vermiothalak", |
["Overmaster Pyron"] = "Gran maestro Pyron", |
["Overseer Tidewrath"] = "Avizor Aleta de Cólera", |
Pandemonius = "Pandemonius", |
["Panzor the Invincible"] = "Panzor el Invencible", |
Patchwerk = "Remendejo", |
["Pathaleon the Calculator"] = "Panthaleon el Calculador", |
Phalanx = "Falange", |
["Phaseshift Bulwark"] = "Baluarte de cambio de fase", |
Pimgib = "Pimgib", |
["Plaguemaw the Rotting"] = "Fauzpeste el Putrefacto", |
["Plugger Spazzring"] = "Plugger Aropatoso", |
["Postmaster Malown"] = "Jefe de correos Malown", |
["Priestess Delrissa"] = "Sacerdotisa Delrissa", |
["Prince Keleseth"] = "PrÃncipe Keleseth", |
["Prince Malchezaar"] = "PrÃncipe Malchezaar", |
["Prince Skaldrenox"] = "PrÃncipe Skaldrenox", |
["Princess Huhuran"] = "Princesa Huhuran", |
["Princess Moira Bronzebeard"] = "Princesa Moira Barbabronce", |
["Princess Tempestria"] = "Princesa Tempestria", |
["Princess Theradras"] = "Princesa Theradras", |
["Princess Yauj"] = "Princesa Yauj", |
["Prince Taldaram"] = "PrÃncipe Taldaram", |
["Prince Tenris Mirkblood"] = "PrÃncipe Tenris Sangre Penumbra", |
["Prince Tortheldrin"] = "PrÃncipe Tortheldrin", |
["Prince Valanar"] = "PrÃncipe Valanar", |
["Professor Putricide"] = "Profesor Putricidio", |
["Pure Spawn of Hydross"] = "Engendro puro de Hydross", |
Pusillin = "PusillÃn", |
["Pyroguard Emberseer"] = "Piroguardián Brasadivino", |
["Pyromancer Loregrain"] = "Piromántico Cultugrano", |
Quagmirran = "Quagmirran", |
["Quartermaster Zigris"] = "Intendente Zigris", |
["Rage Winterchill"] = "Ira FrÃoinvierno", |
Ragglesnout = "Morrandrajos", |
["Raging Spirit"] = "Raging Spirit", -- Needs review |
Ragnaros = "Ragnaros", |
["Ramstein the Gorger"] = "Ramstein el Empachador", |
["Ras Frostwhisper"] = "Ras Levescarcha", |
Rattlegore = "Traquesangre", |
["Razorclaw the Butcher"] = "Zarpador el Carnicero", |
["Razorgore the Untamed"] = "Sangrevaja el Indomable", |
Razorlash = "Lativaja", |
Razorscale = "Tajoescama", |
["Reliquary of Souls"] = "Relicario de Almas", |
Renataki = "Renataki", |
["Restless Skeleton"] = "Esqueleto inquieto", |
Rethilgore = "Rethilgore", -- Needs review |
Revelosh = "Revelosh", |
["Rhahk'Zor"] = "Rhahk'Zor", |
["Ribbly Screwspigot"] = "Ribbly Llavenrosca", |
["Right Arm"] = "Brazo derecho", |
Roar = "Rugido", |
["Rokad the Ravager"] = "Rokad el Devastador", |
["Rokdar the Sundered Lord"] = "Rokdar el Señor Hendido", |
["Rokmar the Crackler"] = "Rokmar el Crujidor", |
Romulo = "Romulo", |
["Romulo & Julianne"] = "Romeo y Julieta", |
Rotface = "Carapútrea", |
Rotgrip = "Escamapodrida", |
["Runemaster Molgeim"] = "Maestro de runas Molgeim", |
["Runok Wildmane"] = "Runok FerocrÃn", |
Ruuzlu = "Ruuzlu", |
["Salramm the Fleshcrafter"] = "Salramm el Modelador de carne", |
["Sanctum Sentry"] = "Centinela del sagrario", |
["Sandarr Dunereaver"] = "Sandarr Asaltadunas", |
["Sandfury Executioner"] = "Ejecutor Furiarena", |
Sapphiron = "Sapphiron", |
Sara = "Sara", |
["Saronite Animus"] = "Animus de saronita", |
Sartharion = "Sartharion", |
["Sathrovarr the Corruptor"] = "Sathrovarr el Corruptor", |
-- ["Saviana Ragefire"] = "", |
["Scarlet Commander Mograine"] = "Comandante Escarlata Mograine", |
["Scourgelord Tyrannus"] = "Señor de la Plaga Tyrannus", |
["Seeth'rel"] = "Seeth'rel", |
["Selin Fireheart"] = "Selin Corazón de Fuego", |
["Sergeant Bly"] = "Sargento Bly", |
["Shade of Akama"] = "Sombra de Akama", |
["Shade of Aran"] = "Sombra de Aran", |
["Shade of Eranikus"] = "Sombra de Eranikus", |
["Shadikith the Glider"] = "Shadikith the Glider", |
["Shadow Hunter Vosh'gajin"] = "Cazador de las Sombras Vosh'gajin", |
["Shadow of Leotheras"] = "Sombra de Leotheras", |
["Shadowpriest Sezz'ziz"] = "Sacerdote oscuro Sezz'ziz", |
Shadron = "Shadron", |
Shazzrah = "Shazzrah", |
["Shirrak the Dead Watcher"] = "Shirrak el VigÃa de los Muertos", |
Sindragosa = "Sindragosa", |
["Sir Zeliek"] = "Sir Zeliek", |
["Sjonnir The Ironshaper"] = "Sjonnir el afilador", |
["Skadi the Ruthless"] = "Skadi el Despiadado", |
["Skarr the Unbreakable"] = "Skarr el Inquebrantable", |
["Skarvald the Constructor"] = "Skarvald el Constructor", |
["Skra'gath"] = "Skra'gath", |
Skul = "Skul", |
Skum = "Skum", |
["Slad'ran"] = "Slad'ran", |
Sneed = "Sneed", |
["Sneed's Shredder"] = "Machacador de Sneed", |
["Solakar Flamewreath"] = "Solakar Corona de Fuego", |
["Solarium Agent"] = "Agente Solarium", |
["Solarium Priest"] = "Sacerdote Solarium", |
["Spirestone Battle Lord"] = "Señor de batalla Cumbrerroca", |
["Spirestone Butcher"] = "Carnicero Cumbrerroca", |
["Spirestone Lord Magus"] = "Señor Magus Cumbrerroca", |
["Staff of Disintegration"] = "Bastón de desintegración", |
Stalagg = "Stalagg", |
Steelbreaker = "Rompeacero", |
["Stomper Kreeg"] = "Vapuleador Kreeg", |
Stonespine = "Pidrespina", |
["Stormcaller Brundir"] = "Clamatormentas Brundir", |
Strawman = "Espantapájaros", |
["Sulfuron Harbinger"] = "Sulfuron Presagista", |
Supremus = "Supremus", |
["Svala Sorrowgrave"] = "Svala Tumbapena", |
["Swamplord Musel'ek"] = "Señor del pantano Musel'ek", |
Taerar = "Taerar", |
["Tainted Spawn of Hydross"] = "Engendro de Hydross corrupto", |
["Talon King Ikiss"] = "Rey Garra Ikiss", |
["Taragaman the Hungerer"] = "Taragaman el Hambriento", |
["Targorr the Dread"] = "Targor el Pavoroso", |
Tavarok = "Tavarok", |
Techbot = "Tecnobot", |
Temporus = "Temporus", |
["Tendris Warpwood"] = "Tendris Madeguerra", |
Tenebron = "Tenebron", |
["Terestian Illhoof"] = "Terestian Pezuña Enferma", |
["Teron Gorefiend"] = "Teron Sanguino", |
Thaddius = "Thaddius", |
["Thaladred the Darkener"] = "Thaladred el Oscurecedor", |
["Thane Korth'azz"] = "Thane Korth'azz", |
["The Beast"] = "La Bestia", |
["The Beasts of Northrend"] = "Las bestias de Rasganorte", |
["The Big Bad Wolf"] = "El Gran Lobo Malvado", |
["The Black Knight"] = "El Caballero Negro", |
["The Black Stalker"] = "La acechadora negra", |
["The Blue Brothers"] = "Los Hermanos Azules", |
["The Bug Family"] = "La Familia Insecto", |
["The Crone"] = "La Vieja Bruja", |
["The Curator"] = "Curator", |
["The Eredar Twins"] = "Los Gemelos Eredar", |
["The Four Horsemen"] = "Los Cuatro Jinetes", |
["The Illidari Council"] = "El concilio Illidari", |
["The Iron Council"] = "La Asamblea de Hierro", |
["Theka the Martyr"] = "Theka la Mártir", |
["The Lich King"] = "El Rey Exánime", |
["The Lurker Below"] = "El Rondador de abajo", |
["The Maker"] = "El Hacedor", |
["The Prophet Skeram"] = "El profeta Skeram", |
["The Prophet Tharon'ja"] = "El Profeta Tharon'ja", |
["The Ravenian"] = "El Devorador", |
["The Razza"] = "El Razza", |
["The Seven Dwarves"] = "Los Siete Enanitos", |
["The Skybreaker"] = "El Rompecielos", |
["The Tribunal of Ages"] = "Cofre del Tribunal", |
["The Twin Emperors"] = "Los Emperadores Gemelos", |
["The Twin Val'kyr"] = "Gemelas Val'kyr", |
["The Unforgiven"] = "El Imperdonable", |
["The Windreaver"] = "El Atracavientos", |
Thorim = "Thorim", |
["Thorngrin the Tender"] = "Thorngrin el Tierno", |
["Tidewalker Lurker"] = "Rondador Levantamareas", |
["Timmy the Cruel"] = "Timmy el Cruel", |
Tinhead = "Cabezalata", |
["Tinkerer Gizlock"] = "Manitas Gizlock", |
["Tirion Fordring"] = "Tirion VadÃn", |
Tito = "Tito", |
["Toravon the Ice Watcher"] = "Toravon the Ice Watcher", -- Needs review |
["Trigore the Lasher"] = "Trigore el Azotador", |
Trollgore = "Cuernotroll", |
["Tsu'zee"] = "Tsu'zee", |
["Tuten'kash"] = "Tuten'kash", |
["Twilight Lord Kelris"] = "Señor Crepuscular Kelris", |
["Urok Doomhowl"] = "Urok Aullapocalipsis", |
["Vaelastrasz the Corrupt"] = "Vaelastrasz el Corrupto", |
["Valithria Dreamwalker"] = "Valithria Caminasueños", |
["Val'kyr Shadowguard"] = "Val'kyr Shadowguard", -- Needs review |
["Varian Wrynn"] = "Varian Wrynn", |
["Varos Cloudstrider"] = "Varos Cloudstrider", |
Vazruden = "Vazruden", |
["Vazruden the Herald"] = "Vazruden el Heraldo", |
Vectus = "Vectus", |
Vem = "Vem", |
Veng = "Veng", |
["Veras Darkshadow"] = "Veras Darkshadow", |
["Verdan the Everliving"] = "Verdan el Eterno", |
Verek = "Verek", |
Vesperon = "Vesperon", |
Vexallus = "Vexallus", |
["Veyzhak the Cannibal"] = "Veyzhak el CanÃbal", |
["Vile'rel"] = "Vil'rel", |
Viscidus = "Viscidus", |
["Viscous Fallout"] = "Radiactivo viscoso", |
["Void Reaver"] = "Atracador del vacÃo", |
Volkhan = "Volkhan", |
["VX-001"] = "VX-001", |
["Warbringer O'mrogg"] = "Belisario O'mrogg", |
["Warchief Blackhand Piece"] = "Jefe de Guerra Mano Negra", |
["Warchief Kargath Bladefist"] = "Jefe de Guerra Kargath Garrafilada", |
["Warchief Rend Blackhand"] = "Jefe de Guerra Desgarro Puño Negro", |
["Warden Mellichar"] = "Celador Mellichar", |
["Warder Stilgiss"] = "Guarda Stilgiss", |
["Warlord Kalithresh"] = "Señor de la Guerra Kalithresh", |
["War Master Voone"] = "Maestro de guerra Voone", |
["Warmaul Champion"] = "Campeón Mazo de Guerra", |
["Warp Slicer"] = "Cercenadora de distorsión", |
["Warp Splinter"] = "Disidente de distorsión", |
["Watchkeeper Gargolmar"] = "Guardián vigÃa Gargolmar", |
Weaver = "Sastrón", |
["Witch Doctor Zum'rah"] = "Médico brujo Zum'rah", |
["Wolf Master Nandos"] = "Maestro de lobos Nandos", |
["Wrath-Scryer Soccothrates"] = "Arúspice de cólera Soccothrates", |
Wushoolay = "Wushoolay", |
Xevozz = "Xevozz", |
["XT-002 Deconstructor"] = "Desarmador XA-002", |
["Yogg-Saron"] = "Yogg-Saron", |
Ysondre = "Ysondre", |
Zekkis = "Zekkis", |
["Zelemar the Wrathful"] = "Zelemar el Colérico", |
["Zereketh the Unbound"] = "Zereketh el Desatado", |
Zerillis = "Zerillis", |
["Zevrim Thornhoof"] = "Zevrim Pezuñahendida", |
Zolo = "Zolo", |
["Zul'Farrak Dead Hero"] = "Héroe muerto Zul'Farrak", |
["Zul'jin"] = "Zul'jin", |
["Zul'Lor"] = "Zul'Lor", |
["Zul'tore"] = "Zul'tore", |
["Zuramat the Obliterator"] = "Zuramat el Obliterador", |
} |
elseif GAME_LOCALE == "esMX" then |
lib:SetCurrentTranslations { |
Acidmaw = "Fauceácida", |
Aeonus = "Aeonus", |
["Aerial Command Unit"] = "Unidad de mando aérea", |
["Agathelos the Raging"] = "Agathelos el Furioso", |
Ahune = "Ahune", |
["Akil'zon"] = "Akil'zon", |
["Aku'mai"] = "Aku'mai", |
["Al'ar"] = "Al'ar", |
["Algalon the Observer"] = "Algalon el Observador", |
["Alzzin the Wildshaper"] = "Alzzin el Formaferal", |
Amanitar = "Amanitar", |
["Ambassador Flamelash"] = "Embajador Latifuego", |
["Ambassador Hellmaw"] = "Embajador Faucinferno", |
["Amnennar the Coldbringer"] = "Amnennar el Gélido", |
["Ancient Stone Keeper"] = "Vigilante pétreo anciano", |
Anetheron = "Anetheron", |
["Anger'rel"] = "Anger'rel", |
Anomalus = "Anomalus", |
["Antu'sul"] = "Antu'sul", |
["Anub'arak"] = "Anub'arak", |
["Anubisath Defender"] = "Defensor Anubisath", |
["Anubisath Guardian"] = "Guardián Anubisath", |
["Anub'Rekhan"] = "Anub'Rekhan", |
["Anub'shiah"] = "Anub'shiah", |
Anzu = "Anzu", |
["Arcane Watchman"] = "Vigilante Arcano", |
["Arcanist Doan"] = "Arcanista Doan", |
Archaedas = "Archaedas", |
["Archavon the Stone Watcher"] = "Archavon el vigÃa de piedra", |
Archimonde = "Archimonde", |
["Archivist Galford"] = "Archivista Galford", |
["Archmage Arugal"] = "Archimago Arugal", |
["Argent Confessor Paletress"] = "confesora Argenta Cabelloclaro", |
["Arugal's Voidwalker"] = "Abisario de Arugal", |
["Assault Bot"] = "Robot de asalto", |
["Atal'alarion"] = "Atal'alarion", |
["Attumen the Huntsman"] = "Attumen el Montero", |
Auriaya = "Auriaya", |
Avalanchion = "Avalanchion", |
["Avatar of Hakkar"] = "Avatar de Hakkar", |
["Ayamiss the Hunter"] = "Ayamiss el Cazador", |
Azgalor = "Azgalor", |
["Azshir the Sleepless"] = "Azshir el Insomne", |
Azuregos = "Azuregos", |
["Bael'Gar"] = "Bael'Gar", |
Baelog = "Baelog", |
Balnazzar = "Balnazzar", |
-- ["Baltharus the Warborn"] = "", |
["Bannok Grimaxe"] = "Bannok Hachamacabra", |
["Baron Aquanis"] = "Barón Aquanis", |
["Baron Charr"] = "Barón Charr", |
["Baroness Anastari"] = "Baronesa Anastari", |
["Baron Geddon"] = "Barón Geddon", |
["Baron Kazum"] = "Barón Kazum", |
["Baron Rivendare"] = "Barón Osahendido", |
["Baron Silverlaine"] = "Barón Filargenta", |
["Battleguard Sartura"] = "Guardia de batalla Sartura", |
["Bazil Thredd"] = "Bazil Thredd", |
Bazzalan = "Bazzalan", |
["Black Guard Swordsmith"] = "Armero Guardia Negra", |
["Blackheart the Inciter"] = "Negrozón el Incitador", |
["Blindeye the Seer"] = "Ciego el Vidente", |
["Blind Hunter"] = "Cazador ciego", |
["Blood Guard Porung"] = "Guardia de sangre Porung", |
["Bloodlord Mandokir"] = "Señor sangriento Mandokir", |
["Bloodmage Thalnos"] = "Mago sangriento Thalnos", |
["Blood Prince Council"] = "Consejo de PrÃncipes de Sangre", |
["Blood Princes"] = "PrÃncipes de Sangre", |
["Blood-Queen Lana'thel"] = "Reina de Sangre Lana'thel", |
["Blood Steward of Kirtonos"] = "Administrador de sangre de Kirtonos", |
Boahn = "Boahn", |
["Bomb Bot"] = "Robot bum", |
["Brain of Yogg-Saron"] = "Cerebro de Yogg-Saron", |
["Brainwashed Noble"] = "Noble aducido", |
Broggok = "Broggok", |
Brokentoe = "Dedorroto", |
Bronjahm = "Bronjahm", |
["Broodlord Lashlayer"] = "Señor de prole Capazote", |
["Bruegal Ironknuckle"] = "Bruegal Nudoferro", |
Brutallus = "Brutallus", |
["Burning Felguard"] = "Guarda vil ardiente", |
["Buru the Gorger"] = "Buru el Manducador", |
["Cache of the Firelord"] = "BotÃn del Señor del Fuego", |
["Cannon Master Willey"] = "Cañonero Jefe Willey", |
["Captain Greenskin"] = "Capitán Verdepel", |
["Captain Kromcrush"] = "Capitán Kromcrush", |
["Captain Skarloc"] = "Capitán Skarloc", |
["Celebras the Cursed"] = "Celebras el Maldito", |
["Charlga Razorflank"] = "Charlga Filonavaja", |
["Chess Event"] = "Evento de ajedrez", |
["Chest of The Seven"] = "Tesoro de los Siete", |
["Chief Ukorz Sandscalp"] = "Jefe Ukorz Cabellarena", |
["Cho'Rush the Observer"] = "Cho'Rush el Observador", |
Chromaggus = "Chromaggus", |
["Chrono Lord Deja"] = "Cronolord Deja", |
["Chrono-Lord Epoch"] = "Cronolord Ãpoca", |
Claw = "Zarpa", |
["Coilfang Elite"] = "Elite Colimillo Torcido", |
["Coilfang Strider"] = "Zancudo Colmillo Torcido", |
["Commander Kolurg"] = "Comandante Kolurg", |
["Commander Sarannis"] = "Comandante Sarannis", |
["Commander Springvale"] = "Comandante Vallefont", |
["Commander Stoutbeard"] = "Comandante Barbarrecia", |
["Constructor & Controller"] = "Constructor & Controlador", |
Cookie = "El Chef", |
["Coren Direbrew"] = "Coren Cerveza Temible", |
["Cosmic Infuser"] = "Infusor cósmico", |
["Crimson Hammersmith"] = "Forjamartillos CarmesÃ", |
["Crowd Pummeler 9-60"] = "Gopleamasa 9-60", |
["Crystal Fang"] = "Colmillor de cristal", |
["C'Thun"] = "C'Thun", |
Cyanigosa = "Cyanigosa", |
["Dalliah the Doomsayer"] = "Dalliah la Decidora del Destino", |
["Dalronn the Controller"] = "Dalronn el Controlador", |
["Dark Iron Ambassador"] = "Embajador Hierro Negro", |
["Darkmaster Gandling"] = "Maestro oscuro Gandling", |
["Darkweaver Syth"] = "Tejeoscuro Syth", |
["Deathbound Ward"] = "Depositario vinculado a la muerte", |
["Deathbringer Saurfang"] = "Libramorte Colmillosauro", |
["Death Knight Darkreaver"] = "Caballero de la Muerte Atracoscuro", |
["Death Knight Understudy"] = "Suplente Caballero de la Muerte", |
["Deathspeaker High Priest"] = "Sumo sacerdote portavoz de la muerte", |
["Death Speaker Jargba"] = "Médium Jargba", |
["Deathstalker Visceri"] = "Mortacechador Visceri", |
["Deathsworn Captain"] = "Capitán Juramorte", |
Devastation = "Devastación", |
["Deviate Faerie Dragon"] = "Dragón férico descarriado", |
["Devourer of Souls"] = "Devorador de Almas", |
["Dextren Ward"] = "Dextren Tutor", |
["Digmaster Shovelphlange"] = "Maestro de excavación Palatiro", |
["Doctor Theolen Krastinov"] = "Doctor Theolen Krastinov", |
["Doom Lord Kazzak"] = "Señor ApocalÃptico Kazzak", |
["Doom'rel"] = "Doom'rel", |
Doomwalker = "Caminante del Destino", |
["Dope'rel"] = "Dope'rel", |
Dorothee = "Dorothea", |
["Drakkari Colossus"] = "Coloso Drakkari", |
["Drakos the Interrogator"] = "Drakos el Interrogador", |
Dreadscale = "Aterraescama", |
Dreamscythe = "Guadañasueños", |
["Dust Covered Chest"] = "Cofre cubierto de polvo", |
Dustwraith = "Ãnima de polvo", |
["Eadric the Pure"] = "Eadric el Puro", |
["Earthcaller Halmgar"] = "Clamor de Tierra Halmgar", |
Ebonroc = "Ebonroc", |
["Eck the Ferocious"] = "Eck el Feroz", |
["Edwin VanCleef"] = "Edwin VanCleef", |
["Elder Brightleaf"] = "Ancestro Hojabrillante", |
["Elder Ironbranch"] = "Ancestro Hierrorrama", |
["Elder Nadox"] = "Ancestro Nadox", |
["Elder Stonebark"] = "Ancestro Cortezapiedra", |
["Electrocutioner 6000"] = "Electrocutor 6000", |
["Emalon the Storm Watcher"] = "Emalon e ViagÃa de la Tormenta", |
Emeriss = "Emeriss", |
["Emperor Dagran Thaurissan"] = "Emperador Dagran Thaurissan", |
["Emperor Vek'lor"] = "Emperador Vek'lor", |
["Emperor Vek'nilash"] = "Emperador Vek'nilash", |
Entropius = "Entropius", |
["Eonar's Gift"] = "Don de Eonar", |
["Epoch Hunter"] = "Cazador de eras", |
Erekem = "Erekem", |
["Eressea Dawnsinger"] = "Eressea Cantoalba", |
["Essence of Anger"] = "Esencia de Cólera", |
["Essence of Desire"] = "Esencia de Deseo", |
["Essence of Suffering"] = "Esencia de Sufrimiento", |
Eviscerator = "Eviscerador", |
["Exarch Maladaar"] = "Exarca Maladaar", |
["Expedition Commander"] = "Comandante de expedición", |
["Eydis Darkbane"] = "Eydis Penaumbra", |
["Eye of C'Thun"] = "Ojo de C'Thun", |
["Faction Champions"] = "Campeones de Facción", |
["Fallen Champion"] = "Campeón caÃdo", |
Falric = "Falric", |
["Falric and Marwyn"] = "Falric y Marwyn", |
["Fankriss the Unyielding"] = "Fankriss el Implacable", |
["Fathom-Lord Karathress"] = "Señor de la profundidades Karathress", |
Felmyst = "Brumavil", |
["Fenrus the Devourer"] = "Fenrus el Devorador", |
["Feral Defender"] = "Defensor Feral", |
Festergut = "Panzachancro", |
Feugen = "Feugen", |
["Fineous Darkvire"] = "Finoso Virunegro", |
Firemaw = "Faucefogo", |
["Fjola Lightbane"] = "Fjola PenÃvea", |
Flamegor = "Flamagor", |
["Flame Leviathan"] = "Leviatán de llamas", |
["Foreman Thistlenettle"] = "Supervisor Cardortiga", |
["Forgemaster Garfrost"] = "Maestro de Forja Gargelus", |
["Four Horsemen Chest"] = "Cofre de los Cuatro Jinetes", |
["Fras Siabi"] = "Fras Siabi", |
Freya = "Freya", |
["Gahz'ranka"] = "Gahz'ranka", |
["Gahz'rilla"] = "Gahz'rilla", |
["Gal'darah"] = "Gal'darah", |
["Galgann Firehammer"] = "Galgann Flamartillo", |
Garr = "Garr", |
["Garrosh Hellscream"] = "Garrosh Garrosh Grito Inferna", |
Gasher = "Gasher", |
["Gatewatcher Gyro-Kill"] = "VÃgia de las puertas Giromata", |
["Gatewatcher Iron-Hand"] = "VigÃa de las puertas Manoyerro", |
["Gathios the Shatterer"] = "Gathios the Shatterer", |
Gehennas = "Gehennas", |
Gelihast = "Gelihast", |
Gelk = "Gelk", |
["General Angerforge"] = "General Forjira", |
["General Bjarngrim"] = "General Bjarngrim", |
["General Drakkisath"] = "General Drakkisath", |
["General Rajaxx"] = "General Rajaxx", |
["General Vezax"] = "General Vezax", |
-- ["General Zarithrian"] = "", |
["Ghamoo-ra"] = "Ghamoo-ra", |
["Ghaz'an"] = "Ghaz'an", |
["Ghok Bashguud"] = "Ghok Bashguud", |
Gilnid = "Gilnid", |
["Gizrul the Slavener"] = "Gizrul el Esclavista", |
["Gloom'rel"] = "Gloom'rel", |
Gluth = "Gluth", |
Glutton = "Glotón", |
["Golemagg the Incinerator"] = "Golemagg el Incinerador", |
["Golem Lord Argelmach"] = "Señor Golem Argelmach", |
["Goraluk Anvilcrack"] = "Goraluk Yunquegrieta", |
["Gormok the Impaler"] = "Gormok el Empalador", |
["Gorosh the Dervish"] = "Gorosh el Endemoniado", |
["Gortok Palehoof"] = "Gortok Pezuña Pálida", |
["Gothik the Harvester"] = "Gothik el Cosechador", |
["Grand Astromancer Capernian"] = "Gran astromántica Capernian", |
["Grand Champions"] = "Grandes Campeones", |
["Grand Magus Telestra"] = "Gran maga Telestra", |
["Grandmaster Vorpil"] = "Maestro mayor Vorpil", |
Grandmother = "Abuela", |
["Grand Warlock Alythess"] = "Bruja suprema Alythess", |
["Grand Warlock Nethekurse"] = "Brujo supremo Malbisal", |
["Grand Widow Faerlina"] = "Gran Viuda Faerlina", |
["Grethok the Controller"] = "Grethok el Controlador", |
["Gri'lek"] = "Gri'lek", |
Grimlok = "Grimlok", |
Grizzle = "\009Grisez", |
Grobbulus = "Grobbulus", |
Grubbis = "Grubbis", |
["Gruul the Dragonkiller"] = "Gruul el Asesino de Dragones", |
["Guard Fengus"] = "Guardia Fengus", |
["Guardian of Yogg-Saron"] = "Guardián de Yogg-Saron", |
["Guard Mol'dar"] = "Guardia Mol'dar", |
["Guard Slip'kik"] = "Guardia Slip'kik", |
["Gurtogg Bloodboil"] = "Gurtogg Sangre Hirviente", |
Gyth = "Gyth", |
Hadronox = "Hadronox", |
Hakkar = "Hakkar", |
Halazzi = "Halazzi", |
-- Halion = "", |
Halycon = "Halycon", |
Hamhock = "Hamhock", |
["Harbinger Skyriss"] = "Presagista Cieloriss", |
["Hate'rel"] = "Odio'rel", |
["Hazza'rah"] = "Hazza'rah", |
Hazzas = "Hazzas", |
["Headless Horseman"] = "Jinete sin Cabeza", |
["Hearthsinger Forresten"] = "Escupezones Foreste", |
["Hedrum the Creeper"] = "Hedrum el Trepador", |
["Heigan the Unclean"] = "Heigan el Impuro", |
["Hellfire Channeler"] = "Canalizador Fuego Infernal", |
["Henry Stern"] = "Henry Stern", |
["Herald Volazj"] = "Heraldo Volazj", |
Herod = "Herod", |
["Hex Lord Malacrass"] = "Señor aojador Malacrass", |
["High Astromancer Solarian"] = "Gran astromántica Solarian", |
["High Botanist Freywinn"] = "Gran botánico Freywinn", |
["High Inquisitor Fairbanks"] = "Alto Inquisidor Ribalimpia", |
["High Inquisitor Whitemane"] = "Alta Inquisidora Melenablanca", |
["High Interrogator Gerstahn"] = "Alto Interrogador Gerstahn", |
["High King Maulgar"] = "Su majestad Maulgar", |
["Highlord Mograine"] = "Alto Señor Mograine", |
["Highlord Omokk"] = "Alto Señor Omokk", |
["High Marshal Whirlaxis"] = "High Marshal Whirlaxis", |
["High Nethermancer Zerevor"] = "High Nethermancer Zerevor", |
["High Overlord Saurfang"] = "Alto señor supremo Colmillosauro", |
["High Priestess Arlokk"] = "Suma Sacerdotisa Arlokk", |
["High Priestess Jeklik"] = "Suma Sacerdotisa Jeklik", |
["High Priestess Mar'li"] = "Suma Sacerdotisa Mar'li", |
["High Priestess of Thaurissan"] = "Alta Sacerdotisa de Thaurissan", |
["High Priest Thekal"] = "Sumo Sacerdote Thekal", |
["High Priest Venoxis"] = "Sumo Sacerdote Venoxis", |
["High Warlord Naj'entus"] = "Gran Señor de la Guerra Naj'entus", |
Hodir = "Hodir", |
["Houndmaster Grebmar"] = "Maestro de canes Grebmar", |
["Houndmaster Loksey"] = "Maestro de canes Loksey", |
Hukku = "Hukku", |
Hungarfen = "Panthambre", |
["Hurley Blackbreath"] = "Hurley Negrálito", |
["Hyakiss the Lurker"] = "Hyakiss el Rondador", |
["Hydromancer Thespia"] = "Hidromántico Thespia", |
["Hydromancer Velratha"] = "Hidromántica Velratha", |
Hydrospawn = "Hidromilecio", |
["Hydross the Unstable"] = "Hydross el Inestable", |
["Icecrown Gunship Battle"] = "Batalla de las Aeronaves de Corona de Hielo", |
Icehowl = "Aullahielo", |
["Ice Sphere"] = "Esfera de hielo", |
Ichoron = "Ãcoron", |
Ick = "Agh", |
["Ignis the Furnace Master"] = "Ignis el Maestro de la Caldera", |
["Illidan Stormrage"] = "Illidan Tempestira", |
["Illidari Council"] = "Concilio Illidari", |
["Illyanna Ravenoak"] = "Illyanna Roblecuervo", |
["Immol'thar"] = "Immol'thar", |
["Infinite Corruptor"] = "Corruptor Infinito", |
["Infinity Blades"] = "Hojas de infinidad", |
["Ingvar the Plunderer"] = "Ingvar the Plunderer", |
["Instructor Malicia"] = "Instructor Malicia", |
["Instructor Razuvious"] = "Instructor Razuvious", |
["Interrogator Vishas"] = "Interrogador Vishas", |
Ionar = "Ionar", |
Ironaya = "Hierraya", |
Ironspine = "Dorsacerado", |
Isalien = "Isalien", |
Jade = "Jade", |
["Jammal'an the Prophet"] = "Jammal'an el Profeta", |
["Jan'alai"] = "Jan'alai", |
["Jandice Barov"] = "Jandice Barov", |
["Jedoga Shadowseeker"] = "Jedoga Buscasombras", |
["Jed Runewatcher"] = "Jed vigÃa de las runas", |
["Jergosh the Invoker"] = "Jergosh el Convocador", |
["Jin'do the Hexxer"] = "Jin'do el Aojador", |
["Jormungar Behemoth"] = "Behemoth Jormungar", |
Jormungars = "Jormungars", |
Julianne = "Julianne", |
["Junk Bot"] = "Chatarrabot", |
["Kael'thas Sunstrider"] = "Kael'thas Caminante del Sol", |
Kalecgos = "Kalecgos", |
["Kam Deepfury"] = "Kam Furiahonda", |
["Kazkaz the Unholy"] = "Kazkaz el Blasfemo", |
["Kaz'rogal"] = "Kaz'rogal", |
["Keli'dan the Breaker"] = "Keli'dan el Ultrajador", |
["Kel'Thuzad"] = "Kel'Thuzad", |
Keristrasza = "Keristrasza", |
["Kiggler the Crazed"] = "Kiggler el Enloquecido", |
["Kil'jaeden"] = "Kil'jaeden", |
["Kil'rek"] = "Kil'rek", |
["King Dred"] = "Rey Dred", |
["King Gordok"] = "Rey Gordok", |
["King Llane Piece"] = "Rey Llane", |
["King Ymiron"] = "Rey Ymiron", |
["Kirtonos the Herald"] = "Kirtonos el Heraldo", |
["Knot Thimblejack's Cache"] = "Carretilla de Knot Llavededo", |
Kolk = "Kolk", |
Kologarn = "Kologarn", |
["Koralon the Flame Watcher"] = "Koralon el VigÃa de las llamas", |
Kormok = "Kormok", |
Kresh = "Kresh", |
Krick = "Puagh", |
["Krick and Ick"] = "Agh y Puagh", |
["Krik'thir the Gatewatcher"] = "Krikâthir el vÃgia de las puertas", |
["Krosh Firehand"] = "Krosh Manofuego", |
Krystallus = "Krystallus", |
Kurinnaxx = "Kurinnaxx", |
["Lady Anacondra"] = "Lady Anacondra", |
["Lady Blaumeux"] = "Lady Blaumeux", |
["Lady Deathwhisper"] = "Lady Susurramuerte", |
["Lady Illucia Barov"] = "Lady Illucia Barov", |
["Lady Malande"] = "Lady Malande", |
["Lady Sacrolash"] = "Lady Sacrolash", |
["Lady Sarevess"] = "Lady Sarevess", |
["Lady Vashj"] = "Lady Vashj", |
Laj = "Laj", |
Landslide = "Derrumblo", |
Lavanthor = "Lavanthor", |
["Left Arm"] = "Brazo Izquierdo", |
["Leotheras the Blind"] = "Leotheras el Ciego", |
Lethon = "Lethon", |
Lethtendris = "Lethtendris", |
["Leviathan Mk II"] = "Mk II de leviatán", |
["Ley-Guardian Eregos"] = "Guardián-Ley Eregos", |
["Lieutenant Drake"] = "Teniente Draco", |
["Lieutenant General Andorov"] = "Teniente General Andorov", |
Loatheb = "Loatheb", |
Loken = "Loken", |
["Lord Alexei Barov"] = "Lord Alexei Barov", |
["Lord Cobrahn"] = "Lord Cobrahn", |
["Lord Hel'nurath"] = "Lord Hel'nurath", |
["Lord Incendius"] = "Lord Incendius", |
["Lord Jaraxxus"] = "Lord Jaraxxus", |
["Lord Kazzak"] = "Lord Kazzak", |
["Lord Kri"] = "Lord Kri", |
["Lord Marrowgar"] = "Lord Tuétano", |
["Lord Pythas"] = "Lord Pythas", |
["Lord Roccor"] = "Lord Roccor", |
["Lord Sanguinar"] = "Lord Sanguinar", |
["Lord Serpentis"] = "Lord Serpentis", |
["Lord Skwol"] = "Lord Skwol", |
["Lord Valthalak"] = "Lord Valthalak", |
["Lord Victor Nefarius"] = "Lord VÃctor Nefarius", |
["Lord Vyletongue"] = "Lord Lenguavil", |
["Lorekeeper Polkelt"] = "Tradicionalista Polkelt", |
Loro = "Loro", |
Lucifron = "Lucifron", |
["Mad Magglish"] = "Magglish el Loco", |
Maexxna = "Maexxna", |
["Mage-Lord Urom"] = "Señor de la Magia Urom", |
["Magister Kalendris"] = "Magister Kalendris", |
["Magistrate Barthilas"] = "Magistrado Barthilas", |
Magmadar = "Magmadar", |
Magmus = "Magmus", |
Magra = "Magra", |
Magtheridon = "Magtheridon", |
["Maiden of Grief"] = "Doncella de Pena", |
["Maiden of Virtue"] = "Doncella de Virtud", |
["Majordomo Executus"] = "Mayordomo Executus", |
Malacrass = "Malacrass", |
["Maleki the Pallid"] = "Maleki el Pálido", |
["Mal'Ganis"] = "Mal'Ganis", |
Malygos = "Malygos", |
Maraudos = "Maraudos", |
["Marduk Blackpool"] = "Marduz Pozonegro", |
["Marisa du'Paige"] = "Marisa du'Paige", |
Marwyn = " Marwyn", |
["Master Engineer Telonicus"] = "Maestro Ingeriero Telonicus", |
["Maur Grimtotem"] = "Maur Tótem Siniestro", |
Meathook = "Gancho", |
["Mechano-Lord Capacitus"] = "Lord-mecano Capacitus", |
Medivh = "Medivh", |
["Mekgineer Steamrigger"] = "Mekigeniero Vaporino", |
["Mekgineer Thermaplugg"] = "Mekigeniero Termochufe", |
["Mennu the Betrayer"] = "Mennu el Traidor", |
["Meshlok the Harvester"] = "Meshlok el Cosechador", |
Midnight = "Medianoche", |
Mijan = "Mijar", |
Mimiron = "Mimiron", |
["Miner Johnson"] = "Minero Johnson", |
["Mistress of Pain"] = "Doncella de Dolor", |
Moam = "Moam", |
Mogor = "Mogor", |
["Mokra the Skullcrusher"] = "Mokra el Trituracráneos", |
Moorabi = "Moorabi", |
Moragg = "Moragg", |
["Mordresh Fire Eye"] = "Mordresh Ojo de Fuego", |
["Mor Grayhoof"] = "Mor Grayhoof", |
Moroes = "Moroes", |
["Morogrim Tidewalker"] = "Morogrim Levantamareas", |
Morphaz = "Morphaz", |
["Mother Shahraz"] = "Madre Shahraz", |
["Mother Smolderweb"] = "Madre Telabrasada", |
["Mr. Smite"] = "Sr. Golpin", |
["Muradin Bronzebeard"] = "Muradin Barbabronce", |
["Murkblood Twin"] = "Gemelo Sangreoscura", |
["Murkblood Twins"] = "Gemelos Sangreoscura", |
Murmur = "Murmur", |
["Murta Grimgut"] = "Murta Tripuriosa", |
["M'uru"] = "M'uru", |
Mushgog = "Mushgog", |
["Mutanus the Devourer"] = "Mutanus el Devorador", |
Nalorakk = "Nalorakk", |
Nazan = "Nazan", |
Nefarian = "Nefarian", |
["Nekrum Gutchewer"] = "Nekrum Cometripas", |
["Nerub'enkan"] = "Nerub'enkan", |
["Nethermancer Sepethrea"] = "Abisálico Sepethrea", |
Netherspite = "Rencor abisal", |
["Netherstrand Longbow"] = "Arco largo de fibra abisal", |
["Nexus-Prince Shaffar"] = "PrÃncipe-nexo Shaffar", |
Nightbane = "Nocturno", |
["Noth the Plaguebringer"] = "Noth el Pesteador", |
["Novos the Summoner"] = "Novos el Invocador", |
Noxxion = "Noxxion", |
["Obsidian Sentinel"] = "Centinela Obsidiano", |
["Odo the Blindwatcher"] = "Odo el vigÃa ciego", |
["Ogom the Wretched"] = "Ogom el Desdichado", |
["Ok'thor the Breaker"] = "Ok'thor el Rompedor", |
["Old Serra'kis"] = "Viejo Serra'kis", |
["Olm the Summoner"] = "Olm el Invocador", |
["Omor the Unscarred"] = "Omor el Sinmarcas", |
Onyxia = "Onyxia", |
["Orgrim's Hammer"] = "Martillo de Orgrim", |
["Ormorok the Tree-Shaper"] = "Ormorok el cortador de árboles", |
["Oro Eyegouge"] = "Oro Bocojo ", |
["Ossirian the Unscarred"] = "Osirio el Sinmarcas", |
Ouro = "Ouro", |
["Overlord Ramtusk"] = "Señor Supremo Colmicarnero", |
["Overlord Wyrmthalak"] = "Señor Supremo Vermiothalak", |
["Overmaster Pyron"] = "Maestro Supremo Pyron", |
["Overseer Tidewrath"] = "Avizor Aleta de Cólera", |
Pandemonius = "Pandemonius", |
["Panzor the Invincible"] = "Panzor el Invencible", |
Patchwerk = "Remendejo", |
["Pathaleon the Calculator"] = "Panthaleon el Calculador", |
Phalanx = "Falange", |
["Phaseshift Bulwark"] = "Baluarte de cambio de fase", |
Pimgib = "Pimgib", |
["Plaguemaw the Rotting"] = "Fauzpeste el Putrefacto", |
["Plugger Spazzring"] = "Plugger Aropatoso", |
["Postmaster Malown"] = "Jefe de correos Malown", |
["Priestess Delrissa"] = "Sacerdotisa Delrissa", |
["Prince Keleseth"] = "PrÃncipe Keleseth", |
["Prince Malchezaar"] = "PrÃncipe Malchezaar", |
["Prince Skaldrenox"] = "PrÃncipe Skaldrenox", |
["Princess Huhuran"] = "Princesa Huhuran", |
["Princess Moira Bronzebeard"] = "Princesa Moira Barbabronce", |
["Princess Tempestria"] = "Princesa Tempestria", |
["Princess Theradras"] = "Princesa Theradras", |
["Princess Yauj"] = "Princesa Yauj", |
["Prince Taldaram"] = "PrÃncipe Taldaram", |
["Prince Tenris Mirkblood"] = "PrÃncipe Tenris Sangre Penumbra", |
["Prince Tortheldrin"] = "PrÃncipe Tortheldrin", |
["Prince Valanar"] = "Principe Valanar", |
["Professor Putricide"] = "Profesor Putricidio", |
["Pure Spawn of Hydross"] = "Engendro puro de Hydross", |
Pusillin = "PusillÃn", |
["Pyroguard Emberseer"] = "Piroguardián Brasadivino", |
["Pyromancer Loregrain"] = "Piromántico Cultugrano", |
Quagmirran = "Quagmirran", |
["Quartermaster Zigris"] = "Intendente Zigris", |
["Rage Winterchill"] = "Ira FrÃoinvierno", |
Ragglesnout = "Morrandrajos", |
["Raging Spirit"] = "EspÃritu enfurecido", |
Ragnaros = "Ragnaros", |
["Ramstein the Gorger"] = "Ramstein el Empachador", |
["Ras Frostwhisper"] = "Ras Levescarcha", |
Rattlegore = "Traquesangre", |
["Razorclaw the Butcher"] = "Zarpador el Carnicero", |
["Razorgore the Untamed"] = "Sangrevaja el Indomable", |
Razorlash = "Lativaja", |
Razorscale = "Tajoescama", |
["Reliquary of Souls"] = "Relicario de Almas", |
Renataki = "Renataki", |
["Restless Skeleton"] = "Esqueleto inquieto", |
Rethilgore = "Rethilgore", |
Revelosh = "Revelosh", |
["Rhahk'Zor"] = "Rhahk'Zor", |
["Ribbly Screwspigot"] = "Ribbly Llavenrosca", |
["Right Arm"] = "Brazo Derecho", |
Roar = "Rugido", |
["Rokad the Ravager"] = "Rokad el Devastador", |
["Rokdar the Sundered Lord"] = "Rokdar el Señor Hendido", |
["Rokmar the Crackler"] = "Rokmar el Crujidor", |
Romulo = "Romulo", |
["Romulo & Julianne"] = "Romeo y Julieta", |
Rotface = "Carapútrea", |
Rotgrip = "Escamapodrida", |
["Runemaster Molgeim"] = "Maestro de runas Molgeim", |
["Runok Wildmane"] = "Runok FerocrÃn", |
Ruuzlu = "Ruuzlu", |
["Salramm the Fleshcrafter"] = "Salramm el Modelador de carne", |
["Sanctum Sentry"] = "Centinela del sagrario", |
["Sandarr Dunereaver"] = "Sandarr Asaltadunas", |
["Sandfury Executioner"] = "Ejecutor Furiarena", |
Sapphiron = "Sapphiron", |
Sara = "Sara", |
["Saronite Animus"] = "Animus de saronita", |
Sartharion = "Sartharion", |
["Sathrovarr the Corruptor"] = "Sathrovarr el Corruptor", |
-- ["Saviana Ragefire"] = "", |
["Scarlet Commander Mograine"] = "Comandante Escarlata Mograine", |
["Scourgelord Tyrannus"] = "Señor de la Plaga Tyrannus", |
["Seeth'rel"] = "Seeth'rel", |
["Selin Fireheart"] = "Selin Corazón de Fuego", |
["Sergeant Bly"] = "Sargento Bly", |
["Shade of Akama"] = "Sombra de Akama", |
["Shade of Aran"] = "Sombra de Aran", |
["Shade of Eranikus"] = "Sombra de Eranikus", |
["Shadikith the Glider"] = "Shadikith the Glider", |
["Shadow Hunter Vosh'gajin"] = "Cazador de las Sombras Vosh'gajin", |
["Shadow of Leotheras"] = "Sombra de Leotheras", |
["Shadowpriest Sezz'ziz"] = "Sacerdote oscuro Sezz'ziz", |
Shadron = "Shadron", |
Shazzrah = "Shazzrah", |
["Shirrak the Dead Watcher"] = "Shirrak el VigÃa de los Muertos", |
Sindragosa = "Sindragosa", |
["Sir Zeliek"] = "Sir Zeliek", |
["Sjonnir The Ironshaper"] = "Sjonnir el Afilador", |
["Skadi the Ruthless"] = "Skadi el Despiadado", |
["Skarr the Unbreakable"] = "Skarr el Inquebrantable", |
["Skarvald the Constructor"] = "Skarvald el Constructor", |
["Skra'gath"] = "Skra'gath", |
Skul = "Skul", |
Skum = "Skum", |
["Slad'ran"] = "Slad'ran", |
Sneed = "Sneed", |
["Sneed's Shredder"] = "Machacador de Sneed", |
["Solakar Flamewreath"] = "Solakar Corona de Fuego", |
["Solarium Agent"] = "Agente Solarium", |
["Solarium Priest"] = "Sacerdote Solarium", |
["Spirestone Battle Lord"] = "Señor de batalla Cumbrerroca", |
["Spirestone Butcher"] = "Carnicero Cumbrerroca", |
["Spirestone Lord Magus"] = "Señor Magus Cumbrerroca", |
["Staff of Disintegration"] = "Bastón de desintegración", |
Stalagg = "Stalagg", |
Steelbreaker = "Rompeacero", |
["Stomper Kreeg"] = "Vapuleador Kreeg", |
Stonespine = "Pidrespina", |
["Stormcaller Brundir"] = "Clamatormentas Brundir", |
Strawman = "Espantapájaros", |
["Sulfuron Harbinger"] = "Sulfuron Presagista", |
Supremus = "Supremus", |
["Svala Sorrowgrave"] = "Svala Tumbapena", |
["Swamplord Musel'ek"] = "Señor del pantano Musel'ek", |
Taerar = "Taerar", |
["Tainted Spawn of Hydross"] = "Engendro de Hydross corrupto", |
["Talon King Ikiss"] = "Rey Garra Ikiss", |
["Taragaman the Hungerer"] = "Taragaman el Hambriento", |
["Targorr the Dread"] = "Targor el Pavoroso", |
Tavarok = "Tavarok", |
Techbot = "Tecnobot", |
Temporus = "Temporus", |
["Tendris Warpwood"] = "Tendris Madeguerra", |
Tenebron = "Tenebron", |
["Terestian Illhoof"] = "Terestian Pezuña Enferma", |
["Teron Gorefiend"] = "Teron Sanguino", |
Thaddius = "Thaddius", |
["Thaladred the Darkener"] = "Thaladred el Oscurecedor", |
["Thane Korth'azz"] = "Thane Korth'azz", |
["The Beast"] = "La Bestia", |
["The Beasts of Northrend"] = "Las bestias de Rasganorte ", |
["The Big Bad Wolf"] = "El Gran Lobo Malvado", |
["The Black Knight"] = "El Caballero Negro", |
["The Black Stalker"] = "La acechadora negra", |
["The Blue Brothers"] = "Los Hermanos Azules", |
["The Bug Family"] = "La Familia Insecto", |
["The Crone"] = "La Vieja Bruja", |
["The Curator"] = "Curator", |
["The Eredar Twins"] = "Los Gemelos Eredar", |
["The Four Horsemen"] = "Los Cuatro Jinetes", |
["The Illidari Council"] = "El concilio Illidari", |
["The Iron Council"] = "Asamblea de Hierro", |
["Theka the Martyr"] = "Theka la Mártir", |
["The Lich King"] = "El Rey Exánime", |
["The Lurker Below"] = "El Rondador de abajo", |
["The Maker"] = "El Hacedor", |
["The Prophet Skeram"] = "El profeta Skeram", |
["The Prophet Tharon'ja"] = "El profeta Tharon'ja", |
["The Ravenian"] = "El Devorador", |
["The Razza"] = "El Razza", |
["The Seven Dwarves"] = "Los Siete Enanitos", |
["The Skybreaker"] = "El Rompecielos", |
["The Tribunal of Ages"] = "El Tribunal de las Eras", |
["The Twin Emperors"] = "Los Emperadores Gemelos", |
["The Twin Val'kyr"] = "las Gemelas Val'kyr", |
["The Unforgiven"] = "El Imperdonable", |
["The Windreaver"] = "El Atracavientos", |
Thorim = "Thorim", |
["Thorngrin the Tender"] = "Thorngrin el Tierno", |
["Tidewalker Lurker"] = "Rondador Levantamareas", |
["Timmy the Cruel"] = "Timmy el Cruel", |
Tinhead = "Cabezalata", |
["Tinkerer Gizlock"] = "Manitas Gizlock", |
["Tirion Fordring"] = "Tirion VadÃn", |
Tito = "Tito", |
["Toravon the Ice Watcher"] = "Toravon el VigÃa de Hielo", |
["Trigore the Lasher"] = "Trigore el Azotador", |
Trollgore = "Cuernotrol", |
["Tsu'zee"] = "Tsu'zee", |
["Tuten'kash"] = "Tuten'kash", |
["Twilight Lord Kelris"] = "Señor Crepuscular Kelris", |
["Urok Doomhowl"] = "Urok Aullapocalipsis", |
["Vaelastrasz the Corrupt"] = "Vaelastrasz el Corrupto", |
["Valithria Dreamwalker"] = "Valithria Caminasueños", |
["Val'kyr Shadowguard"] = "Guardia de las Sombras Val'kyr", |
["Varian Wrynn"] = "Varian Wrynn", |
["Varos Cloudstrider"] = "Varos Zancanubes", |
Vazruden = "Vazruden", |
["Vazruden the Herald"] = "Vazruden el Heraldo", |
Vectus = "Vectus", |
Vem = "Vem", |
Veng = "Veng", |
["Veras Darkshadow"] = "Veras Darkshadow", |
["Verdan the Everliving"] = "Verdan el Eterno", |
Verek = "Verek", |
Vesperon = "Vesperon", |
Vexallus = "Vexallus", |
["Veyzhak the Cannibal"] = "Veyzhak el CanÃbal", |
["Vile'rel"] = "Vil'rel", |
Viscidus = "Viscidus", |
["Viscous Fallout"] = "Radiactivo viscoso", |
["Void Reaver"] = "Atracador del vacÃo", |
Volkhan = "Volkhan", |
["VX-001"] = "VX-001", |
["Warbringer O'mrogg"] = "Belisario O'mrogg", |
["Warchief Blackhand Piece"] = "Jefe de Guerra Mano Negra", |
["Warchief Kargath Bladefist"] = "Jefe de Guerra Kargath Garrafilada", |
["Warchief Rend Blackhand"] = "Jefe de Guerra Desgarro Puño Negro", |
["Warden Mellichar"] = "Celador Mellichar", |
["Warder Stilgiss"] = "Guarda Stilgiss", |
["Warlord Kalithresh"] = "Señor de la Guerra Kalithresh", |
["War Master Voone"] = "Maestro de guerra Voone", |
["Warmaul Champion"] = "Campeón Mazo de Guerra", |
["Warp Slicer"] = "Cercenadora de distorsión", |
["Warp Splinter"] = "Disidente de distorsión", |
["Watchkeeper Gargolmar"] = "Guardián vigÃa Gargolmar", |
Weaver = "Sastrón", |
["Witch Doctor Zum'rah"] = "Médico brujo Zum'rah", |
["Wolf Master Nandos"] = "Maestro de lobos Nandos", |
["Wrath-Scryer Soccothrates"] = "Arúspice de cólera Soccothrates", |
Wushoolay = "Wushoolay", |
Xevozz = "Xevozz", |
["XT-002 Deconstructor"] = "Desarmarmador XA-002", |
["Yogg-Saron"] = "Yogg-Saron", |
Ysondre = "Ysondre", |
Zekkis = "Zekkis", |
["Zelemar the Wrathful"] = "Zelemar el Colérico", |
["Zereketh the Unbound"] = "Zereketh el Desatado", |
Zerillis = "Zerillis", |
["Zevrim Thornhoof"] = "Zevrim Pezuñahendida", |
Zolo = "Zolo", |
["Zul'Farrak Dead Hero"] = "Héroe muerto Zul'Farrak", |
["Zul'jin"] = "Zul'jin", |
["Zul'Lor"] = "Zul'Lor", |
["Zul'tore"] = "Zul'tore", |
["Zuramat the Obliterator"] = "Zuramat el Obliterador", |
} |
elseif GAME_LOCALE == "ruRU" then |
lib:SetCurrentTranslations { |
Acidmaw = "ÐиÑлоÑÐ½Ð°Ñ Ð£ÑÑоба", |
Aeonus = "ÐонÑÑ", |
["Aerial Command Unit"] = "ÐоздÑÑное ÑÑдно", |
["Agathelos the Raging"] = "ÐгаÑÐµÐ»Ð¾Ñ Ð¡Ð²Ð¸ÑепÑй", |
Ahune = "ÐÑ Ñн", |
["Akil'zon"] = "Ðкил'зон", |
["Aku'mai"] = "ÐкÑ'май", |
["Al'ar"] = "Ðл'аÑ", |
["Algalon the Observer"] = "Ðлгалон ÐаблÑдаÑелÑ", |
["Alzzin the Wildshaper"] = "Ðлззин ÐеÑевеÑÑенÑ", |
Amanitar = "ÐманиÑаÑ", |
["Ambassador Flamelash"] = "ÐоÑол ÐÐ³Ð½ÐµÑ Ð»ÑÑÑ", |
["Ambassador Hellmaw"] = "ÐоÑол ÐиблоÑÑев", |
["Amnennar the Coldbringer"] = "ÐÐ¼Ð½ÐµÐ½Ð½Ð°Ñ Ð¥Ð»Ð°Ð´Ð¾Ð²ÐµÐ¹", |
["Ancient Stone Keeper"] = "ÐÑевний Ð¥ÑаниÑÐµÐ»Ñ ÐамнÑ", |
Anetheron = "ÐнеÑеÑон", |
["Anger'rel"] = "Ðнев'Ñел", |
Anomalus = "ÐномалÑÑ", |
["Antu'sul"] = "ÐнÑÑ'ÑÑл", |
["Anub'arak"] = "ÐнÑб'аÑак", |
["Anubisath Defender"] = "ÐаÑиÑник-анÑбиÑаÑ", |
["Anubisath Guardian"] = "ÐнÑбиÑаÑ-ÑÑÑаж", |
["Anub'Rekhan"] = "ÐнÑб'Рекан", |
["Anub'shiah"] = "ÐнÑб'Ñиа", |
Anzu = "ÐнзÑ", |
["Arcane Watchman"] = "ЧаÑодейÑкий ÑÑÑажник", |
["Arcanist Doan"] = "ЧаÑодей Ðоан", |
Archaedas = "ÐÑкедаÑ", |
["Archavon the Stone Watcher"] = "ÐÑкавон СÑÑаж ÐамнÑ", |
Archimonde = "ÐÑÑ Ð¸Ð¼Ð¾Ð½Ð´", |
["Archivist Galford"] = "ÐÑÑ Ð¸Ð²Ð°ÑиÑÑ ÐалÑоÑд", |
["Archmage Arugal"] = "ÐеÑÑ Ð¾Ð²Ð½Ñй маг ÐÑÑгал", |
["Argent Confessor Paletress"] = "ÐÑповедниÑа СеÑебÑÑного ÐвангаÑда ÐейлÑÑеÑÑ", |
["Arugal's Voidwalker"] = "Ðемон ÐÐµÐ·Ð´Ð½Ñ ÐÑÑгала", |
["Assault Bot"] = "ШÑÑÑмовой ÑобоÑ", |
["Atal'alarion"] = "ÐÑал'алаÑион", |
["Attumen the Huntsman"] = "ÐовÑий ÐÑÑÑмен", |
Auriaya = "ÐÑÑиайÑ", |
Avalanchion = "Ðавинион", |
["Avatar of Hakkar"] = "ÐваÑаÑа ХаккаÑа", |
["Ayamiss the Hunter"] = "ÐйамиÑÑа ÐÑ Ð¾ÑниÑа", |
Azgalor = "ÐзгалоÑ", |
["Azshir the Sleepless"] = "ÐзÑÐ¸Ñ ÐеÑпÑÑий", |
Azuregos = "ÐзÑÑегоÑ", |
["Bael'Gar"] = "Ðейл'ÐоÑ", |
Baelog = "Ðейлог", |
Balnazzar = "ÐалназзаÑ", |
-- ["Baltharus the Warborn"] = "", |
["Bannok Grimaxe"] = "Ðаннок ÐÑÑоÑез", |
["Baron Aquanis"] = "ÐаÑон ÐкваниÑ", |
["Baron Charr"] = "ÐаÑон ÐгнеÑÑ", |
["Baroness Anastari"] = "ÐаÑонеÑÑа ÐнаÑÑаÑи", |
["Baron Geddon"] = "ÐаÑон Ðеддон", |
["Baron Kazum"] = "ÐаÑон ÐазÑм", |
["Baron Rivendare"] = "ÐаÑон РивендеÑ", |
["Baron Silverlaine"] = "ÐаÑон СÑебÑолен", |
["Battleguard Sartura"] = "Ðоевой ÑÑÑаж СаÑÑÑÑа", |
["Bazil Thredd"] = "ÐÐ°Ð·Ð¸Ð»Ñ Ð¢Ñедд", |
Bazzalan = "Ðаззалан", |
["Black Guard Swordsmith"] = "ÐÑÑжейник ЧеÑной СÑÑажи", |
["Blackheart the Inciter"] = "ЧеÑноÑеÑд ÐÑоповедник", |
["Blindeye the Seer"] = "Слепоглаз ЯÑновидеÑ", |
["Blind Hunter"] = "Слепой Ð¾Ñ Ð¾Ñник", |
["Blood Guard Porung"] = "ÐÑовавÑй ÑÑÑаж ÐоÑÑнг", |
["Bloodlord Mandokir"] = "ÐÐ°Ð½Ð´Ð¾ÐºÐ¸Ñ ÐовелиÑÐµÐ»Ñ ÐÑови", |
["Bloodmage Thalnos"] = "ÐолÑебник ÐÑови ТалноÑ", |
["Blood Prince Council"] = "Ð¡Ð¾Ð²ÐµÑ ÐÑинÑев ÐÑови", |
["Blood Princes"] = "Ð¡Ð¾Ð²ÐµÑ ÐÑинÑев ÐÑови", |
["Blood-Queen Lana'thel"] = "ÐÑÐ¾Ð²Ð°Ð²Ð°Ñ ÐºÐ¾Ñолева Ðана'ÑелÑ", |
["Blood Steward of Kirtonos"] = "ÐÑÐ¾Ð²Ð°Ð²Ð°Ñ Ð¿ÑиÑлÑжниÑа ÐиÑÑоноÑа", |
Boahn = "Ðоан", |
["Bomb Bot"] = "ÐомбоÑ", |
["Brain of Yogg-Saron"] = "Ðозг Ðогг-СаÑона", |
["Brainwashed Noble"] = "ÐомбиÑованнÑй двоÑÑнин", |
Broggok = "ÐÑоггок", |
Brokentoe = "Ð¥Ñомоног", |
Bronjahm = "ÐÑонÑÑм", |
["Broodlord Lashlayer"] = "ÐÑедводиÑÐµÐ»Ñ Ð´Ñаконов РазÑÑий ÐиÑ", |
["Bruegal Ironknuckle"] = "ÐÑÑгал ÐелезнÑй ÐÑлак", |
Brutallus = "ÐÑÑÑалл", |
["Burning Felguard"] = "ÐÑлаÑÑий ÑÑÑаж СквеÑнÑ", |
["Buru the Gorger"] = "ÐÑÑÑ ÐенаÑÑÑнÑй", |
["Cache of the Firelord"] = "Тайник повелиÑÐµÐ»Ñ Ð¾Ð³Ð½Ñ", |
["Cannon Master Willey"] = "ÐаÑÑеÑ-ÐºÐ°Ð½Ð¾Ð½Ð¸Ñ Ðилли", |
["Captain Greenskin"] = "ÐапиÑан ÐеленÑмÑ", |
["Captain Kromcrush"] = "ÐапиÑан ÐавигÑом", |
["Captain Skarloc"] = "ÐапиÑан СкаÑлок", |
["Celebras the Cursed"] = "СелебÑÐ°Ñ ÐÑоклÑÑÑй", |
["Charlga Razorflank"] = "ЧаÑлга ÐÑÑÑобок", |
["Chess Event"] = "Ð¨Ð°Ñ Ð¼Ð°ÑÑ", |
["Chest of The Seven"] = "СÑндÑк СемеÑÑÑ ", |
["Chief Ukorz Sandscalp"] = "ÐÐ¾Ð¶Ð´Ñ Ð£ÐºÐ¾Ñз ÐеÑÑÐ°Ð½Ð°Ñ ÐлеÑÑ", |
["Cho'Rush the Observer"] = "Чо'Ð Ð°Ñ ÐаблÑдаÑелÑ", |
Chromaggus = "Ð¥ÑоммагÑÑ", |
["Chrono Lord Deja"] = "ÐовелиÑÐµÐ»Ñ Ð²Ñемени Ðежа", |
["Chrono-Lord Epoch"] = "Ð¥ÑонолоÑд ÐÐ¿Ð¾Ñ ", |
Claw = "ÐогоÑÑ", |
["Coilfang Elite"] = "ÐваÑÐ´ÐµÐµÑ ÑезеÑвÑаÑа ÐÑивого ÐлÑка", |
["Coilfang Strider"] = "СÑÑанник ÑезеÑвÑаÑа ÐÑивого ÐлÑка", |
["Commander Kolurg"] = "ÐÐ¾Ð¼Ð°Ð½Ð´Ð¸Ñ ÐолÑÑг", |
["Commander Sarannis"] = "ÐÐ¾Ð¼Ð°Ð½Ð´Ð¸Ñ Ð¡Ð°ÑанниÑ", |
["Commander Springvale"] = "ÐÐ¾Ð¼Ð°Ð½Ð´Ð¸Ñ Ð ÑÑÑедол", |
["Commander Stoutbeard"] = "ÐÐ¾Ð¼Ð°Ð½Ð´Ð¸Ñ ÐивобоÑод", |
["Constructor & Controller"] = "СÑÑоиÑÐµÐ»Ñ Ð¸ ÐонÑÑолиÑÑÑÑий", |
Cookie = "ÐиÑожок", |
["Coren Direbrew"] = "ÐоÑен Ð¥ÑдоваÑ", |
["Cosmic Infuser"] = "ÐÑеленÑкий Ð²Ð´Ð¾Ñ Ð½Ð¾Ð²Ð¸ÑелÑ", |
["Crimson Hammersmith"] = "ÐолоÑÐ¾Ð±Ð¾ÐµÑ Ð¸Ð· ÐагÑового Ðегиона", |
["Crowd Pummeler 9-60"] = "Толпогон 9-60", |
["Crystal Fang"] = "Ð¥ÑÑÑÑалÑнÑй ÐлÑк", |
["C'Thun"] = "Ð'ТÑн", |
Cyanigosa = "СинигоÑа", |
["Dalliah the Doomsayer"] = "ÐÐ°Ð»Ð¸Ñ ÐлаÑаÑай СÑдÑбÑ", |
["Dalronn the Controller"] = "ÐалÑонн ÐонÑÑолиÑÑÑÑий", |
["Dark Iron Ambassador"] = "ÐоÑол из клана ЧеÑного Ðелеза", |
["Darkmaster Gandling"] = "ТемнÑй магиÑÑÑ Ðандлинг", |
["Darkweaver Syth"] = "ТемнопÑÑд СиÑ", |
-- ["Deathbound Ward"] = "", |
["Deathbringer Saurfang"] = "СаÑÑÑанг СмеÑÑоноÑнÑй", |
["Death Knight Darkreaver"] = "Ð ÑÑаÑÑ ÑмеÑÑи ТемнÑй ТеÑзаÑелÑ", |
["Death Knight Understudy"] = "УÑеник ÑÑÑаÑÑ ÑмеÑÑи", |
-- ["Deathspeaker High Priest"] = "", |
["Death Speaker Jargba"] = "ÐеÑÑник ÑмеÑÑи ÐжаÑгба", |
["Deathstalker Visceri"] = "СÑÑаж ÑмеÑÑи ÐизеÑи", |
["Deathsworn Captain"] = "ÐапиÑан ÑлÑжиÑелей СмеÑÑи", |
Devastation = "СокÑÑÑиÑелÑ", |
["Deviate Faerie Dragon"] = "ÐагадоÑнÑй волÑебнÑй дÑакон", |
["Devourer of Souls"] = "ÐожиÑаÑÐµÐ»Ñ ÐÑÑ", |
["Dextren Ward"] = "ÐекÑÑÑен ÐаÑд", |
["Digmaster Shovelphlange"] = "ÐаÑÑÐµÑ ÐопаÑоÑÑк", |
["Doctor Theolen Krastinov"] = "ÐокÑÐ¾Ñ Ð¢ÐµÐ¾Ð»ÐµÐ½ ÐÑаÑÑинов", |
["Doom Lord Kazzak"] = "ÐладÑка СÑдеб Ðаззак", |
["Doom'rel"] = "Рок'Ñел", |
Doomwalker = "СÑдÑболом", |
["Dope'rel"] = "ÐÑаздн'Ñел", |
Dorothee = "ÐоÑоÑи", |
["Drakkari Colossus"] = "ÐолоÑÑ ÐÑаккаÑи", |
["Drakos the Interrogator"] = "ÐÑÐ°ÐºÐ¾Ñ ÐознаваÑелÑ", |
Dreadscale = "ÐÑÑÐºÐ°Ñ Ð§ÐµÑÑÑ", |
Dreamscythe = "ÐÐ½ÐµÑ Ð¡Ð½Ð¾Ð²", |
["Dust Covered Chest"] = "ÐÑлÑнÑй ÑÑндÑк", |
Dustwraith = "ÐÑлÑнÑй ÐÑизÑак", |
["Eadric the Pure"] = "ÐдÑик ЧиÑÑÑй", |
["Earthcaller Halmgar"] = "ÐаклинаÑелÑниÑа земли ХалмгаÑ", |
Ebonroc = "ЧеÑноÑкал", |
["Eck the Ferocious"] = "Ðк СвиÑепÑй", |
["Edwin VanCleef"] = "Ðдвин ван ÐлиÑ", |
["Elder Brightleaf"] = "ÐÑÐµÐ²ÐµÐ½Ñ Ð¯Ñкий ÐиÑÑ", |
["Elder Ironbranch"] = "ÐÑÐµÐ²ÐµÐ½Ñ ÐÐµÐ»ÐµÐ·Ð½Ð°Ñ ÐеÑвÑ", |
["Elder Nadox"] = "СÑаÑейÑина ÐадокÑ", |
["Elder Stonebark"] = "ÐÑÐµÐ²ÐµÐ½Ñ ÐÐ°Ð¼ÐµÐ½Ð½Ð°Ñ ÐоÑа", |
["Electrocutioner 6000"] = "ÐлекÑÑоÑÐ¾ÐºÐµÑ 6000", |
["Emalon the Storm Watcher"] = "Ðмалон СÑÑаж ÐÑÑи", |
Emeriss = "ÐмеÑиÑÑ", |
["Emperor Dagran Thaurissan"] = "ÐмпеÑаÑÐ¾Ñ ÐагÑан ТаÑÑиÑан", |
["Emperor Vek'lor"] = "ÐмпеÑаÑÐ¾Ñ Ðек'лоÑ", |
["Emperor Vek'nilash"] = "ÐмпеÑаÑÐ¾Ñ Ðек'нилаÑ", |
Entropius = "ÐнÑÑопий", |
["Eonar's Gift"] = "ÐÐ°Ñ ÐонаÑа", |
["Epoch Hunter"] = "ÐÑ Ð¾Ñник ÐеÑноÑÑи", |
Erekem = "ÐÑекем", |
["Eressea Dawnsinger"] = "ÐÑеÑÑÐµÑ ÐевиÑа РаÑÑвеÑа", |
["Essence of Anger"] = "ÐоплоÑение гнева", |
["Essence of Desire"] = "ÐоплоÑение желаниÑ", |
["Essence of Suffering"] = "ÐоплоÑение ÑÑÑаданиÑ", |
Eviscerator = "ÐоÑÑоÑиÑелÑ", |
["Exarch Maladaar"] = "ÐкзаÑÑ ÐаладааÑ", |
["Expedition Commander"] = "ÐаÑалÑник ÑкÑпедиÑии", |
["Eydis Darkbane"] = "ÐÐ¹Ð´Ð¸Ñ ÐÐ¾Ð³Ð¸Ð±ÐµÐ»Ñ Ð¢ÑмÑ", |
["Eye of C'Thun"] = "Ðко Ð'ТÑна", |
["Faction Champions"] = "Ð§ÐµÐ¼Ð¿Ð¸Ð¾Ð½Ñ ÑÑакÑий", |
["Fallen Champion"] = "ÐавÑий воиÑелÑ", |
Falric = "ФалÑик", |
["Falric and Marwyn"] = "ФалÑик и ÐаÑвин", |
["Fankriss the Unyielding"] = "ФанкÑиÑÑ ÐепÑиклоннÑй", |
["Fathom-Lord Karathress"] = "ÐовелиÑÐµÐ»Ñ Ð³Ð»Ñбин ÐаÑаÑÑеÑÑ", |
Felmyst = "ÐÑоÑок СквеÑнÑ", |
["Fenrus the Devourer"] = "ФенÑÑÑ ÐожиÑаÑелÑ", |
["Feral Defender"] = "Ðикий заÑиÑник", |
Festergut = "ТÑÑ Ð»Ð¾Ð¿Ñз", |
Feugen = "Фойген", |
["Fineous Darkvire"] = "ТоÑÐµÐ½Ñ Ð¢ÐµÐ¼Ð½Ð¾ÑÑÑой", |
Firemaw = "ÐгнеÑÑев", |
["Fjola Lightbane"] = "ФÑола ÐÐ¾Ð³Ð¸Ð±ÐµÐ»Ñ Ð¡Ð²ÐµÑа", |
Flamegor = "ÐламегоÑ", |
["Flame Leviathan"] = "ÐгненнÑй ÐевиаÑан", |
["Foreman Thistlenettle"] = "ШÑÐµÐ¹Ð³ÐµÑ Ð§ÐµÑÑÐ¾Ð¿Ð¾Ð»Ð¾Ñ ", |
["Forgemaster Garfrost"] = "ÐаÑалÑник кÑзни ÐаÑÑ Ð»Ð°Ð´", -- Needs review |
["Four Horsemen Chest"] = "СÑндÑк ЧеÑÑÑÐµÑ ÐÑадников", |
["Fras Siabi"] = "ФÑÐ°Ñ Ð¡Ð¸Ð°Ð±Ð¸", |
Freya = "ФÑейÑ", |
["Gahz'ranka"] = "Ðаз'Ñанка", |
["Gahz'rilla"] = "Ðаз'Ñилла", |
["Gal'darah"] = "Ðал'даÑа", |
["Galgann Firehammer"] = "Ðалганн ÐгнемолоÑ", |
Garr = "ÐаÑÑ", |
["Garrosh Hellscream"] = "ÐаÑÑÐ¾Ñ ÐдÑкий ÐÑик", |
Gasher = "Ранокол", |
["Gatewatcher Gyro-Kill"] = "СÑÑаж воÑÐ¾Ñ Ð¢Ð¾ÑенÑй Ðож", |
["Gatewatcher Iron-Hand"] = "СÑÑаж воÑÐ¾Ñ Ð¡ÑалÑÐ½Ð°Ñ ÐлеÑнÑ", |
["Gathios the Shatterer"] = "ÐаÑÐ¸Ð¾Ñ ÐзÑвеÑ", |
Gehennas = "ÐееннаÑ", |
Gelihast = "ÐÐµÐ»Ð¸Ñ Ð°ÑÑ", |
Gelk = "Ðжелк", |
["General Angerforge"] = "ÐенеÑал ÐÑÐ·Ð½Ñ Ðнева", |
["General Bjarngrim"] = "ÐенеÑал ÐÑÑÑнгÑин", |
["General Drakkisath"] = "ÐенеÑал ÐÑаккиÑаÑ", |
["General Rajaxx"] = "ÐенеÑал РаджакÑ", |
["General Vezax"] = "ÐенеÑал ÐезакÑ", |
-- ["General Zarithrian"] = "", |
["Ghamoo-ra"] = "ÐÑ Ð°Ð¼Ñ-Ñа", |
["Ghaz'an"] = "Ðаз'ан", |
["Ghok Bashguud"] = "Ðок ÐÑепкобив", |
Gilnid = "Ðилнид", |
["Gizrul the Slavener"] = "ÐизÑÑл ÐоÑабоÑиÑелÑ", |
["Gloom'rel"] = "ÐÑак'нел", |
Gluth = "ÐлÑÑ", |
Glutton = "ÐбжоÑа", |
["Golemagg the Incinerator"] = "Ðаг-лоÑд из клана ÐоÑдок", |
["Golem Lord Argelmach"] = "ÐовелиÑÐµÐ»Ñ Ð³Ð¾Ð»ÐµÐ¼Ð¾Ð² ÐÑÐ³ÐµÐ»Ð¼Ð°Ñ ", |
["Goraluk Anvilcrack"] = "ÐоÑалÑк ТÑеÑнÑвÑÐ°Ñ ÐаковалÑнÑ", |
["Gormok the Impaler"] = "ÐоÑмок ÐÑонзаÑÑий ÐивенÑ", |
["Gorosh the Dervish"] = "ÐоÑÐ¾Ñ ÐеÑвиÑ", |
["Gortok Palehoof"] = "ÐоÑÑок Ðледное ÐопÑÑо", |
["Gothik the Harvester"] = "ÐоÑик ÐнеÑ", |
["Grand Astromancer Capernian"] = "ÐеÑÑ Ð¾Ð²Ð½Ñй звездоÑÐµÑ ÐапеÑниан", |
["Grand Champions"] = "ÐбÑолÑÑнÑе ÑемпионÑ", |
["Grand Magus Telestra"] = "ÐÐµÐ»Ð¸ÐºÐ°Ñ Ð²ÐµÐ´ÑнÑÑ Ð¢ÐµÐ»ÐµÑÑÑа", |
["Grandmaster Vorpil"] = "Ðеликий маÑÑÐµÑ ÐоÑпил", |
Grandmother = "ÐабÑÑка", |
["Grand Warlock Alythess"] = "ÐÐ»Ð°Ð²Ð½Ð°Ñ ÑеÑнокнижниÑа ÐлиÑеÑÑа", |
["Grand Warlock Nethekurse"] = "ÐлавнÑй ÑеÑнокнижник ÐÑÑÑоклÑÑ", |
["Grand Widow Faerlina"] = "ÐÐµÐ»Ð¸ÐºÐ°Ñ Ð²Ð´Ð¾Ð²Ð° ФаÑлина", |
["Grethok the Controller"] = "ÐÑеÑок РегÑлÑÑоÑ", |
["Gri'lek"] = "ÐÑи'лек", |
Grimlok = "ÐÑимлок", |
Grizzle = "ÐÑиззл", |
Grobbulus = "ÐÑоббÑлÑÑ", |
Grubbis = "ÐÑÑзнÑк", |
["Gruul the Dragonkiller"] = "ÐÑÑÑл ÐÑаконобой", |
["Guard Fengus"] = "СÑÑажник ФенгÑÑ", |
["Guardian of Yogg-Saron"] = "СÑÑаж Ðогг-СаÑона", |
["Guard Mol'dar"] = "СÑÑажник Ðол'даÑ", |
["Guard Slip'kik"] = "СÑÑажник Слип'кик", |
["Gurtogg Bloodboil"] = "ÐÑÑÑогг ÐипÑÑÐ°Ñ ÐÑовÑ", |
Gyth = "ÐиÑ", |
Hadronox = "ХадÑонокÑ", |
Hakkar = "ХаккаÑ", |
Halazzi = "Халаззи", |
Halion = "Халион", |
Halycon = "Халикон", |
Hamhock = "Ð¥ÑÑпконог", |
["Harbinger Skyriss"] = "ÐÑедвеÑÑник СкайÑиÑÑ", |
["Hate'rel"] = "Ðлоб'Ñел", |
["Hazza'rah"] = "Хазза'ÑÐ°Ñ ", |
Hazzas = "ХаззаÑ", |
["Headless Horseman"] = "ÐÑадник без головÑ", |
["Hearthsinger Forresten"] = "ÐевÑий ФоÑÑеÑÑен", |
["Hedrum the Creeper"] = "ХедÑÑм ÐолзÑн", |
["Heigan the Unclean"] = "Хейган ÐеÑеÑÑивÑй", |
["Hellfire Channeler"] = "ЧаÑоÑвоÑÐµÑ Ð¸Ð· ÑиÑадели ÐдÑкого Ðламени", |
["Henry Stern"] = "ÐенÑи ШÑеÑн", |
["Herald Volazj"] = "ÐлаÑаÑай Ðолаж", |
Herod = "ÐеÑод", |
["Hex Lord Malacrass"] = "ÐовелиÑÐµÐ»Ñ Ð¿ÑоклÑÑий ÐалакÑаÑÑ", |
["High Astromancer Solarian"] = "ÐеÑÑ Ð¾Ð²Ð½Ñй звездоÑÐµÑ Ð¡Ð¾Ð»Ð°Ñиан", |
["High Botanist Freywinn"] = "ÐеÑÑ Ð¾Ð²Ð½Ñй боÑаник ФÑейвин", |
["High Inquisitor Fairbanks"] = "ÐеÑÑ Ð¾Ð²Ð½Ñй инквизиÑÐ¾Ñ Ð¤ÑйÑбанкÑ", |
["High Inquisitor Whitemane"] = "ÐеÑÑ Ð¾Ð²Ð½Ñй инквизиÑÐ¾Ñ ÐайÑмейн", |
["High Interrogator Gerstahn"] = "ÐеÑÑ Ð¾Ð²Ð½Ñй дознаваÑÐµÐ»Ñ ÐеÑÑÑан", |
["High King Maulgar"] = "ÐоÑÐ¾Ð»Ñ ÐолгаÑ", |
["Highlord Mograine"] = "ÐеÑÑ Ð¾Ð²Ð½Ñй лоÑд ÐогÑейн", |
["Highlord Omokk"] = "ÐÐ¾Ð¶Ð´Ñ Ðмокк", |
["High Marshal Whirlaxis"] = "ÐаÑÑал ÐолÑÑекÑÑÑ", |
["High Nethermancer Zerevor"] = "ÐеÑÑ Ð¾Ð²Ð½Ñй пÑÑÑÐ¾Ð¼Ð°Ð½Ñ ÐеÑевоÑ", |
["High Overlord Saurfang"] = "ÐеÑÑ Ð¾Ð²Ð½Ñй пÑавиÑÐµÐ»Ñ Ð¡Ð°ÑÑÑанг", |
["High Priestess Arlokk"] = "ÐеÑÑ Ð¾Ð²Ð½Ð°Ñ Ð¶ÑиÑа ÐÑлокк", |
["High Priestess Jeklik"] = "ÐеÑÑ Ð¾Ð²Ð½Ð°Ñ Ð¶ÑиÑа Ðжеклик", |
["High Priestess Mar'li"] = "ÐеÑÑ Ð¾Ð²Ð½Ð°Ñ Ð¶ÑиÑа ÐаÑ'ли", |
["High Priestess of Thaurissan"] = "ÐеÑÑ Ð¾Ð²Ð½Ð°Ñ Ð¶ÑиÑа ТаÑÑиÑÑана", |
["High Priest Thekal"] = "ÐеÑÑ Ð¾Ð²Ð½Ñй жÑÐµÑ Ð¢ÐµÐºÐ°Ð»", |
["High Priest Venoxis"] = "ÐеÑÑ Ð¾Ð²Ð½Ñй жÑÐµÑ ÐенокÑиÑ", |
["High Warlord Naj'entus"] = "ÐеÑÑ Ð¾Ð²Ð½Ñй ÐÐ¾Ð»ÐºÐ¾Ð²Ð¾Ð´ÐµÑ Ðадж'енÑÑÑ", |
Hodir = "ХодиÑ", |
["Houndmaster Grebmar"] = "ÐÑаÑÑ ÐÑебмаÑ", |
["Houndmaster Loksey"] = "ÐÑаÑÑ ÐокÑи", |
Hukku = "Ð¥ÑккÑ", |
Hungarfen = "Топеглад", |
["Hurley Blackbreath"] = "ХаÑли ЧеÑнопÑÑ ", |
["Hyakiss the Lurker"] = "ХиакиÑÑ Ð¡ÐºÑÑÑенÑ", |
["Hydromancer Thespia"] = "ÐидÑÐ¾Ð¼Ð°Ð½Ñ Ð¢ÐµÑпиÑ", |
["Hydromancer Velratha"] = "ÐидÑÐ¾Ð¼Ð°Ð½Ñ ÐелÑаÑа", |
Hydrospawn = "ÐидÑоÑваÑÑ", |
["Hydross the Unstable"] = "ÐидÑоÑÑ ÐеÑÑабилÑнÑй", |
["Icecrown Gunship Battle"] = "Ðой на коÑаблÑÑ ", |
Icehowl = "ÐедÑной Рев", |
["Ice Sphere"] = "ÐедÑÐ½Ð°Ñ ÑÑеÑа", |
Ichoron = "ÐнойÑон", |
Ick = "Ðк", -- Needs review |
["Ignis the Furnace Master"] = "ÐовелиÑÐµÐ»Ñ ÐоÑнов ÐгниÑ", |
["Illidan Stormrage"] = "Ðллидан ЯÑоÑÑÑ ÐÑÑи", |
["Illidari Council"] = "Ð¡Ð¾Ð²ÐµÑ ÐллидаÑи", |
["Illyanna Ravenoak"] = "Ðллиана ÐоÑонÑÑ ÐлÑÑ Ð°", |
["Immol'thar"] = "ÐеÑÑмеÑ'ÑеÑ", |
["Infinite Corruptor"] = "ÐÑквеÑниÑÐµÐ»Ñ Ð¸Ð· Ñода ÐеÑконеÑноÑÑи", |
["Infinity Blades"] = "Ðлинки ÐеÑконеÑноÑÑи", |
["Ingvar the Plunderer"] = "ÐÐ½Ð³Ð²Ð°Ñ Ð Ð°ÑÑ Ð¸ÑиÑелÑ", |
["Instructor Malicia"] = "ÐнÑÑÑÑкÑÐ¾Ñ ÐоваÑниÑа", |
["Instructor Razuvious"] = "ÐнÑÑÑÑкÑÐ¾Ñ Ð Ð°Ð·Ñвий", |
["Interrogator Vishas"] = "ÐознаваÑÐµÐ»Ñ ÐиÑаÑ", |
Ionar = "ÐонаÑ", |
Ironaya = "ÐÑонайа", |
Ironspine = "ÐелезноÑпин", |
Isalien = "Ðзалиен", |
Jade = "ÐеÑÑиÑ", |
["Jammal'an the Prophet"] = "Ðжаммал'ан ÐÑоÑок", |
["Jan'alai"] = "Ðжан'алай", |
["Jandice Barov"] = "ÐÐ¶Ð°Ð½Ð´Ð¸Ñ ÐаÑова", |
["Jedoga Shadowseeker"] = "Ðжедога ÐÑкаÑелÑниÑа Теней", |
["Jed Runewatcher"] = "Ðжед Ð Ñновед", |
["Jergosh the Invoker"] = "ÐеÑÐ³Ð¾Ñ ÐÑизÑваÑÐµÐ»Ñ ÐÑÑ Ð¾Ð²", |
["Jin'do the Hexxer"] = "Ðжин'до ÐÑоклинаÑелÑ", |
["Jormungar Behemoth"] = "ÐоÑмÑнгаÑÑкое ÑÑдовиÑе", |
Jormungars = "ÐоÑмÑнгаÑÑ", |
Julianne = "ÐжÑлианна", |
["Junk Bot"] = "ÐаÑÐ°Ñ Ð»Ð¾Ð±Ð¾Ñ", |
["Kael'thas Sunstrider"] = "ÐелÑ'ÑÐ°Ñ Ð¡Ð¾Ð»Ð½ÐµÑнÑй СкиÑалеÑ", |
Kalecgos = "ÐалеÑгоÑ", |
["Kam Deepfury"] = "Ðам ÐневливÑй", |
["Kazkaz the Unholy"] = "Ðазказ ÐеÑиÑÑÑй", |
["Kaz'rogal"] = "Ðаз'Ñогал", |
["Keli'dan the Breaker"] = "Ðели'дан РазÑÑÑиÑелÑ", |
["Kel'Thuzad"] = "Ðел'ТÑзад", |
Keristrasza = "ÐеÑиÑÑÑаза", |
["Kiggler the Crazed"] = "ÐÐ¸Ð³Ð³Ð»ÐµÑ ÐезÑмнÑй", |
["Kil'jaeden"] = "Ðил'джеден", |
["Kil'rek"] = "Ðил'Ñек", |
["King Dred"] = "ÐоÑÐ¾Ð»Ñ ÐÑед", |
["King Gordok"] = "ÐоÑÐ¾Ð»Ñ ÐоÑдок", |
["King Llane Piece"] = "ÐоÑÐ¾Ð»Ñ Ðлейн", |
["King Ymiron"] = "ÐоÑÐ¾Ð»Ñ ÐмиÑон", |
["Kirtonos the Herald"] = "ÐиÑÑÐ¾Ð½Ð¾Ñ ÐлаÑаÑай", |
["Knot Thimblejack's Cache"] = "Тайник Уззла ÐапеÑÑÑÑка", |
Kolk = "Ðолк", |
Kologarn = "ÐологаÑн", |
["Koralon the Flame Watcher"] = "ÐоÑалон СÑÑаж ÐгнÑ", |
Kormok = "ÐоÑмок", |
Kresh = "ÐÑиг", |
Krick = "ÐÑик", |
["Krick and Ick"] = "ÐÑик и Ðк", -- Needs review |
["Krik'thir the Gatewatcher"] = "ÐÑик'Ð¢Ð¸Ñ Ð¥ÑаниÑÐµÐ»Ñ ÐÑаÑ", |
["Krosh Firehand"] = "ÐÑÐ¾Ñ ÐÐ³Ð½ÐµÐ½Ð½Ð°Ñ Ð Ñка", |
Krystallus = "ÐÑиÑÑаллÑÑ", |
Kurinnaxx = "ÐÑÑиннакÑ", |
["Lady Anacondra"] = "ÐовелиÑелÑниÑа ÐнакондÑа", |
["Lady Blaumeux"] = "Ðеди Ðломе", |
["Lady Deathwhisper"] = "Ðеди СмеÑÑнÑй ШепоÑ", |
["Lady Illucia Barov"] = "Ðеди ÐллÑÑÐ¸Ñ ÐаÑова", |
["Lady Malande"] = "Ðеди Ðаланда", |
["Lady Sacrolash"] = "Ðеди СакÑолаÑ", |
["Lady Sarevess"] = "Ðеди СаÑевеÑÑ", |
["Lady Vashj"] = "Ðеди ÐайÑ", |
Laj = "Ðадж", |
Landslide = "СелÑ", |
Lavanthor = "ÐаванÑоÑ", |
["Left Arm"] = "ÐÐµÐ²Ð°Ñ ÑÑка", |
["Leotheras the Blind"] = "ÐеоÑеÑÐ°Ñ Ð¡Ð»ÐµÐ¿ÐµÑ", |
Lethon = "ÐеÑон", |
Lethtendris = "ÐеÑÑендÑиÑ", |
["Leviathan Mk II"] = "ÐевиаÑан II", |
["Ley-Guardian Eregos"] = "Ð¥ÑаниÑÐµÐ»Ñ ÑнеÑгии ÐÑегоÑ", |
["Lieutenant Drake"] = "ÐейÑÐµÐ½Ð°Ð½Ñ ÐÑейк", |
["Lieutenant General Andorov"] = "ÐенеÑал-лейÑÐµÐ½Ð°Ð½Ñ ÐндоÑов", |
Loatheb = "ÐоÑÑ Ð¸Ð±", |
Loken = "Ðокен", |
["Lord Alexei Barov"] = "ÐоÑд ÐлекÑей ÐаÑов", |
["Lord Cobrahn"] = "ÐоÑд ÐобÑан", |
["Lord Hel'nurath"] = "ÐоÑд Хел'нÑÑаÑ", |
["Lord Incendius"] = "ÐоÑд ÐпалиÑелÑ", |
["Lord Jaraxxus"] = "ÐоÑд ÐжаÑакÑÑÑ", |
["Lord Kazzak"] = "ÐоÑд Ðаззак", |
["Lord Kri"] = "ÐоÑд ÐÑи", |
["Lord Marrowgar"] = "ÐоÑд РебÑад", |
["Lord Pythas"] = "ÐоÑд ÐиÑонаÑ", |
["Lord Roccor"] = "ÐоÑд РоккоÑ", |
["Lord Sanguinar"] = "ÐоÑд СангвинаÑ", |
["Lord Serpentis"] = "ÐоÑд СеÑпенÑиÑ", |
["Lord Skwol"] = "ÐоÑд Сквол", |
["Lord Valthalak"] = "ÐоÑд ÐалÑÑÑ Ð°Ð»Ð°Ðº", |
["Lord Victor Nefarius"] = "ÐоÑд ÐикÑÐ¾Ñ ÐеÑаÑиÑÑ", |
["Lord Vyletongue"] = "ÐоÑд ÐлоÑзÑкий", |
["Lorekeeper Polkelt"] = "СказиÑÐµÐ»Ñ ÐолкелÑ", |
Loro = "ÐоÑо", |
Lucifron = "ÐÑÑиÑÑон", |
["Mad Magglish"] = "ÐезÑмнÑй ÐагглиÑ", |
Maexxna = "ÐекÑна", |
["Mage-Lord Urom"] = "Ðаг-лоÑд УÑом", |
["Magister Kalendris"] = "ÐагиÑÑÑ ÐалендÑиÑ", |
["Magistrate Barthilas"] = "ÐиÑовой ÑÑдÑÑ ÐаÑÑилаÑ", |
Magmadar = "ÐагмадаÑ", |
Magmus = "ÐагмÑÑ", |
Magra = "ÐагÑа", |
Magtheridon = "ÐагÑеÑидон", |
["Maiden of Grief"] = "Ðева СкоÑби", |
["Maiden of Virtue"] = "ÐлагоÑеÑÑÐ¸Ð²Ð°Ñ Ð´ÐµÐ²Ð°", |
["Majordomo Executus"] = "ÐажоÑдом ÐкзекÑÑÑÑ", |
Malacrass = "ÐалакÑаÑÑ", |
["Maleki the Pallid"] = "Ðалекай ÐледнÑй", |
["Mal'Ganis"] = "Ðал'ÐаниÑ", |
Malygos = "ÐалигоÑ", |
Maraudos = "ÐаÑодоÑ", |
["Marduk Blackpool"] = "ÐаÑдÑк ÐлÑкпÑл", |
["Marisa du'Paige"] = "ÐаÑиÑа Ð´Ñ ÐÑж", |
Marwyn = "ÐаÑвин", |
["Master Engineer Telonicus"] = "СÑаÑÑий Ð¸Ð½Ð¶ÐµÐ½ÐµÑ Ð¢ÐµÐ»Ð¾Ð½Ð¸ÐºÑÑ", |
["Maur Grimtotem"] = "ÐаÑÑ ÐловеÑий ТоÑем", |
Meathook = "ÐÑÑной ÐÑÑк", |
["Mechano-Lord Capacitus"] = "ÐÐµÑ Ð°Ð½Ð¾-лоÑд ÐонденÑаÑон", |
Medivh = "Ðедив", |
["Mekgineer Steamrigger"] = "ÐÐµÐºÐ¶Ð¸Ð½ÐµÑ ÐаÑопÑÑк", |
["Mekgineer Thermaplugg"] = "ÐÐµÐºÐ¶Ð¸Ð½ÐµÑ Ð¢ÐµÑмоÑÑепÑелÑ", |
["Mennu the Betrayer"] = "ÐÐµÐ½Ð½Ñ ÐÑедаÑелÑ", |
["Meshlok the Harvester"] = "ÐеÑлок ÐнеÑ", |
Midnight = "ÐолноÑÑ", |
Mijan = "Ðиджан", |
Mimiron = "ÐимиÑон", |
["Miner Johnson"] = "Ð¨Ð°Ñ ÑÐµÑ ÐжонÑон", |
["Mistress of Pain"] = "ÐоÑпожа Ðоли", |
Moam = "Ðоам", |
Mogor = "ÐогоÑ", |
["Mokra the Skullcrusher"] = "ÐокÑа ÐÑобиÑÐµÐ»Ñ Ð§ÐµÑепов", |
Moorabi = "ÐÑÑаби", |
Moragg = "ÐоÑагг", |
["Mordresh Fire Eye"] = "ÐоÑдÑÐµÑ ÐгненнÑй Ðлаз", |
["Mor Grayhoof"] = "ÐÐ¾Ñ Ð¡ÐµÑое ÐопÑÑо", |
Moroes = "ÐоÑоÑз", |
["Morogrim Tidewalker"] = "ÐоÑогÑим ÐолноÑÑÑп", |
Morphaz = "ÐоÑÑаз", |
["Mother Shahraz"] = "ÐаÑÑÑка Ð¨Ð°Ñ Ñаз", |
["Mother Smolderweb"] = "ÐаÑÑ ÐÑÐ¼Ð½Ð°Ñ ÐаÑÑина", |
["Mr. Smite"] = "ÐиÑÑÐµÑ ÐаÑк", |
["Muradin Bronzebeard"] = "ÐÑÑадин ÐÑонзобоÑод", |
["Murkblood Twin"] = "ÐÐ»Ð¸Ð·Ð½ÐµÑ Ð¢ÐµÐ¼Ð½Ð¾Ð¹ ÐÑови", |
["Murkblood Twins"] = "ÐлизнеÑÑ Ð¢ÐµÐ¼Ð½Ð¾Ð¹ ÐÑови", |
Murmur = "ÐоÑмоÑÑн", |
["Murta Grimgut"] = "ÐÑÑÑа ÐÑаÑнобÑÑÑ ", |
["M'uru"] = "Ð'аÑÑ", |
Mushgog = "ÐÑÑгог", |
["Mutanus the Devourer"] = "ÐÑÑанÑÑ ÐожиÑаÑелÑ", |
Nalorakk = "ÐалоÑакк", |
Nazan = "Ðазан", |
Nefarian = "ÐеÑаÑиан", |
["Nekrum Gutchewer"] = "ÐекÑÑм ÐиÑкожÑй", |
["Nerub'enkan"] = "ÐеÑÑб'Ñнкан", |
["Nethermancer Sepethrea"] = "ÐÑÑÑÐ¾Ð¼Ð°Ð½Ñ Ð¡ÐµÐ¿ÐµÑÑеÑ", |
Netherspite = "Ðнев ÐÑÑÑоÑÑ", |
["Netherstrand Longbow"] = "ÐлиннÑй лÑк ÐÑÐ°Ñ ÐÑÑÑоÑÑ", |
["Nexus-Prince Shaffar"] = "ÐÑÐ¸Ð½Ñ Ð¨Ð°ÑÑаÑ", |
Nightbane = "ÐоÑÐ½Ð°Ñ ÐогибелÑ", |
["Noth the Plaguebringer"] = "ÐÐ¾Ñ Ð§Ñмной", |
["Novos the Summoner"] = "ÐÐ¾Ð²Ð¾Ñ ÐÑизÑваÑелÑ", |
Noxxion = "ÐокÑион", |
["Obsidian Sentinel"] = "ÐбÑидиановÑй ÑаÑовой", |
["Odo the Blindwatcher"] = "Ðдо Слепой СÑÑаж", |
["Ogom the Wretched"] = "Ðгом ÐÑезÑеннÑй", |
["Ok'thor the Breaker"] = "Ðк'ÑÐ¾Ñ Ð Ð°Ð·ÑÑÑиÑелÑ", |
["Old Serra'kis"] = "СÑаÑина СеÑÑакиÑ", |
["Olm the Summoner"] = "Ðлм СозÑваÑÑий", |
["Omor the Unscarred"] = "ÐÐ¼Ð¾Ñ ÐеодолимÑй", |
Onyxia = "ÐникÑиÑ", |
["Orgrim's Hammer"] = "ÐÐ¾Ð»Ð¾Ñ ÐÑгÑима", |
["Ormorok the Tree-Shaper"] = "ÐÑмоÑок ÐоÑпиÑаÑÐµÐ»Ñ ÐеÑев", |
["Oro Eyegouge"] = "ÐÑо ÐÑÑвиглаз", |
["Ossirian the Unscarred"] = "ÐÑÑиÑиан ÐеÑÑзвимÑй", |
Ouro = "ÐÑÑо", |
["Overlord Ramtusk"] = "ÐлаÑÑиÑÐµÐ»Ñ Ð¢Ð°ÑаннÑй ÐлÑк", |
["Overlord Wyrmthalak"] = "ÐлаÑÑиÑÐµÐ»Ñ ÐмейÑалак", |
["Overmaster Pyron"] = "ÐодÑиниÑÐµÐ»Ñ ÐиÑон", |
["Overseer Tidewrath"] = "ÐаблÑдаÑÐµÐ»Ñ Ðнев ÐÑилива", |
Pandemonius = "Ðандемоний", |
["Panzor the Invincible"] = "ÐанÑÐµÑ ÐепобедимÑй", |
Patchwerk = "ÐоÑкÑÑик", |
["Pathaleon the Calculator"] = "ÐаÑалеон ÐÑÑиÑлиÑелÑ", |
Phalanx = "ФаланкÑ", |
["Phaseshift Bulwark"] = "ФазовÑй колеÑ", |
Pimgib = "Ðимгиб", |
["Plaguemaw the Rotting"] = "ЧÑмобÑÑÑ Ðнилой", |
["Plugger Spazzring"] = "ШÑÐ¾Ð¿Ð¿Ð¾Ñ ÐаливалÑ", |
["Postmaster Malown"] = "ÐоÑÑалÑон ÐÑлоÑн", |
["Priestess Delrissa"] = "ÐÑиÑа ÐелÑиÑÑа", |
["Prince Keleseth"] = "ÐÑÐ¸Ð½Ñ ÐелеÑеÑ", |
["Prince Malchezaar"] = "ÐÑÐ¸Ð½Ñ ÐалÑезаÑ", |
["Prince Skaldrenox"] = "ÐÑÐ¸Ð½Ñ Ð¡ÐºÐ°Ð»ÑдÑенокÑ", |
["Princess Huhuran"] = "ÐÑинÑеÑÑа Ð¥ÑÑ ÑÑан", |
["Princess Moira Bronzebeard"] = "ÐÑинÑеÑÑа ÐойÑа ÐÑонзобоÑод", |
["Princess Tempestria"] = "ÐÑинÑеÑÑа ÐÑÑилла", |
["Princess Theradras"] = "ÐÑинÑеÑÑа ТеÑадÑаÑ", |
["Princess Yauj"] = "ÐÑинÑеÑÑа ЯÑдж", |
["Prince Taldaram"] = "ÐÑÐ¸Ð½Ñ Ð¢Ð°Ð»Ð´Ð°Ñам", |
["Prince Tenris Mirkblood"] = "ÐÑÐ¸Ð½Ñ Ð¢ÐµÐ½ÑÐ¸Ñ ÐÑÑÐ½Ð°Ñ ÐÑовÑ", |
["Prince Tortheldrin"] = "ÐÑÐ¸Ð½Ñ Ð¢Ð¾ÑÑелдÑин", |
["Prince Valanar"] = "ÐÑÐ¸Ð½Ñ ÐаланаÑ", |
["Professor Putricide"] = "ÐÑоÑеÑÑÐ¾Ñ ÐеÑзоÑид", |
["Pure Spawn of Hydross"] = "ЧиÑÑое поÑождение ÐидÑоÑÑа", |
Pusillin = "ÐÑзиллин", |
["Pyroguard Emberseer"] = "ÐиÑоÑÑÑаж СозеÑÑаÑÐµÐ»Ñ Ð£Ð³Ð»ÐµÐ¹", |
["Pyromancer Loregrain"] = "ÐиÑоман ÐеÑно ÐÑдÑоÑÑи", |
Quagmirran = "ÐвагмиÑÑан", |
["Quartermaster Zigris"] = "ÐнÑÐµÐ½Ð´Ð°Ð½Ñ ÐигÑиÑ", |
["Rage Winterchill"] = "ÐÑÑÑй Хлад", |
Ragglesnout = "ÐÑÑглоÑÑл", |
["Raging Spirit"] = "ÐневнÑй дÑÑ ", |
Ragnaros = "РагнаÑоÑ", |
["Ramstein the Gorger"] = "РамÑÑайн ÐенаÑÑÑнÑй", |
["Ras Frostwhisper"] = "Ð Ð°Ñ ÐедÑной ШепоÑ", |
Rattlegore = "ÐÑомоклин", |
["Razorclaw the Butcher"] = "ÐÑÑÑоклÑк ÐÑÑник", |
["Razorgore the Untamed"] = "ÐÑиÑвоÑмеÑÑ ÐеÑкÑоÑимÑй", |
Razorlash = "ÐÑиÑÐ²Ð¾Ñ Ð»ÐµÑÑ", |
Razorscale = "ÐÑÑÑокÑÑлаÑ", |
["Reliquary of Souls"] = "ÐÑобниÑа дÑÑ", |
Renataki = "РенаÑаки", |
["Restless Skeleton"] = "ÐедÑемлÑÑий ÑкелеÑ", |
Rethilgore = "РеÑилгоÑ", |
Revelosh = "РевелоÑ", |
["Rhahk'Zor"] = "Рак'ÐоÑ", |
["Ribbly Screwspigot"] = "Риббли ÐÑÑÑипÑоб", |
["Right Arm"] = "ÐÑÐ°Ð²Ð°Ñ ÑÑка", |
Roar = "Ð¥Ð¾Ñ Ð¾ÑÑн", |
["Rokad the Ravager"] = "Рокад ÐпÑÑÑоÑиÑелÑ", |
["Rokdar the Sundered Lord"] = "Ð Ð¾ÐºÐ´Ð°Ñ ÐокинÑÑÑй ÐоÑд", |
["Rokmar the Crackler"] = "Ð Ð¾ÐºÐ¼Ð°Ñ Ð¢ÑеÑкÑн", |
Romulo = "РомÑло", |
["Romulo & Julianne"] = "РомÑло и ÐжÑлÑенна", |
Rotface = "ÐниломоÑд", |
Rotgrip = "ÐнилопаÑÑÑ", |
["Runemaster Molgeim"] = "ÐаÑÑÐµÑ ÑÑн Ðолгейм", |
["Runok Wildmane"] = "Ð Ñнок ÐÑйногÑивÑй", |
Ruuzlu = "Ð ÑÑзлÑ", |
["Salramm the Fleshcrafter"] = "СалÑамм ÐлоÑоÑез", |
["Sanctum Sentry"] = "ЧаÑовой ÑвÑÑилиÑа", |
["Sandarr Dunereaver"] = "СандаÑÑ Ð Ð°Ð·Ð¾ÑиÑÐµÐ»Ñ ÐаÑÑ Ð°Ð½Ð¾Ð²", |
["Sandfury Executioner"] = "ÐÐ°Ð»Ð°Ñ Ð¸Ð· клана ÐеÑÑаной ÐÑÑи", |
Sapphiron = "СапÑиÑон", |
Sara = "СаÑа", |
["Saronite Animus"] = "СаÑониÑовÑй вÑаг", |
Sartharion = "СаÑÑаÑион", |
["Sathrovarr the Corruptor"] = "СаÑÑоваÑÑ ÐÑквеÑниÑелÑ", |
-- ["Saviana Ragefire"] = "", |
["Scarlet Commander Mograine"] = "ÐÐ¾Ð¼Ð°Ð½Ð´Ð¸Ñ ÐогÑейн из Ðлого оÑдена", |
["Scourgelord Tyrannus"] = "ÐовелиÑÐµÐ»Ñ ÐлеÑи ТиÑаний", |
["Seeth'rel"] = "СиÑ'Ñел", |
["Selin Fireheart"] = "Селин Ðгненное СеÑдÑе", |
["Sergeant Bly"] = "СеÑÐ¶Ð°Ð½Ñ Ðлай", |
["Shade of Akama"] = "Ð¢ÐµÐ½Ñ ÐкамÑ", |
["Shade of Aran"] = "Ð¢ÐµÐ½Ñ ÐÑана", |
["Shade of Eranikus"] = "Ð¢ÐµÐ½Ñ ÐÑаникÑÑа", |
["Shadikith the Glider"] = "Ð¨Ð°Ð´Ð¸ÐºÐ¸Ñ Ð¡ÐºÐ¾Ð»ÑзÑÑий", |
["Shadow Hunter Vosh'gajin"] = "Ð¢ÐµÐ¼Ð½Ð°Ñ Ð¾Ñ Ð¾ÑниÑа ÐоÑ'гаджин", |
["Shadow of Leotheras"] = "Ð¢ÐµÐ½Ñ ÐеоÑеÑаÑа", |
["Shadowpriest Sezz'ziz"] = "ТемнÑй жÑÐµÑ Ð¨ÐµÐ·Ð·'зиз", |
Shadron = "ШадÑон", |
Shazzrah = "ШаззÑÐ°Ñ ", |
["Shirrak the Dead Watcher"] = "ШиÑÑак СÑÑаж ÐеÑÑвÑÑ ", |
Sindragosa = "СиндÑагоÑа", |
["Sir Zeliek"] = "СÑÑ Ðелиек", |
["Sjonnir The Ironshaper"] = "СÑÐ¾Ð½Ð½Ð¸Ñ ÐиÑейÑик", |
["Skadi the Ruthless"] = "Скади ÐезжалоÑÑнÑй", |
["Skarr the Unbreakable"] = "СкаÑÑ ÐепÑеклоннÑй", |
["Skarvald the Constructor"] = "СкалÑваÑд СÑÑоиÑелÑ", |
["Skra'gath"] = "СкÑагаÑ", |
Skul = "ЧеÑеп", |
Skum = "Шкам", |
["Slad'ran"] = "Слад'Ñан", |
Sneed = "Снид", |
["Sneed's Shredder"] = "ÐÑоÑÑÐµÑ Ð¡Ð½Ð¸Ð´Ð°", |
["Solakar Flamewreath"] = "СолакаÑÑкий огнеÑеÑвÑ", |
["Solarium Agent"] = "ÐÐ³ÐµÐ½Ñ Ð¡Ð¾Ð»Ð½ÐµÑной ÑеÑÑаÑÑ", |
["Solarium Priest"] = "ÐÑÐµÑ Ð¡Ð¾Ð»Ð½ÐµÑной ÑеÑÑаÑÑ", |
["Spirestone Battle Lord"] = "ÐÐ¾Ð»ÐºÐ¾Ð²Ð¾Ð´ÐµÑ Ð¸Ð· клана ЧеÑной ÐеÑÑинÑ", |
["Spirestone Butcher"] = "ÐÑÑник из клана ЧеÑной ÐеÑÑинÑ", |
["Spirestone Lord Magus"] = "ÐоÑд-Ð²Ð¾Ð»Ñ Ð² из клана ЧеÑной ÐеÑÑинÑ", |
["Staff of Disintegration"] = "ÐоÑÐ¾Ñ Ð Ð°ÑпÑлениÑ", |
Stalagg = "СÑалагг", |
Steelbreaker = "СÑалелом", |
["Stomper Kreeg"] = "ТопоÑÑн ÐÑиг", |
Stonespine = "ÐаменнÑй ÐÑебенÑ", |
["Stormcaller Brundir"] = "ÐÑÑевеÑÑник ÐÑÑндиÑ", |
Strawman = "ÐалбеÑ", |
["Sulfuron Harbinger"] = "ÐÑедвеÑÑник СÑлÑÑÑÑон", |
Supremus = "СÑпÑемÑÑ", |
["Svala Sorrowgrave"] = "Свала ÐеÑноÑкоÑбÑÑаÑ", |
["Swamplord Musel'ek"] = "ÐладÑка болоÑа ÐÑÑел'ек", |
Taerar = "ТаÑÑаÑ", |
["Tainted Spawn of Hydross"] = "ÐÑквеÑненное поÑождение ÐидÑоÑÑа", |
["Talon King Ikiss"] = "ÐоÑÐ¾Ð»Ñ Ð²Ð¾Ñонов ÐйкиÑÑ", |
["Taragaman the Hungerer"] = "ТаÑагаман ÐенаÑÑÑнÑй", |
["Targorr the Dread"] = "ТаÑгоÑÑ Ð£Ð¶Ð°ÑнÑй", |
Tavarok = "ТаваÑок", |
Techbot = "Ð¢ÐµÑ Ð±Ð¾Ñ", |
Temporus = "ТемпоÑÑÑ", |
["Tendris Warpwood"] = "ТендÑÐ¸Ñ ÐÑиводÑев", |
Tenebron = "ТенебÑон", |
["Terestian Illhoof"] = "ТеÑеÑÑиан ÐолÑное ÐопÑÑо", |
["Teron Gorefiend"] = "ТеÑон ÐÑовожад", |
Thaddius = "ТаддиÑÑ", |
["Thaladred the Darkener"] = "ТаладÑед ÐаÑемниÑелÑ", |
["Thane Korth'azz"] = "Тан ÐоÑÑазз", |
["The Beast"] = "ÐвеÑÑ", |
["The Beasts of Northrend"] = "ÐоÑдÑколÑÑкие ÑÑдовиÑа", |
["The Big Bad Wolf"] = "Ðлой и ÑÑÑаÑнÑй ÑеÑÑй волк", |
["The Black Knight"] = "ЧеÑнÑй ÑÑÑаÑÑ", |
["The Black Stalker"] = "ЧеÑÐ½Ð°Ñ ÐÑ Ð¾ÑниÑа", |
["The Blue Brothers"] = "Синие бÑаÑÑÑ", |
["The Bug Family"] = "СемейÑÑво наÑекомÑÑ ", |
["The Crone"] = "ÐедÑма", |
["The Curator"] = "СмоÑÑиÑелÑ", |
["The Eredar Twins"] = "ÐлизнеÑÑ ÐÑедаÑа", |
["The Four Horsemen"] = "ЧеÑÑÑе ÐÑадника", |
["The Illidari Council"] = "Ð¡Ð¾Ð²ÐµÑ ÐллидаÑи", |
["The Iron Council"] = "Ðелезное ÑобÑание", |
["Theka the Martyr"] = "Тека ÐÑÑеник", |
["The Lich King"] = "ÐоÑолÑ-лиÑ", |
["The Lurker Below"] = "СкÑÑÑÐµÐ½Ñ Ð³Ð»Ñбин", |
["The Maker"] = "ÐаÑÑеÑ", |
["The Prophet Skeram"] = "ÐÑоÑок СкеÑам", |
["The Prophet Tharon'ja"] = "ÐÑоÑок ТаÑон'джа", |
["The Ravenian"] = "Равениан", |
["The Razza"] = "Разза", |
["The Seven Dwarves"] = "ТемнÑе Ñ ÑаниÑели", |
["The Skybreaker"] = "УÑмиÑиÑÐµÐ»Ñ Ð½ÐµÐ±ÐµÑ", |
["The Tribunal of Ages"] = "ТÑибÑнал веков", |
["The Twin Emperors"] = "ÐлизнеÑÑ ÐмпеÑаÑоÑа", |
["The Twin Val'kyr"] = "ÐалÑ'киÑÑ-близнеÑÑ", |
["The Unforgiven"] = "ÐепÑоÑеннÑй", |
["The Windreaver"] = "ÐеÑÑобой", |
Thorim = "ТоÑим", |
["Thorngrin the Tender"] = "СкалезÑб СкоÑбнÑй", |
["Tidewalker Lurker"] = "ÐÑиливнÑй кÑаденÑ", |
["Timmy the Cruel"] = "ТайлеÑ", |
Tinhead = "ÐедноголовÑй", |
["Tinkerer Gizlock"] = "РемонÑник Ðизлок", |
["Tirion Fordring"] = "ТиÑион ФоÑдÑинг", |
Tito = "ТиÑо", |
["Toravon the Ice Watcher"] = "ТоÑавон СÑÑаж ÐÑда", |
["Trigore the Lasher"] = "ТÑÐ¸Ð³Ð¾Ñ Ð¥Ð»ÐµÑÑÑн", |
Trollgore = "ÐÑовоÑÑоллÑ", |
["Tsu'zee"] = "ЦÑ'зи", |
["Tuten'kash"] = "ТÑÑен'каÑ", |
["Twilight Lord Kelris"] = "ÐовелиÑÐµÐ»Ñ ÑÑмÑака ÐелÑиÑ", |
["Urok Doomhowl"] = "ÐÑÑок СмеÑÑнÑй ÐоплÑ", |
["Vaelastrasz the Corrupt"] = "ÐалеÑÑÑаз ÐоÑоÑнÑй", |
["Valithria Dreamwalker"] = "ÐалиÑÑÐ¸Ñ Ð¡Ð½Ð¾Ñ Ð¾Ð´Ð¸Ñа", |
["Val'kyr Shadowguard"] = "ÐалÑ'киÑа - ÑÑÑаж ТÑмÑ", |
["Varian Wrynn"] = "ÐаÑиан Ринн", |
["Varos Cloudstrider"] = "ÐаÑÐ¾Ñ ÐаоблаÑнÑй СÑÑанник", |
Vazruden = "ÐазÑÑден", |
["Vazruden the Herald"] = "ÐеÑалÑд ÐазÑÑден", |
Vectus = "ÐекÑÑÑ", |
Vem = "Ðем", |
Veng = "Ðенг", |
["Veras Darkshadow"] = "ÐеÑÐ°Ñ ÐлÑбокий ÐÑак", |
["Verdan the Everliving"] = "ÐеÑдан ÐеÑÑмеÑÑнÑй", |
Verek = "ÐеÑек", |
Vesperon = "ÐеÑпеÑон", |
Vexallus = "ÐекÑалиÑÑ", |
["Veyzhak the Cannibal"] = "Ðейжак Ðаннибал", |
["Vile'rel"] = "ÐнÑÑ'Ñел", |
Viscidus = "ÐеÑиÑÑоÑон", |
["Viscous Fallout"] = "ÐÐ¸Ð¿ÐºÐ°Ñ Ð¼ÑÑÑ", |
["Void Reaver"] = "СÑÑаж ÐезднÑ", |
Volkhan = "ÐÐ¾Ð»Ñ Ð°Ð½", |
["VX-001"] = "VX-001", |
["Warbringer O'mrogg"] = "Ð'мÑогг ÐавоеваÑелÑ", |
["Warchief Blackhand Piece"] = "Ðоевой Ð²Ð¾Ð¶Ð´Ñ Ð§ÐµÑноÑÑк", |
["Warchief Kargath Bladefist"] = "ÐÐ¾Ð¶Ð´Ñ ÐаÑÐ³Ð°Ñ ÐÑÑÑоÑÑк", |
["Warchief Rend Blackhand"] = "ÐÐ¾Ð¶Ð´Ñ Ð ÐµÐ½Ð´ ЧеÑноÑÑк", |
["Warden Mellichar"] = "СÑÑаж ÐеллиÑаÑ", |
["Warder Stilgiss"] = "ТÑÑемÑик СÑилгиÑÑ", |
["Warlord Kalithresh"] = "ÐÐ¾Ð»ÐºÐ¾Ð²Ð¾Ð´ÐµÑ ÐалиÑÑеÑ", |
["War Master Voone"] = "Ðоевода ÐÑн", |
["Warmaul Champion"] = "Чемпион клана Ðоевого ÐолоÑа", |
["Warp Slicer"] = "ÐÑкоÑÐµÐ¶ÐµÐ½Ð½Ð°Ñ Ð»Ð¾Ð¼ÑеÑезка", |
["Warp Splinter"] = "УзлодÑевенÑ", |
["Watchkeeper Gargolmar"] = "ÐаÑалÑник ÑÑÑажи ÐаÑголмаÑ", |
Weaver = "ТкаÑик", |
["Witch Doctor Zum'rah"] = "ÐÐ½Ð°Ñ Ð°ÑÑ ÐÑм'ÑÐ°Ñ ", |
["Wolf Master Nandos"] = "ÐÐ¾Ð¼Ð°Ð½Ð´Ð¸Ñ Ð²Ð¾Ñгенов ÐандоÑ", |
["Wrath-Scryer Soccothrates"] = "ÐÑÐ¾Ð²Ð¸Ð´ÐµÑ Ðнева СоккоÑаÑ", |
Wushoolay = "ÐÑÑÑлай", |
Xevozz = "ÐÑевозз", |
["XT-002 Deconstructor"] = "РазÑÑÑиÑÐµÐ»Ñ XT-002", |
["Yogg-Saron"] = "Ðогг-СаÑон", |
Ysondre = "ÐÑондÑа", |
Zekkis = "ÐеккиÑ", |
["Zelemar the Wrathful"] = "ÐÐµÐ»ÐµÐ¼Ð°Ñ ÐневнÑй", |
["Zereketh the Unbound"] = "ÐеÑÐµÐºÐµÑ ÐездоннÑй", |
Zerillis = "ÐеÑиллиÑ", |
["Zevrim Thornhoof"] = "ÐевÑим ТеÑновое ÐопÑÑо", |
Zolo = "Ðоло", |
["Zul'Farrak Dead Hero"] = "ÐеÑÑвÑй ÐеÑой ÐÑл'ФаÑÑака", |
["Zul'jin"] = "ÐÑл'джин", |
["Zul'Lor"] = "ÐÑл'ÐоÑ", |
["Zul'tore"] = "ÐÑл'ÑоÑ", |
["Zuramat the Obliterator"] = "ÐÑÑÐ°Ð¼Ð°Ñ Ð£Ð½Ð¸ÑÑожиÑелÑ", |
} |
elseif GAME_LOCALE == "zhCN" then |
lib:SetCurrentTranslations { |
Acidmaw = "é ¸å", |
Aeonus = "å欧åªæ¯", |
["Aerial Command Unit"] = "空ä¸ææ¥åä½", |
["Agathelos the Raging"] = "æ´æçé¿è¿¦èµç½æ¯", |
Ahune = "åéæ©", |
["Akil'zon"] = "ååºå°æ¾", |
["Aku'mai"] = "é¿åºéº¦å°", |
["Al'ar"] = "奥", |
["Algalon the Observer"] = "è§å¯è 奥å°å é", |
["Alzzin the Wildshaper"] = "å¥¥å ¹æ©", |
Amanitar = "åæ¼å°¼å¡", |
["Ambassador Flamelash"] = "å¼è±ææ¯å¤§ä½¿", |
["Ambassador Hellmaw"] = "赫å°é»å¤§ä½¿", |
["Amnennar the Coldbringer"] = "å¯å°ä¹çäºé¨çº³å°", |
["Ancient Stone Keeper"] = "å¤ä»£çç³å¤´çå®è ", |
Anetheron = "å®çº³å¡é", |
["Anger'rel"] = "å®æ ¼é·å°", |
Anomalus = "é¿è¯ºçé²æ¯", |
["Antu'sul"] = "å®å¾èå°", |
["Anub'arak"] = "é¿åªå·´æå ", |
["Anubisath Defender"] = "é¿åªæ¯è¨æ¯é²å¾¡è ", |
["Anubisath Guardian"] = "é¿åªæ¯è¨æ¯å®å«è ", |
["Anub'Rekhan"] = "é¿åªå¸é·å", |
["Anub'shiah"] = "é¿åªå¸å°", |
Anzu = "å®è", |
["Arcane Watchman"] = "奥æ¯çå®", |
["Arcanist Doan"] = "奥æ³å¸æå®", |
Archaedas = "é¿æè¾¾æ¯", |
["Archavon the Stone Watcher"] = "岩ç³çå®è é¿å°å¡å¯", |
Archimonde = "é¿å èå¾·", |
["Archivist Galford"] = "æ¡£æ¡ç®¡çåå å°ç¦ç¹", |
["Archmage Arugal"] = "大æ³å¸é¿é²é«", |
["Argent Confessor Paletress"] = "é¶è²ç¥å®å¸å°å´ä¸", |
["Arugal's Voidwalker"] = "é¿é²é«çè空è¡è ", |
["Assault Bot"] = "çªå»æºå¨äºº", |
["Atal'alarion"] = "é¿å¡æå©æ©", |
["Attumen the Huntsman"] = "çæé¿å¾é¨", |
Auriaya = "欧å°èäº", |
Avalanchion = "é¿ç¦å °å¥å¥¥", |
["Avatar of Hakkar"] = "åå¡çå身", |
["Ayamiss the Hunter"] = "ç©çè é¿äºç±³æ¯", |
Azgalor = "é¿å ¹å æ´", |
["Azshir the Sleepless"] = "æ°¸éçè¾å¸å°", |
Azuregos = "è¾ç´¢é·èæ¯", |
["Bael'Gar"] = "è´å°å ", |
Baelog = "å·´å°æ´æ", |
Balnazzar = "巴纳æå°", |
["Baltharus the Warborn"] = "Baltharus the Warborn", -- Needs review |
["Bannok Grimaxe"] = "ç诺å ·巨æ§", |
["Baron Aquanis"] = "é¿å¥å°¼æ¯ç·çµ", |
["Baron Charr"] = "ç«ç°ç·çµæ¥å°", |
["Baroness Anastari"] = "å®å¨ä¸å¡ä¸½ç·çµå¤«äºº", |
["Baron Geddon"] = "迦顿ç·çµ", |
["Baron Kazum"] = "å¡èå§ç·çµ", |
["Baron Rivendare"] = "çææ´å°ç·çµ", |
["Baron Silverlaine"] = "å¸ç¦è±æ©ç·çµ", |
["Battleguard Sartura"] = "æ²å°å¾æ", |
["Bazil Thredd"] = "å·´åºå°Â·æ¯çå¾·", |
Bazzalan = "å·´æå °", |
["Black Guard Swordsmith"] = "é»è¡£å®å«é¸åå¸", |
["Blackheart the Inciter"] = "ç ½å¨è å¸è±å¡ç¹", |
["Blindeye the Seer"] = "ç²ç¼å ç¥", |
["Blind Hunter"] = "ç²ç¼çæ", |
["Blood Guard Porung"] = "è¡å«å£«ä¼¯é²æ©", |
["Bloodlord Mandokir"] = "è¡é¢ä¸»æ¼å¤åºå°", |
["Bloodmage Thalnos"] = "è¡æ³å¸è¨å°è¯ºæ¯", |
["Blood Prince Council"] = "é²è¡çåè®®ä¼", |
["Blood Princes"] = "é²è¡çå", |
["Blood-Queen Lana'thel"] = "é²è¡å¥³çå °å¨çå°", |
["Blood Steward of Kirtonos"] = "åºå°å¾è¯ºæ¯çå«å£«", |
Boahn = "åè¾æ©", |
["Bomb Bot"] = "ç¸å¼¹æºå¨äºº", |
["Brain of Yogg-Saron"] = "å°¤æ ¼-è¨éç大è", |
["Brainwashed Noble"] = "被æ´èçè´µæ", |
Broggok = "å¸æ´æå ", |
Brokentoe = "æè¹", |
Bronjahm = "å¸éäºå§", |
["Broodlord Lashlayer"] = "åä»é·å°", |
["Bruegal Ironknuckle"] = "å¸é²é«Â·éæ³", |
Brutallus = "å¸é²å¡å¢æ¯", |
["Burning Felguard"] = "çç§å°ç±å«å£«", |
["Buru the Gorger"] = "åå½è å¸é²", |
["Cache of the Firelord"] = "ç«ç°ä¹ççå®ç®±", |
["Cannon Master Willey"] = "ç®æå¨å©", |
["Captain Greenskin"] = "绿ç®éé¿", |
["Captain Kromcrush"] = "å ç½å¡æ¯", |
["Captain Skarloc"] = "æ¯å¡æ´å ä¸å°", |
["Celebras the Cursed"] = "è¢«è¯ åçå¡é·å¸ææ¯", |
["Charlga Razorflank"] = "å¡å°å ·åºè", |
["Chess Event"] = "å½é 象æ£", |
["Chest of The Seven"] = "ä¸è´¤ä¹ç®±", |
["Chief Ukorz Sandscalp"] = "ä¹å å ¹Â·æ²é¡¶", |
["Cho'Rush the Observer"] = "è§å¯è å é²ä»", |
Chromaggus = "å æ´çå¤æ¯", |
["Chrono Lord Deja"] = "æ¶ç©ºé¢ä¸»å¾·äº", |
["Chrono-Lord Epoch"] = "æ¶å é¢ä¸»ååå ", |
Claw = "å å³æ©", |
["Coilfang Elite"] = "ççç²¾è±", |
["Coilfang Strider"] = "ççå·¡é»è ", |
["Commander Kolurg"] = "ææ¥å®åºé²å°æ ¼", |
["Commander Sarannis"] = "ææ¥å®è¨æ妮ä¸", |
["Commander Springvale"] = "ææ¥å®æ¯æ®æç¦å°", |
["Commander Stoutbeard"] = "ææ¥å®æ¯ææ¯å¾·", |
["Constructor & Controller"] = "建çå¸ä¸æ§å¶è ", |
Cookie = "æ²å¥", |
["Coren Direbrew"] = "ç§æ·çé ", |
["Cosmic Infuser"] = "å®å®ç注è ", |
["Crimson Hammersmith"] = "红衣é¸é¤å¸", |
["Crowd Pummeler 9-60"] = "群ä½æå»è 9-60", |
["Crystal Fang"] = "æ°´æ¶ä¹ç", |
["C'Thun"] = "å èæ©", |
Cyanigosa = "å¡å®å¦®èè¨", |
["Dalliah the Doomsayer"] = "æ«æ¥é¢è¨è è¾¾å°èå®", |
["Dalronn the Controller"] = "æ§å¶è è¾¾å°é", |
["Dark Iron Ambassador"] = "é»é大å¸", |
["Darkmaster Gandling"] = "é»æé¢é¿å ä¸", |
["Darkweaver Syth"] = "é»æç¼ç»è å¡æ¯", |
["Deathbound Ward"] = "ç¼äº¡å®å«", |
["Deathbringer Saurfang"] = "æ»äº¡ä½¿è è¨é²æ³å°", |
["Death Knight Darkreaver"] = "æ»äº¡éªå£«è¾¾å é·å°", |
["Death Knight Understudy"] = "è§ä¹ æ»äº¡éªå£«", |
["Deathspeaker High Priest"] = "亡è¯é«é¶ç¥å¸", |
["Death Speaker Jargba"] = "亡è¯è è´¾æ ¼å·´", |
["Deathstalker Visceri"] = "æ»äº¡çæç»´çé", |
["Deathsworn Captain"] = "æ»äº¡ä¹èª", |
Devastation = "æ¯å", |
["Deviate Faerie Dragon"] = "åå¼ç²¾çµé¾", |
["Devourer of Souls"] = "å¬éè ", |
["Dextren Ward"] = "迪å æ¯ç¹Â·ç¦å¾·", |
["Digmaster Shovelphlange"] = "ææä¸å®¶èå°å¼ææ ¼", |
["Doctor Theolen Krastinov"] = "çå°æ·å¡æ¯è¿ªè¯ºå¤«ææ", |
["Doom Lord Kazzak"] = "æ«æ¥é¢ä¸»å¡æå ", |
["Doom'rel"] = "æå§é·å°", |
Doomwalker = "æ«æ¥è¡è ", |
["Dope'rel"] = "å¤æ®é·å°", |
Dorothee = "å¤èè", |
["Drakkari Colossus"] = "è¾¾å¡è±å·¨å", |
["Drakos the Interrogator"] = "审讯è è¾¾åºæ¯", |
Dreadscale = "æé³", |
Dreamscythe = "å¾·å§å¡å¡å°", |
["Dust Covered Chest"] = "ç°å°è¦ççç®±å", |
Dustwraith = "ç°å°æ¨çµ", |
["Eadric the Pure"] = "纯æ´è è¶å¾·çå ", |
["Earthcaller Halmgar"] = "å¤å°è åç©å ", |
Ebonroc = "åå诺å ", |
["Eck the Ferocious"] = "å¶æ®çä¼å ", |
["Edwin VanCleef"] = "è¾å¾·æ¸©Â·èå é夫", |
["Elder Brightleaf"] = "æå¶é¿è", |
["Elder Ironbranch"] = "éæé¿è", |
["Elder Nadox"] = "纳å¤å æ¯é¿è", |
["Elder Stonebark"] = "ç³æ é¿è", |
["Electrocutioner 6000"] = "çµåå¨6000å", |
["Emalon the Storm Watcher"] = "é£æ´çå®è åçå°é", |
Emeriss = "è¾è«èä¸", |
["Emperor Dagran Thaurissan"] = "è¾¾æ ¼å °Â·ç´¢ç森大å¸", |
["Emperor Vek'lor"] = "ç»´å æ´å°å¤§å¸", |
["Emperor Vek'nilash"] = "ç»´å å°¼ææ¯å¤§å¸", |
Entropius = "çµé", |
["Eonar's Gift"] = "è¾æ¬§å¨å°ç礼ç©", |
["Epoch Hunter"] = "æ¶ç©ºçæ", |
Erekem = "åé·å å§", |
["Eressea Dawnsinger"] = "ä¼è¾å¸äºÂ·æ¨æ", |
["Essence of Anger"] = "æ¤æç²¾å", |
["Essence of Desire"] = "欲æç²¾å", |
["Essence of Suffering"] = "è¦çç²¾å", |
Eviscerator = "åç¼è ", |
["Exarch Maladaar"] = "大主æçæè¾¾å°", |
["Expedition Commander"] = "è¿å¾åææ¥å®", |
["Eydis Darkbane"] = "é»æéªä½¿è¾èä¸", |
["Eye of C'Thun"] = "å èæ©ä¹ç¼", |
["Faction Champions"] = "éµè¥å å", |
["Fallen Champion"] = "æ»çµå士", |
Falric = "æ³çå ", |
["Falric and Marwyn"] = "æ³çå åçç»´æ©", |
["Fankriss the Unyielding"] = "顽强çèå çæ¯", |
["Fathom-Lord Karathress"] = "深水é¢ä¸»å¡æçé·æ¯", |
Felmyst = "è²ç±³ä¸", |
["Fenrus the Devourer"] = "åå¬è è¬é²æ¯", |
["Feral Defender"] = "éæ§é²å¾¡è ", |
Festergut = "çè ", |
Feugen = "è´¹å°æ ¹", |
["Fineous Darkvire"] = "å¼è¯ºæ¯Â·è¾¾å ç»´å°", |
Firemaw = "è´¹å°é»", |
["Fjola Lightbane"] = "å æéªä½¿è²å¥¥æ", |
Flamegor = "å¼è±æ ¼å°", |
["Flame Leviathan"] = "çç°å·¨å ½", |
["Foreman Thistlenettle"] = "工头å¸æ¯èç¹", |
["Forgemaster Garfrost"] = "ççä¹ä¸»å å¼æ¯ç¹", |
["Four Horsemen Chest"] = "åéªå£«ä¹ç®±", |
["Fras Siabi"] = "å¼ææ¯Â·å¸äºæ¯", |
Freya = "å¼è¾äº", |
["Gahz'ranka"] = "å å ¹å °å¡", |
["Gahz'rilla"] = "å å ¹çæ", |
["Gal'darah"] = "迦å°è¾¾æ", |
["Galgann Firehammer"] = "å å æ©Â·ç«é¤", |
Garr = "å å°", |
["Garrosh Hellscream"] = "å å°é²ä»Â·å°ç±åå®", |
Gasher = "å ä»å°", |
["Gatewatcher Gyro-Kill"] = "çå®è çç½åºå°", |
["Gatewatcher Iron-Hand"] = "çå®è åéæ±", |
["Gathios the Shatterer"] = "å»ç¢è å 西奥æ¯", |
Gehennas = "åºèµ«çº³æ¯", |
Gelihast = "æ ¼éåæ¯ç¹", |
Gelk = "åå°å ", |
["General Angerforge"] = "å®æ ¼å¼å°å", |
["General Bjarngrim"] = "æ¯äºæ ¼éå°å", |
["General Drakkisath"] = "è¾¾åºè¨æ¯å°å", |
["General Rajaxx"] = "æè´¾å æ¯å°å", |
["General Vezax"] = "ç»´æå æ¯å°å", |
["General Zarithrian"] = "General Zarithrian", -- Needs review |
["Ghamoo-ra"] = "å æ©æ", |
["Ghaz'an"] = "å å ¹å®", |
["Ghok Bashguud"] = "éå ·巴ä»å¤å¾·", |
Gilnid = "åºå°å°¼æ ¼", |
["Gizrul the Slavener"] = "奴役è åºå ¹é²å°", |
["Gloom'rel"] = "æ ¼é²é·å°", |
Gluth = "æ ¼ææ¯", |
Glutton = "æ´é£è ", |
["Golemagg the Incinerator"] = "çåè å¤é·æ¼æ ¼", |
["Golem Lord Argelmach"] = "åå¡ç»å¸ é¿æ ¼æ¼å¥", |
["Goraluk Anvilcrack"] = "å¤æé²å ", |
["Gormok the Impaler"] = "ç©¿åºè å¥è«å ", |
["Gorosh the Dervish"] = "ä¿®è¡è é«ç½ä»", |
["Gortok Palehoof"] = "ææå ·èè¹", |
["Gothik the Harvester"] = "æ¶å²è ææå ", |
["Grand Astromancer Capernian"] = "ææ¯å¸å¡æ³¢å¦®å¨ ", |
["Grand Champions"] = "æ»å å", |
["Grand Magus Telestra"] = "大é导å¸æ³°è¾ä¸å¡", |
["Grandmaster Vorpil"] = "æ²å¹å°å¤§å¸", |
Grandmother = "è奶奶", |
["Grand Warlock Alythess"] = "é«é¶æ¯å£«å¥¥è¾å¡ä¸", |
["Grand Warlock Nethekurse"] = "é«é¶æ¯å£«å¥çåºæ¯", |
["Grand Widow Faerlina"] = "é»å¥³å·«æ³ç³å¨", |
["Grethok the Controller"] = "é»ç¿¼æ§å¶è ", |
["Gri'lek"] = "æ ¼éé·å ", |
Grimlok = "æ ¼çå§æ´å ", |
Grizzle = "æ ¼éå ¹å°", |
Grobbulus = "æ ¼ç½å¸é²æ¯", |
Grubbis = "æ ¼é²æ¯æ¯", |
["Gruul the Dragonkiller"] = "å± é¾è æ ¼é²å°", |
["Guard Fengus"] = "å«å µè¬å¤æ¯", |
["Guardian of Yogg-Saron"] = "å°¤æ ¼-è¨éçå«å£«", |
["Guard Mol'dar"] = "å«å µæ©å°è¾¾", |
["Guard Slip'kik"] = "å«å µæ¯éåºå ", |
["Gurtogg Bloodboil"] = "å¤å°å¾æ ¼Â·è¡æ²¸", |
Gyth = "çæ¯", |
Hadronox = "åå¤è¯ºå æ¯", |
Hakkar = "åå¡", |
Halazzi = "åå°æå ¹", |
Halion = "Halion", -- Needs review |
Halycon = "åé·è¯", |
Hamhock = "åå§éå ", |
["Harbinger Skyriss"] = "é¢è¨è æ¯å çæ¯", |
["Hate'rel"] = "é»ç¹é·å°", |
["Hazza'rah"] = "åææå°", |
Hazzas = "åææ¯", |
["Headless Horseman"] = "æ 头éªå£«", |
["Hearthsinger Forresten"] = "å¼é·æ¯ç¹æ©", |
["Hedrum the Creeper"] = "ç¬è¡è 赫æå§", |
["Heigan the Unclean"] = "è®èçå¸å°ç", |
["Hellfire Channeler"] = "å°ç±ç«å¯¼éè ", |
["Henry Stern"] = "亨å©Â·æ¯ç¹æ©", |
["Herald Volazj"] = "ä¼ ä»¤å®æ²æå ¹", |
Herod = "赫æ´å¾·", |
["Hex Lord Malacrass"] = "å¦æ¯é¢ä¸»çæå¡æ¯", |
["High Astromancer Solarian"] = "大ææ¯å¸ç´¢å °èå®", |
["High Botanist Freywinn"] = "é«çº§æ¤ç©å¦å®¶å¼é·æ¸©", |
["High Inquisitor Fairbanks"] = "大æ£å¯å®æ³å°çå æ¯", |
["High Inquisitor Whitemane"] = "大æ£å¯å®æç¹è¿æ©", |
["High Interrogator Gerstahn"] = "审讯å®æ ¼æ¯å¡æ©", |
["High King Maulgar"] = "è«å å°å¤§ç", |
["Highlord Mograine"] = "大é¢ä¸»è«æ ¼è±å°¼", |
["Highlord Omokk"] = "欧è«å 大ç", |
["High Marshal Whirlaxis"] = "大å å¸ ç»´æå¸æ¯", |
["High Nethermancer Zerevor"] = "é«é¶çµæ¯å¸å¡åæ²å°", |
["High Overlord Saurfang"] = "è¨é²æ³å°å¤§ç", |
["High Priestess Arlokk"] = "é«é¶ç¥å¸å¨ å°ç½", |
["High Priestess Jeklik"] = "é«é¶ç¥å¸è¶å éå ", |
["High Priestess Mar'li"] = "é«é¶ç¥å¸çå°é", |
["High Priestess of Thaurissan"] = "ç´¢ç森é«é¶å¥³ç¥å¸", |
["High Priest Thekal"] = "é«é¶ç¥å¸å¡å¡å°", |
["High Priest Venoxis"] = "é«é¶ç¥å¸æ¸©è¯ºå¸æ¯", |
["High Warlord Naj'entus"] = "é«é¶ç£å纳å å¾æ¯", |
Hodir = "é迪å°", |
["Houndmaster Grebmar"] = "驯ç¬è æ ¼é·å¸çå°", |
["Houndmaster Loksey"] = "驯ç¬è æ´å å¸", |
Hukku = "è¡åº", |
Hungarfen = "éå å°è¬", |
["Hurley Blackbreath"] = "éå°é·Â·é»é¡»", |
["Hyakiss the Lurker"] = "æ½ä¼è å¸äºå ¶æ¯", |
["Hydromancer Thespia"] = "æ°´æ¯å¸çä¸æ¯å¨ ", |
["Hydromancer Velratha"] = "æ°´å å¸ç»´è¾è¨", |
Hydrospawn = "æµ·å¤æ¯åæ©", |
["Hydross the Unstable"] = "ä¸ç¨³å®ç海度æ¯", |
["Icecrown Gunship Battle"] = "å°å ç®è°ææ", |
Icehowl = "å°å¼", |
["Ice Sphere"] = "Ice Sphere", -- Needs review |
Ichoron = "è¾åºé", |
Ick = "ä¼å ", |
["Ignis the Furnace Master"] = "æçè ä¼æ ¼å°¼æ¯", |
["Illidan Stormrage"] = "ä¼å©ä¸¹Â·æé£", |
["Illidari Council"] = "ä¼å©è¾¾é·è®®ä¼", |
["Illyanna Ravenoak"] = "ä¼ç³å¨Â·ææ¨", |
["Immol'thar"] = "ä¼è«å¡å°", |
["Infinite Corruptor"] = "æ°¸æè èè ", |
["Infinity Blades"] = "æ å°½ä¹å", |
["Ingvar the Plunderer"] = "å«æ è å æ ¼ç¦å°", |
["Instructor Malicia"] = "讲å¸ç丽å¸äº", |
["Instructor Razuvious"] = "æå®æè维奥æ¯", |
["Interrogator Vishas"] = "审讯åé¦æ²æ¯", |
Ionar = "è¾æ¬§çº³å°", |
Ironaya = "è¾é纳äº", |
Ironspine = "éèæ»çµ", |
Isalien = "ä¼è¨å©æ©", |
Jade = "çé¾", |
["Jammal'an the Prophet"] = "é¢è¨è 迦çå °", |
["Jan'alai"] = "å äºè±", |
["Jandice Barov"] = "詹迪æ¯Â·å·´ç½å¤«", |
["Jedoga Shadowseeker"] = "è¶æè¾¾Â·è§ å½±è ", |
["Jed Runewatcher"] = "æ°å¾·", |
["Jergosh the Invoker"] = "ç¥æ±è è¶æä»", |
["Jin'do the Hexxer"] = "å¦æ¯å¸é度", |
["Jormungar Behemoth"] = "è°çå·¨è«", |
Jormungars = "å°è«", |
Julianne = "æ±ä¸½å¶", |
["Junk Bot"] = "åºç©æºå¨äºº", |
["Kael'thas Sunstrider"] = "å¯å°è¨æ¯Â·éæ¥è ", |
Kalecgos = "å¡é·èæ¯", |
["Kam Deepfury"] = "å¡å§Â·æ·±æ", |
["Kazkaz the Unholy"] = "éªæ¶çå¡è¨å¡å ¹", |
["Kaz'rogal"] = "å¡å ¹æ´å ", |
["Keli'dan the Breaker"] = "å»ç¢è å é丹", |
["Kel'Thuzad"] = "å å°èå å¾·", |
Keristrasza = "å èæ¯å¡è¨", |
["Kiggler the Crazed"] = "ç¯ççåºæå°", |
["Kil'jaeden"] = "åºå°å 丹", |
["Kil'rek"] = "åºå°éå ", |
["King Dred"] = "æ´é¾ä¹ççµå¾·", |
["King Gordok"] = "æå¤å 大ç", |
["King Llane Piece"] = "è±æ©å½ç", |
["King Ymiron"] = "ä¼ç±³éå½ç", |
["Kirtonos the Herald"] = "ä¼ ä»¤å®åºå°å¾è¯ºæ¯", |
["Knot Thimblejack's Cache"] = "诺ç¹Â·å¸å§å å çå¨ç©ç®±", |
Kolk = "èå°å ", |
Kologarn = "ç§éå æ©", |
["Koralon the Flame Watcher"] = "ç«ç°çå®è ç§æé", |
Kormok = "åºå°è«å ", |
Kresh = "å é·ä»", |
Krick = "ç§éå ", |
["Krick and Ick"] = "ç§éå åä¼å ", |
["Krik'thir the Gatewatcher"] = "çé¨è å éå å¸å°", |
["Krosh Firehand"] = "å æ´ä»Â·ç«æ³", |
Krystallus = "å è±æ¯å¡å¢æ¯", |
Kurinnaxx = "åºæ纳å æ¯", |
["Lady Anacondra"] = "å®å¨ç§å¾·æ", |
["Lady Blaumeux"] = "å¥³å ¬çµå¸å³ç¼ªå ä¸", |
["Lady Deathwhisper"] = "亡è¯è 女士", |
["Lady Illucia Barov"] = "ä¼é²å¸äºÂ·å·´ç½å¤«", |
["Lady Malande"] = "å¥³å ¬çµçå °å¾·", |
["Lady Sacrolash"] = "è¨æ´æä¸å¥³ç", |
["Lady Sarevess"] = "è¨å©ç»´ä¸", |
["Lady Vashj"] = "ç¦ä¸çª", |
Laj = "æä¼", |
Landslide = "å °æ¯å©å¾·", |
Lavanthor = "ææç´¢å°", |
["Left Arm"] = "å·¦è", |
["Leotheras the Blind"] = "ç²ç¼è è±æ¬§çææ¯", |
Lethon = "è±ç´¢æ©", |
Lethtendris = "è¾çå¡èä¸", |
["Leviathan Mk II"] = "å·¨å ½äºå", |
["Ley-Guardian Eregos"] = "éç½å®æ¤è åé·èæ¯", |
["Lieutenant Drake"] = "å¾·æå ä¸å°", |
["Lieutenant General Andorov"] = "å®å¤æ´å¤«ä¸å°", |
Loatheb = "æ´æ¬§å¡å¸", |
Loken = "æ´è¯", |
["Lord Alexei Barov"] = "é¿é·å æ¯Â·å·´ç½å¤«", |
["Lord Cobrahn"] = "èå¸è±æ©", |
["Lord Hel'nurath"] = "赫å°åªææ¯", |
["Lord Incendius"] = "ä¼æ£®è¿ªå¥¥æ¯", |
["Lord Jaraxxus"] = "å æå èæ¯å¤§ç", |
["Lord Kazzak"] = "æ«æ¥é¢ä¸»å¡æå ", |
["Lord Kri"] = "å éåçµ", |
["Lord Marrowgar"] = "çæ´å å°é¢ä¸»", |
["Lord Pythas"] = "ç®è¨æ¯", |
["Lord Roccor"] = "æ´èå°", |
["Lord Sanguinar"] = "è¨å¤çº³å°ç·çµ", |
["Lord Serpentis"] = "çè¬è¿ªæ¯", |
["Lord Skwol"] = "æ¯å¤æ©ç·çµ", |
["Lord Valthalak"] = "ç¦å¡æå å ¬çµ", |
["Lord Victor Nefarius"] = "ç»´å å¤Â·å¥æ³é奥æ¯", |
["Lord Vyletongue"] = "ç»´å©å¡æ©", |
["Lorekeeper Polkelt"] = "åå¦è æ®å å°ç¹", |
Loro = "æ´è¥å°", |
Lucifron = "é²è¥¿å¼é", |
["Mad Magglish"] = "ç¯ççé©¬æ ¼å©ä»", |
Maexxna = "è¿å æ¯çº³", |
["Mage-Lord Urom"] = "æ³å¸é¢ä¸»ä¼æ´å§", |
["Magister Kalendris"] = "å¡é·è¿ªæ¯éé¿", |
["Magistrate Barthilas"] = "å·´çææ¯éé¿", |
Magmadar = "çæ ¼æ¼è¾¾", |
Magmus = "çæ ¼å§æ¯", |
Magra = "çæ ¼æ", |
Magtheridon = "ççéé¡¿", |
["Maiden of Grief"] = "æ²ä¼¤å£å¥³", |
["Maiden of Virtue"] = "è´èå£å¥³", |
["Majordomo Executus"] = "管çè åå ç´¢å¾æ¯", |
Malacrass = "çæå¡æ¯", |
["Maleki the Pallid"] = "èç½ççååº", |
["Mal'Ganis"] = "çå°å å°¼æ¯", |
Malygos = "çéèæ¯", |
Maraudos = "çæå¤æ¯", |
["Marduk Blackpool"] = "马æå ·å¸è±å æ³¢å°", |
["Marisa du'Paige"] = "çéè·ææ´¾æ ¼", |
Marwyn = "çç»´æ©", |
["Master Engineer Telonicus"] = "é¦å¸æå¸å¡éå°¼åºæ¯", |
["Maur Grimtotem"] = "çå°Â·ææå¾è ¾", |
Meathook = "èé©", |
["Mechano-Lord Capacitus"] = "æºæ¢°é¢ä¸»å¡å¸è¥¿å¾æ¯", |
Medivh = "麦迪æ", |
["Mekgineer Steamrigger"] = "æºæ¢°å¸æ¯èéæ ¼", |
["Mekgineer Thermaplugg"] = "麦å å°¼å°Â·ççæ®ææ ¼", |
["Mennu the Betrayer"] = "èåè é¨åª", |
["Meshlok the Harvester"] = "æ¶å²è 麦ä»æ´å ", |
Midnight = "åå¤", |
Mijan = "ç±³æ", |
Mimiron = "米米å°é", |
["Miner Johnson"] = "ç¿å·¥çº¦ç¿°æ£®", |
["Mistress of Pain"] = "çè¦å¥³ç", |
Moam = "è«é¿å§", |
Mogor = "ç©æå°", |
["Mokra the Skullcrusher"] = "ç¢é¢ è è«å æ", |
Moorabi = "è«ææ¯", |
Moragg = "æ©ææ ¼", |
["Mordresh Fire Eye"] = "ç«ç¼è«å¾·é·æ¯", |
["Mor Grayhoof"] = "è«å°Â·ç°è¹", |
Moroes = "è«ç½æ¯", |
["Morogrim Tidewalker"] = "è«æ´æ ¼é·è¸æ½®è ", |
Morphaz = "æ©å¼ææ¯", |
["Mother Shahraz"] = "è赫æä¸ä¸»æ¯", |
["Mother Smolderweb"] = "çç½èå", |
["Mr. Smite"] = "éæ³å ç", |
["Muradin Bronzebeard"] = "ç©æä¸Â·éé¡»", |
["Murkblood Twin"] = "æè¡åå", |
["Murkblood Twins"] = "æè¡åå", |
Murmur = "æ©æ©å°", |
["Murta Grimgut"] = "ç©å°å¡", |
["M'uru"] = "ç©é²", |
Mushgog = "å§æ¯é«æ ¼", |
["Mutanus the Devourer"] = "åå¬è ç©å¦åªæ¯", |
Nalorakk = "纳æ´æå ", |
Nazan = "纳æ", |
Nefarian = "å¥æ³å©å®", |
["Nekrum Gutchewer"] = "èå é²å§", |
["Nerub'enkan"] = "å¥é²å¸æ©å", |
["Nethermancer Sepethrea"] = "çµæ¯å¸å¡æ¯çè¾", |
Netherspite = "è空幽é¾", |
["Netherstrand Longbow"] = "çµå¼¦é¿å¼", |
["Nexus-Prince Shaffar"] = "èç¹äº²çæ²æ³å°", |
Nightbane = "å¤ä¹é", |
["Noth the Plaguebringer"] = "çç«ä½¿è 诺æ¯", |
["Novos the Summoner"] = "å¬å¤è 诺æ²æ¯", |
Noxxion = "诺å èµæ©", |
["Obsidian Sentinel"] = "é»æç³å¨å µ", |
["Odo the Blindwatcher"] = "ç²ç¼å®å«å¥¥æ", |
["Ogom the Wretched"] = "å¯æ²ç奥æå§", |
["Ok'thor the Breaker"] = "ç ´åè 奥ç§ç´¢å°", |
["Old Serra'kis"] = "çæåæ¯", |
["Olm the Summoner"] = "å¬å¤è æ²å°å§", |
["Omor the Unscarred"] = "æ ç¤è 奥æ©å°", |
Onyxia = "奥妮å å¸äº", |
["Orgrim's Hammer"] = "å¥¥æ ¼çå§ä¹é¤", |
["Ormorok the Tree-Shaper"] = "å¡æ è 奥è«æ´å ", |
["Oro Eyegouge"] = "欧ç½Â·è¡ç¼", |
["Ossirian the Unscarred"] = "æ ç¤è 奥æ¯éå®", |
Ouro = "奥ç½", |
["Overlord Ramtusk"] = "主宰æå§å¡æ¯", |
["Overlord Wyrmthalak"] = "ç»´å§è¨æå ", |
["Overmaster Pyron"] = "å¾æè æ´¾é", |
["Overseer Tidewrath"] = "工头泰德ç¦æ¯", |
Pandemonius = "æ½å¾·è«åªæ¯", |
["Panzor the Invincible"] = "æ æçæ½ä½å°", |
Patchwerk = "å¸å¥ç»´å ", |
["Pathaleon the Calculator"] = "计ç®è å¸è¨é·æ©", |
Phalanx = "æ¹éµ", |
["Phaseshift Bulwark"] = "ç¸ä½å£å", |
Pimgib = "å¹å§åå¸", |
["Plaguemaw the Rotting"] = "è ççæ®é·è«å°", |
["Plugger Spazzring"] = "æ®ææ ¼", |
["Postmaster Malown"] = "é®å·®é©¬é¾", |
["Priestess Delrissa"] = "女ç¥å¸å¾·èå¸äº", |
["Prince Keleseth"] = "å¯é·å¡æ¯çå", |
["Prince Malchezaar"] = "çå æå°çå", |
["Prince Skaldrenox"] = "æ¯å¡å¾·è¯ºå æ¯çå", |
["Princess Huhuran"] = "åéå °å ¬ä¸»", |
["Princess Moira Bronzebeard"] = "éçå ¡å ¬ä¸»èè¾æ·éé¡»", |
["Princess Tempestria"] = "æ³°æ¯æ¯èäºå ¬ä¸»", |
["Princess Theradras"] = "çè±å¾·ä¸å ¬ä¸»", |
["Princess Yauj"] = "äºå°åºå ¬ä¸»", |
["Prince Taldaram"] = "å¡è¾¾æå§çå", |
["Prince Tenris Mirkblood"] = "ç¹éæ¯Â·é»¯è¡çå", |
["Prince Tortheldrin"] = "æå¡å¾·æçå", |
["Prince Valanar"] = "ç¦æ纳çå", |
["Professor Putricide"] = "æ®å´å¡å¾·ææ", |
["Pure Spawn of Hydross"] = "纯åç海度æ¯çªç", |
Pusillin = "æ®å¸æ", |
["Pyroguard Emberseer"] = "çç°å«å£«è¾åå¸å°", |
["Pyromancer Loregrain"] = "æ§ç«å¸ç½æ ¼é·æ©", |
Quagmirran = "å¤¸æ ¼ç±³æ", |
["Quartermaster Zigris"] = "åéå®å ¹æ ¼é·æ¯", |
["Rage Winterchill"] = "é·åºÂ·å¬å¯", |
Ragglesnout = "æææ¯è¯ºç¹", |
["Raging Spirit"] = "Raging Spirit", -- Needs review |
Ragnaros = "ææ ¼çº³ç½æ¯", |
["Ramstein the Gorger"] = "åå½è æå§æ¯ç»", |
["Ras Frostwhisper"] = "è±æ¯Â·éè¯", |
Rattlegore = "è¡éª¨åå¡", |
["Razorclaw the Butcher"] = "å± å¤«æä½å å³", |
["Razorgore the Untamed"] = "çéçæä½æ ¼å°", |
Razorlash = "éåºéç¬è ", |
Razorscale = "éé³", |
["Reliquary of Souls"] = "çµéä¹å£", |
Renataki = "é·çº³å¡åº", |
["Restless Skeleton"] = "æ æ³å®æ¯çéª·é« ", |
Rethilgore = "é·å¸æå°", |
Revelosh = "é²ç»´ç½ä»", |
["Rhahk'Zor"] = "æå ä½", |
["Ribbly Screwspigot"] = "é·å¸é·æ¯åºæ¯æ ¼ç¹", |
["Right Arm"] = "å³è", |
Roar = "èå°çç®å", |
["Rokad the Ravager"] = "è¹èºè æ´å¡å¾·", |
["Rokdar the Sundered Lord"] = "è£ç³ä¹çæ´å¡è¾¾å°", |
["Rokmar the Crackler"] = "å·¨é³é²å çå°", |
Romulo = "ç½å¯æ¬§", |
["Romulo & Julianne"] = "ç½å¯æ¬§ä¸æ±ä¸½å¶", |
Rotface = "è é¢", |
Rotgrip = "æ´ç¹æ ¼éæ®", |
["Runemaster Molgeim"] = "符æ大å¸è«å°åºå§", |
["Runok Wildmane"] = "é²è¯ºå ·è®é¬", |
Ruuzlu = "å¢å ¹é²", |
["Salramm the Fleshcrafter"] = "å¡è¡è æ²å°æå§", |
["Sanctum Sentry"] = "å£æè¦å«", |
["Sandarr Dunereaver"] = "æè¾¾å°Â·æ²æ è ", |
["Sandfury Executioner"] = "æ²æå½åæ", |
Sapphiron = "è¨è²é", |
Sara = "è¨æ", |
["Saronite Animus"] = "è¨ééªéç¸ä½", |
Sartharion = "è¨å¡é奥", |
["Sathrovarr the Corruptor"] = "è èè è¨ç´¢ç¦å°", |
["Saviana Ragefire"] = "Saviana Ragefire", -- Needs review |
["Scarlet Commander Mograine"] = "è¡è²åååææ¥å®è«æ ¼è±å°¼", |
["Scourgelord Tyrannus"] = "天ç¾é¢ä¸»æ³°å °åªæ¯", |
["Seeth'rel"] = "西æ¯é·å°", |
["Selin Fireheart"] = "å¡æ·ç«å¿", |
["Sergeant Bly"] = "å¸è±ä¸å£«", |
["Shade of Akama"] = "é¿å¡çä¹å½±", |
["Shade of Aran"] = "åå °ä¹å½±", |
["Shade of Eranikus"] = "ä¼å °å°¼åºæ¯çé´å½±", |
["Shadikith the Glider"] = "æ»ç¿è æ²å¾·åºæ¯", |
["Shadow Hunter Vosh'gajin"] = "æå½±çææ²ä»å æ¯", |
["Shadow of Leotheras"] = "è±æ¬§çææ¯ä¹å½±", |
["Shadowpriest Sezz'ziz"] = "æå½±ç¥å¸å¡çæ¯", |
Shadron = "æ²å¾·é", |
Shazzrah = "æ²æ¯æå°", |
["Shirrak the Dead Watcher"] = "æ»äº¡è§å¯è å¸å°æå ", |
Sindragosa = "è¾è¾¾èè¨", |
["Sir Zeliek"] = "çéè¶å çµå£«", |
["Sjonnir The Ironshaper"] = "å¡éè æ¯çº¦å°¼å°", |
["Skadi the Ruthless"] = "æ®å¿çæ¯å¡è¿ª", |
["Skarr the Unbreakable"] = "æ æçæ¯å¡å°", |
["Skarvald the Constructor"] = "建çå¸æ¯å¡ç¦å°å¾·", |
["Skra'gath"] = "çå æå æ¯", |
Skul = "æ¯åºå°", |
Skum = "æ¯å¡å§", |
["Slad'ran"] = "æ¯æå¾·å °", |
Sneed = "æ¯å°¼å¾·", |
["Sneed's Shredder"] = "æ¯å°¼å¾·çä¼æ¨æº", |
["Solakar Flamewreath"] = "ç´¢æå¡Â·ç«å ", |
["Solarium Agent"] = "æ¥æ·å¯æ¢", |
["Solarium Priest"] = "æ¥æ·ç¥å¸", |
["Spirestone Battle Lord"] = "å°ç³ç»å¸ ", |
["Spirestone Butcher"] = "å°ç³å± 夫", |
["Spirestone Lord Magus"] = "å°ç³é¦å¸æ³å¸", |
["Staff of Disintegration"] = "ç¦è§£æ³æ", |
Stalagg = "æ¯å¡ææ ¼", |
Steelbreaker = "æé¢è ", |
["Stomper Kreeg"] = "è·µè¸è å é·æ ¼", |
Stonespine = "ç³è", |
["Stormcaller Brundir"] = "å¤é·è å¸é迪å°", |
Strawman = "稻è人", |
["Sulfuron Harbinger"] = "è¨å¼éå 驱è ", |
Supremus = "èæ®é·å§æ¯", |
["Svala Sorrowgrave"] = "å¸ç¦æÂ·ç´¢æ ¼è¾", |
["Swamplord Musel'ek"] = "æ²¼å°é¢ä¸»ç©å¡é·å ", |
Taerar = "æ³°æå°", |
["Tainted Spawn of Hydross"] = "污æç海度æ¯çªç", |
["Talon King Ikiss"] = "å©çªä¹çè¾åæ¯", |
["Taragaman the Hungerer"] = "饥饿è å¡æå æ¼", |
["Targorr the Dread"] = "å¯æçå¡æ ¼å°", |
Tavarok = "å¡ç¦æ´å ", |
Techbot = "å°ç«¯æºå¨äºº", |
Temporus = "å¦æ®å¢æ¯", |
["Tendris Warpwood"] = "ç¹è¿ªæ¯Â·ææ¨", |
Tenebron = "å¡å°¼å¸é", |
["Terestian Illhoof"] = "ç¹é·æ¯å¦Â·éªè¹", |
["Teron Gorefiend"] = "å¡é·è¡é", |
Thaddius = "å¡è¿ªä¹æ¯", |
["Thaladred the Darkener"] = "亵æ¸è è¨æå¾·é·", |
["Thane Korth'azz"] = "åºå°å¡å ¹é¢ä¸»", |
["The Beast"] = "æ¯æ¯å·¨å ½", |
["The Beasts of Northrend"] = "诺森德çå ½", |
["The Big Bad Wolf"] = "大ç°ç¼", |
["The Black Knight"] = "é»éªå£«", |
["The Black Stalker"] = "é»è²éæ¥è ", |
["The Blue Brothers"] = "èè²å å¼", |
["The Bug Family"] = "è«åä¸å®¶", |
["The Crone"] = "å·«å©", |
["The Curator"] = "é¦é¿", |
["The Eredar Twins"] = "è¾çè¾¾åå", |
["The Four Horsemen"] = "åéªå£«", |
["The Illidari Council"] = "ä¼å©è¾¾é·è®®ä¼", |
["The Iron Council"] = "é¢éè®®ä¼", |
["Theka the Martyr"] = "æ®æè å¡å¡", |
["The Lich King"] = "å·«å¦ç", |
["The Lurker Below"] = "é±¼æ¯æ", |
["The Maker"] = "å¶é è ", |
["The Prophet Skeram"] = "é¢è¨è æ¯å æå§", |
["The Prophet Tharon'ja"] = "å ç¥è¨éäº", |
["The Ravenian"] = "ææå°¼äº", |
["The Razza"] = "ææå°", |
["The Seven Dwarves"] = "ä¸è´¤ç®äºº", |
["The Skybreaker"] = "ç ´å¤©å·", |
["The Tribunal of Ages"] = "è¿å¤æ³åº", |
["The Twin Emperors"] = "ååçå¸", |
["The Twin Val'kyr"] = "ç¦æ ¼éåå", |
["The Unforgiven"] = "ä¸å¯å®½æè ", |
["The Windreaver"] = "çé£æ 夺è ", |
Thorim = "æéå§", |
["Thorngrin the Tender"] = "ç管è ç´¢æ©æ ¼æ", |
["Tidewalker Lurker"] = "è¸æ½®æ½ä¼è ", |
["Timmy the Cruel"] = "æ²æ¨çæç±³", |
Tinhead = "éç®äºº", |
["Tinkerer Gizlock"] = "å·¥å åå ¹æ´å ", |
["Tirion Fordring"] = "æé奧·å¼ä¸", |
Tito = "ææ", |
["Toravon the Ice Watcher"] = "å¯å°çå®è å¾ææº", |
["Trigore the Lasher"] = "éç¬è ç¹éé«é·", |
Trollgore = "æå°æ", |
["Tsu'zee"] = "èæ¯", |
["Tuten'kash"] = "å¾ç¹å¡ä»", |
["Twilight Lord Kelris"] = "梦游è å å°éæ¯", |
["Urok Doomhowl"] = "ä¹æ´å ", |
["Vaelastrasz the Corrupt"] = "å è½çç¦ææ¯å¡å ¹", |
["Valithria Dreamwalker"] = "è¸æ¢¦è ç¦èççå¨ ", |
["Val'kyr Shadowguard"] = "Val'kyr Shadowguard", -- Needs review |
["Varian Wrynn"] = "ç¦éå®Â·ä¹çæ©", |
["Varos Cloudstrider"] = "ç¦å°æ´æ¯Â·äºå»", |
Vazruden = "ç¦å ¹å¾·", |
["Vazruden the Herald"] = "ä¼ ä»¤å®ç¦å ¹å¾·", |
Vectus = "ç»´å å¾æ¯", |
Vem = "ç»´å§", |
Veng = "æ¸©æ ¼", |
["Veras Darkshadow"] = "ç»´å°è±æ¯Â·æ·±å½±", |
["Verdan the Everliving"] = "æ°¸çè æ²å°ä¸¹", |
Verek = "ç»´é·å ", |
Vesperon = "ç»´æ¯å¹é", |
Vexallus = "ç»´è¨é²æ¯", |
["Veyzhak the Cannibal"] = "é£å°¸è ç»´è¨å ", |
["Vile'rel"] = "ç¦åé·å°", |
Viscidus = "ç»´å¸åº¦æ¯", |
["Viscous Fallout"] = "ç²æ§è¾å°å°", |
["Void Reaver"] = "空çµæºç²", |
Volkhan = "æ²å°å", |
["VX-001"] = "VX-001", |
["Warbringer O'mrogg"] = "æäºä½¿è æ²å§ç½æ ¼", |
["Warchief Blackhand Piece"] = "é»æé é¿", |
["Warchief Kargath Bladefist"] = "é é¿å¡å æ¯Â·åæ³", |
["Warchief Rend Blackhand"] = "大é é¿é·å¾·Â·é»æ", |
["Warden Mellichar"] = "çæ¤è æ¢ éå¡å°", |
["Warder Stilgiss"] = "å ¸ç±å®æ¯è¿ªå°åºæ¯", |
["Warlord Kalithresh"] = "ç£åå¡å©çéæ¯", |
["War Master Voone"] = "ææ¥å®æ²æ©", |
["Warmaul Champion"] = "ææ§å士", |
["Warp Slicer"] = "è¿è·åå²è ", |
["Warp Splinter"] = "è¿è·ææ¨", |
["Watchkeeper Gargolmar"] = "å·¡è§è å æç", |
Weaver = "å¾·æç»´æ²å°", |
["Witch Doctor Zum'rah"] = "å·«å»ç¥ç©ææ©", |
["Wolf Master Nandos"] = "ç¼çåææ¯", |
["Wrath-Scryer Soccothrates"] = "天æé¢è¨è èå æåº", |
Wushoolay = "ä¹èé·", |
Xevozz = "è°¢æ²å ¹", |
["XT-002 Deconstructor"] = "XT-002æ解è ", |
["Yogg-Saron"] = "å°¤æ ¼-è¨é", |
Ysondre = "ä¼æ£®å¾·é·", |
Zekkis = "æ³½åºæ¯", |
["Zelemar the Wrathful"] = "æ¤æè å¡é·çå°", |
["Zereketh the Unbound"] = "èªç±ççé·å¯æ¯", |
Zerillis = "æ³½é·å©æ¯", |
["Zevrim Thornhoof"] = "çé·å§Â·åºè¹", |
Zolo = "ç¥ç½", |
["Zul'Farrak Dead Hero"] = "ç¥å°æ³æå éµäº¡è±é", |
["Zul'jin"] = "ç¥å°é", |
["Zul'Lor"] = "ç¥ç½å°", |
["Zul'tore"] = "ç¥å°æ", |
["Zuramat the Obliterator"] = "æ¹®çè ç¥æçç¹", |
} |
elseif GAME_LOCALE == "zhTW" then |
lib:SetCurrentTranslations { |
Acidmaw = "é ¸å", |
Aeonus = "è¾å¥§é£æ¯", |
["Aerial Command Unit"] = "空ä¸ææ®è£ç½®", |
["Agathelos the Raging"] = "æ´æçé¿è¿¦è³½ç¾ æ¯", |
Ahune = "è¾è¡æ©", |
["Akil'zon"] = "é¿å¥ç¾æ£®", |
["Aku'mai"] = "é¿åº«éº¥ç¾", |
["Al'ar"] = "æç¾", |
["Algalon the Observer"] = "ãè§å¯è ãè¾ç¾å é", |
["Alzzin the Wildshaper"] = "ãçéè®å½¢è ã奧è²æ©", |
Amanitar = "æ¯èé", |
["Ambassador Flamelash"] = "å¼èææ¯å¤§ä½¿", |
["Ambassador Hellmaw"] = "æµ·ç¾çªå¤§ä½¿", |
["Amnennar the Coldbringer"] = "ãå¯å°ä½¿è ãäºéç´ç¾", |
["Ancient Stone Keeper"] = "å¤ä»£çç³é çå®è ", |
Anetheron = "å®ç´å¡é", |
["Anger'rel"] = "å®æ ¼é·ç¾", |
Anomalus = "è¾è«¾çªè·¯æ¯", |
["Antu'sul"] = "å®åèç¾", |
["Anub'arak"] = "é¿åªå·´æå ", |
["Anubisath Defender"] = "é¿åªæ¯è©æ¯é²è¡è ", |
["Anubisath Guardian"] = "é¿åªæ¯è©æ¯å®è¡è ", |
["Anub'Rekhan"] = "é¿åªæ¯çå æ¼¢", |
["Anub'shiah"] = "é¿åªå¸ç¾", |
Anzu = "å®ç¥", |
["Arcane Watchman"] = "ç§æ³è¦åè ", |
["Arcanist Doan"] = "ç§æ³å¸«æå®", |
Archaedas = "é¿æéæ¯", |
["Archavon the Stone Watcher"] = "ãç³ä¹çå®è ãäºå¤æ¢µ", |
Archimonde = "é¿å èå¾·", |
["Archivist Galford"] = "æªæ¡ç®¡çå¡å ç¾ç¦ç¹", |
["Archmage Arugal"] = "大æ³å¸«é¿é¯é«", |
["Argent Confessor Paletress"] = "éç½å解è å¸ç¾ççµ²", |
["Arugal's Voidwalker"] = "é¿é¯é«çèç¡è¡è ", |
["Assault Bot"] = "çªè¥²æ©å¨äºº", |
["Atal'alarion"] = "é¿å¡æå©æ©", |
["Attumen the Huntsman"] = "çµäººé¿åæ¼", |
Auriaya = "奧è®é ", |
Avalanchion = "é¿ç¦èå¥å¥§", |
["Avatar of Hakkar"] = "åå¡çå身", |
["Ayamiss the Hunter"] = "ãç©çµè ãé¿äºç±³æ¯", |
Azgalor = "äºè²å æ´", |
["Azshir the Sleepless"] = "ä¸ç çè¾å¸ç¾", |
Azuregos = "è¾ç´¢é·èæ¯", |
["Bael'Gar"] = "è²ç¾å ", |
Baelog = "å·´ç¾æ´æ", |
Balnazzar = "å·´ç´æç¾", |
["Baltharus the Warborn"] = "ãæ°çä¹åãå·´ç¾è©é¯æ¯", |
["Bannok Grimaxe"] = "ç諾å ·巨æ§", |
["Baron Aquanis"] = "é¿å¥å°¼æ¯ç·çµ", |
["Baron Charr"] = "ç«ç°ç·çµæ¥ç¾", |
["Baroness Anastari"] = "å®å¨çµ²å¡éºç·çµå¤«äºº", |
["Baron Geddon"] = "迦é ç·çµ", |
["Baron Kazum"] = "å¡èå§ç·çµ", |
["Baron Rivendare"] = "çææ´ç¾ç·çµ", |
["Baron Silverlaine"] = "å¸ç¦èæ©ç·çµ", |
["Battleguard Sartura"] = "æ²ç¾åæ", |
["Bazil Thredd"] = "å·´åºç¾Â·æ¯çå¾·", |
Bazzalan = "å·´æè", |
["Black Guard Swordsmith"] = "é»è¡£å®è¡éå師", |
["Blackheart the Inciter"] = "ç ½åè é»å¿", |
["Blindeye the Seer"] = "å ç¥ç²ç¼", |
["Blind Hunter"] = "ç²ç¼çµæ", |
["Blood Guard Porung"] = "è¡è¡å£«æ³¢æ´å ", |
["Bloodlord Mandokir"] = "è¡é 主æ¼å¤åºç¾", |
["Bloodmage Thalnos"] = "è¡æ³å¸«è©ç¾è«¾æ¯", |
["Blood Prince Council"] = "è¡è¦ªçè°æ", |
["Blood Princes"] = "è¡è¦ªç", |
["Blood-Queen Lana'thel"] = "è¡è ¥å¥³çèå¨è©ç¾", |
["Blood Steward of Kirtonos"] = "åºç¾å諾æ¯çè¡å£«", |
Boahn = "åè¾æ©", |
["Bomb Bot"] = "ç¸å½æ©å¨äºº", |
["Brain of Yogg-Saron"] = "å°¤æ ¼è©å«çè ¦é¨", |
["Brainwashed Noble"] = "被æ´è ¦çè²´æ", |
Broggok = "å¸æ´å ", |
Brokentoe = "æ·è¶¾", |
Bronjahm = "å¸æåå§", |
["Broodlord Lashlayer"] = "é¾é 主å西é·ç¾", |
["Bruegal Ironknuckle"] = "å¸é¯æ·è¾ç¾å ç´å¯", |
Brutallus = "å¸é¯æé¯æ¯", |
["Burning Felguard"] = "ççæ¡éå®è¡", |
["Buru the Gorger"] = "ãæ´é£è ãå¸é¯", |
["Cache of the Firelord"] = "ç«ç°ä¹çç寶箱", |
["Cannon Master Willey"] = "ç ²æå¨å©", |
["Captain Greenskin"] = "ç¶ ç®éé·", |
["Captain Kromcrush"] = "å ç¾ å¡æ¯", |
["Captain Skarloc"] = "å²å¡æå ä¸å°", |
["Celebras the Cursed"] = "被è©åçå¡é·å¸ææ¯", |
["Charlga Razorflank"] = "å¡ç¾å ·åºè", |
["Chess Event"] = "西æ´æ£äºä»¶", |
["Chest of The Seven"] = "ä¸è³¢ä¹ç®±", |
["Chief Ukorz Sandscalp"] = "çå è²Â·æ²é ", |
["Cho'Rush the Observer"] = "ãè§å¯è ãå é¯ä»", |
Chromaggus = "å æ´çªå¤æ¯", |
["Chrono Lord Deja"] = "æéé 主迪è³", |
["Chrono-Lord Epoch"] = "ç´å æéé 主", |
Claw = "è£çª", |
["Coilfang Elite"] = "ç¤çç²¾è±", |
["Coilfang Strider"] = "ç¤çæ è¡è ", |
["Commander Kolurg"] = "ææ®å®å¯åæ ¼", |
["Commander Sarannis"] = "ææ®å®è©çå°¼æ¯", |
["Commander Springvale"] = "ææ®å®æ¯æ®æç¦ç¾", |
["Commander Stoutbeard"] = "ææ®å®åé¬", |
["Constructor & Controller"] = "ã建é è ãèãæ§å¶è ã", |
Cookie = "å»å¸«", |
["Coren Direbrew"] = "å¯ä»Â·æé ", |
["Cosmic Infuser"] = "å®å®çæºè ", |
["Crimson Hammersmith"] = "ç´ è¡£éé師", |
["Crowd Pummeler 9-60"] = "群é«ææè 9-60", |
["Crystal Fang"] = "æ°´æ¶ä¹ç", |
["C'Thun"] = "å èæ©", |
Cyanigosa = "é妮èè", |
["Dalliah the Doomsayer"] = "æ«æ¥é è¨è éå©äº", |
["Dalronn the Controller"] = "ãæ§å¶è ãééæ©", |
["Dark Iron Ambassador"] = "é»éµå¤§ä½¿", |
["Darkmaster Gandling"] = "é»æé¢é·å ä¸", |
["Darkweaver Syth"] = "ææ³å¸«å¸æ¯", |
["Deathbound Ward"] = "亡ç¸å®è¡", |
["Deathbringer Saurfang"] = "æ»äº¡ä½¿è è©é¯æ³ç¾", |
["Death Knight Darkreaver"] = "æ»äº¡é¨å£«éå é·ç¾", |
["Death Knight Understudy"] = "æ»äº¡é¨å£«å¯¦ç¿è ", |
["Deathspeaker High Priest"] = "亡é è é«éç¥å¸", |
["Death Speaker Jargba"] = "亡èªè è³æ ¼å·´", |
["Deathstalker Visceri"] = "亡éå¨å µå¨çç", |
["Deathsworn Captain"] = "æ»äº¡èªè¨è éé·", |
Devastation = "æ¯æ» ", |
["Deviate Faerie Dragon"] = "è®ç°ç²¾éé¾", |
["Devourer of Souls"] = "ç¾éåå¬è ", |
["Dextren Ward"] = "迪å æ¯ç¹Â·ç¦å¾·", |
["Digmaster Shovelphlange"] = "ææå°å®¶èç¾å¼ææ ¼", |
["Doctor Theolen Krastinov"] = "çç¾æ·å¡æ¯è¿ªè«¾å¤«ææ", |
["Doom Lord Kazzak"] = "æ¯æ» é 主å¡æå ", |
["Doom'rel"] = "æå§é·ç¾", |
Doomwalker = "åéè¡è ", |
["Dope'rel"] = "å¤æ®é·ç¾", |
Dorothee = "æ¡æ¨çµ²", |
["Drakkari Colossus"] = "å¾·æå çå·¨å", |
["Drakos the Interrogator"] = "ã審åè ãå¾·æé«æ¯", |
Dreadscale = "æ¼é±", |
Dreamscythe = "å¾·å§å¡å¡ç¾", |
["Dust Covered Chest"] = "滿ä½ç°å¡µç®±å", |
Dustwraith = "ç°å¡µæ¨é", |
["Eadric the Pure"] = "ãç´æ·¨è ãååå ", |
["Earthcaller Halmgar"] = "åå°è åç©å ", |
Ebonroc = "åå諾å ", |
["Eck the Ferocious"] = "ãå çãåå ", |
["Edwin VanCleef"] = "è¾å¾·æº«Â·èå é夫", |
["Elder Brightleaf"] = "亮èé·è ", |
["Elder Ironbranch"] = "éµæé·è ", |
["Elder Nadox"] = "èé£ææ¯", |
["Elder Stonebark"] = "ç³æ¨é·è ", |
["Electrocutioner 6000"] = "é»åå¨6000å", |
["Emalon the Storm Watcher"] = "ã風æ´çå®è ãè¾çªé", |
Emeriss = "è¾è«èçµ²", |
["Emperor Dagran Thaurissan"] = "éæ ¼è·索ç森大å¸", |
["Emperor Vek'lor"] = "ç¶å æ´ç¾å¤§å¸", |
["Emperor Vek'nilash"] = "ç¶å å°¼ææ¯å¤§å¸", |
Entropius = "å®åæ®æ¯", |
["Eonar's Gift"] = "ä¼æå¨çè´ç¦®", |
["Epoch Hunter"] = "ç´å ç©çµè ", |
Erekem = "ä¼é³å", |
["Eressea Dawnsinger"] = "è¾ç西é ·æ¦è© ", |
["Essence of Anger"] = "æ¤æç²¾è¯", |
["Essence of Desire"] = "æ ¾æç²¾è¯", |
["Essence of Suffering"] = "åé£ç²¾è¯", |
Eviscerator = "åç¼è ", |
["Exarch Maladaar"] = "主æçªæéç¾", |
["Expedition Commander"] = "é å¾éææ®å®", |
["Eydis Darkbane"] = "è¾ç絲·æå¯", |
["Eye of C'Thun"] = "å èæ©ä¹ç¼", |
["Faction Champions"] = "é£çå士", |
["Fallen Champion"] = "亡éå士", |
Falric = "æ³åçå ", |
["Falric and Marwyn"] = "æ³åçå å麥ç¾æº«", |
["Fankriss the Unyielding"] = "ä¸å±çèå éæ¯", |
["Fathom-Lord Karathress"] = "深淵ä¹çå¡æè©çæ¯", |
Felmyst = "éé¾è¬é§", |
["Fenrus the Devourer"] = "ãåå¬è ãè¬é¯æ¯", |
["Feral Defender"] = "éæ§é²è¡è ", |
Festergut = "è¿è ¸", |
Feugen = "ä¼æ¨", |
["Fineous Darkvire"] = "å¼è«¾æ¯Â·éå ç¶ç¾", |
Firemaw = "è²»ç¾é»", |
["Fjola Lightbane"] = "è²ææ·å å¯", |
Flamegor = "å¼èæ ¼ç¾", |
["Flame Leviathan"] = "çç°æ°è¼ª", |
["Foreman Thistlenettle"] = "å·¥é å¸æ¯èç¹", |
["Forgemaster Garfrost"] = "éé 大師å å¼ç¾ æ¯", |
["Four Horsemen Chest"] = "åé¨å£«ç®±å", |
["Fras Siabi"] = "å¼ææ¯Â·å¸äºæ¯", |
Freya = "èè¾é ", |
["Gahz'ranka"] = "å è²èå¡", |
["Gahz'rilla"] = "å è²çæ", |
["Gal'darah"] = "èç¾éæ", |
["Galgann Firehammer"] = "å å æ©Â·ç«é", |
Garr = "å ç¾", |
["Garrosh Hellscream"] = "å¡ç¾æ´æ¯Â·å°çå¼", |
Gasher = "å ä»ç¾", |
["Gatewatcher Gyro-Kill"] = "çå®è èæ´å¥æ", |
["Gatewatcher Iron-Hand"] = "çå®è éµæ", |
["Gathios the Shatterer"] = "ç²ç¢è é«å¸æ", |
Gehennas = "åºèµ«ç´æ¯", |
Gelihast = "æ ¼éåæ¯ç¹", |
Gelk = "åç¾å ", |
["General Angerforge"] = "å®æ ¼å¼å°è»", |
["General Bjarngrim"] = "ç¢äºæ ¼æå°è»", |
["General Drakkisath"] = "éåºè©æ¯å°è»", |
["General Rajaxx"] = "æè³å æ¯å°è»", |
["General Vezax"] = "å¨ææ¯å°è»", |
["General Zarithrian"] = "æéæ¯å©å®å°è»", |
["Ghamoo-ra"] = "å æ©æ", |
["Ghaz'an"] = "é«è©å®", |
["Ghok Bashguud"] = "éå ·巴ä»å¤å¾·", |
Gilnid = "åºç¾å°¼æ ¼", |
["Gizrul the Slavener"] = "ã奴役è ãåºè²ç§ç¾", |
["Gloom'rel"] = "æ ¼é¯é·ç¾", |
Gluth = "å¤é¯æ¯", |
Glutton = "æ´é£è ", |
["Golemagg the Incinerator"] = "ãçåè ãå¤é·æ¼æ ¼", |
["Golem Lord Argelmach"] = "éåé 主é¿æ ¼æ¼å¥", |
["Goraluk Anvilcrack"] = "å¤æé¯å ", |
["Gormok the Impaler"] = "ãç©¿åºè ãæè«å ", |
["Gorosh the Dervish"] = "ãä¿®è¡è ãé«ç¾ ä»", |
["Gortok Palehoof"] = "ææå ·ç½è¹", |
["Gothik the Harvester"] = "ãæ¶å²è ãé«å¸", |
["Grand Astromancer Capernian"] = "大æè¡å¸«å¡æ®å°¼æ©", |
["Grand Champions"] = "大å士", |
["Grand Magus Telestra"] = "大éå°å¸«ç¹é·æ¯ç¿ ", |
["Grandmaster Vorpil"] = "é å°è ç¦ç®æ", |
Grandmother = "å¤å©", |
["Grand Warlock Alythess"] = "大è¡å£«è¾é»ççµ²", |
["Grand Warlock Nethekurse"] = "大è¡å£«å¥å¾·å æ¯", |
["Grand Widow Faerlina"] = "大寡婦費ç³å¨", |
["Grethok the Controller"] = "ãæ§å¶è ãèçæå ", |
["Gri'lek"] = "æ ¼éé·å ", |
Grimlok = "æ ¼çå§æ´å ", |
Grizzle = "æ ¼éè²ç¾", |
Grobbulus = "èç¾ å·´æ¯", |
Grubbis = "æ ¼é¯æ¯æ¯", |
["Gruul the Dragonkiller"] = "å¼é¾è æé¯ç¾", |
["Guard Fengus"] = "è¡å µè¬å¤æ¯", |
["Guardian of Yogg-Saron"] = "å°¤æ ¼è©å«å®è·è ", |
["Guard Mol'dar"] = "è¡å µæ©ç¾é", |
["Guard Slip'kik"] = "è¡å µæ¯éåºå ", |
["Gurtogg Bloodboil"] = "èå¡æ ¼Â·è¡æ²¸", |
Gyth = "èæ¯", |
Hadronox = "åå諾å æ¯", |
Hakkar = "åå¡", |
Halazzi = "åæé½", |
Halion = "æµ·èæ©", |
Halycon = "åé·è¯", |
Hamhock = "åå§éå ", |
["Harbinger Skyriss"] = "å é© è å²èåå¸", |
["Hate'rel"] = "é»ç¹é·ç¾", |
["Hazza'rah"] = "åææç¾", |
Hazzas = "åææ¯", |
["Headless Horseman"] = "ç¡é é¨å£«", |
["Hearthsinger Forresten"] = "å¼é·æ¯ç¹æ©", |
["Hedrum the Creeper"] = "ãç¬è¡è ã赫æå§", |
["Heigan the Unclean"] = "ãä¸æ½è ãæµ·æ ¹", |
["Hellfire Channeler"] = "å°çç«å°é師", |
["Henry Stern"] = "亨å©Â·æ¯ç¹æ©", |
["Herald Volazj"] = "信使æ²èé½", |
Herod = "赫æ´å¾·", |
["Hex Lord Malacrass"] = "å¦è¡é 主çªæå é·æ¯", |
["High Astromancer Solarian"] = "é«éæè¡å¸«ç´¢æçæ©", |
["High Botanist Freywinn"] = "大æ¤ç©å¸å®¶è²»çè¡æ©", |
["High Inquisitor Fairbanks"] = "é«ç審å¤å®æ³ç¾çå æ¯", |
["High Inquisitor Whitemane"] = "é«ç審å¤å®æ·ç¹éæ©", |
["High Interrogator Gerstahn"] = "審è¨å®æ ¼æ¯å¡æ©", |
["High King Maulgar"] = "大åçè«å¡ç¾", |
["Highlord Mograine"] = "大é 主è«æ ¼èå°¼", |
["Highlord Omokk"] = "æè«å 大ç", |
["High Marshal Whirlaxis"] = "大å 帥ç¶æå¸æ¯", |
["High Nethermancer Zerevor"] = "é«çè空è¡å¸«æçä½", |
["High Overlord Saurfang"] = "è©é¯æ³ç¾é¸ç", |
["High Priestess Arlokk"] = "åå¡èå ç¥", |
["High Priestess Jeklik"] = "é«éç¥å¸è¶å éå ", |
["High Priestess Mar'li"] = "åå¡èå®éè ", |
["High Priestess of Thaurissan"] = "ç´¢ç森é«é女ç¥å¸", |
["High Priest Thekal"] = "é«éç¥å¸å¡å¡ç¾", |
["High Priest Venoxis"] = "é«éç¥å¸æº«è«¾å¸æ¯", |
["High Warlord Naj'entus"] = "é«éç£è»ç´çå¡æ¯", |
Hodir = "é迪ç¾", |
["Houndmaster Grebmar"] = "馴ç¬è æ ¼é·å¸çªç¾", |
["Houndmaster Loksey"] = "馴ç¬è æ´å å¸", |
Hukku = "è¡åº«", |
Hungarfen = "飢é¤ä¹ç", |
["Hurley Blackbreath"] = "éç¾é·Â·é»é¬", |
["Hyakiss the Lurker"] = "æ½ä¼è äºå¥æ¯", |
["Hydromancer Thespia"] = "æµ·æ³å¸«å¸æ¯æ¯äº", |
["Hydromancer Velratha"] = "æ°´å 師ç¶è¾è©", |
Hydrospawn = "æµ·å¤æ¯åæ©", |
["Hydross the Unstable"] = "ä¸ç©©å®è æµ·åå¸", |
["Icecrown Gunship Battle"] = "å¯å°çå 空ä¸è¦èæ°", |
Icehowl = "å°å", |
["Ice Sphere"] = "å¯å°çé«", |
Ichoron = "ä¼ä»é", |
Ick = "è¾å ", |
["Ignis the Furnace Master"] = "ãç«çä¹ä¸»ãä¼æ ¼å°¼å¸", |
["Illidan Stormrage"] = "ä¼å©ä¸¹Â·æ風", |
["Illidari Council"] = "ä¼å©éçè°æ", |
["Illyanna Ravenoak"] = "ä¼ç³å¨Â·é´æ©¡", |
["Immol'thar"] = "ä¼è«å¡ç¾", |
["Infinite Corruptor"] = "æé¾å¢®è½è ", |
["Infinity Blades"] = "ç¡ç¡ä¹å", |
["Ingvar the Plunderer"] = "ãçæ è ãå æ ¼ç¦", |
["Instructor Malicia"] = "è¬å¸«çªéºå¸äº", |
["Instructor Razuvious"] = "è¬å¸«æç¥ç¶æ¯", |
["Interrogator Vishas"] = "審è¨å¡éæ²æ¯", |
Ionar = "åæç´", |
Ironaya = "è¾éç´äº", |
Ironspine = "éµèæ»é", |
Isalien = "ä¾è©å©æ©", |
Jade = "çé¾", |
["Jammal'an the Prophet"] = "ãé è¨è ã迦çªè", |
["Jan'alai"] = "è³ç´é·", |
["Jandice Barov"] = "詹迪æ¯Â·å·´ç¾ 夫", |
["Jedoga Shadowseeker"] = "æ½æ佳·å°å½±è ", |
["Jed Runewatcher"] = "åå¾·", |
["Jergosh the Invoker"] = "ãå¡è½å¸«ãè¶æä»", |
["Jin'do the Hexxer"] = "ãå¦è¡å¸«ãé度", |
["Jormungar Behemoth"] = "èçå·¨ç¸", |
Jormungars = "å·¨è²", |
Julianne = "è±éºè", |
["Junk Bot"] = "åå¾æ©å¨äºº", |
["Kael'thas Sunstrider"] = "å±ç¾è©æ¯Â·éæ¥è ", |
Kalecgos = "å¡é·èæ¯", |
["Kam Deepfury"] = "å¡å§Â·æ·±æ", |
["Kazkaz the Unholy"] = "éªæ¡çå¡è©å¡è²", |
["Kaz'rogal"] = "å¡è²æ´å ", |
["Keli'dan the Breaker"] = "ãç ´å£è ãå±å©ä¸¹", |
["Kel'Thuzad"] = "ç§ç¾èå å¾·", |
Keristrasza = "å±çå²åè", |
["Kiggler the Crazed"] = "çç²è å¥å å", |
["Kil'jaeden"] = "åºç¾å 丹", |
["Kil'rek"] = "åºçå ", |
["King Dred"] = "å´å¾·ç", |
["King Gordok"] = "æå¤å 大ç", |
["King Llane Piece"] = "èæ©çæ£å", |
["King Ymiron"] = "ä¾ç±³å«ç", |
["Kirtonos the Herald"] = "å³ä»¤å®åºç¾å諾æ¯", |
["Knot Thimblejack's Cache"] = "諾ç¹Â·å¸å§å å çå²ç©ç®±", |
Kolk = "èç¾å ", |
Kologarn = "æ¯æ´åæ©", |
["Koralon the Flame Watcher"] = "ãçç°çå®è ãå¯æé", |
Kormok = "ç§ç¾è«å ", |
Kresh = "å é·ä»", |
Krick = "å çå ", |
["Krick and Ick"] = "è¾å èå çå ", |
["Krik'thir the Gatewatcher"] = "ãå®éè ãé½åå 西ç¾", |
["Krosh Firehand"] = "å ç¾ æ¯Â·ç«æ", |
Krystallus = "å å©æ¯æé¯æ¯", |
Kurinnaxx = "庫æç´å æ¯", |
["Lady Anacondra"] = "å®å¨ç§å¾·æ", |
["Lady Blaumeux"] = "å¸æ´è«æ¯å¥³å£«", |
["Lady Deathwhisper"] = "亡èªå¥³å£«", |
["Lady Illucia Barov"] = "ä¼é²å¸äºÂ·å·´ç¾ 夫女士", |
["Lady Malande"] = "çªèé»å¥³å£«", |
["Lady Sacrolash"] = "èçè¾å¸å¥³å£«", |
["Lady Sarevess"] = "è©å©ç¶çµ²å¥³å£«", |
["Lady Vashj"] = "ç¦è¨±å¥³å£«", |
Laj = "ææ°", |
Landslide = "èæ¯å©å¾·", |
Lavanthor = "ææ¹ç´¢", |
["Left Arm"] = "å·¦è", |
["Leotheras the Blind"] = "ãç²ç®è ãæ奧è©ææ¯", |
Lethon = "é·ç´¢", |
Lethtendris = "è¾çå¡èçµ²", |
["Leviathan Mk II"] = "æ°è¼ªMK II", |
["Ley-Guardian Eregos"] = "å°èå®è·è ä¼çèæ¯", |
["Lieutenant Drake"] = "ä¸å°å´å ", |
["Lieutenant General Andorov"] = "å®å¤æ´å¤«ä¸å°", |
Loatheb = "ææ¨è ", |
Loken = "æ´è¯", |
["Lord Alexei Barov"] = "é¿èå æ¯Â·å·´ç¾ 夫é 主", |
["Lord Cobrahn"] = "èå¸èæ©é 主", |
["Lord Hel'nurath"] = "赫ç¾åªææ¯é 主", |
["Lord Incendius"] = "ä¼æ£®è¿ªå¥§æ¯é 主", |
["Lord Jaraxxus"] = "è³æå çæ¯é 主", |
["Lord Kazzak"] = "æ¯æ» é 主å¡æå ", |
["Lord Kri"] = "å éé 主", |
["Lord Marrowgar"] = "çªæ´åé 主", |
["Lord Pythas"] = "ç®è©æ¯é 主", |
["Lord Roccor"] = "æ´èç¾é 主", |
["Lord Sanguinar"] = "æ¡å¤ç´ç¾é 主", |
["Lord Serpentis"] = "çè¬è¿ªæ¯é 主", |
["Lord Skwol"] = "æ¯å¤æ©é 主", |
["Lord Valthalak"] = "ç¦è©æå é 主", |
["Lord Victor Nefarius"] = "ç¶å å¤Â·å¥æ³å©æ¯é 主", |
["Lord Vyletongue"] = "ç¶å©å¡æ©é 主", |
["Lorekeeper Polkelt"] = "åå¸è æ®å ç¾ç¹", |
Loro = "æ´è¥ç¾", |
Lucifron = "é¯è¥¿å¼é", |
["Mad Magglish"] = "çççé¦¬æ ¼å©ä»", |
Maexxna = "æ¢ å çµ²å¨", |
["Mage-Lord Urom"] = "æ³å¸«é 主åé", |
["Magister Kalendris"] = "å¡é·è¿ªæ¯é®é·", |
["Magistrate Barthilas"] = "å·´çææ¯é®é·", |
Magmadar = "çªæ ¼æ¼é", |
Magmus = "çªæ ¼å§æ¯", |
Magra = "çªæ ¼æ", |
Magtheridon = "çªçéé ", |
["Maiden of Grief"] = "æ²åå°å¥³", |
["Maiden of Virtue"] = "è²æ½è女", |
["Majordomo Executus"] = "管çè åå ç´¢åæ¯", |
Malacrass = "çªæå é·æ¯", |
["Maleki the Pallid"] = "è¼ç½ççªååº", |
["Mal'Ganis"] = "çªç¾å å°¼æ¯", |
Malygos = "çªéèæ¯", |
Maraudos = "çªæå¤æ¯", |
["Marduk Blackpool"] = "馬æå ·å¸èå æ³¢ç¾", |
["Marisa du'Paige"] = "çªéè·ææ´¾æ ¼", |
Marwyn = "麥ç¾æº«", |
["Master Engineer Telonicus"] = "å·¥ç¨å¤§å¸«æ³°éå°¼å¡æ¯", |
["Maur Grimtotem"] = "çªç¾Â·ææå騰", |
Meathook = "èé¤", |
["Mechano-Lord Capacitus"] = "æ©æ¢°çå¡å¸å¸ç¹æ¯", |
Medivh = "麥迪æ", |
["Mekgineer Steamrigger"] = "ç±³å åå·è¸æ°£ææ§è ", |
["Mekgineer Thermaplugg"] = "麥å å°¼ç¾Â·ççªæ®ææ ¼", |
["Mennu the Betrayer"] = "èåè æ¼ç´", |
["Meshlok the Harvester"] = "ãæ¶å²è ã麥ä»æ´å ", |
Midnight = "åå¤", |
Mijan = "ç±³æ", |
Mimiron = "å½ç±³å«", |
["Miner Johnson"] = "礦工ç´ç¿°æ£®", |
["Mistress of Pain"] = "çè¦ä»å¥³", |
Moam = "è«é¿å§", |
Mogor = "è«å¤", |
["Mokra the Skullcrusher"] = "ãç¢é¡±è ãè«å æ", |
Moorabi = "æ ææ¯", |
Moragg = "æ©æé©", |
["Mordresh Fire Eye"] = "ç«ç¼è«å¾·é·æ¯", |
["Mor Grayhoof"] = "è«ç¾Â·ç°è¹", |
Moroes = "æ©æ´", |
["Morogrim Tidewalker"] = "è«æ´èå©å§Â·æ½®è¡è ", |
Morphaz = "æ©å¼ææ¯", |
["Mother Shahraz"] = "è©æè²å¥³å£«", |
["Mother Smolderweb"] = "ç 網èå", |
["Mr. Smite"] = "éæ³å ç", |
["Muradin Bronzebeard"] = "ç©æä¸Â·é é¬", |
["Murkblood Twin"] = "é»æä¹è¡éå", |
["Murkblood Twins"] = "é»æä¹è¡éå", |
Murmur = "è«ç¾å¢¨", |
["Murta Grimgut"] = "è«ç¾å¡", |
["M'uru"] = "è«é¯", |
Mushgog = "å§æ¯é«æ ¼", |
["Mutanus the Devourer"] = "ãåå¬è ãç©å¦åªæ¯", |
Nalorakk = "ç´ç¾ æå ", |
Nazan = "ç´æ¡", |
Nefarian = "å¥æ³å©å®", |
["Nekrum Gutchewer"] = "èå é¯å§", |
["Nerub'enkan"] = "å¥å¹½å¸æ©å", |
["Nethermancer Sepethrea"] = "è空è¡å¸«è³½è²çé ", |
Netherspite = "尼德æ¯", |
["Netherstrand Longbow"] = "è空ä¹çµé·å¼", |
["Nexus-Prince Shaffar"] = "å¥è©æ¯çåè©æ³ç¾", |
Nightbane = "å¤ç¦", |
["Noth the Plaguebringer"] = "ãçç«ä½¿è ã諾æ¯", |
["Novos the Summoner"] = "ãå¬åè ã諾æ²å¸", |
Noxxion = "諾å è³½æ©", |
["Obsidian Sentinel"] = "é»æç³å¨å µ", |
["Odo the Blindwatcher"] = "ãç²ç¼å®è¡ã奧æ", |
["Ogom the Wretched"] = "å¯æ²ç奧æå§", |
["Ok'thor the Breaker"] = "ãç ´å£è ã奧ç§ç´¢ç¾", |
["Old Serra'kis"] = "çæåæ¯", |
["Olm the Summoner"] = "å¬åè æè«", |
["Omor the Unscarred"] = "ç¡ç¤è æçªç¾", |
Onyxia = "奧妮å å¸äº", |
["Orgrim's Hammer"] = "å¥§æ ¼æä¹é", |
["Ormorok the Tree-Shaper"] = "ã樹æ¨é å½¢è ãæç¾è«æ´å ", |
["Oro Eyegouge"] = "æé¯Â·é¿ç¼", |
["Ossirian the Unscarred"] = "ãç¡ç¤è ã奧æ¯éå®", |
Ouro = "å¥§ç¾ ", |
["Overlord Ramtusk"] = "æå§å¡æ¯ä¸»å®°", |
["Overlord Wyrmthalak"] = "ç¶å§è©æå 主宰", |
["Overmaster Pyron"] = "å¾æè æ´¾é", |
["Overseer Tidewrath"] = "ç£ç£è æ³°æ´æ¯", |
Pandemonius = "çæèå°¼åæ¯", |
["Panzor the Invincible"] = "ç¡æµçæ½ä½ç¾", |
Patchwerk = "縫è£è ", |
["Pathaleon the Calculator"] = "æ縱è å¸è©éæ", |
Phalanx = "æ³æå æ¯", |
["Phaseshift Bulwark"] = "ç¸ä½å£å£", |
Pimgib = "å¹å§åå¸", |
["Plaguemaw the Rotting"] = "è ççæ®é·è«ç¾", |
["Plugger Spazzring"] = "æ®ææ ¼", |
["Postmaster Malown"] = "éµå·®çªç¾ æ©", |
["Priestess Delrissa"] = "女ç§å¸«æ´å©è", |
["Prince Keleseth"] = "å±é·å¸æ¯è¦ªç", |
["Prince Malchezaar"] = "è«å æçå", |
["Prince Skaldrenox"] = "æ¯å¡å¾·è«¾å æ¯çå", |
["Princess Huhuran"] = "åéèå ¬ä¸»", |
["Princess Moira Bronzebeard"] = "èè¾æ·é é¬å ¬ä¸»", |
["Princess Tempestria"] = "æ³°æ¯æ¯èäºå ¬ä¸»", |
["Princess Theradras"] = "çèå¾·çµ²å ¬ä¸»", |
["Princess Yauj"] = "äºç¾åºå ¬ä¸»", |
["Prince Taldaram"] = "æ³°ç¾éæ親ç", |
["Prince Tenris Mirkblood"] = "å¦çæ¯Â·æè¡çå", |
["Prince Tortheldrin"] = "æå¡å¾·æçå", |
["Prince Valanar"] = "ç¦æç´ç¾è¦ªç", |
["Professor Putricide"] = "æ®å´å¸å¾·ææ", |
["Pure Spawn of Hydross"] = "ç´æ£çæµ·åå¸åå£", |
Pusillin = "æ®å¸æ", |
["Pyroguard Emberseer"] = "çç°è¡å£«è¾åå¸ç¾", |
["Pyromancer Loregrain"] = "æ§ç«å¸«ç¾ æ ¼é·æ©", |
Quagmirran = "å¥å ç±³ç", |
["Quartermaster Zigris"] = "è»éå®è²æ ¼é·æ¯", |
["Rage Winterchill"] = "çé½Â·åå¬", |
Ragglesnout = "æææ¯è«¾ç¹", |
["Raging Spirit"] = "çæç鬼é", |
Ragnaros = "ææ ¼ç´ç¾ æ¯", |
["Ramstein the Gorger"] = "ãæ´é£è ãæå§æ¯ç»", |
["Ras Frostwhisper"] = "èæ¯Â·éèª", |
Rattlegore = "è¡éª¨åå¡", |
["Razorclaw the Butcher"] = "å± å¤«æä½å å", |
["Razorgore the Untamed"] = "çéçæä½æ ¼ç¾", |
Razorlash = "é³åºéç¬è ", |
Razorscale = "é³é±", |
["Reliquary of Souls"] = "ééä¹å£", |
Renataki = "é·ç´å¡åº", |
["Restless Skeleton"] = "æ°¸ä¸å®æ¯ç骷é«", |
Rethilgore = "é·å¸æç¾", |
Revelosh = "é¯ç¶ç¾ ä»", |
["Rhahk'Zor"] = "æå ä½", |
["Ribbly Screwspigot"] = "é·å¸é·æ¯åº«æ¯æ ¼ç¹", |
["Right Arm"] = "å³è", |
Roar = "ç å", |
["Rokad the Ravager"] = "å«æ¯è æå¡", |
["Rokdar the Sundered Lord"] = "ãç¢è£é 主ãæ´å é", |
["Rokmar the Crackler"] = "çè£è æ´å çª", |
Romulo = "ç¾ æ æ", |
["Romulo & Julianne"] = "ç¾ æ æèè±éºè", |
Rotface = "è è", |
Rotgrip = "æ´ç¹æ ¼éæ®", |
["Runemaster Molgeim"] = "符æ大師墨åå§", |
["Runok Wildmane"] = "é¯è«¾å Â·è »é¬", |
Ruuzlu = "ç§è²é¯", |
["Salramm the Fleshcrafter"] = "ãè¡èå·¥å ãå¡ææå§", |
["Sanctum Sentry"] = "èæå¨å µ", |
["Sandarr Dunereaver"] = "æéç¾Â·æ²æ è ", |
["Sandfury Executioner"] = "æ²æååæ", |
Sapphiron = "è©è²é", |
Sara = "è©æ", |
["Saronite Animus"] = "è©å«èæ¡é«", |
Sartharion = "æç¾è©éå®", |
["Sathrovarr the Corruptor"] = "ã墮è½è ãå¡æ¯è«¾ç¦", |
["Saviana Ragefire"] = "è©èå®å¨â§æç°", |
["Scarlet Commander Mograine"] = "è¡è²ååè»ææ®å®è«æ ¼èå°¼", |
["Scourgelord Tyrannus"] = "天è´é 主ææç´æ¯", |
["Seeth'rel"] = "西æ¯é·ç¾", |
["Selin Fireheart"] = "è³½æ·çå¿", |
["Sergeant Bly"] = "å¸èä¸å£«", |
["Shade of Akama"] = "é¿å¡çªçé»æé¢", |
["Shade of Aran"] = "åèä¹å½±", |
["Shade of Eranikus"] = "ä¼è尼庫æ¯çé°å½±", |
["Shadikith the Glider"] = "æ»ç¿è è迪ä¾æ¯", |
["Shadow Hunter Vosh'gajin"] = "æå½±çµææ²è¨±å æ¯", |
["Shadow of Leotheras"] = "æ奧è©ææ¯çé°å½±", |
["Shadowpriest Sezz'ziz"] = "æå½±ç¥å¸å¡çæ¯", |
Shadron = "å¤å¾·æ", |
Shazzrah = "æ²æ¯æç¾", |
["Shirrak the Dead Watcher"] = "æ»äº¡çå®è è¾çå ", |
Sindragosa = "è¾å¾·æèè", |
["Sir Zeliek"] = "æéå çµå£«", |
["Sjonnir The Ironshaper"] = "ãå¡éµè ãæ¯éå°¼ç¾", |
["Skadi the Ruthless"] = "ç¡æ çæ¯å¡è¿ª", |
["Skarr the Unbreakable"] = "ç¡æµçæ¯å¡ç¾", |
["Skarvald the Constructor"] = "ã建é è ãå²å¡æ²", |
["Skra'gath"] = "å²å¡æå æ¯", |
Skul = "æ¯åº«ç¾", |
Skum = "æ¯å¡å§", |
["Slad'ran"] = "å²æå¾·é³", |
Sneed = "æ¯å°¼å¾·", |
["Sneed's Shredder"] = "æ¯å°¼å¾·çä¼æ¨æ©", |
["Solakar Flamewreath"] = "ç´¢æå¡Â·ç«å ", |
["Solarium Agent"] = "æ¥å ä¹å®¤å¯æ¢", |
["Solarium Priest"] = "æ¥å ä¹å®¤ç§å¸«", |
["Spirestone Battle Lord"] = "å°ç³æ°é¬¥çµ±å¸¥", |
["Spirestone Butcher"] = "å°ç³å± 夫", |
["Spirestone Lord Magus"] = "å°ç³é¦å¸éå°å¸«", |
["Staff of Disintegration"] = "ç¦è§£ä¹æ", |
Stalagg = "æ¯å¡ææ ¼", |
Steelbreaker = "ç ´é¼è ", |
["Stomper Kreeg"] = "è¸è¸è å é·æ ¼", |
Stonespine = "ç³è", |
["Stormcaller Brundir"] = "風æ´å¬åè å¸å«è¿ªç¾", |
Strawman = "稻è人", |
["Sulfuron Harbinger"] = "è©å¼éå é© è ", |
Supremus = "çæ®è«æ¯", |
["Svala Sorrowgrave"] = "çµ²ç¦æ·æ²å·äº¡å¢", |
["Swamplord Musel'ek"] = "沼澤ä¹çè«æ¯èå ", |
Taerar = "æ³°æç¾", |
["Tainted Spawn of Hydross"] = "è åçæµ·åå¸ä¹å", |
["Talon King Ikiss"] = "é·¹çä¼å¥æ¯", |
["Taragaman the Hungerer"] = "ã飢é¤è ãå¡æå æ¼", |
["Targorr the Dread"] = "å¯æçå¡é«ç¾", |
Tavarok = "å¡ç¦æ´å ", |
Techbot = "å°ç«¯æ©å¨äºº", |
Temporus = "å¦æ®ææ¯", |
["Tendris Warpwood"] = "ç¹è¿ªæ¯Â·ææ¨", |
Tenebron = "å¦ç´ä¼¯æ", |
["Terestian Illhoof"] = "æ³°çæ¯æå®Â·ç«è¹", |
["Teron Gorefiend"] = "æ³°æ·è¡é", |
Thaddius = "泰迪æ¯", |
["Thaladred the Darkener"] = "ææ²é è¨å®¶è©æçå¾·", |
["Thane Korth'azz"] = "å¯æ¯è¾è²æé·", |
["The Beast"] = "æ¯æ¯å·¨ç¸", |
["The Beasts of Northrend"] = "åè£å¢å·¨ç¸", |
["The Big Bad Wolf"] = "大éç¼", |
["The Black Knight"] = "é»é¨å£«", |
["The Black Stalker"] = "é»è²æçµè ", |
["The Blue Brothers"] = "æ鬱å å¼é»¨", |
["The Bug Family"] = "è²å家æ", |
["The Crone"] = "èå·«å©", |
["The Curator"] = "館é·", |
["The Eredar Twins"] = "åé·éç¾éå", |
["The Four Horsemen"] = "åé¨å£«", |
["The Illidari Council"] = "ä¼å©éçè°äº", |
["The Iron Council"] = "éµä¹éæ", |
["Theka the Martyr"] = "ãæ®æè ãå¡å¡", |
["The Lich King"] = "å·«å¦ç", |
["The Lurker Below"] = "æµ·åºæ½ä¼è ", |
["The Maker"] = "åµé è ", |
["The Prophet Skeram"] = "é è¨è æ¯å æå§", |
["The Prophet Tharon'ja"] = "é è¨è è©éæ°", |
["The Ravenian"] = "ææå°¼äº", |
["The Razza"] = "ææ", |
["The Seven Dwarves"] = "ä¸è³¢äºº", |
["The Skybreaker"] = "ç ´å¤©è è", |
["The Tribunal of Ages"] = "æ²æè°åº", |
["The Twin Emperors"] = "éåçå¸", |
["The Twin Val'kyr"] = "è¯ç¾çªéå", |
["The Unforgiven"] = "ä¸å¯å¯¬æè ", |
["The Windreaver"] = "ç風æ¶å¥ªè ", |
Thorim = "ç´¢æå§", |
["Thorngrin the Tender"] = "ãç管è ãç´¢å¤æ", |
["Tidewalker Lurker"] = "æ½®è¡è æ½ä¼è ", |
["Timmy the Cruel"] = "æ²æ çæç±³", |
Tinhead = "æ©å¨äºº", |
["Tinkerer Gizlock"] = "æå·¥åè²æ´å ", |
["Tirion Fordring"] = "æé奧·å¼ä¸", |
Tito = "å¤å¤", |
["Toravon the Ice Watcher"] = "ãå¯å°çå®è ãææ梵", |
["Trigore the Lasher"] = "ãéç¬è ãç¹éé«é·", |
Trollgore = "è¡è§é£äººå¦", |
["Tsu'zee"] = "èæ¯", |
["Tuten'kash"] = "åç¹å¡ä»", |
["Twilight Lord Kelris"] = "æ®å é 主å ç¾éæ¯", |
["Urok Doomhowl"] = "çæ´å ", |
["Vaelastrasz the Corrupt"] = "墮è½çç¦ææ¯å¡è²", |
["Valithria Dreamwalker"] = "ç¦èçµ²çé ·夢è¡è ", |
["Val'kyr Shadowguard"] = "è¯ç¾çªå½±è¡", |
["Varian Wrynn"] = "ç¦éå®Â·ççæ©", |
["Varos Cloudstrider"] = "ç¦ç¾ æ¯Â·é²è¡è ", |
Vazruden = "ç¶æ¯è·¯ç»", |
["Vazruden the Herald"] = "ã信使ãç¶æ¯è·¯ç»", |
Vectus = "ç¶å åæ¯", |
Vem = "ç¶å§", |
Veng = "æº«æ ¼", |
["Veras Darkshadow"] = "ç¶ææ¯Â·æ·±å½±", |
["Verdan the Everliving"] = "æ°¸ççæ²ç¾ä¸¹", |
Verek = "ç¶é·å ", |
Vesperon = "ç¶æ¯ä½©æ", |
Vexallus = "ç¶å ç´¢é¯æ¯", |
["Veyzhak the Cannibal"] = "ãé£äººè ãç¶è©å ", |
["Vile'rel"] = "ç¦åé·ç¾", |
Viscidus = "ç¶å¸åº¦æ¯", |
["Viscous Fallout"] = "ç²æ§è¼»å°å¡µ", |
["Void Reaver"] = "èç¡æ¶å¥ªè ", |
Volkhan = "渥å ç", |
["VX-001"] = "VX-001", |
["Warbringer O'mrogg"] = "æ°ç製é è ·æå§ææ ¼", |
["Warchief Blackhand Piece"] = "é»æ大é é·æ£å", |
["Warchief Kargath Bladefist"] = "大é é·å¡å æ¯Â·åæ³", |
["Warchief Rend Blackhand"] = "大é é·é·å¾·Â·é»æ", |
["Warden Mellichar"] = "çå®è ç±³å©æ°ç¾", |
["Warder Stilgiss"] = "å®è¡æ¯è¿ªç¾åºæ¯", |
["Warlord Kalithresh"] = "ç£è»å¡å©æ¯ç", |
["War Master Voone"] = "ææ®å®æ²æ©", |
["Warmaul Champion"] = "æ°æ§å士", |
["Warp Slicer"] = "ææ²åå²è ", |
["Warp Splinter"] = "ææ²åè£è ", |
["Watchkeeper Gargolmar"] = "çè·è å¡ç¾å¤çª", |
Weaver = "å¾·æç¶æ²ç¾", |
["Witch Doctor Zum'rah"] = "å·«é«Â·ç¥ç©ææ©", |
["Wolf Master Nandos"] = "ç¼çåææ¯", |
["Wrath-Scryer Soccothrates"] = "æé®è ç´¢å¯æ¯çç¹", |
Wushoolay = "çèé·", |
Xevozz = "åºæ²æ»", |
["XT-002 Deconstructor"] = "XT-002æ解è ", |
["Yogg-Saron"] = "å°¤æ ¼è©å«", |
Ysondre = "ä¼ç´¢å¾·é·", |
Zekkis = "澤åºæ¯", |
["Zelemar the Wrathful"] = "æ¤æçè³½åçªç¾", |
["Zereketh the Unbound"] = "ç¡ç´æçå¸çå¥æ¯", |
Zerillis = "澤é·å©æ¯", |
["Zevrim Thornhoof"] = "çé·å§Â·åºè¹", |
Zolo = "ç¥ç¾ ", |
["Zul'Farrak Dead Hero"] = "ç¥ç¾æ³æå é£äº¡è±é", |
["Zul'jin"] = "ç¥ç¾é", |
["Zul'Lor"] = "ç¥ç¾ ç¾", |
["Zul'tore"] = "ç¥ç¾æ", |
["Zuramat the Obliterator"] = "ãæ¶æ» è ãèæéç¹", |
} |
else |
error(("%s: Locale %q not supported"):format(MAJOR_VERSION, GAME_LOCALE)) |
end |
## Interface: 30300 |
## LoadOnDemand: 1 |
## Title: Lib: Babble-Boss-3.0 |
## Notes: A library to help with localization of bosses. |
## 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. |
## Author: ckknight |
## X-eMail: ckknight@gmail.com |
## X-Category: Library |
## X-License: MIT |
## X-Curse-Packaged-Version: r287 |
## X-Curse-Project-Name: LibBabble-Boss-3.0 |
## X-Curse-Project-ID: libbabble-boss-3-0 |
## X-Curse-Repository-ID: wow/libbabble-boss-3-0/mainline |
LibStub\LibStub.lua |
lib.xml |
-- 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 |
<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-Boss-3.0.lua" /> |
</Ui> |
<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="LibTalentQuery-1.0.lua"/> |
</Ui> |
--[[ $Id: CallbackHandler-1.0.lua 60697 2008-02-09 16:51:20Z 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. |
--[[ |
Name: LibTalentQuery-1.0 |
Revision: $Rev: 80 $ |
Author: Rich Martel (richmartel@gmail.com) |
Documentation: http://wowace.com/wiki/LibTalentQuery-1.0 |
SVN: svn://svn.wowace.com/wow/libtalentquery-1-0/mainline/trunk |
Description: Library to help with querying unit talents |
Dependancies: LibStub, CallbackHandler-1.0 |
License: LGPL v2.1 |
Example Usage: |
local TalentQuery = LibStub:GetLibrary("LibTalentQuery-1.0") |
TalentQuery.RegisterCallback(self, "TalentQuery_Ready") |
local raidTalents = {} |
... |
TalentQuery:Query(unit) |
... |
function MyAddon:TalentQuery_Ready(e, name, realm, unitid) |
local isnotplayer = not UnitIsUnit(unitid, "player") |
local spec = {} |
for tab = 1, GetNumTalentTabs(isnotplayer) do |
local treename, _, pointsspent = GetTalentTabInfo(tab, isnotplayer) |
tinsert(spec, pointsspent) |
end |
raidTalents[UnitGUID(unitid)] = spec |
end |
]] |
local MAJOR, MINOR = "LibTalentQuery-1.0", 90000 + tonumber(("$Rev: 80 $"):match("(%d+)")) |
local lib = LibStub:NewLibrary(MAJOR, MINOR) |
if not lib then return end |
local INSPECTDELAY = 1 |
local INSPECTTIMEOUT = 5 |
if not lib.events then |
lib.events = LibStub("CallbackHandler-1.0"):New(lib) |
end |
local validateTrees |
local enteredWorld = IsLoggedIn() |
local frame = lib.frame |
if not frame then |
frame = CreateFrame("Frame", MAJOR .. "_Frame") |
lib.frame = frame |
end |
frame:UnregisterAllEvents() |
frame:RegisterEvent("INSPECT_TALENT_READY") |
frame:RegisterEvent("PLAYER_ENTERING_WORLD") |
frame:RegisterEvent("PLAYER_LEAVING_WORLD") |
frame:RegisterEvent("PLAYER_LOGIN") |
frame:SetScript("OnEvent", function(this, event, ...) |
return lib[event](lib, ...) |
end) |
do |
local lastUpdateTime = 0 |
frame:SetScript("OnUpdate", function(this, elapsed) |
lastUpdateTime = lastUpdateTime + elapsed |
if lastUpdateTime > INSPECTDELAY then |
lib:CheckInspectQueue() |
lastUpdateTime = 0 |
end |
end) |
frame:Hide() |
end |
local inspectQueue = lib.inspectQueue or {} |
lib.inspectQueue = inspectQueue |
local garbageQueue = lib.garbageQueue or {} -- Added a second queue to things. Inspects that initially fail are now |
lib.garbageQueue = garbageQueue -- thrown into second queue will will be processed once main queue is empty |
if next(inspectQueue) then |
frame:Show() |
end |
local UnitIsPlayer = _G.UnitIsPlayer |
local UnitName = _G.UnitName |
local UnitExists = _G.UnitExists |
local UnitGUID = _G.UnitGUID |
local GetNumRaidMembers = _G.GetNumRaidMembers |
local GetNumPartyMembers = _G.GetNumPartyMembers |
local UnitIsVisible = _G.UnitIsVisible |
local UnitIsConnected = _G.UnitIsConnected |
local UnitCanAttack = _G.UnitCanAttack |
local CanInspect = _G.CanInspect |
local function UnitFullName(unit) |
local name, realm = UnitName(unit) |
local namerealm = realm and realm ~= "" and name .. "-" .. realm or name |
return namerealm |
end |
-- GuidToUnitID |
local function GuidToUnitID(guid) |
local prefix, min, max = "raid", 1, GetNumRaidMembers() |
if max == 0 then |
prefix, min, max = "party", 0, GetNumPartyMembers() |
end |
-- Prioritise getting direct units first because other players targets |
-- can change between notify and event which can bugger things up |
for i = min, max do |
local unit = i == 0 and "player" or prefix .. i |
if (UnitGUID(unit) == guid) then |
return unit |
end |
end |
-- This properly detects target units |
if (UnitGUID("target") == guid) then |
return "target" |
elseif (UnitGUID("focus") == guid) then |
return "focus" |
end |
for i = min, max + 3 do |
local unit |
if i == 0 then |
unit = "player" |
elseif i == max + 1 then |
unit = "target" |
elseif i == max + 2 then |
unit = "focus" |
elseif i == max + 3 then |
unit = "mouseover" |
else |
unit = prefix .. i |
end |
if (UnitGUID(unit .. "target") == guid) then |
return unit .. "target" |
elseif (i <= max and UnitGUID(unit.."pettarget") == guid) then |
return unit .. "pettarget" |
end |
end |
return nil |
end |
-- Query |
function lib:Query(unit) |
if (UnitLevel(unit) < 10 or UnitName(unit) == UNKNOWN) then |
return |
end |
self.lastQueuedInspectReceived = nil |
if UnitIsUnit(unit, "player") then |
self.events:Fire("TalentQuery_Ready", UnitName("player"), nil, "player") |
else |
if type(unit) ~= "string" then |
error(("Bad argument #2 to 'Query'. Expected %q, received %q (%s)"):format("string", type(unit), tostring(unit)), 2) |
elseif not UnitExists(unit) or not UnitIsPlayer(unit) then |
error(("Bad argument #2 to 'Query'. %q is not a valid player unit"):format(tostring(unit)), 2) |
elseif not UnitExists(unit) or not UnitIsPlayer(unit) then |
error(("Bad argument #2 to 'Query'. %q does not require a server query before reading talents"):format("player"), 2) |
else |
local name = UnitFullName(unit) |
if (not inspectQueue[name]) then |
inspectQueue[name] = UnitGUID(unit) |
garbageQueue[name] = nil |
end |
frame:Show() |
end |
end |
end |
-- CheckInspectQueue |
-- Originally, it would wait until no pending NotifyInspect() were expected, and then do it's own. |
-- It was also only bother looking at ready results if it had triggered the Notify for that occasion. |
-- For the changes I've done, no assumption is made about which mod is performing NotifyInspect(). |
-- We note the name, unit, time of any inspects done whether from this queue or any other source, |
-- we remove from our queue any we were expecting, and use a seperate event in case extra talent |
-- info is any time wanted (opportunistic refreshes etc) - Zeksie, 20th May 2009 |
function lib:CheckInspectQueue() |
if (_G.InspectFrame and _G.InspectFrame:IsShown()) then |
return |
end |
if (not self.lastInspectTime or self.lastInspectTime < GetTime() - INSPECTTIMEOUT) then |
self.lastInspectPending = 0 |
end |
if (self.lastInspectPending > 0 or not enteredWorld) then |
return |
end |
if (self.lastQueuedInspectReceived and self.lastQueuedInspectReceived < GetTime() - 60) then |
-- No queued results received for a minute, so purge the queue as invalid and move on with our lives |
self.lastQueuedInspectReceived = nil |
inspectQueue = {} |
lib.inspectQueue = inspectQueue |
garbageQueue = {} |
lib.garbageQueue = garbageQueue |
frame:Hide() |
return |
end |
for name,guid in pairs(inspectQueue) do |
local unit = GuidToUnitID(guid) |
if (not unit) then |
inspectQueue[name] = nil |
else |
if (UnitIsVisible(unit) and UnitIsConnected(unit) and not UnitCanAttack("player", unit) and not UnitCanAttack(unit, "player") and CanInspect(unit) and UnitClass(unit)) then |
NotifyInspect(unit) |
break |
else |
garbageQueue[name] = guid -- Not available, throw into secondary queue and continue |
inspectQueue[name] = nil |
end |
end |
end |
if (not next(inspectQueue)) then |
if (next(garbageQueue)) then |
-- Retry initially failed inspects |
lib.inspectQueue = garbageQueue |
inspectQueue = lib.inspectQueue |
lib.garbageQueue = {} |
garbageQueue = lib.garbageQueue |
else |
frame:Hide() |
end |
end |
end |
-- NotifyInspect |
if not lib.NotifyInspect then -- don't hook twice |
hooksecurefunc("NotifyInspect", function(...) return lib:NotifyInspect(...) end) |
end |
function lib:NotifyInspect(unit) |
if (not (UnitExists(unit) and UnitIsVisible(unit) and UnitIsConnected(unit) and CheckInteractDistance(unit, 4))) then |
return |
end |
self.lastInspectUnit = unit |
self.lastInspectGUID = UnitGUID(unit) |
self.lastInspectTime = GetTime() |
self.lastInspectName = UnitFullName(unit) |
self.lastInspectPending = self.lastInspectPending + 1 |
local isnotplayer = not UnitIsUnit("player", unit) |
self.lastInspectTree = GetTalentTabInfo(1, isnotplayer) -- Talent tree names are available immediately |
end |
-- Reset |
function lib:Reset() |
self.lastInspectPending = 0 |
self.lastInspectUnit = nil |
self.lastInspectTime = nil |
self.lastInspectName = nil |
self.lastInspectGUID = nil |
self.lastInspectTree = nil |
end |
-- INSPECT_TALENT_READY |
function lib:INSPECT_TALENT_READY() |
self.lastInspectPending = self.lastInspectPending - 1 |
-- Results are valid only when we have received as many events as we have posted notifies |
if (self.lastInspectName and self.lastInspectPending == 0) then |
-- Check unit ID is still pointing to same actual unit |
if (UnitGUID(self.lastInspectUnit) == self.lastInspectGUID) then |
local guid = inspectQueue[self.lastInspectName] |
inspectQueue[self.lastInspectName] = nil |
local name, realm = strsplit("-", self.lastInspectName) |
self.lastQueuedInspectReceived = GetTime() |
-- Notify of expected talent results |
local isnotplayer = not UnitIsUnit("player", self.lastInspectName) |
local group = GetActiveTalentGroup(isnotplayer) |
local tree1, _, spent1 = GetTalentTabInfo(1, isnotplayer, nil, group) |
if (tree1 ~= self.lastInspectTree) then |
-- Expected talent tree name to be the same as it was when we triggered the NotifyInspect() |
garbageQueue[self.lastInspectName] = self.lastInspectGUID |
self:Reset() |
self:CheckInspectQueue() |
return |
elseif (validateTrees) then |
-- Double checking here. Check the tree name matches what we expect for this class |
local _, class = UnitClass(self.lastInspectUnit) |
if (tree1 ~= validateTrees[class]) then |
garbageQueue[self.lastInspectName] = self.lastInspectGUID |
self:Reset() |
self:CheckInspectQueue() |
return |
end |
end |
local tree2, _, spent2 = GetTalentTabInfo(2, isnotplayer, nil, group) |
local tree3, _, spent3 = GetTalentTabInfo(3, isnotplayer, nil, group) |
if ((spent1 or 0) + (spent2 or 0) + (spent3 or 0) > 0) then |
if (guid) then |
-- It was in our queue |
self.events:Fire("TalentQuery_Ready", name, realm, self.lastInspectUnit) |
else |
-- Also notify of non-expected ones, as it's entirely useful to refresh them if they're there |
-- It is up to the receiving applicating to determine whether they want to receive the information |
self.events:Fire("TalentQuery_Ready_Outsider", name, realm, self.lastInspectUnit) |
end |
else |
-- Tree came back with zero points spent, probably an issue while logging in |
garbageQueue[self.lastInspectName] = guid |
end |
end |
self:Reset() |
self:CheckInspectQueue() |
end |
end |
function lib:PLAYER_ENTERING_WORLD() |
-- We can't inspect other's talents until now |
-- We just get 0/0/0 back even though we get an INSPECT_TALENT_READY event |
enteredWorld = true |
end |
function lib:PLAYER_LEAVING_WORLD() |
enteredWorld = nil |
end |
function lib:PLAYER_LOGIN() |
validateTrees = { |
DRUID = "Balance", |
PRIEST = "Discipline", |
ROGUE = "Assassination", |
HUNTER = "Beast Mastery", |
WARLOCK = "Affliction", |
WARRIOR = "Arms", |
DEATHKNIGHT = "Blood", |
PALADIN = "Holy", |
SHAMAN = "Elemental", |
MAGE = "Arcane", |
} |
if (GetLocale() ~= "enUS" and GetLocale() ~= "enGB") then |
-- LibBabble-TalentTree-3.0 only loaded if present and not enUS |
local LBT = LibStub("LibBabble-TalentTree-3.0", true) |
if (not LBT) then |
LoadAddOn("LibBabble-TalentTree-3.0") |
LBT = LibStub("LibBabble-TalentTree-3.0", true) |
end |
LBT = LBT and LBT:GetLookupTable() |
if (LBT) then |
for class,tree1 in pairs(validateTrees) do |
validateTrees[class] = LBT[tree1] |
end |
else |
validateTrees = nil |
end |
end |
self.PLAYER_LOGIN = nil |
end |
lib:Reset() |
-- 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 |
## 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: r82 |
## X-Curse-Project-Name: LibTalentQuery-1.0 |
## X-Curse-Project-ID: libtalentquery-1-0 |
## X-Curse-Repository-ID: wow/libtalentquery-1-0/mainline |
LibStub.lua |
## Interface: 30300 |
## LoadOnDemand: 1 |
## Title: Lib: TalentQuery 1.0 |
## Notes: Library to help with querying unit talents. |
## Author: Peragor |
## Version: $Rev: 82 $ |
## X-Category: Library |
## X-ReleaseDate: $Date: 2009-12-09 11:08:46 +0000 (Wed, 09 Dec 2009) $ |
## X-Website: http://wowace.com/wiki/LibTalentQuery-1.0 |
## X-License: LGPL v2.1 |
## X-Curse-Packaged-Version: r82 |
## X-Curse-Project-Name: LibTalentQuery-1.0 |
## X-Curse-Project-ID: libtalentquery-1-0 |
## X-Curse-Repository-ID: wow/libtalentquery-1-0/mainline |
LibStub\LibStub.lua |
CallbackHandler-1.0\CallbackHandler-1.0.lua |
lib.xml |
-- 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 |
## 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 |
## Interface: 30300 |
## 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: r268 |
## 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 |
-- 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 |
-- 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 |
--[[ |
Name: LibBabble-Zone-3.0 |
Revision: $Rev: 268 $ |
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: 268 $"):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", |
["Blackwind Lake"] = "Blackwind Lake", |
["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 Reflection"] = "Halls of Reflection", |
["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", |
["Hrothgar's Landing"] = "Hrothgar's Landing", |
Hyjal = "Hyjal", |
["Hyjal Summit"] = "Hyjal Summit", |
Icecrown = "Icecrown", |
["Icecrown Citadel"] = "Icecrown Citadel", |
["Insidion's Perch"] = "Insidion's Perch", |
Ironforge = "Ironforge", |
["Isle of Conquest"] = "Isle of Conquest", |
["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", |
["Marshlight Lake"] = "Marshlight Lake", |
["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", |
["Pit of Saron"] = "Pit of Saron", |
["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", |
["Scalebeard's Cave"] = "Scalebeard's Cave", |
["Scarlet Monastery"] = "Scarlet Monastery", |
Scholomance = "Scholomance", |
["Searing Gorge"] = "Searing Gorge", |
["Serpent Lake"] = "Serpent Lake", |
["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", |
["Skysong Lake"] = "Skysong Lake", |
["Sporewind Lake"] = "Sporewind Lake", |
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", |
["Terokk's Rest"] = "Terokk's Rest", |
["The Arachnid Quarter"] = "The Arachnid Quarter", |
["The Arcatraz"] = "The Arcatraz", |
["The Argent Coliseum"] = "The Argent Coliseum", |
["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 Forge of Souls"] = "The Forge of Souls", |
["The Frozen Halls"] = "The Frozen Halls", |
["The Frozen Sea"] = "The Frozen Sea", |
["The Great Sea"] = "The Great Sea", |
["The Halls of Winter"] = "The Halls of Winter", |
["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", |
["The Prison of Yogg-Saron"] = "The Prison of Yogg-Saron", |
["Theramore Isle"] = "Theramore Isle", |
["The Ring of Valor"] = "The Ring of Valor", |
["The Ruby Sanctum"] = "The Ruby Sanctum", |
["The Scarlet Enclave"] = "The Scarlet Enclave", |
["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", |
["Trial of the Champion"] = "Trial of the Champion", |
["Trial of the Crusader"] = "Trial of the Crusader", |
["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", |
["Blackwind Lake"] = "Schattenwindsee", |
["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"] = "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"] = "Frostwyrmbau", |
["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 Reflection"] = "Hallen der Reflexion", |
["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", |
["Hrothgar's Landing"] = "Hrothgars Landestelle", |
Hyjal = "Hyjal", |
["Hyjal Summit"] = "Hyjalgipfel", |
Icecrown = "Eiskrone", |
["Icecrown Citadel"] = "Eiskronenzitadelle", |
["Insidion's Perch"] = "Isidions Hort", |
Ironforge = "Eisenschmiede", |
["Isle of Conquest"] = "Insel der Eroberung", |
["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", |
["Marshlight Lake"] = "Sumpflichtsee", |
["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", |
["Pit of Saron"] = "Grube von Saron", |
["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", |
["Scalebeard's Cave"] = "Schuppenbarts Höhle", |
["Scarlet Monastery"] = "Das Scharlachrote Kloster", |
Scholomance = "Scholomance", |
["Searing Gorge"] = "Sengende Schlucht", |
["Serpent Lake"] = "Schlangensee", |
["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", |
["Skysong Lake"] = "Himmelsweisensee", |
["Sporewind Lake"] = "Sporenwindsee", |
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", |
["Terokk's Rest"] = "Terokks Ruh", |
["The Arachnid Quarter"] = "Das Arachnidenviertel", |
["The Arcatraz"] = "Die Arkatraz", |
["The Argent Coliseum"] = "Das Kolosseum der Kreuzfahrer", |
["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 Forge of Souls"] = "Die Schmiede der Seelen", |
["The Frozen Halls"] = "Die gefrorenen Hallen", |
["The Frozen Sea"] = "Die gefrorene See", |
["The Great Sea"] = "Das groÃe Meer", |
["The Halls of Winter"] = "Die Hallen des Winters", |
["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", |
["The Prison of Yogg-Saron"] = "Das Gefängnis von Yogg-Saron", |
["Theramore Isle"] = "Insel Theramore", |
["The Ring of Valor"] = "Der Ring der Ehre", |
["The Ruby Sanctum"] = "Das Rubinsanktum", |
["The Scarlet Enclave"] = "Die Scharlachrote Enklave", |
["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", |
["Trial of the Champion"] = "Prüfung des Champions", |
["Trial of the Crusader"] = "Prüfung des Kreuzfahrers", |
["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", |
["Blackwind Lake"] = "Lac Noirvent", |
["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 Reflection"] = "Les salles des Reflets", |
["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", |
["Hrothgar's Landing"] = "Accostage de Hrothgar", |
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 Conquest"] = "Ãle des Conquérants", |
["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", |
["Marshlight Lake"] = "Lac des furoles", |
["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", |
["Pit of Saron"] = "Fosse de Saron", |
["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", |
["Scalebeard's Cave"] = "Caverne de Barbe-d'écailles", |
["Scarlet Monastery"] = "Monastère écarlate", |
Scholomance = "Scholomance", |
["Searing Gorge"] = "Gorge des Vents brûlants", |
["Serpent Lake"] = "Lac des Serpents", |
["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", |
["Skysong Lake"] = "Lac Chanteciel", |
["Sporewind Lake"] = "Lac Ventespore", |
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", |
["Terokk's Rest"] = "Repos de Terokk", |
["The Arachnid Quarter"] = "Le quartier des Arachnides", |
["The Arcatraz"] = "L'Arcatraz", |
["The Argent Coliseum"] = "Le colisée d'Argent", |
["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 Forge of Souls"] = "La Forge des âmes", |
["The Frozen Halls"] = "Les salles Gelées", |
["The Frozen Sea"] = "La mer Gelée", |
["The Great Sea"] = "La Grande mer", |
["The Halls of Winter"] = "Les salles de l'Hiver", |
["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", |
["The Prison of Yogg-Saron"] = "La prison de Yogg-Saron", |
["Theramore Isle"] = "Ãle de Theramore", |
["The Ring of Valor"] = "L'Arène des valeureux", |
["The Ruby Sanctum"] = "Le sanctum Rubis", |
["The Scarlet Enclave"] = "L'enclave Ãcarlate", |
["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", |
["Trial of the Champion"] = "L'épreuve du champion", |
["Trial of the Crusader"] = "L'épreuve du croisé", |
["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"] = "ê²ì ì¬ì", |
["Blackwind Lake"] = "ê²ìë°ë í¸ì", |
["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 Reflection"] = "í¬ìì ì ë¹", |
["Halls of Stone"] = "ëì ì ë¹", |
["Hellfire Citadel"] = "ì§ì¥ë¶ ì±ì±", |
["Hellfire Peninsula"] = "ì§ì¥ë¶ ë°ë", |
["Hellfire Ramparts"] = "ì§ì¥ë¶ ì±ë£¨", |
["Hillsbrad Foothills"] = "íì¤ë¸ëë 구ë¦ì§", |
["Horde Encampment"] = "í¸ë ì¼ìì§", |
["Howling Fjord"] = "ì¸ë¶ì§ë íë§", |
["Hrothgar's Landing"] = "íë¡ì¤ê°ë¥´ ìë¥ì§", |
Hyjal = "íì´ì", |
["Hyjal Summit"] = "íì´ì ì ì", |
Icecrown = "ì¼ììê´", |
["Icecrown Citadel"] = "ì¼ììê´ ì±ì±", |
["Insidion's Perch"] = "ì¸ìëì¨ì ë¥ì§", |
Ironforge = "ìì´ì¸í¬ì§", |
["Isle of Conquest"] = "ì ë³µì ì¬", |
["Isle of Quel'Danas"] = "ì¿ ìë¤ëì¤ ì¬", |
Kalimdor = "칼림ëì´", |
Karazhan = "ì¹´ë¼ì", |
["Krasus' Landing"] = "í¬ë¼ìì¤ ì°©ë¥ì¥", |
Library = "ëìê´", |
["Loch Modan"] = "ëª¨ë¨ í¸ì", |
["Lower Blackrock Spire"] = "ê²ìë°ì 첨í í층", |
["Magisters' Terrace"] = "ë§ë²íìì ì ì", |
["Magtheridon's Lair"] = "ë§ê·¸í 리ëì ë¥ì§", |
["Mana-Tombs"] = "ë§ë 무ë¤", |
Maraudon = "ë§ë¼ì°ë", |
["Marshlight Lake"] = "ìë ë±ë¶ í¸ì", |
["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 = "ììëë", |
["Pit of Saron"] = "ì¬ë¡ ì 구ë©ì´", |
["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"] = "ë¡ë°ë¡ ì íí", |
["Scalebeard's Cave"] = "ë¹ëìì¼ ëêµ´", |
["Scarlet Monastery"] = "ë¶ìììêµ° ìëì", |
Scholomance = "ì¤ì¹¼ë¡ë§¨ì¤", |
["Searing Gorge"] = "ì´ê¸ê±°ë¦¬ë í곡", |
["Serpent Lake"] = "물ê°í´ í¸ì", |
["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"] = "íëê²½ë¹ë ì ì´ê¸°ì§", |
["Skysong Lake"] = "íëë ¸ë í¸ì", |
["Sporewind Lake"] = "í¬ìë°ë í¸ì", |
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"] = "í ë¡ì¹´ë¥´ ì²", |
["Terokk's Rest"] = "í ë¡í¬ì ììì²", |
["The Arachnid Quarter"] = "거미 ì§êµ¬", |
["The Arcatraz"] = "ìì¹´í¸ë¼ì¦", |
["The Argent Coliseum"] = "ììêµ° ìí경기ì¥", |
["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 Forge of Souls"] = "ìí¼ì ì ë ¨ì", |
["The Frozen Halls"] = "ì¼ì´ë¶ì ì ë¹", |
["The Frozen Sea"] = "ì¼ì´ë¶ì ë°ë¤", |
["The Great Sea"] = "ëí´", |
["The Halls of Winter"] = "겨ì¸ì ì ë¹", |
["The Hinterlands"] = "ëë¶ ë´ë¥ì§", |
["The Mechanar"] = "ë©ì¹´ë르", |
["The Military Quarter"] = "êµ°ì¬ ì§êµ¬", |
["The Nexus"] = "ë§ë ¥ì í", |
["The North Sea"] = "ë¶í´", |
["The Obsidian Sanctum"] = "íìì ì±ì", |
["The Oculus"] = "ë§ë ¥ì ë", |
["The Plague Quarter"] = "ìë³ ì§êµ¬", |
["The Prison of Yogg-Saron"] = "ìê·¸ì¬ë¡ ì ê°ì¥", |
["Theramore Isle"] = "í ë¼ëª¨ì´ ì¬", |
["The Ring of Valor"] = "ì©ë§¹ì í¬ê¸°ì¥", |
["The Ruby Sanctum"] = "ë£¨ë¹ ì±ì", -- Needs review |
["The Scarlet Enclave"] = "ì§íë¹ ì ë¹", |
["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"] = "í°ë¦¬ì¤í ì²", |
["Trial of the Champion"] = "ì©ì¬ì ìíì¥", |
["Trial of the Crusader"] = "ììêµ°ì ìíì¥", |
["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", |
["Blackwind Lake"] = "Lago Vientonegro", |
["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 Reflection"] = "Cámaras de Reflexión", |
["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", |
["Hrothgar's Landing"] = "Desembarco de Hrothgar", |
Hyjal = "Hyjal", |
["Hyjal Summit"] = "Cima Hyjal", |
Icecrown = "Corona de Hielo", |
["Icecrown Citadel"] = "Ciudadela de la Corona de Hielo", |
["Insidion's Perch"] = "Nido de Insidion", |
Ironforge = "Forjaz", |
["Isle of Conquest"] = "Isla de la Conquista", |
["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", |
["Marshlight Lake"] = "Lago Luz Pantanosa", |
["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", |
["Pit of Saron"] = "Foso de Saron", |
["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", |
["Scalebeard's Cave"] = "Cueva de Barbascamas", |
["Scarlet Monastery"] = "Monasterio Escarlata", |
Scholomance = "Scholomance", |
["Searing Gorge"] = "La Garganta de Fuego", |
["Serpent Lake"] = "Lago Serpiente", |
["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", |
["Skysong Lake"] = "Lago Sol Celeste", |
["Sporewind Lake"] = "Lago Espora Volante", |
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", |
["Terokk's Rest"] = "Sosiego de Terokk", |
["The Arachnid Quarter"] = "Ala Arácnida", |
["The Arcatraz"] = "El Alcatraz", |
["The Argent Coliseum"] = "El Coliseo Argenta", |
["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 Forge of Souls"] = "La Forja de Almas", |
["The Frozen Halls"] = "Las Cámaras Heladas", |
["The Frozen Sea"] = "El Mar Gélido", |
["The Great Sea"] = "Mare Magnum", |
["The Halls of Winter"] = "Las Cámaras del Invierno", |
["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", |
["The Prison of Yogg-Saron"] = "La Prisión de Yogg-Saron", |
["Theramore Isle"] = "Isla Theramore", |
["The Ring of Valor"] = "El Anillo del Valor", |
-- ["The Ruby Sanctum"] = "", |
["The Scarlet Enclave"] = "Tierras de la Peste: El Enclave Escarlata", |
["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", |
["Trial of the Champion"] = "Prueba del Cruzado", |
["Trial of the Crusader"] = "Prueba del Cruzado", |
["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", |
["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", |
["Blackwind Lake"] = "Lago Vientonegro", |
["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 Reflection"] = "Camáras de Reflexión", |
["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", |
["Hrothgar's Landing"] = "Desembarco de Hrothgar", |
Hyjal = "Hyjal", |
["Hyjal Summit"] = "Cima Hyjal", |
Icecrown = "Corona de Hielo", |
["Icecrown Citadel"] = "Ciudadela de la Corona de Hielo", |
["Insidion's Perch"] = "Nido de Insidion", |
Ironforge = "Forjaz", |
["Isle of Conquest"] = "Isla de la Conquista", |
["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", |
["Marshlight Lake"] = "Lago Luz Pantanosa", |
["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", |
["Pit of Saron"] = "Foso de Saron", |
["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", |
["Scalebeard's Cave"] = "Cueva de Barbaescamas", |
["Scarlet Monastery"] = "Monasterio Escarlata", |
Scholomance = "Scholomance", |
["Searing Gorge"] = "La Garganta de Fuego", |
["Serpent Lake"] = "Lago Serpiente", |
["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", |
["Skysong Lake"] = "Lago Son Celeste", |
["Sporewind Lake"] = "Lago Espora Volante", |
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", |
["Terokk's Rest"] = "Sosiego de Terokk", |
["The Arachnid Quarter"] = "Ala Arácnida", |
["The Arcatraz"] = "El Alcatraz", |
["The Argent Coliseum"] = "El Coliseo Argenta", |
["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 Forge of Souls"] = "La Forja de Almas", |
["The Frozen Halls"] = "Las Salas Gélidas", |
["The Frozen Sea"] = "El Mar Gélido", |
["The Great Sea"] = "Mare Magnum", |
["The Halls of Winter"] = "Las Cámaras del Invierno", |
["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", |
["The Prison of Yogg-Saron"] = "La Prisión de Yogg-Saron", |
["Theramore Isle"] = "Isla Theramore", |
["The Ring of Valor"] = "El Anillo del Valor", |
-- ["The Ruby Sanctum"] = "", |
["The Scarlet Enclave"] = "El Enclave Escarlata", |
["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", |
["Trial of the Champion"] = "Pueba del Campeon", |
["Trial of the Crusader"] = "Prueba del Cruzado", |
["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 == "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"] = "ЧеÑнÑй Ñ Ñам", |
["Blackwind Lake"] = "ÐзеÑо ЧеÑного ÐеÑÑа", |
["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 Reflection"] = "ÐÐ°Ð»Ñ ÐÑÑажений", |
["Halls of Stone"] = "ЧеÑÑоги ÐамнÑ", |
["Hellfire Citadel"] = "ЦиÑÐ°Ð´ÐµÐ»Ñ ÐдÑкого Ðламени", |
["Hellfire Peninsula"] = "ÐолÑоÑÑÑов ÐдÑкого Ðламени", |
["Hellfire Ramparts"] = "ÐаÑÑÐ¸Ð¾Ð½Ñ ÐдÑкого Ðламени", |
["Hillsbrad Foothills"] = "ÐÑедгоÑÑÑ Ð¥Ð¸Ð»ÑбÑада", |
["Horde Encampment"] = "СÑоÑнка ÐÑдÑ", |
["Howling Fjord"] = "РевÑÑий ÑÑоÑд", |
["Hrothgar's Landing"] = "ÐагеÑÑ Ð¥ÑоÑгаÑа", |
Hyjal = "Хиджал", |
["Hyjal Summit"] = "ÐеÑÑина Хиджала", |
Icecrown = "ÐедÑÐ½Ð°Ñ ÐоÑона", |
["Icecrown Citadel"] = "ЦиÑÐ°Ð´ÐµÐ»Ñ ÐедÑной ÐоÑонÑ", |
["Insidion's Perch"] = "Ðнездо ÐнÑидиона", |
Ironforge = "СÑалÑгоÑн", |
["Isle of Conquest"] = "ÐÑÑÑов Ðавоеваний", |
["Isle of Quel'Danas"] = "ÐÑÑÑов ÐелÑ'ÐанаÑ", |
Kalimdor = "ÐалимдоÑ", |
Karazhan = "ÐаÑажан", |
["Krasus' Landing"] = "ÐлоÑадка ÐÑаÑа", |
Library = "ÐиблиоÑека", |
["Loch Modan"] = "Ðок Ðодан", |
["Lower Blackrock Spire"] = "Ðижний ÑÑÑÑ Ð§ÐµÑной гоÑÑ", |
["Magisters' Terrace"] = "ТеÑÑаÑа ÐагиÑÑÑов", |
["Magtheridon's Lair"] = "Ðогово ÐагÑеÑидона", |
["Mana-Tombs"] = "ÐÑобниÑÑ ÐанÑ", |
Maraudon = "ÐаÑодон", |
["Marshlight Lake"] = "ÐзеÑо ÐолоÑнÑÑ ÐгонÑков", |
["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 = "ÐапÑеделÑе", |
["Pit of Saron"] = "Яма СаÑона", |
["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"] = "Ð ÑÐ¸Ð½Ñ ÐоÑдеÑона", |
["Scalebeard's Cave"] = "ÐеÑеÑа ЧеÑÑебоÑода", |
["Scarlet Monastery"] = "ÐонаÑÑÑÑÑ Ðлого оÑдена", |
Scholomance = "ÐекÑоÑиÑеÑ", |
["Searing Gorge"] = "ТлеÑÑее ÑÑелÑе", |
["Serpent Lake"] = "Ðмеиное озеÑо", |
["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"] = "ÐаÑÑава СÑÑажи ÐебеÑ", |
["Skysong Lake"] = "ÐзеÑо ÐебеÑной ÐеÑни", |
["Sporewind Lake"] = "ÐзеÑо СпоÑовеÑÑа", |
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"] = "ÐÐµÑ Ð¢ÐµÑоккаÑ", |
["Terokk's Rest"] = "Ðокой ТеÑокка", |
["The Arachnid Quarter"] = "ÐаÑÑий кваÑÑал", |
["The Arcatraz"] = "ÐÑкаÑÑаÑ", |
["The Argent Coliseum"] = "ÐÑпÑÑание кÑеÑÑоноÑÑа", |
["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 Forge of Souls"] = "ÐÑÐ·Ð½Ñ ÐÑÑ", |
["The Frozen Halls"] = "ÐедÑнÑе залÑ", -- Needs review |
["The Frozen Sea"] = "ÐедÑное моÑе", |
["The Great Sea"] = "Ðеликое моÑе", |
["The Halls of Winter"] = "ÐÐ°Ð»Ñ ÐимÑ", -- Needs review |
["The Hinterlands"] = "ÐнÑÑÑенние земли", |
["The Mechanar"] = "ÐÐµÑ Ð°Ð½Ð°Ñ", |
["The Military Quarter"] = "ÐоеннÑй кваÑÑал", |
["The Nexus"] = "ÐекÑÑÑ", |
["The North Sea"] = "СевеÑное моÑе", |
["The Obsidian Sanctum"] = "ÐбÑидиановое ÑвÑÑилиÑе", |
["The Oculus"] = "ÐкÑлÑÑ", |
["The Plague Quarter"] = "ЧÑмной кваÑÑал", |
["The Prison of Yogg-Saron"] = "ТемниÑа Ðогг-СаÑона", -- Needs review |
["Theramore Isle"] = "ÐÑÑÑов ТеÑамоÑ", |
["The Ring of Valor"] = "ÐÑÑг ÐоблеÑÑи", |
["The Ruby Sanctum"] = "Ð Ñбиновое ÑвÑÑилиÑе", |
["The Scarlet Enclave"] = "Ðнклав Ðлого оÑдена", -- Needs review |
["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"] = "ТиÑиÑÑалÑÑкие леÑа", |
["Trial of the Champion"] = "ÐÑпÑÑание Ñемпиона", |
["Trial of the Crusader"] = "ÐÑпÑÑание кÑеÑÑоноÑÑа", |
["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"] = "é»æç¥æ®¿", |
["Blackwind Lake"] = "é»é£æ¹", |
["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 Reflection"] = "æ å大å ", |
["Halls of Stone"] = "岩ç³å¤§å ", |
["Hellfire Citadel"] = "å°ç±ç«å ¡å", |
["Hellfire Peninsula"] = "å°ç±ç«åå²", |
["Hellfire Ramparts"] = "å°ç±ç«åå¢", |
["Hillsbrad Foothills"] = "å¸å°æ¯å¸è±å¾·ä¸éµ", |
["Horde Encampment"] = "é¨è½è¥å°", |
["Howling Fjord"] = "åé£å³¡æ¹¾", |
["Hrothgar's Landing"] = "æ´æ¯å å°ç»éç¹", |
Hyjal = "æµ·å å°å±±", |
["Hyjal Summit"] = "æµ·å å°å³°", |
Icecrown = "å°å å°å·", |
["Icecrown Citadel"] = "å°å å ¡å", |
["Insidion's Perch"] = "å æ¯è¿ªå®æ æ¨", |
Ironforge = "éçå ¡", |
["Isle of Conquest"] = "å¾æä¹å²", |
["Isle of Quel'Danas"] = "å¥å°ä¸¹çº³æ¯å²", |
Kalimdor = "å¡å©å§å¤", |
Karazhan = "å¡æèµ", |
["Krasus' Landing"] = "å æèæ¯å¹³å°", |
Library = "å¾ä¹¦é¦", |
["Loch Modan"] = "æ´å è«ä¸¹", |
["Lower Blackrock Spire"] = "ä¸å±é»ç³å¡", |
["Magisters' Terrace"] = "é导å¸å¹³å°", |
["Magtheridon's Lair"] = "ççéé¡¿ç巢穴", |
["Mana-Tombs"] = "æ³åéµå¢", |
Maraudon = "çæé¡¿", |
["Marshlight Lake"] = "æ²¼å æ¹", |
["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 = "å¤å", |
["Pit of Saron"] = "è¨éç¿å", |
["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"] = "æ´ä¸¹ä¼¦åºå¢", |
["Scalebeard's Cave"] = "é³é¡»æµ·é¾æ´ç©´", |
["Scarlet Monastery"] = "è¡è²ä¿®éé¢", |
Scholomance = "éçµå¦é¢", |
["Searing Gorge"] = "ç¼ç峡谷", |
["Serpent Lake"] = "æ¯èæ¹", |
["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"] = "天空å«éå¨ç«", |
["Skysong Lake"] = "天ææ¹", |
["Sporewind Lake"] = "å¢åæ¹", |
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"] = "æ³°ç½å¡æ£®æ", |
["Terokk's Rest"] = "æ³°ç½å ä¹å¢", |
["The Arachnid Quarter"] = "èèåº", |
["The Arcatraz"] = "ç¦éçç±", |
["The Argent Coliseum"] = "é¶è²è¯ç¼åº", -- Needs review |
["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 Forge of Souls"] = "çµéæ´ªç", |
["The Frozen Halls"] = "The Frozen Halls", -- Needs review |
["The Frozen Sea"] = "å°å»ä¹æµ·", |
["The Great Sea"] = "æ å°½ä¹æµ·", |
["The Halls of Winter"] = "å¯å¬ä¹å ", |
["The Hinterlands"] = "è¾ç¹å °", |
["The Mechanar"] = "è½æºè°", |
["The Military Quarter"] = "åäºåº", |
["The Nexus"] = "éæ¢", |
["The North Sea"] = "åæµ·", |
["The Obsidian Sanctum"] = "é»æç³å£æ®¿", |
["The Oculus"] = "éç¯", |
["The Plague Quarter"] = "çç«åº", |
["The Prison of Yogg-Saron"] = "å°¤æ ¼-è¨éççç±", |
["Theramore Isle"] = "å¡ææ©å²", |
["The Ring of Valor"] = "åæ°ç«æåº", |
["The Ruby Sanctum"] = "The Ruby Sanctum", -- Needs review |
["The Scarlet Enclave"] = "è¡è²é¢å°", |
["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"] = "æçæ¯æ³æå°", |
["Trial of the Champion"] = "å åçè¯ç¼", |
["Trial of the Crusader"] = "åååçè¯ç¼", |
["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"] = "é»æç¥å»", |
["Blackwind Lake"] = "é»é¢¨æ¹", |
["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 Reflection"] = "å影大廳", |
["Halls of Stone"] = "ç³ä¹å¤§å»³", |
["Hellfire Citadel"] = "å°çç«å ¡å£", |
["Hellfire Peninsula"] = "å°çç«å島", |
["Hellfire Ramparts"] = "å°çç«å£å£", |
["Hillsbrad Foothills"] = "å¸ç¾æ¯å¸èå¾·ä¸éµ", |
["Horde Encampment"] = "é¨è½çå°", |
["Howling Fjord"] = "å風峽ç£", |
["Hrothgar's Landing"] = "赫é¯æ¯å èºå°", |
Hyjal = "æµ·å ç¾å±±", |
["Hyjal Summit"] = "æµ·å ç¾å±±", |
Icecrown = "å¯å°çå ", |
["Icecrown Citadel"] = "å°å åå¡", |
["Insidion's Perch"] = "å°å¸è¿ªæ©æ£²æ", |
Ironforge = "éµçå ¡", |
["Isle of Conquest"] = "å¾æä¹å³¶", |
["Isle of Quel'Danas"] = "å¥ç¾éç´æ¯ä¹å³¶", |
Kalimdor = "å¡æå¤", |
Karazhan = "å¡æè´", |
["Krasus' Landing"] = "å¡è©æ¯å¹³èº", |
Library = "åæ¸é¤¨", |
["Loch Modan"] = "æ´å è«ä¸¹", |
["Lower Blackrock Spire"] = "é»ç³å¡", |
["Magisters' Terrace"] = "åå¸è 殿å ", |
["Magtheridon's Lair"] = "çªçéé ç巢穴", |
["Mana-Tombs"] = "æ³åå¢å°", |
Maraudon = "çªæé ", |
["Marshlight Lake"] = "沼澤å ä¹æ¹", |
["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 = "å¤å", |
["Pit of Saron"] = "è©å«ä¹æ·µ", |
["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"] = "ç¾ å¾·é廢å¢", |
["Scalebeard's Cave"] = "é±é¬æ´ç©´", |
["Scarlet Monastery"] = "è¡è²ä¿®éé¢", |
Scholomance = "ééå¸é¢", |
["Searing Gorge"] = "ç¼ç±å³½è°·", |
["Serpent Lake"] = "æ¯èä¹æ¹", |
["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"] = "禦天è å´å¨", |
["Skysong Lake"] = "天ææ¹", |
["Sporewind Lake"] = "å¢å風ä¹æ¹", |
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"] = "æ³°æ´å¡æ£®æ", |
["Terokk's Rest"] = "æ³°æ´å ä¹å¢", |
["The Arachnid Quarter"] = "èèå", |
["The Arcatraz"] = "äºå å´è²", |
["The Argent Coliseum"] = "éç½å¤§ç«¶æå ´", |
["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 Forge of Souls"] = "ç¾éçç", |
["The Frozen Halls"] = "å°å°å¤§å»³", |
["The Frozen Sea"] = "å°åä¹æµ·", |
["The Great Sea"] = "ç¡ç¡ä¹æµ·", |
["The Halls of Winter"] = "åå¬ä¹å»³", |
["The Hinterlands"] = "è¾ç¹è", |
["The Mechanar"] = "麥å ç´ç¾", |
["The Military Quarter"] = "è»äºå", |
["The Nexus"] = "å¥§æ ¸ä¹å¿", |
["The North Sea"] = "åæµ·", |
["The Obsidian Sanctum"] = "é»æèæ", |
["The Oculus"] = "å¥§æ ¸ä¹ç¼", |
["The Plague Quarter"] = "çç«å", |
["The Prison of Yogg-Saron"] = "å°¤æ ¼è©å«ä¹ç", |
["Theramore Isle"] = "å¡ææ©å³¶", |
["The Ring of Valor"] = "åæ¦ä¹ç°", |
["The Ruby Sanctum"] = "æ¶ç´ èæ", |
["The Scarlet Enclave"] = "è¡è²é å", |
["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"] = "æéæ¯æ³æå°", |
["Trial of the Champion"] = "å士試ç ", |
["Trial of the Crusader"] = "ååè»è©¦ç ", |
["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 |
<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> |
<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> |
--- **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 895 2009-12-06 16:28:55Z nevcairiel $ |
local MAJOR,MINOR = "AceLocale-3.0", 2 |
local AceLocale, oldminor = LibStub:NewLibrary(MAJOR, MINOR) |
if not AceLocale then return end -- no upgrade needed |
-- Lua APIs |
local assert, tostring, error = assert, tostring, error |
local setmetatable, rawset, rawget = setmetatable, rawset, rawget |
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded |
-- List them here for Mikk's FindGlobals script |
-- GLOBALS: GAME_LOCALE, geterrorhandler |
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 |
<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> |
--[[ $Id: CallbackHandler-1.0.lua 895 2009-12-06 16:28:55Z nevcairiel $ ]] |
local MAJOR, MINOR = "CallbackHandler-1.0", 5 |
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} |
-- Lua APIs |
local tconcat = table.concat |
local assert, error, loadstring = assert, error, loadstring |
local setmetatable, rawset, rawget = setmetatable, rawset, rawget |
local next, select, pairs, type, tostring = next, select, pairs, type, tostring |
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded |
-- List them here for Mikk's FindGlobals script |
-- GLOBALS: geterrorhandler |
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", tconcat(OLD_ARGS, ", ")):gsub("ARGS", tconcat(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. |
<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> |
--- **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 878 2009-11-02 18:51:58Z nevcairiel $ |
local MAJOR,MINOR = "AceConsole-3.0", 7 |
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 |
-- Lua APIs |
local tconcat, tostring, select = table.concat, tostring, select |
local type, pairs, error = type, pairs, error |
local format, strfind, strsub = string.format, string.find, string.sub |
local max = math.max |
-- WoW APIs |
local _G = _G |
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded |
-- List them here for Mikk's FindGlobals script |
-- GLOBALS: DEFAULT_CHAT_FRAME, SlashCmdList, hash_SlashCmdList |
local tmp={} |
local function Print(self,frame,...) |
local n=0 |
if self ~= AceConsole then |
n=n+1 |
tmp[n] = "|cff33ff99"..tostring( self ).."|r:" |
end |
for i=1, select("#", ...) do |
n=n+1 |
tmp[n] = tostring(select(i, ...)) |
end |
frame:AddMessage( tconcat(tmp," ",1,n) ) |
end |
--- 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 frame = ... |
if type(frame) == "table" and frame.AddMessage then -- Is first argument something with an .AddMessage member? |
return Print(self, frame, select(2,...)) |
else |
return Print(self, DEFAULT_CHAT_FRAME, ...) |
end |
end |
--- Formatted (using format()) print to DEFAULT_CHAT_FRAME or given ChatFrame (anything with an .AddMessage function) |
-- @paramsig [chatframe ,] "format"[, ...] |
-- @param chatframe Custom ChatFrame to print to (or any frame with an .AddMessage function) |
-- @param format Format string - same syntax as standard Lua format() |
-- @param ... Arguments to the format string |
function AceConsole:Printf(...) |
local frame = ... |
if type(frame) == "table" and frame.AddMessage then -- Is first argument something with an .AddMessage member? |
return Print(self, frame, format(select(2,...))) |
else |
return Print(self, DEFAULT_CHAT_FRAME, format(...)) |
end |
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", |
"Printf", |
"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 |
--[[ |
Name: LibGroupTalents-1.0 |
Revision: $Rev: 53 $ |
Author: Zek |
Documentation: http://wowace.com/wiki/LibGroupTalents-1.0 |
SVN: svn://svn.wowace.com/wow/libgrouptalents-1-0/mainline/trunk |
Description: Talent Library abstraction layer to provide easy interface to the lower level system |
Dependancies: LibStub, CallbackHandler-1.0, LibTalentQuery-1.0 |
License: GPL v3 |
Purpose: |
LibGroupTalents-1.0 is intended to do the following basic functions usually handled at the mod level. |
- Maintain a raid wide table of talents, automatically updated on roster changes, notifying you on talent receipts. |
- Provide easy access to talent queries (spec weight, spec name, specific talent presence) |
- Monitor talent changes in players, and notify of changes (respec, talent swap, update after out of sight, level up) |
- Monitor player roles, and notify of changes (melee, tank, healer, caster) |
- Communicate directly with itself to other users to update talents via addon channel when possible |
Notes: |
The LibTalentQuery-1.0 dependancy must be included before LibGroupTalents-1.0 in any lib.xml or mod side TOC declarations. |
Functions: |
UnitHasTalent(unit, talentName[, group])-- Returns: Points spent in talent or nil |
GUIDHasTalent(guid, talentName[, group])-- As UnitHasTalent |
GetUnitTalentSpec(unitid[, group]) -- Returns: Dominant Tree, spent1, spent2, spent3 |
GetGUIDTalentSpec(guid[, group]) -- As GetUnitTalentSpec |
GetUnitTalents(unit, refresh) -- Returns: Raw talent information in form of table of 3 strings of points spent. The refresh arg will force a re-query of the unit's talents |
GetGUIDTalents(guid, refresh) -- As GetUnitTalents |
GetUnitRole(unit) -- Returns one of: "melee", "caster", "healer", "tank" |
GetGUIDRole(guid) -- As GetUnitRole |
RefreshTalentsByUnit(unit) -- Force a refresh of talents for the specific unit |
RefreshTalentsByGUID(guid) -- Force a refresh of talents for the specific player GUID |
GetTreeNames(class) -- Returns: The three talent tree names for that class (Note: These return values are only valid after a player of that class has been inspected) |
GetTreeIcons(class) -- Returns: The three talent tree icons for that class (Note: As above) |
GetTalentCount() -- Returns: Talent info got, Talent info missing |
GetTalentMissingNames() -- Returns: Comma delimited list of player names we're missing talents for |
GetClassTalentInfo(class, talentName) -- Returns: Max Rank, Icon, Tab, Tier, Column, Tree Index |
GetUnitStorageString(unit) -- Returns: An encoded data string containing talent information for the player which can be stored by mods to set in later sessions using SetStorageString() |
GetGUIDStorageString(guid) -- As GetUnitStorageString |
SetStorageString(talentString) -- Returns: true on success (applicable). Any second return value indicates the data was invalid and should not be kept |
GetUnitGlyphs(unit[, group]) -- Returns: Up to 6 spell IDs for the currently assigned Glyphs (Note: For the moment, we can only see the glyphs of players running LibGroupTalents-1.0) |
GetGUIDGlyphs(guid[, group]) -- As GetUnitGlyphs |
UnitHasGlyph(unit, glyph [, group]) -- Returns: true if the player has the glyph associated with spellID or spellName (Note: For the moment, we can only see the glyphs of players running LibGroupTalents-1.0) |
GUIDHasGlyph(unit, glyph [, group]) -- As UnitHasGlyph |
PurgeAndRescanTalents() -- Wipe current roster of all talents and rescan from start |
Convenience Functions (Similar to Blizzard API functions, but callable with a unit ID): |
GetActiveTalentGroup(unit) -- Returns: Active talent group for unit |
GetNumTalentGroups(unit) -- Returns: Number of talent groups for unit |
GetNumTalentTabs(unit) -- Returns: Number of talent tabs. Here's a clue; it's going to be 3... |
GetTalentTabInfo(unit, tab[, group]) -- Returns: Tree Name, Tree Icon, Points Spent, Tree Background |
GetNumTalents(unit, tab) -- Returns: Number of talents for specified tree |
GetTalentInfo(unit, tab, index[, group])-- Returns: Talent Name, Icon, Tier, Column, Points Spent, Max Rank (Note that preview return values are not given unless called with "player") |
GetUnspentTalentPoints(unit[, group]) -- Returns: Number of un-spent talent points for the unit |
Events: |
LibGroupTalents_Update(guid, unit, newSpec, n1, n2, n3 [, oldSpec, o1, o2, o3]) -- Received updated talents. If it's a respec, or old set is know, it passes the old info also (this is not sent if new talent scan is same as previous) |
LibGroupTalents_UpdateComplete(guid1, guid2[, ...]) -- Sent when there are no more pending talent reads due (passes all GUIDs that were updated since last time this event was fired) |
LibGroupTalents_Add(guid, unit, name, realm) -- Unit added to talent roster (Talents not necessarily available yet, but this is the mod's chance to feed talents using SetStorageString) |
LibGroupTalents_Remove(guid, name, realm) -- Unit removed from talent roster (This is your last chance to store talents if required using GetUnitStorageString) |
LibGroupTalents_RoleChange(guid, unit, newrole, oldrole) -- Roles are: "melee", "caster", "healer", "tank" |
LibGroupTalents_GlyphUpdate(guid, unit) -- Fired when a player's glyphs change (Note: For the moment, we can only see the glyphs of players running LibGroupTalents-1.0) |
]] |
local TalentQuery = LibStub("LibTalentQuery-1.0") |
local MAJOR, MINOR = "LibGroupTalents-1.0", tonumber(("$Rev: 53 $"):match("(%d+)")) |
local lib = LibStub:NewLibrary(MAJOR, MINOR) |
if not lib then return end |
local ChatThrottleLib = _G.ChatThrottleLib |
lib.roster = lib.roster or {} |
lib.classTalentData = lib.classTalentData or {} |
lib.batch = lib.batch or {} |
lib.pendingStorageStrings = lib.pendingStorageStrings or {} |
local function UnitFullName(unit) |
local name, realm = UnitName(unit) |
local namerealm = realm and realm ~= "" and name .. "-" .. realm or name |
return namerealm |
end |
local specChangers = {} |
for index,spellid in ipairs(_G.TALENT_ACTIVATION_SPELLS) do |
specChangers[GetSpellInfo(spellid)] = index |
end |
local frame = lib.frame |
if (not frame) then |
frame = CreateFrame("Frame", "LibGroupTalents_Frame") |
lib.frame = frame |
end |
frame:UnregisterAllEvents() |
frame:RegisterEvent("RAID_ROSTER_UPDATE") |
frame:RegisterEvent("PARTY_MEMBERS_CHANGED") |
frame:RegisterEvent("UNIT_NAME_UPDATE") |
frame:RegisterEvent("PLAYER_TALENT_UPDATE") |
frame:RegisterEvent("UNIT_LEVEL") |
frame:RegisterEvent("UNIT_AURA") -- Always get a UNIT_AURA when a unit's UnitIsVisible() changes |
frame:RegisterEvent("CHAT_MSG_ADDON") |
frame:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED") |
frame:RegisterEvent("PLAYER_LOGIN") |
frame:RegisterEvent("GLYPH_ADDED") |
frame:RegisterEvent("GLYPH_REMOVED") |
frame:RegisterEvent("GLYPH_UPDATED") |
frame:SetScript("OnEvent", function(self, event, ...) |
return lib[event](lib, ...) |
end) |
if not lib.events then |
lib.events = LibStub("CallbackHandler-1.0"):New(lib) |
end |
local next, select, pairs, type = next, select, pairs, type |
local new, del, deepDel |
do |
local list = setmetatable({},{__mode='k'}) |
function new(...) |
local t = next(list) |
if t then |
list[t] = nil |
for i = 1, select('#', ...) do |
t[i] = select(i, ...) |
end |
return t |
else |
return {...} |
end |
end |
function del(t) |
if (t) then |
wipe(t) |
t[''] = true |
t[''] = nil |
list[t] = true |
end |
end |
function deepDel(t) |
if (t) then |
for k,v in pairs(t) do |
if type(v) == "table" then |
deepDel(v) |
end |
t[k] = nil |
end |
t[''] = true |
t[''] = nil |
list[t] = true |
end |
end |
end |
do |
local delay = 0 |
frame:SetScript("OnUpdate", function(self, elapsed) |
if (lib.raidRosterUpdate) then |
lib.raidRosterUpdate = nil |
lib:OnRaidRosterUpdate() |
end |
if (lib.refreshCheckTimer) then |
lib.refreshCheckTimer = lib.refreshCheckTimer - elapsed |
if (lib.refreshCheckTimer < 0) then |
lib.refreshCheckTimer = nil |
lib:CheckForMissingTalents() |
end |
end |
if (lib.talentTimers) then |
delay = delay + elapsed |
if (delay > 1) then |
delay = 0 |
local now = GetTime() |
local triggers |
for guid,when in pairs(lib.talentTimers) do |
if (now > when) then |
-- Pass to second table to process, because RefreshTimers can affect this talentTimers table |
-- So it's important we're not still iterating it at the time |
if (not triggers) then |
triggers = new() |
end |
triggers[guid] = true |
lib.talentTimers[guid] = nil |
if (not next(lib.talentTimers)) then |
lib.talentTimers = del(lib.talentTimers) |
break |
end |
end |
end |
if (triggers) then |
for guid in pairs(triggers) do |
lib:RefreshTalentsByGUID(guid) |
end |
del(triggers) |
end |
end |
end |
if (not lib.talentTimers and not lib.refreshCheckTimer) then |
self:Hide() |
end |
end) |
end |
frame:Show() |
lib.raidRosterUpdate = true |
-- GetGUIDTalentsRaw |
local function GetGUIDTalentsRaw(guid, group) |
local r = guid and lib.roster[guid] |
return r and r.talents and r.talents[group or r.active], r |
end |
-- PLAYER_LOGIN |
function lib:PLAYER_LOGIN() |
ChatThrottleLib = _G.ChatThrottleLib |
lib.PLAYER_LOGIN = nil |
end |
-- RAID_ROSTER_UPDATE |
function lib:RAID_ROSTER_UPDATE() |
self.raidRosterUpdate = true |
frame:Show() |
end |
lib.PARTY_MEMBERS_CHANGED = lib.RAID_ROSTER_UPDATE |
-- UNIT_NAME_UPDATE |
function lib:UNIT_NAME_UPDATE(unit) |
local guid = unit and UnitGUID(unit) |
local r = guid and self.roster[guid] |
if (r) then |
local needsAdd = r.name == UNKNOWN |
r.name, r.realm = UnitName(unit) |
if (r.realm == "") then |
r.realm = nil |
end |
r.class = select(2, UnitClass(unit)) |
r.level = UnitLevel(unit) |
if (not r.talents) then |
if (needsAdd) then |
self.events:Fire("LibGroupTalents_Add", guid, unit, r.name, r.realm) |
end |
self:CheckForMissingTalents() |
end |
end |
end |
-- AnyPending |
local function AnyPending() |
local checkUpdate |
for guid,info in pairs(lib.roster) do |
if (UnitIsConnected(info.name)) then |
if (lib.wasOffline) then |
lib.wasOffline[guid] = nil |
end |
if (not info.talents or info.refresh) then |
return true |
end |
else |
if (not lib.wasOffline) then |
lib.wasOffline = new() |
end |
lib.wasOffline[guid] = true |
end |
end |
if (lib.wasOffline and not next(lib.wasOffline)) then |
lib.wasOffline = del(lib.wasOffline) |
end |
end |
-- CheckForUpdateComplete |
local function CheckForUpdateComplete() |
-- When all pending updates are complete, send an event to notify nothing else is due |
if (next(lib.batch)) then |
if (not AnyPending()) then |
lib.events:Fire("LibGroupTalents_UpdateComplete", unpack(lib.batch)) |
wipe(lib.batch) |
end |
end |
end |
-- UNIT_LEVEL |
function lib:UNIT_LEVEL(unit) |
if (UnitInParty(unit) or UnitInRaid(unit)) then |
local guid = UnitGUID(unit) |
local r = guid and self.roster[guid] |
if (r) then |
r.level = UnitLevel(unit) |
self:RefreshTalentsByUnit(unit) |
end |
end |
end |
-- UNIT_AURA |
function lib:UNIT_AURA(unit) |
local guid = UnitGUID(unit) |
if (not UnitIsVisible(unit) or (self.wasOffline and self.wasOffline[guid])) then |
if (not self.outOfSight) then |
self.outOfSight = {} |
end |
self.outOfSight[guid] = true |
self:RefreshTalentsByGUID(guid) |
end |
end |
-- OnRaidRosterUpdate |
function lib:OnRaidRosterUpdate() |
local instanceType = select(2, IsInInstance()) |
if (instanceType == "pvp" or instanceType == "arena") then |
self.distribution = "BATTLEGROUND" |
else |
if (GetNumRaidMembers() > 0) then |
self.distribution = "RAID" |
elseif (GetNumPartyMembers() > 0) then |
self.distribution = "PARTY" |
else |
self.distribution = nil |
end |
end |
if (self.distribution) then |
if (self.sentHello ~= self.distribution) then |
self.sentHello = self.distribution |
self:SendCommMessage("HELLO "..MINOR, nil, self.distribution) |
end |
else |
self.sentHello = nil |
self.talentThrottle = del(self.talentThrottle) |
self.wasOffline = del(self.wasOffline) |
self.outOfSight = del(self.outOfSight) |
wipe(self.pendingStorageStrings) |
end |
-- Now check for roster changes |
local subtractions = new() |
local additions = new() |
local changes = new() |
if (self.roster) then |
for guid,info in pairs(self.roster) do |
subtractions[guid] = info.level or 0 |
end |
end |
for unit in self:IterateRoster() do |
local guid = UnitGUID(unit) |
if (guid) then |
local n = self.roster[guid] |
if (not n) then |
n = new() |
self.roster[guid] = n |
end |
n.name, n.realm = UnitName(unit) |
if (n.realm == "") then |
n.realm = nil -- Fix this already.. |
end |
n.level = UnitLevel(unit) |
n.class = select(2, UnitClass(unit)) |
n.unit = unit |
if (subtractions[guid]) then |
if (subtractions[guid] ~= n.level) then |
changes[guid] = unit -- Level changed, needs a rescan |
end |
subtractions[guid] = nil |
else |
if (n.name ~= UNKNOWN) then |
self.events:Fire("LibGroupTalents_Add", guid, unit, n.name, n.realm) |
end |
additions[guid] = unit |
end |
end |
end |
if (next(additions)) then |
for guid,unit in pairs(additions) do |
self:GetUnitTalents(unit) |
end |
end |
if (next(changes)) then |
for guid,unit in pairs(changes) do |
self:GetUnitTalents(unit) |
end |
end |
if (next(subtractions)) then |
for guid in pairs(subtractions) do |
local r = self.roster[guid] |
if (r) then |
self.events:Fire("LibGroupTalents_Remove", guid, r.name, r.realm) |
self.roster[guid] = deepDel(r) |
local classStorageStrings = self.pendingStorageStrings[r.class] |
if (classStorageStrings) then |
classStorageStrings[guid] = del(classStorageStrings[guid]) |
if (not next(classStorageStrings)) then |
self.pendingStorageStrings[r.class] = del(self.pendingStorageStrings[r.class]) |
end |
end |
end |
end |
CheckForUpdateComplete() |
end |
del(additions) |
del(subtractions) |
del(changes) |
self:CheckForMissingTalents() |
end |
-- ValidateUnit |
local function ValidateUnit(r, guid) |
local unit = r.unit |
if (UnitGUID(unit) ~= guid) then |
local name = r.name .. (r.realm and "-" or "") .. (r.realm or "") |
local index = UnitInRaid(name) |
if (index) then |
r.unit = "raid"..index |
return true |
else |
if (UnitGUID("player") == guid) then |
r.unit = "player" |
return true |
elseif (UnitInParty(name)) then |
for i = 1,4 do |
if (UnitGUID("party"..i) == guid) then |
r.unit = "party"..i |
return true |
end |
end |
end |
end |
return |
end |
return true |
end |
-- CountTree |
local function CountTree(branch) |
local count = 0 |
for i = 1,#branch do |
count = count + branch:byte(i) - 48 |
end |
return count |
end |
-- TalentWeight |
local function TalentWeight(talents, class) |
if (talents and #talents == 3 and class) then |
local c1, c2, c3 = CountTree(talents[1]), CountTree(talents[2]), CountTree(talents[3]) |
local weight = 1 |
if (c2 > c1 and c2 > c3) then |
weight = 2 |
elseif (c3 > c1 and c3 > c2) then |
weight = 3 |
end |
local data = lib.classTalentData[class] |
if (data and data[weight]) then |
return data[weight].name, c1, c2, c3 |
end |
return weight, c1, c2, c3 |
end |
return nil, 0, 0, 0 |
end |
do |
-- First segment: Player ID (from GUID), Name, level, class, activePage, TalentString |
-- Subsequent: spec number, talentString() |
-- crc |
local function crc32(str) |
local val = tonumber((select(2, GetBuildInfo()))) -- Use WoW build as CRC base |
for i = 1,#str do |
val = bit.band(val * 2 + str:byte(i), 0xFFFF) |
end |
return val |
end |
-- GetUnitStorageString |
function lib:GetUnitStorageString(unit) |
return self:GetGUIDStorageString(UnitGUID(unit)) |
end |
-- GetGUIDStorageString |
-- Make a storage string for mods to store talents. |
-- Rules: 1) Your own realm only 2) Their talents are complete (nothing unspent) |
function lib:GetGUIDStorageString(guid) |
local r = self.roster[guid] |
if (r) then |
local id |
local playerGUID = UnitGUID("player") |
if (playerGUID:sub(1, 6) == guid:sub(1, 6)) then |
-- Same realm code, so just trim it off. This is likely always true from what I've seen |
id = format("%X", tonumber(guid:sub(7), 16)) |
else |
id = guid:sub(4) |
end |
if (r.talents and r.active and not r.realm and (not r.unspent or not r.unspent[r.active])) then |
if (r.level < 1) then |
r.level = UnitLevel(r.name) or 0 |
end |
local str = format("%s,%d,%s,%d,%d", id, r.level, r.class, r.active, r.numActive) |
for i = 1,r.numActive do |
local t = r.talents[i] |
if (t) then |
str = format("%s;%d,%s", str, i, table.concat(t, "-")) |
end |
end |
return format("%s;%d", str, crc32(str)) |
end |
end |
end |
-- SetStorageString |
function lib:SetStorageString(str, comms) |
local ret, retInfo |
if (str) then |
local parts = new(strsplit(";", str)) |
if (#parts >= 2) then |
local strCRC = tonumber(parts[#parts]) |
local temp = table.concat(parts, ";", 1, #parts - 1) |
if (crc32(temp) == strCRC) then |
local part1 = new(strsplit(",", parts[1])) |
while true do |
local guid |
local id = part1[1] |
if (id:len() < 12) then |
-- Trimmed GUID, we'll prefix it with our own GUID's realm code |
guid = format("%s%012X", UnitGUID("player"):sub(1, 6), tonumber(id, 16)) |
else |
guid = format("0x0%015s", id) |
end |
local r = self.roster[guid] |
if (not r) then |
retInfo = format("Unexpected SetStorageString for ID %s", guid) |
ret = true -- Still return true, we just didn't want this string yet |
break |
elseif (r.name == UNKNOWN) then |
retInfo = format("Premature SetStorageString for ID %s", guid) |
ret = true -- Still return true, we just didn't want this string yet |
break |
end |
if (r.talents) then |
-- We've already received talents for this player |
ret = true -- Still return true, we just didn't want this string because we have their talents |
break |
end |
if (not self.classTalentData[r.class]) then |
-- Received a storage string for a class that we've not yet been able to scan |
-- the talent trees for. We store this until we have that data |
local classStorageStrings = self.pendingStorageStrings[r.class] |
if (not classStorageStrings) then |
classStorageStrings = new() |
self.pendingStorageStrings[r.class] = classStorageStrings |
end |
classStorageStrings[guid] = str |
ret = true |
break |
end |
local level = tonumber(part1[2]) |
local class = part1[3] |
local active = tonumber(part1[4]) |
local numActive = tonumber(part1[5]) |
if (r.level < 1) then |
r.level = UnitLevel(r.name) or 0 |
end |
if (level ~= r.level and r.level > 1) then |
-- Won't accept talents for mismatched levels (but ignore errors reading the UnitLevel early) |
retInfo = "Wrong level" |
break |
end |
if (not r.class and class) then |
-- If we don't have the class, but the storage string does, we'll take it |
r.class = class |
end |
if (class ~= r.class) then |
-- Class doesn't match, probably a char delete/remake or xrealm |
retInfo = format("Wrong class: expected %q, got %q", tostring(r.class), tostring(class)) |
break |
end |
-- Now the talent trees |
local talents = new() |
for i = 2,#parts - 1 do |
local partN = new(strsplit(",", parts[i])) |
if (#partN == 2) then |
local specNumber = tonumber(partN[1]) |
local specTalents = new(strsplit("-", partN[2])) |
if (specNumber and #specTalents >= 3) then |
talents[specNumber] = specTalents |
else |
del(specTalents) |
talents = del(talents) |
retInfo = "Invalid talent specs in tree "..i |
break |
end |
end |
end |
if (talents) then |
r.talents = talents |
r.active = active |
r.numActive = numActive |
if (comms ~= r.name) then |
-- If comms part sends player name along with packet, then we'll skip the refresh later |
-- which we'd normally do when Storage is set via app startup |
r.refresh = true |
else |
r.refresh = nil |
end |
ValidateUnit(r, guid) |
local newSpec, n1, n2, n3 = TalentWeight(r.talents[r.active], r.class) |
self.events:Fire("LibGroupTalents_Update", guid, r.unit, newSpec, n1, n2, n3) |
self:GetGUIDRole(guid, true) |
ret = true |
end |
break |
end |
del(part1) |
else |
retInfo = "Invalid string" |
end |
end |
del(parts) |
end |
return ret, retInfo |
end |
end |
-- GetClassTalentData |
-- Builds an internal table for talent name -> tree/index lookups. |
function GetClassTalentData(unit) |
local _, class = UnitClass(unit) |
if (class) then |
local data = lib.classTalentData[class] |
if (not data) then |
local isnotplayer = not UnitIsUnit("player", unit) |
if (GetNumTalentTabs(isnotplayer) > 0) then |
data = new() |
for tab = 1, GetNumTalentTabs(isnotplayer) do |
local tree = new() |
local _ |
tree.name, tree.icon, _, tree.background = GetTalentTabInfo(tab, isnotplayer) |
tinsert(data, tree) |
tree.list = new() |
for i = 1,GetNumTalents(tab, isnotplayer) do |
local name, icon, tier, column, currentRank, maxRank = GetTalentInfo(tab, i, isnotplayer) |
if (name) then |
local entry = new() |
entry.name = name |
entry.icon = icon |
entry.tier = tier |
entry.column = column |
entry.maxRank = maxRank |
entry.index = i |
entry.treeIndex = tab |
tinsert(tree.list, entry) |
if (not data.list) then |
data.list = new() |
end |
data.list[name] = entry |
end |
end |
end |
if (next(data)) then |
lib.classTalentData[class] = data |
--for guid,r in pairs(lib.roster) do |
-- if (r.class == class and r.talents) then |
-- -- We picked up class talent data for a class after receiving talents for them via comms |
-- -- So, we fire an Update event for any members of the class we already have so that |
-- -- talents can now be interpreted correctly. |
-- local spec, n1, n2, n3 = TalentWeight(r.talents[r.active], class) |
-- lib.events:Fire("LibGroupTalents_Update", guid, unit, spec, n1, n2, n3) |
-- end |
--end |
local classStorageStrings = lib.pendingStorageStrings[class] |
if (classStorageStrings) then |
local unitGUID = UnitGUID(unit) |
for guid, str in pairs(classStorageStrings) do |
if (guid ~= unitGUID) then |
lib:SetStorageString(str) |
end |
end |
lib.pendingStorageStrings[class] = del(lib.pendingStorageStrings[class]) |
end |
else |
deepDel(data) |
end |
end |
end |
end |
end |
-- GetTreeNames |
function lib:GetTreeNames(class) |
local info = self.classTalentData[class] |
if (info) then |
return info[1].name, info[2].name, info[3].name |
end |
end |
-- GetTreeIcons |
function lib:GetTreeIcons(class) |
local info = self.classTalentData[class] |
if (info) then |
return info[1].icon, info[2].icon, info[3].icon |
end |
end |
-- ReadTalentGroup |
local function ReadTalentGroup(isnotplayer, group, class) |
local numTabs = GetNumTalentTabs(isnotplayer) |
if (numTabs and numTabs >= 3 and GetNumTalents(1, isnotplayer) > 0) then |
local ctd = lib.classTalentData[class] |
--[===[@debug@ |
assert(ctd and ctd[1] and ctd[2] and ctd[3]) |
assert(ctd[1].list and ctd[2].list and ctd[3].list) |
--@end-debug@]===] |
local n = new() |
for tab = 1, numTabs do |
local branchLength = GetNumTalents(tab, isnotplayer, nil, group) |
if (branchLength ~= #ctd[tab].list) then |
-- Tab tree size is not what we expected for this class |
del(n) |
return |
end |
local t = new() |
local trim |
for i = 1,branchLength do |
local name, icon, tier, column, currentRank, maxRank = GetTalentInfo(tab, i, isnotplayer, nil, group) |
tinsert(t, currentRank) |
if (currentRank > 0) then |
trim = i -- We strip off trailing zeros from talent strings to save storage space |
end |
end |
tinsert(n, table.concat(t, nil, 1, trim or 0)) |
del(t) |
end |
return n |
end |
end |
-- TalentQuery_Ready |
function lib:TalentQuery_Ready_Outsider(e, name, realm, unit) |
self:TalentQuery_Ready(e, name, realm, unit) |
end |
-- TalentQuery_Ready |
function lib:TalentQuery_Ready(e, name, realm, unit) |
GetClassTalentData(unit) |
local guid = unit and UnitGUID(unit) |
local r = guid and self.roster[guid] |
if (r) then |
local namerealm = realm and realm ~= "" and name .. "-" .. realm or name |
local isnotplayer = not UnitIsUnit(unit, "player") |
if (GetTalentTabInfo(1, isnotplayer)) then |
local active = GetActiveTalentGroup(isnotplayer) |
local numActive = GetNumTalentGroups(isnotplayer) |
local listUnspent, invalid |
local talents = new() |
for group = 1,numActive do |
local n = ReadTalentGroup(isnotplayer, group, r.class) |
if (n and #n >= 3) then |
talents[group] = n |
else |
invalid = true |
break |
end |
local unspent = GetUnspentTalentPoints(isnotplayer, nil, group) |
if (unspent and unspent > 0) then |
if (not listUnspent) then |
listUnspent = new() |
end |
listUnspent[group] = unspent |
end |
end |
if (isnotplayer and (invalid or (listUnspent and listUnspent[active] or 0) > 0)) then |
-- Unit didn't have all their points spent in active group, so we'll have another look in 10 seconds |
-- Don't need to check when it's "player" because we get PLAYER_TALENT_UPDATE event on changes |
self:TriggerRefreshTalents(guid, 10) |
end |
if (not invalid) then |
if (active > numActive) then |
-- May be better to discard instead? We'll see |
active = 1 |
end |
self:OnReceiveTalents(guid, unit, talents, active, numActive, listUnspent) |
end |
end |
end |
end |
TalentQuery.RegisterCallback(lib, "TalentQuery_Ready") |
TalentQuery.RegisterCallback(lib, "TalentQuery_Ready_Outsider") |
-- GetUnitTalentSpec |
function lib:GetUnitTalentSpec(unit, group) |
return self:GetGUIDTalentSpec(UnitGUID(unit), group) |
end |
-- GetGUIDTalentSpec |
function lib:GetGUIDTalentSpec(guid, group) |
local talents, r = GetGUIDTalentsRaw(guid, group) |
if (talents) then |
return TalentWeight(talents, r.class) |
end |
end |
-- CompareTalents |
local function CompareTalents(tree1, tree2) |
if ((tree1 ~= nil) ~= (tree2 ~= nil)) then |
return |
end |
if (tree1 and tree2 and #tree1 == #tree2) then |
for i = 1,#tree1 do |
if (tree1[i] ~= tree2[i]) then |
return |
end |
end |
return true |
end |
end |
-- OnReceiveTalents |
function lib:OnReceiveTalents(guid, unit, talents, active, numActive, listUnspent) |
local r = self.roster[guid] |
if (r) then |
if (active ~= r.active or numActive ~= r.numActive or not CompareTalents(talents and talents[active], r.talents and r.talents[r.active])) then |
local oldTalents |
if (r.talents) then |
oldTalents = r.talents[r.active] |
end |
del(r.unspent) |
r.talents = talents |
r.active = active |
r.numActive = numActive |
r.unspent = listUnspent |
local newSpec, n1, n2, n3 = TalentWeight(r.talents[active], r.class) |
local fired |
if (oldTalents) then |
-- For those cases when we didn't have the alternate talents for a player for whatever reason. |
-- Maybe they just picked up dual talent spec, or gated to trainer to respec. |
local oldSpec, o1, o2, o3 = TalentWeight(oldTalents, r.class) |
if (o1 ~= n1 or o2 ~= n2 or o3 ~= n3) then |
self.events:Fire("LibGroupTalents_Update", guid, unit, newSpec, n1, n2, n3, oldSpec, o1, o2, o3) |
fired = true |
end |
end |
if (not fired) then |
self.events:Fire("LibGroupTalents_Update", guid, unit, newSpec, n1, n2, n3) |
end |
self:GetGUIDRole(guid, true) |
tinsert(self.batch, guid) |
CheckForUpdateComplete() |
oldTalents = del(oldTalents) |
return |
end |
end |
del(talents) |
end |
-- OnReceiveGlyphs |
function lib:OnReceiveGlyphs(guid, sender, glyphs) |
local r = self.roster[guid] |
if (r) then |
if (ValidateUnit(r, guid)) then |
local oldGlyphs |
if (r.glyphs) then |
oldGlyphs = r.glyphs[r.active] |
r.glyphs = del(r.glyphs) |
end |
r.glyphs = glyphs |
local newGlyphs = r.glyphs and r.glyphs[r.active] |
if (newGlyphs ~= oldGlyphs) then |
self.events:Fire("LibGroupTalents_GlyphUpdate", guid, r.unit) |
end |
return |
end |
end |
del(glyphs) |
end |
-- GetUnitGlyphs |
function lib:GetUnitGlyphs(unit, group) |
return self:GetGUIDGlyphs(UnitGUID(unit), group) |
end |
-- GetGUIDGlyphs |
function lib:GetGUIDGlyphs(guid, group) |
local r = self.roster[guid] |
if (r) then |
local g = r.glyphs and r.glyphs[group or r.active] |
if (g) then |
local temp = new(strsplit(",", g)) |
for i,str in ipairs(temp) do |
temp[i] = tonumber(str) |
end |
local a, b, c, d, e, f = unpack(temp) |
del(temp) |
return a, b, c, d, e, f |
end |
end |
end |
-- UnitHasGlyph |
function lib:UnitHasGlyph(unit, glyphID, group) |
return lib:GUIDHasGlyph(UnitGUID(unit), glyphID, group) |
end |
-- GUIDHasGlyph |
function lib:GUIDHasGlyph(guid, glyphID, group) |
local ret |
local r = self.roster[guid] |
if (r) then |
local g = r.glyphs and r.glyphs[group or r.active] |
if (g) then |
local temp = new(strsplit(",", g)) |
for i,str in ipairs(temp) do |
local id = tonumber(str) |
if (type(glyphID) == "number") then |
if (glyphID == id) then |
ret = true |
break |
end |
else |
if (glyphID == GetSpellInfo(id)) then |
ret = true |
break |
end |
end |
end |
del(temp) |
end |
end |
return ret |
end |
-- GLYPH_ADDED |
function lib:GLYPH_ADDED(index, a, b, c) |
self:RefreshPlayerGlyphs() |
end |
-- GLYPH_REMOVED |
function lib:GLYPH_REMOVED(index, a, b, c) |
self:RefreshPlayerGlyphs() |
end |
-- GLYPH_UPDATED |
function lib:GLYPH_UPDATED(index, a, b, c) |
self:RefreshPlayerGlyphs() |
end |
-- RefreshPlayerGlyphs |
function lib:RefreshPlayerGlyphs() |
local guid = UnitGUID("player") |
local r = self.roster[guid] |
if (not r) then |
return |
end |
local glyphs = new() |
local any |
for talentGroup = 1,GetNumTalentGroups() do |
local list = new() |
for i = 1,GetNumGlyphSockets() do |
local enabled, glyphType, glyphSpell, icon = GetGlyphSocketInfo(i, talentGroup) |
if (enabled and glyphType and glyphSpell) then |
tinsert(list, glyphSpell) |
any = true |
end |
end |
glyphs[talentGroup] = table.concat(list, ",") |
del(list) |
end |
local oldGlyphs = r.glyphs |
if (any) then |
r.glyphs = glyphs |
else |
del(glyphs) |
end |
local change = (oldGlyphs and oldGlyphs[r.active]) ~= (r.glyphs and r.glyphs[r.active]) |
if (change) then |
self:SendMyGlyphs() |
self.events:Fire("LibGroupTalents_GlyphUpdate", guid, "player") |
end |
del(oldGlyphs) |
end |
-- PLAYER_TALENT_UPDATE |
function lib:PLAYER_TALENT_UPDATE() |
self:TriggerRefreshTalents(UnitGUID("player"), 2) |
end |
-- UNIT_SPELLCAST_SUCCEEDED |
function lib:UNIT_SPELLCAST_SUCCEEDED(unit, spell) |
local newActiveGroup = specChangers[spell] |
if (newActiveGroup) then |
local guid = UnitGUID(unit) |
local r = guid and self.roster[guid] |
if (r) then |
if (newActiveGroup == r.active) then |
-- We obviously didn't see them switch from this set |
self:GetGUIDRole(guid, true) |
return |
end |
if (r.talents) then |
local oldSet = r.talents[r.active] |
local newSet = r.talents[newActiveGroup] |
if (oldSet and newSet) then |
-- We have the other talent set, so no need to refresh anything. Just compare and notify |
r.active = newActiveGroup |
local oldSpec, o1, o2, o3 = TalentWeight(oldSet, r.class) |
local newSpec, n1, n2, n3 = TalentWeight(newSet, r.class) |
if (o1 ~= n1 or o2 ~= n2 or o3 ~= n3) then |
self.events:Fire("LibGroupTalents_Update", guid, unit, newSpec, n1, n2, n3, oldSpec, o1, o2, o3) |
else |
self.events:Fire("LibGroupTalents_Update", guid, unit, newSpec, n1, n2, n3) |
end |
self:GetGUIDRole(guid, true) |
return |
end |
end |
-- If we get this far, then someone probably gated to respec |
self:RefreshTalentsByGUID(guid) |
end |
end |
end |
-- TriggerRefreshTalents |
function lib:TriggerRefreshTalents(guid, delay) |
if (not self.talentTimers) then |
self.talentTimers = new() |
end |
if (guid) then |
self.talentTimers[guid] = GetTime() + delay |
frame:Show() |
end |
end |
-- RefreshTalentsByUnit |
function lib:RefreshTalentsByUnit(unit) |
local guid = UnitGUID(unit) |
if (guid) then |
self:RefreshTalentsByGUID(guid) |
end |
end |
-- RefreshTalentsByGUID |
function lib:RefreshTalentsByGUID(guid) |
local r = self.roster[guid] |
if (not r) then |
return |
end |
if (not ValidateUnit(r, guid)) then |
return |
end |
if (self.talentTimers) then |
self.talentTimers[guid] = nil |
end |
if (not self.talentThrottle) then |
self.talentThrottle = {} |
end |
for guidThrottle,when in pairs(self.talentThrottle) do |
if (when < GetTime() - 5) then |
self.talentThrottle[guidThrottle] = nil |
elseif (guid == guidThrottle) then |
return |
end |
end |
self.talentThrottle[guid] = GetTime() |
if (self.commQueried) then |
self.commQueried[guid] = nil |
if (not next(self.commQueried)) then |
self.commQueried = del(self.commQueried) |
end |
end |
r.refresh = true |
self:CheckForMissingTalents() |
if (UnitGUID("player") == guid) then |
self:SendMyTalents() |
end |
end |
-- CheckForMissingTalents |
function lib:CheckForMissingTalents() |
local any |
for guid,info in pairs(self.roster) do |
if (not info.talents or (not UnitIsVisible(info.name) and UnitExists(info.name)) or info.refresh) then |
any = true |
info.refresh = nil |
self:GetUnitTalents(info.unit, true) |
end |
end |
if (any) then |
lib.refreshCheckTimer = 15 |
frame:Show() |
end |
end |
do |
local survivalOfTheFittest = GetSpellInfo(33853) -- Survival of the Fittest |
local protectorOfThePack = GetSpellInfo(57873) -- Protector of the Pack |
local dkBladeBarrier = GetSpellInfo(49182) -- Blade Barrier |
local dkToughness = GetSpellInfo(49042) -- Toughness |
local dkAnticipation = GetSpellInfo(55129) -- Anticipation |
-- GetUnitRole |
function lib:GetUnitRole(unit, reset) |
local guid = UnitGUID(unit) |
if (guid) then |
return self:GetGUIDRole(guid, reset) |
end |
end |
-- GetGUIDRole |
function lib:GetGUIDRole(guid, reset) |
local r = guid and self.roster[guid] |
if (not r) then |
return |
end |
if (r.role and not reset) then |
return r.role |
end |
if (not ValidateUnit(r, guid)) then |
return |
end |
local class = r.class |
local role |
local unit = r.unit |
if (class == "ROGUE" or class == "HUNTER") then |
role = "melee" |
elseif (class == "MAGE" or class == "WARLOCK") then |
role = "caster" |
elseif (r.talents and r.talents[r.active]) then |
if (class == "DEATHKNIGHT") then |
local score = self:GUIDHasTalent(guid, dkBladeBarrier) and 1 or 0 |
score = score + (self:GUIDHasTalent(guid, dkToughness) and 1 or 0) |
score = score + (self:GUIDHasTalent(guid, dkAnticipation) and 1 or 0) |
role = score >= 2 and "tank" or "melee" -- Has 2 of the 3 tanking talents at least |
else |
local specName, t1, t2, t3 = TalentWeight(r.talents[r.active], class) |
if (class == "PRIEST") then |
role = ((t1 + t2) > t3) and "healer" or "caster" |
elseif (class == "WARRIOR") then |
role = ((t1 + t2) > t3) and "melee" or "tank" |
else |
local heavy = (t1 > t2 and t1 > t3 and 1) or (t2 > t1 and t2 > t3 and 2) or (t3 > t1 and t3 > t2 and 3) or 0 |
if (class == "PALADIN") then |
role = heavy == 1 and "healer" or heavy == 2 and "tank" or heavy == 3 and "melee" |
elseif (class == "DRUID") then |
if (heavy == 2) then |
if (self:GUIDHasTalent(guid, survivalOfTheFittest) and self:GUIDHasTalent(guid, protectorOfThePack)) then |
role = "tank" |
else |
role = "melee" |
end |
else |
role = heavy == 1 and "caster" or "healer" |
end |
elseif (class == "SHAMAN") then |
role = heavy == 1 and "caster" or heavy == 2 and "melee" or heavy == 3 and "healer" |
end |
end |
end |
end |
local oldrole = r.role |
r.role = role |
if (role and role ~= oldrole) then |
self.events:Fire("LibGroupTalents_RoleChange", guid, unit, role, oldrole) |
end |
return role |
end |
end |
-- GetUnitTalents |
function lib:GetUnitTalents(unit, refetch) |
local guid = UnitGUID(unit) |
if (not guid) then |
return |
end |
return self:GetGUIDTalents(guid, refetch) |
end |
-- CanCommQuery |
local function CanCommQuery(guid) |
if (not lib.commQueried or not lib.commQueried[guid]) then |
if (not lib.commQueried) then |
lib.commQueried = new() |
end |
lib.commQueried[guid] = true |
return true |
end |
end |
-- GetGUIDTalents |
function lib:GetGUIDTalents(guid, refetch) |
local r = self.roster[guid] |
if (not r) then |
return |
end |
if (not ValidateUnit(r, guid)) then |
return |
end |
local unit = r.unit |
local name, realm = UnitName(unit) |
local activeTalents = r.talents and r.talents[r.active] |
if (activeTalents) then |
-- If someone is out of sight, we won't catch their talent swap spell cast, so we'll invalidate them here and recheck talents |
if ((not UnitIsVisible(unit) and UnitIsConnected(unit)) or (self.outOfSight and self.outOfSight[guid])) then |
if (not r.version) then |
refetch = true |
end |
end |
end |
if (not activeTalents or refetch) then |
if (UnitIsUnit("player", unit)) then |
self:RefreshPlayerGlyphs() |
self:TalentQuery_Ready(nil, name, nil, unit) |
elseif ((UnitInRaid(unit) or UnitInParty(unit)) and UnitIsConnected(unit)) then |
TalentQuery:Query(unit) |
local namerealm = UnitFullName(unit) |
if (not r.talents and not r.requested) then |
-- Don't need to query on a 'refetch' because they'll send changes anyway via comms |
local skipGlyphs |
if (not UnitIsVisible(unit) or not CanInspect(unit)) then |
if (r.version) then |
if (CanCommQuery(guid)) then |
-- We request talents via comms for anyone that may be out of inspect range |
self:SendCommMessage("REQUESTTALENTS", namerealm) |
r.requested = true |
skipGlyphs = true |
end |
end |
end |
end |
if (not r.glyphs and not skipGlyphs) then |
if (r.version and r.version >= 15) then |
if (CanCommQuery(guid)) then |
-- They're in range to inspect, but we'll still want to ask for their glyphs |
self:SendCommMessage("REQUESTGLYPHS", namerealm) |
end |
end |
end |
end |
if (self.outOfSight) then |
self.outOfSight[guid] = nil |
end |
end |
return activeTalents |
end |
-- SendCommMessage |
function lib:SendCommMessage(msg, target, channel) |
if (msg) then |
if (ChatThrottleLib) then |
ChatThrottleLib:SendAddonMessage("NORMAL", MAJOR, msg, channel or "WHISPER", target) |
else |
SendAddonMessage(MAJOR, msg, channel or "WHISPER", target) |
end |
end |
end |
-- Throttle - Purposely local to here |
-- Abuse prevention. Yes, who would abuse addon comms? Noone would make a macro to crash a mod user would they. Right? |
-- Well, this one time, at band camp. Someone thought it was super funny to make a macro that DCd PallyPower users |
local throttle |
local function Throttle(sender, key) |
if (not throttle) then |
throttle = {} |
end |
local s = throttle[sender] |
if (not s) then |
s = {} |
throttle[sender] = s |
end |
if ((s[key] or 0) < GetTime() - 4.5) then |
-- Same message key only allowable once every 4.5 secs from 1 person (Respec cast time is 5 seconds) |
s[key] = GetTime() |
return true |
end |
end |
-- CHAT_MSG_ADDON |
function lib:CHAT_MSG_ADDON(prefix, msg, channel, sender) |
if (prefix == MAJOR) then |
if (sender == UnitName("player")) then |
return |
elseif (not UnitInRaid(sender) and not UnitInParty(sender)) then |
return |
end |
local guid = UnitGUID(sender) |
if (not guid) then |
return |
end |
local r = self.roster[guid] |
if (not r) then |
return |
end |
local cmd, str = msg:match("^(%a+) *(.*)$") |
if (not cmd) then |
return |
end |
if (cmd == "TALENTS") then |
-- Talents come in form of: |
local t = r.talents |
r.talents = nil -- SetStorageString won't overwrite talents usually, but we want it to here, without providing a means to do it easily with an arg from a mod |
if (not self:SetStorageString(str, sender)) then |
r.talents = t |
else |
deepDel(t) |
end |
elseif (cmd == "GLYPHS") then |
local invalid |
local pages = new(strsplit(";", str)) |
local glyphs = new() |
for page,info in ipairs(pages) do |
local list = new(strsplit(",", info)) |
local tab = tonumber(tremove(list, 1)) |
if (tab) then |
glyphs[tab] = table.concat(list, ",") |
del(list) |
else |
invalid = true |
del(glyphs) |
del(list) |
break |
end |
end |
if (not invalid) then |
self:OnReceiveGlyphs(guid, sender, glyphs) |
end |
del(pages) |
elseif (cmd == "REQUESTTALENTS") then |
if (Throttle(sender, "REQUESTTALENTS")) then |
if ((r.version or 0) < 39) then |
if (lib.sentToOld and lib.sentToOld[guid]) then |
return |
end |
if (not lib.sentToOld) then |
lib.sentToOld = new() |
end |
lib.sentToOld[guid] = time() |
end |
self:SendMyTalents(sender) |
self:SendMyGlyphs(sender) |
end |
elseif (cmd == "REQUESTGLYPHS") then |
if (Throttle(sender, "REQUESTGLYPHS")) then |
self:SendMyGlyphs(sender) |
end |
elseif (cmd == "HELLO") then |
r.version = tonumber(str) |
if (channel ~= "WHISPER") then |
if (lib.sentToOld) then |
lib.sentToOld[guid] = nil |
end |
if (UnitIsConnected(sender) and Throttle(sender, "HELLO")) then |
self:SendCommMessage("HELLO "..MINOR, sender) |
self:SendMyGlyphs(sender) |
end |
end |
end |
end |
end |
-- SendMy |
local function SendMy(sender, str) |
if (sender) then |
if (UnitIsConnected(sender)) then |
lib:SendCommMessage(str, sender) |
end |
else |
for guid,info in pairs(lib.roster) do |
if (info.version and UnitIsConnected(info.name)) then |
lib:SendCommMessage(str, info.name) |
end |
end |
end |
end |
-- SendMyTalents |
function lib:SendMyTalents(sender) |
if (sender or self:UserCount() > 0) then |
local str = self:GetGUIDStorageString(UnitGUID("player")) |
if (str) then |
SendMy(sender, "TALENTS "..str) |
end |
end |
end |
-- SendMyGlyphs |
function lib:SendMyGlyphs(sender) |
if (sender or self:UserCount() > 0) then |
local r = self.roster[UnitGUID("player")] |
if (r and r.glyphs) then |
local str = "GLYPHS " |
local i = 1 |
for tab,g in pairs(r.glyphs) do |
local temp = format("%d,%s", tab, g) |
str = str .. (i > 1 and ";" or "") .. temp |
i = i + 1 |
end |
SendMy(sender, str) |
end |
end |
end |
-- UserCount |
function lib:UserCount() |
local count = 0 |
for guid,info in pairs(self.roster) do |
if (info.version and not UnitIsUnit("player", info.name)) then |
count = count + 1 |
end |
end |
return count |
end |
-- UnitHasTalent |
-- eg: lib:UnitHasTalent("player", GetSpellInfo(talentSpellID)) |
-- Returns: nil, or number of points spent into talent |
-- If the talent group is not specified, then the active talent group is used |
function lib:UnitHasTalent(unit, talentName, group) |
return unit and self:GUIDHasTalent(UnitGUID(unit), talentName, group) |
end |
-- GUIDHasTalent |
-- Returns: nil, or number of points spent into talent |
function lib:GUIDHasTalent(guid, talentName, group) |
local talents, r = GetGUIDTalentsRaw(guid, group) |
if (talents and r.class) then |
local data = self.classTalentData[r.class] |
if (data) then |
local info = data.list and data.list[talentName] |
if (info) then |
local str = talents[info.treeIndex] |
if (str) then |
local amount = (str:byte(info.index) or 48) - 48 |
return (amount or 0) > 0 and amount or nil |
end |
end |
end |
end |
end |
-- GetClassTalentInfo |
function lib:GetClassTalentInfo(class, talentName) |
-- Returns: Max Rank, Icon, Tab, Tier, Column, Tree Index |
local data = self.classTalentData[class] |
if (data) then |
local info = data.list and data.list[talentName] |
if (info) then |
return info.maxRank, info.icon, info.treeIndex, info.column, info.tier, info.index |
end |
end |
end |
-- GetActiveTalentGroup |
function lib:GetActiveTalentGroup(unit) |
if (UnitIsUnit(unit, "player")) then |
return GetActiveTalentGroup() |
else |
local guid = unit and UnitGUID(unit) |
local r = guid and self.roster[guid] |
return r and r.active or nil |
end |
end |
-- GetNumTalentGroups |
function lib:GetNumTalentGroups(unit) |
if (UnitIsUnit(unit, "player")) then |
return GetNumTalentGroups() |
else |
local guid = unit and UnitGUID(unit) |
local r = guid and self.roster[guid] |
return r and r.numActive or nil |
end |
end |
-- GetTalentTabInfo |
function lib:GetTalentTabInfo(unit, tab, group) |
if (UnitIsUnit(unit, "player")) then |
return GetTalentTabInfo(tab, nil, nil, group or GetActiveTalentGroup()) |
else |
local guid = unit and UnitGUID(unit) |
local r = guid and self.roster[guid] |
if (r and r.class) then |
local ctd = self.classTalentData[r.class] |
if (ctd and tab >= 1 and tab <= #ctd) then |
local spec, c1, c2, c3 = self:GetGUIDTalentSpec(guid, group) |
return ctd[tab].name, ctd[tab].icon, tab == 1 and c1 or tab == 2 and c2 or c3, ctd[tab].background, 0 |
end |
end |
end |
end |
-- GetNumTalents |
function lib:GetNumTalents(unit, tab) |
if (UnitIsUnit(unit, "player")) then |
return GetNumTalents(tab) |
else |
local _, class = UnitClass(unit) |
if (class) then |
local ctd = self.classTalentData[class] |
if (ctd and tab >= 1 and tab <= #ctd) then |
return #ctd[tab].list |
end |
end |
end |
end |
-- GetTalentInfo |
function lib:GetTalentInfo(unit, tab, index, group) |
if (UnitIsUnit(unit, "player")) then |
return GetTalentInfo(tab, index, nil, nil, group or GetActiveTalentGroup()) |
else |
local _, class = UnitClass(unit) |
if (class) then |
local ctd = self.classTalentData[class] |
if (ctd and tab >= 1 and tab <= #ctd) then |
local info = ctd[tab].list[index] |
if (info) then |
local spent = self:UnitHasTalent(unit, info.name, group) |
return info.name, info.icon, info.tier, info.column, spent or 0, info.maxRank |
end |
end |
end |
end |
end |
-- GetNumTalentTabs |
function lib:GetNumTalentTabs() |
return GetNumTalentTabs() |
end |
-- GetNumTalentTabs |
function lib:GetUnspentTalentPoints(unit, group) |
if (UnitIsUnit(unit, "player")) then |
return GetUnspentTalentPoints(nil, nil, group) |
else |
local guid = unit and UnitGUID(unit) |
local r = guid and self.roster[guid] |
if (r) then |
return r.unspent and r.unspent[group or r.active or 1] |
end |
end |
end |
-- GetTalentCount |
function lib:GetTalentCount() |
local count, missing = 0, 0 |
for guid,info in pairs(self.roster) do |
if (info.talents) then |
count = count + 1 |
else |
missing = missing + 1 |
end |
end |
return count, missing |
end |
-- GetTalentMissingNames |
function lib:GetTalentMissingNames() |
local list = new() |
for unit in self:IterateRoster() do |
local guid = UnitGUID(unit) |
local r = guid and self.roster[guid] |
if (not r or not r.talents) then |
tinsert(list, UnitFullName(unit)) |
end |
end |
local ret |
if (next(list)) then |
ret = table.concat(list, ",") |
end |
del(list) |
return ret |
end |
-- PurgeAndRescanTalents |
function lib:PurgeAndRescanTalents() |
if (self.roster) then |
wipe(self.pendingStorageStrings) |
for guid,info in pairs(self.roster) do |
info.talents = del(info.talents) |
info.active = nil |
info.numActive = nil |
info.requested = nil |
end |
end |
self:CheckForMissingTalents() |
end |
-- Roster iterator |
do |
local function iter(t) |
local key = t.id |
local ret |
if (t.mode == "raid") then |
if (key > t.r) then |
del(t) |
return nil |
end |
ret = "raid"..key |
else |
if (key > t.p) then |
del(t) |
return nil |
end |
ret = key == 0 and "player" or "party"..key |
end |
t.id = key + 1 |
return ret |
end |
-- IterateRoster |
function lib:IterateRoster() |
local t = new() |
if (GetNumRaidMembers() > 0) then |
t.mode = "raid" |
t.id = 1 |
t.r = GetNumRaidMembers() |
else |
t.mode = "party" |
t.id = 0 |
t.p = GetNumPartyMembers() |
end |
return iter, t |
end |
end |
## Interface: 30300 |
## LoadOnDemand: 1 |
## Title: Lib: GroupTalents-1.0 |
## Notes: Library to help with querying unit talents. |
## Author: Zek |
## Version: $Rev: 51 $ |
## OptionalDeps: Ace3, LibTalentQuery-1.0 |
## X-Category: Library |
## X-ReleaseDate: $Date$ |
## X-Website: http://wowace.com/wiki/LibGroupTalents-1.0 |
## X-License: MIT |
## X-Curse-Packaged-Version: r53 |
## X-Curse-Project-Name: LibGroupTalents-1.0 |
## X-Curse-Project-ID: libgrouptalents-1-0 |
## X-Curse-Repository-ID: wow/libgrouptalents-1-0/mainline |
lib.xml |
<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="LibGroupTalents-1.0.lua"/> |
</Ui> |